diff --git a/.azure/pipelines/quarantined-pr.yml b/.azure/pipelines/quarantined-pr.yml index d6e4b61ed2..adcff0e305 100644 --- a/.azure/pipelines/quarantined-pr.yml +++ b/.azure/pipelines/quarantined-pr.yml @@ -28,7 +28,7 @@ jobs: jobName: Helix_quarantined_x64 jobDisplayName: 'Tests: Helix' agentOs: Windows - timeoutInMinutes: 240 + timeoutInMinutes: 120 steps: # Build the shared framework - script: ./build.cmd -ci -nobl -all -pack -arch x64 /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log @@ -53,7 +53,7 @@ jobs: jobName: Windows_Quarantined_x64 jobDisplayName: 'Tests: Windows x64' agentOs: Windows - timeoutInMinutes: 240 + timeoutInMinutes: 90 isTestingJob: true steps: - powershell: "& ./build.ps1 -CI -nobl -all -pack -NoBuildJava" @@ -86,7 +86,7 @@ jobs: jobName: MacOS_Quarantined_Test jobDisplayName: "Tests: macOS 10.14" agentOs: macOS - timeoutInMinutes: 240 + timeoutInMinutes: 60 isTestingJob: true steps: - bash: ./build.sh --all --pack --ci --nobl --no-build-java @@ -119,7 +119,7 @@ jobs: jobName: Linux_Quarantined_Test jobDisplayName: "Tests: Ubuntu 16.04 x64" agentOs: Linux - timeoutInMinutes: 240 + timeoutInMinutes: 60 isTestingJob: true useHostedUbuntu: false steps: diff --git a/AspNetCore.sln b/AspNetCore.sln index 968ff850f8..f7535666dd 100644 --- a/AspNetCore.sln +++ b/AspNetCore.sln @@ -393,10 +393,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HttpOverrides", "HttpOverri EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpOverrides", "src\Middleware\HttpOverrides\src\Microsoft.AspNetCore.HttpOverrides.csproj", "{34F24889-22D2-40A1-A2AB-A43B9061FE0D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NodeServices", "NodeServices", "{ED90A0D9-867B-4212-846F-3E09D60A5B7E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.NodeServices", "src\Middleware\NodeServices\src\Microsoft.AspNetCore.NodeServices.csproj", "{C68A3531-E47A-4F2F-842E-4A3A7C844CC1}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ResponseCompression", "ResponseCompression", "{512EFCA7-1590-492A-8D06-84744F79DA91}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ResponseCompression", "src\Middleware\ResponseCompression\src\Microsoft.AspNetCore.ResponseCompression.csproj", "{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}" @@ -405,10 +401,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SpaServices.Extensions", "S 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}") = "SpaServices", "SpaServices", "{1EBEF6FF-4A0D-4668-A9F3-74587ECAC969}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices", "src\Middleware\SpaServices\src\Microsoft.AspNetCore.SpaServices.csproj", "{797B9228-5BC9-4C0C-B444-C490A98D057E}" -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}" @@ -493,10 +485,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication.Msal", "Auth EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Authentication.WebAssembly.Msal", "src\Components\WebAssembly\Authentication.Msal\src\Microsoft.Authentication.WebAssembly.Msal.csproj", "{09F72EF0-2BDE-4B73-B116-A87E38C432FE}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DebugProxy", "DebugProxy", "{F01E5B0D-1277-481D-8879-41A87F3F9524}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.DebugProxy", "src\Components\WebAssembly\DebugProxy\src\Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj", "{67F51062-6897-4019-AA88-6BDB5E30B015}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JSInterop", "JSInterop", "{44161B20-CC30-403A-AC94-247592ED7590}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.JSInterop.WebAssembly", "src\Components\WebAssembly\JSInterop\src\Microsoft.JSInterop.WebAssembly.csproj", "{E0B1F2AA-4EBA-4DC7-92D5-2F081354C8DE}" @@ -839,12 +827,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HttpSys", "HttpSys", "{166E EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.HttpSys", "src\Servers\HttpSys\src\Microsoft.AspNetCore.Server.HttpSys.csproj", "{AC0CBDEB-B750-4B81-AEC3-F218A384FB16}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{81AF139E-F3BB-46FD-B8DB-93A645E5222C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NodeServicesExamples", "src\Middleware\NodeServices\samples\NodeServicesExamples\NodeServicesExamples.csproj", "{49EAD781-92BF-4863-9159-08674548D1BE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.NodeServices.Tests", "src\Middleware\NodeServices\test\Microsoft.AspNetCore.NodeServices.Tests.csproj", "{F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HeaderPropagation", "HeaderPropagation", "{5527E368-FD50-4E8C-B8D8-C3D1374BE4F1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HeaderPropagation", "src\Middleware\HeaderPropagation\src\Microsoft.AspNetCore.HeaderPropagation.csproj", "{EC7CA990-BB0E-44AF-81B6-44E0E27FDE9B}" @@ -877,8 +859,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{EE65018D-F 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.SpaServices.Tests", "src\Middleware\SpaServices\test\Microsoft.AspNetCore.SpaServices.Tests.csproj", "{81E8CF5B-F285-40C6-B935-6E5F7AA7A072}" -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}") = "MusicStore", "MusicStore", "{884AED21-7931-42A3-B08A-E58F7B0D6E7F}" @@ -1063,7 +1043,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor. EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AspNetCore.Razor.Tools", "Microsoft.AspNetCore.Razor.Tools", "{B9704650-5360-416C-9393-FAF707766AA8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Tools", "src\Razor\Microsoft.AspNetCore.Razor.Tools\src\rzc.csproj", "{4C84173F-5C1F-49A1-895A-C0CA11DE84B1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "rzc", "src\Razor\Microsoft.AspNetCore.Razor.Tools\src\rzc.csproj", "{4C84173F-5C1F-49A1-895A-C0CA11DE84B1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Tools.Test", "src\Razor\Microsoft.AspNetCore.Razor.Tools\test\Microsoft.AspNetCore.Razor.Tools.Test.csproj", "{FE095F11-4CD2-406D-A2BB-1BE569603BF0}" EndProject @@ -1295,7 +1275,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDes EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GetDocumentInsider", "GetDocumentInsider", "{A1B75FC7-A777-4412-A635-D0C9ED8FE7A0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GetDocumentInsider", "src\Tools\GetDocumentInsider\src\GetDocument.Insider.csproj", "{DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GetDocument.Insider", "src\Tools\GetDocumentInsider\src\GetDocument.Insider.csproj", "{DD63EA3C-929C-48FF-8E8A-8F3CC553E93B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.ApiDescription.Client.Tests", "src\Tools\Extensions.ApiDescription.Client\test\Microsoft.Extensions.ApiDescription.Client.Tests.csproj", "{34E40892-48C1-4D3D-AB49-FAC3C4C00B42}" EndProject @@ -1415,8 +1395,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web.Extensions", "Web.Exten EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.Web.Extensions", "src\Components\Web.Extensions\src\Microsoft.AspNetCore.Components.Web.Extensions.csproj", "{8294A74F-7DAA-4B69-BC56-7634D93C9693}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.Web.Extensions.Tests", "src\Components\Web.Extensions\test\Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj", "{157605CB-5170-4C1A-980F-4BAE42DB60DE}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{FED4267E-E5E4-49C5-98DB-8B3F203596EE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.BlazorWebAssembly", "src\Components\WebAssembly\Sdk\src\Microsoft.NET.Sdk.BlazorWebAssembly.csproj", "{6B2734BF-C61D-4889-ABBF-456A4075D59B}" @@ -1509,6 +1487,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagno EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.JSInterop.Tests", "src\JSInterop\Microsoft.JSInterop\test\Microsoft.JSInterop.Tests.csproj", "{DAAB6B35-CBD2-4573-B633-CDD42F583A0E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProtectedBrowserStorage", "ProtectedBrowserStorage", "{1B06FD32-3A1D-46A4-B2AF-99159FAD8127}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.ProtectedBrowserStorage", "src\Components\ProtectedBrowserStorage\src\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj", "{9059AC97-7547-4CC1-A076-680CBCCC1F33}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests", "src\Components\ProtectedBrowserStorage\test\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj", "{943FD3EC-D330-4277-B3F3-3DFABB57D3B5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.KeyPerFile", "src\Configuration.KeyPerFile\src\Microsoft.Extensions.Configuration.KeyPerFile.csproj", "{498A4F54-F11A-46C5-A58D-09DE56C6A034}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration.KeyPerFile", "Configuration.KeyPerFile", "{AEB1933E-9369-4305-B20E-F186F888158F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.KeyPerFile.Tests", "src\Configuration.KeyPerFile\test\Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj", "{B9D37BCF-80D1-489D-9FC6-55191FDBB033}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Manifest.MSBuildTask", "Manifest.MSBuildTask", "{8C15FD04-7F90-43FC-B488-023432FE3CE1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.FileProviders.Embedded.Manifest.Task", "src\FileProviders\Manifest.MSBuildTask\src\Microsoft.Extensions.FileProviders.Embedded.Manifest.Task.csproj", "{37329855-01B8-4B03-9765-1A941B06E43C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.FileProviders.Embedded.Manifest.Task.Tests", "src\FileProviders\Manifest.MSBuildTask\test\Microsoft.Extensions.FileProviders.Embedded.Manifest.Task.Tests.csproj", "{D3246226-BC1A-47F1-8E3E-C3380A8F13FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.FileProviders.Embedded.Tests", "src\FileProviders\Embedded\test\Microsoft.Extensions.FileProviders.Embedded.Tests.csproj", "{B06ADD57-E855-4D8C-85DC-B323509AE540}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2623,18 +2620,6 @@ Global {34F24889-22D2-40A1-A2AB-A43B9061FE0D}.Release|x64.Build.0 = Release|Any CPU {34F24889-22D2-40A1-A2AB-A43B9061FE0D}.Release|x86.ActiveCfg = Release|Any CPU {34F24889-22D2-40A1-A2AB-A43B9061FE0D}.Release|x86.Build.0 = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|x64.ActiveCfg = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|x64.Build.0 = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|x86.ActiveCfg = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Debug|x86.Build.0 = Debug|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|Any CPU.Build.0 = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|x64.ActiveCfg = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|x64.Build.0 = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|x86.ActiveCfg = Release|Any CPU - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1}.Release|x86.Build.0 = Release|Any CPU {CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -2659,18 +2644,6 @@ Global {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 - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|x64.ActiveCfg = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|x64.Build.0 = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|x86.ActiveCfg = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Debug|x86.Build.0 = Debug|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Release|Any CPU.Build.0 = Release|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Release|x64.ActiveCfg = Release|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Release|x64.Build.0 = Release|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.Release|x86.ActiveCfg = Release|Any CPU - {797B9228-5BC9-4C0C-B444-C490A98D057E}.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 @@ -2935,18 +2908,6 @@ Global {09F72EF0-2BDE-4B73-B116-A87E38C432FE}.Release|x64.Build.0 = Release|Any CPU {09F72EF0-2BDE-4B73-B116-A87E38C432FE}.Release|x86.ActiveCfg = Release|Any CPU {09F72EF0-2BDE-4B73-B116-A87E38C432FE}.Release|x86.Build.0 = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|x64.ActiveCfg = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|x64.Build.0 = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|x86.ActiveCfg = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Debug|x86.Build.0 = Debug|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|Any CPU.Build.0 = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|x64.ActiveCfg = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|x64.Build.0 = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|x86.ActiveCfg = Release|Any CPU - {67F51062-6897-4019-AA88-6BDB5E30B015}.Release|x86.Build.0 = Release|Any CPU {E0B1F2AA-4EBA-4DC7-92D5-2F081354C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E0B1F2AA-4EBA-4DC7-92D5-2F081354C8DE}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0B1F2AA-4EBA-4DC7-92D5-2F081354C8DE}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -4303,30 +4264,6 @@ Global {AC0CBDEB-B750-4B81-AEC3-F218A384FB16}.Release|x64.Build.0 = Release|Any CPU {AC0CBDEB-B750-4B81-AEC3-F218A384FB16}.Release|x86.ActiveCfg = Release|Any CPU {AC0CBDEB-B750-4B81-AEC3-F218A384FB16}.Release|x86.Build.0 = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|x64.ActiveCfg = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|x64.Build.0 = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|x86.ActiveCfg = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Debug|x86.Build.0 = Debug|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|Any CPU.Build.0 = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|x64.ActiveCfg = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|x64.Build.0 = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|x86.ActiveCfg = Release|Any CPU - {49EAD781-92BF-4863-9159-08674548D1BE}.Release|x86.Build.0 = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|x64.ActiveCfg = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|x64.Build.0 = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|x86.ActiveCfg = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Debug|x86.Build.0 = Debug|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|Any CPU.Build.0 = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|x64.ActiveCfg = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|x64.Build.0 = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|x86.ActiveCfg = Release|Any CPU - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F}.Release|x86.Build.0 = Release|Any CPU {EC7CA990-BB0E-44AF-81B6-44E0E27FDE9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EC7CA990-BB0E-44AF-81B6-44E0E27FDE9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {EC7CA990-BB0E-44AF-81B6-44E0E27FDE9B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -4447,18 +4384,6 @@ Global {A8E1962B-688E-44B3-81F3-BBB9891534CE}.Release|x64.Build.0 = Release|Any CPU {A8E1962B-688E-44B3-81F3-BBB9891534CE}.Release|x86.ActiveCfg = Release|Any CPU {A8E1962B-688E-44B3-81F3-BBB9891534CE}.Release|x86.Build.0 = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|Any CPU.Build.0 = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|x64.ActiveCfg = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|x64.Build.0 = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|x86.ActiveCfg = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Debug|x86.Build.0 = Debug|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|Any CPU.ActiveCfg = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|Any CPU.Build.0 = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|x64.ActiveCfg = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|x64.Build.0 = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|x86.ActiveCfg = Release|Any CPU - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072}.Release|x86.Build.0 = Release|Any CPU {8A745E35-8098-4EB4-AC55-587B9F0DC4BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8A745E35-8098-4EB4-AC55-587B9F0DC4BE}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A745E35-8098-4EB4-AC55-587B9F0DC4BE}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -6751,18 +6676,6 @@ Global {8294A74F-7DAA-4B69-BC56-7634D93C9693}.Release|x64.Build.0 = Release|Any CPU {8294A74F-7DAA-4B69-BC56-7634D93C9693}.Release|x86.ActiveCfg = Release|Any CPU {8294A74F-7DAA-4B69-BC56-7634D93C9693}.Release|x86.Build.0 = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|x64.ActiveCfg = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|x64.Build.0 = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|x86.ActiveCfg = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Debug|x86.Build.0 = Debug|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|Any CPU.Build.0 = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|x64.ActiveCfg = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|x64.Build.0 = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|x86.ActiveCfg = Release|Any CPU - {157605CB-5170-4C1A-980F-4BAE42DB60DE}.Release|x86.Build.0 = Release|Any CPU {6B2734BF-C61D-4889-ABBF-456A4075D59B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6B2734BF-C61D-4889-ABBF-456A4075D59B}.Debug|Any CPU.Build.0 = Debug|Any CPU {6B2734BF-C61D-4889-ABBF-456A4075D59B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -7193,6 +7106,90 @@ Global {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x64.Build.0 = Release|Any CPU {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x86.ActiveCfg = Release|Any CPU {DAAB6B35-CBD2-4573-B633-CDD42F583A0E}.Release|x86.Build.0 = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|x64.ActiveCfg = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|x64.Build.0 = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|x86.ActiveCfg = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Debug|x86.Build.0 = Debug|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|Any CPU.Build.0 = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|x64.ActiveCfg = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|x64.Build.0 = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|x86.ActiveCfg = Release|Any CPU + {9059AC97-7547-4CC1-A076-680CBCCC1F33}.Release|x86.Build.0 = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|x64.Build.0 = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|x86.ActiveCfg = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Debug|x86.Build.0 = Debug|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|Any CPU.Build.0 = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|x64.ActiveCfg = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|x64.Build.0 = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|x86.ActiveCfg = Release|Any CPU + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5}.Release|x86.Build.0 = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|Any CPU.Build.0 = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|x64.ActiveCfg = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|x64.Build.0 = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|x86.ActiveCfg = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Debug|x86.Build.0 = Debug|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|Any CPU.ActiveCfg = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|Any CPU.Build.0 = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|x64.ActiveCfg = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|x64.Build.0 = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|x86.ActiveCfg = Release|Any CPU + {498A4F54-F11A-46C5-A58D-09DE56C6A034}.Release|x86.Build.0 = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|x64.ActiveCfg = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|x64.Build.0 = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|x86.ActiveCfg = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Debug|x86.Build.0 = Debug|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|Any CPU.Build.0 = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|x64.ActiveCfg = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|x64.Build.0 = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|x86.ActiveCfg = Release|Any CPU + {B9D37BCF-80D1-489D-9FC6-55191FDBB033}.Release|x86.Build.0 = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|x64.ActiveCfg = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|x64.Build.0 = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|x86.ActiveCfg = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Debug|x86.Build.0 = Debug|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|Any CPU.Build.0 = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|x64.ActiveCfg = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|x64.Build.0 = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|x86.ActiveCfg = Release|Any CPU + {37329855-01B8-4B03-9765-1A941B06E43C}.Release|x86.Build.0 = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|x64.ActiveCfg = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|x64.Build.0 = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|x86.ActiveCfg = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Debug|x86.Build.0 = Debug|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|Any CPU.Build.0 = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|x64.ActiveCfg = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|x64.Build.0 = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|x86.ActiveCfg = Release|Any CPU + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB}.Release|x86.Build.0 = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|x64.ActiveCfg = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|x64.Build.0 = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|x86.ActiveCfg = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Debug|x86.Build.0 = Debug|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|Any CPU.Build.0 = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|x64.ActiveCfg = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|x64.Build.0 = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|x86.ActiveCfg = Release|Any CPU + {B06ADD57-E855-4D8C-85DC-B323509AE540}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -7391,14 +7388,10 @@ Global {7FC5CFC7-9BFE-4C19-90DE-A84A76A8E03D} = {58915BB2-CEF5-4CA3-8886-A61156564505} {39086512-EBC8-4061-BE34-DCCA5D1BA585} = {E5963C9F-20A6-4385-B364-814D2581FADF} {34F24889-22D2-40A1-A2AB-A43B9061FE0D} = {39086512-EBC8-4061-BE34-DCCA5D1BA585} - {ED90A0D9-867B-4212-846F-3E09D60A5B7E} = {E5963C9F-20A6-4385-B364-814D2581FADF} - {C68A3531-E47A-4F2F-842E-4A3A7C844CC1} = {ED90A0D9-867B-4212-846F-3E09D60A5B7E} {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} - {1EBEF6FF-4A0D-4668-A9F3-74587ECAC969} = {E5963C9F-20A6-4385-B364-814D2581FADF} - {797B9228-5BC9-4C0C-B444-C490A98D057E} = {1EBEF6FF-4A0D-4668-A9F3-74587ECAC969} {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} @@ -7441,8 +7434,6 @@ Global {0C610220-E00C-4752-98A0-44A3D4B96A21} = {13683DEB-FB7E-4F20-ACB2-015381943541} {1FD5F261-6384-4AE1-A6DA-4D08A0BCE1CF} = {562D5067-8CD8-4F19-BCBB-873204932C61} {09F72EF0-2BDE-4B73-B116-A87E38C432FE} = {1FD5F261-6384-4AE1-A6DA-4D08A0BCE1CF} - {F01E5B0D-1277-481D-8879-41A87F3F9524} = {562D5067-8CD8-4F19-BCBB-873204932C61} - {67F51062-6897-4019-AA88-6BDB5E30B015} = {F01E5B0D-1277-481D-8879-41A87F3F9524} {44161B20-CC30-403A-AC94-247592ED7590} = {562D5067-8CD8-4F19-BCBB-873204932C61} {E0B1F2AA-4EBA-4DC7-92D5-2F081354C8DE} = {44161B20-CC30-403A-AC94-247592ED7590} {E33C36A1-481C-4A93-BCBE-22CCBA53349B} = {562D5067-8CD8-4F19-BCBB-873204932C61} @@ -7614,9 +7605,6 @@ Global {A01B523B-35CA-4C14-B792-3887F8741E99} = {48BEABD3-2446-466C-8694-D34EF0949369} {166E48ED-9738-4E13-8618-0D805F6F0F65} = {0ACCEDA7-339C-4B4D-8DD4-1AC271F31C04} {AC0CBDEB-B750-4B81-AEC3-F218A384FB16} = {166E48ED-9738-4E13-8618-0D805F6F0F65} - {81AF139E-F3BB-46FD-B8DB-93A645E5222C} = {ED90A0D9-867B-4212-846F-3E09D60A5B7E} - {49EAD781-92BF-4863-9159-08674548D1BE} = {81AF139E-F3BB-46FD-B8DB-93A645E5222C} - {F7E4CC45-B553-4D58-8B3E-B9F426FAF67F} = {ED90A0D9-867B-4212-846F-3E09D60A5B7E} {5527E368-FD50-4E8C-B8D8-C3D1374BE4F1} = {E5963C9F-20A6-4385-B364-814D2581FADF} {EC7CA990-BB0E-44AF-81B6-44E0E27FDE9B} = {5527E368-FD50-4E8C-B8D8-C3D1374BE4F1} {399AC9FB-7DCA-4868-B299-2EE4C88D41AD} = {5527E368-FD50-4E8C-B8D8-C3D1374BE4F1} @@ -7633,7 +7621,6 @@ Global {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} - {81E8CF5B-F285-40C6-B935-6E5F7AA7A072} = {1EBEF6FF-4A0D-4668-A9F3-74587ECAC969} {8A745E35-8098-4EB4-AC55-587B9F0DC4BE} = {EE65018D-FA12-461D-B2C5-44CA6E385530} {884AED21-7931-42A3-B08A-E58F7B0D6E7F} = {017429CC-C5FB-48B4-9C46-034E29EE2F06} {8DA88110-5A13-41A9-9F9D-674D921EB442} = {884AED21-7931-42A3-B08A-E58F7B0D6E7F} @@ -7902,7 +7889,6 @@ Global {1542DC58-1836-4191-A9C5-51D1716D2543} = {05A169C7-4F20-4516-B10A-B13C5649D346} {F71FE795-9923-461B-9809-BB1821A276D0} = {60D51C98-2CC0-40DF-B338-44154EFEE2FF} {8294A74F-7DAA-4B69-BC56-7634D93C9693} = {F71FE795-9923-461B-9809-BB1821A276D0} - {157605CB-5170-4C1A-980F-4BAE42DB60DE} = {F71FE795-9923-461B-9809-BB1821A276D0} {FED4267E-E5E4-49C5-98DB-8B3F203596EE} = {562D5067-8CD8-4F19-BCBB-873204932C61} {6B2734BF-C61D-4889-ABBF-456A4075D59B} = {FED4267E-E5E4-49C5-98DB-8B3F203596EE} {83371889-9A3E-4D16-AE77-EB4F83BC6374} = {FED4267E-E5E4-49C5-98DB-8B3F203596EE} @@ -7949,6 +7935,16 @@ Global {55CACC1F-FE96-47C8-8073-91F4CAA55C75} = {2A91479A-4ABE-4BB7-9A5E-CA3B9CCFC69E} {7509AA1E-3093-4BEE-984F-E11579E98A11} = {7CB09412-C9B0-47E8-A8C3-311AA4CFDE04} {DAAB6B35-CBD2-4573-B633-CDD42F583A0E} = {16898702-3E33-41C1-B8D8-4CE3F1D46BD9} + {1B06FD32-3A1D-46A4-B2AF-99159FAD8127} = {60D51C98-2CC0-40DF-B338-44154EFEE2FF} + {9059AC97-7547-4CC1-A076-680CBCCC1F33} = {1B06FD32-3A1D-46A4-B2AF-99159FAD8127} + {943FD3EC-D330-4277-B3F3-3DFABB57D3B5} = {1B06FD32-3A1D-46A4-B2AF-99159FAD8127} + {498A4F54-F11A-46C5-A58D-09DE56C6A034} = {AEB1933E-9369-4305-B20E-F186F888158F} + {AEB1933E-9369-4305-B20E-F186F888158F} = {017429CC-C5FB-48B4-9C46-034E29EE2F06} + {B9D37BCF-80D1-489D-9FC6-55191FDBB033} = {AEB1933E-9369-4305-B20E-F186F888158F} + {8C15FD04-7F90-43FC-B488-023432FE3CE1} = {FED63417-432B-49CD-AB4B-44ADA837C2E7} + {37329855-01B8-4B03-9765-1A941B06E43C} = {8C15FD04-7F90-43FC-B488-023432FE3CE1} + {D3246226-BC1A-47F1-8E3E-C3380A8F13FB} = {8C15FD04-7F90-43FC-B488-023432FE3CE1} + {B06ADD57-E855-4D8C-85DC-B323509AE540} = {898F7E0B-1671-42CB-9DFB-689AFF212ED3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F} diff --git a/Directory.Build.props b/Directory.Build.props index 520064f60c..9fef8a526e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -88,8 +88,12 @@ true - + net5.0 + net461 diff --git a/Directory.Build.targets b/Directory.Build.targets index d4a4e9a2a0..34e36b4b06 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -134,14 +134,20 @@ $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).0.0 + + $(DefaultNetCoreTargetFramework) + netcoreapp$(TargetFrameworkVersion.TrimStart('vV')) + + - $(MicrosoftNETCoreAppRuntimeVersion) + $(MicrosoftNETCoreAppRuntimeVersion) - $(MicrosoftNETCoreAppRuntimeVersion) + $(MicrosoftNETCoreAppRuntimeVersion) - $(MicrosoftNETCoreAppRefPackageVersion) + $(MicrosoftNETCoreAppRefPackageVersion) diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props index c4f0bf31d3..d3894b52f0 100644 --- a/eng/Baseline.Designer.props +++ b/eng/Baseline.Designer.props @@ -8,12 +8,10 @@ 3.0.3 - 3.0.3 - 3.1.7 @@ -29,7 +27,7 @@ 3.1.7 - + @@ -48,7 +46,7 @@ 3.1.7 - + @@ -56,7 +54,7 @@ 3.1.7 - + @@ -64,53 +62,48 @@ 3.1.7 - 3.1.7 - 3.1.7 - 3.1.7 - + 3.1.7 - 3.1.7 - + 3.1.7 - + 3.1.7 - 3.1.7 - + @@ -118,7 +111,7 @@ 3.1.7 - + @@ -132,7 +125,7 @@ 3.1.7 - + @@ -147,7 +140,7 @@ 3.1.7 - + @@ -160,7 +153,7 @@ - + @@ -173,7 +166,7 @@ 3.1.7 - + @@ -185,7 +178,7 @@ 3.1.7 - + @@ -196,7 +189,7 @@ 3.1.7 - + @@ -230,7 +223,6 @@ 3.2.1 - 3.2.1 @@ -243,7 +235,6 @@ 3.2.1 - 3.2.1 @@ -255,7 +246,7 @@ 3.1.7 - + @@ -263,7 +254,7 @@ 3.1.7 - + @@ -280,8 +271,6 @@ 3.1.7 - - 3.1.7 @@ -289,7 +278,7 @@ - + @@ -299,7 +288,7 @@ 3.1.7 - + @@ -324,8 +313,6 @@ 3.1.7 - - 3.1.7 @@ -356,7 +343,7 @@ 3.1.7 - + @@ -376,14 +363,14 @@ 3.1.7 - + 3.1.7 - + @@ -391,7 +378,7 @@ 3.1.7 - + @@ -412,7 +399,7 @@ 3.1.7 - + @@ -423,7 +410,7 @@ 3.1.7 - + @@ -435,7 +422,7 @@ 3.1.7 - + @@ -447,7 +434,7 @@ 3.1.7 - + @@ -458,7 +445,7 @@ 3.1.7 - + @@ -475,20 +462,18 @@ 3.1.7 - - 3.1.7 - + 3.1.7 - + @@ -497,7 +482,7 @@ 3.1.7 - + @@ -506,7 +491,7 @@ 3.1.7 - + @@ -515,7 +500,7 @@ 3.1.7 - + @@ -523,12 +508,11 @@ 3.1.7 - 3.1.7 - + @@ -565,7 +549,7 @@ 3.1.7 - + @@ -578,7 +562,7 @@ 3.1.7 - + @@ -604,7 +588,7 @@ 3.1.7 - + @@ -616,7 +600,7 @@ 3.1.7 - + @@ -625,14 +609,14 @@ 3.1.7 - + 3.1.7 - + @@ -640,7 +624,7 @@ 3.1.7 - + @@ -684,7 +668,7 @@ 3.1.7 - + @@ -698,7 +682,7 @@ 3.1.7 - + diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 68e1f6149c..c242829120 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -69,6 +69,7 @@ and are generated based on the last package release. + @@ -123,6 +124,7 @@ and are generated based on the last package release. + @@ -166,7 +168,6 @@ and are generated based on the last package release. - diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props index 96983d78af..0e0a9a7c79 100644 --- a/eng/ProjectReferences.props +++ b/eng/ProjectReferences.props @@ -86,14 +86,12 @@ - - @@ -142,6 +140,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index db9cc55f62..fa6b0d6f03 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,313 +13,321 @@ https://github.com/dotnet/blazor cc449601d638ffaab58ae9487f0fd010bb178a12 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/efcore - 9638c0cda4bfb2eb8b70a047baefc982ffa7dade + a87a862e78a4eb37a9662e86074531b86b36a277 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 + + + https://github.com/dotnet/runtime + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/runtime - f4e99f4afa445b519abcd7c5c87cbf54771614db + 54e597d3a5c2b6c0e9dc556a79bba08fb0c67eb9 - + https://github.com/dotnet/arcade - 56a95cc477558c1ccdf16d7abe962849ea970ba4 + 4be47e467013f8a07a1ed7b6e49e39c8150bde54 - + https://github.com/dotnet/arcade - 56a95cc477558c1ccdf16d7abe962849ea970ba4 + 4be47e467013f8a07a1ed7b6e49e39c8150bde54 + + + https://github.com/dotnet/arcade + 4be47e467013f8a07a1ed7b6e49e39c8150bde54 https://github.com/dotnet/roslyn diff --git a/eng/Versions.props b/eng/Versions.props index 9c2fd0000e..3215d890f0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -64,84 +64,87 @@ 3.8.0-2.20407.3 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 - 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 + 5.0.0-rc.1.20451.2 - 5.0.0-rc.1.20425.1 + 5.0.0-rc.1.20451.2 3.2.0 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 - 5.0.0-rc.1.20425.4 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + 5.0.0-rc.1.20451.1 + + 5.0.0-beta.20431.1 + 2.1.1 2.2.0 - 3.1.3-servicing-20163-14 + 3.1.7-servicing-20372-13 $(MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion) $(MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion) @@ -258,9 +262,8 @@ 4.0.4 4.0.4 2.1.90 - 0.2.1-preview - 0.2.1-preview - 3.8.0 + 0.3.1-preview + 0.3.1-preview $(MessagePackPackageVersion) 4.10.0 0.11.2 diff --git a/eng/Workarounds.targets b/eng/Workarounds.targets index a2cc87f1a0..863e0c4716 100644 --- a/eng/Workarounds.targets +++ b/eng/Workarounds.targets @@ -22,7 +22,9 @@ - + @@ -40,11 +42,6 @@ - - $(DefaultNetCoreTargetFramework) - netcoreapp5.0 - - Sets warnaserror msbuild parameter ('true' or 'false')" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host " -useDefaultDotnetInstall Use dotnet-install.* scripts from public location as opposed to from eng common folder" Write-Host "" Write-Host "Command line arguments not listed above are passed thru to msbuild." diff --git a/eng/common/build.sh b/eng/common/build.sh index 6d7c5a1f69..19849adbee 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -36,6 +36,8 @@ usage() echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo " --useDefaultDotnetInstall Use dotnet-install.* scripts from public location as opposed to from eng common folder" + echo "" echo "Command line arguments not listed above are passed thru to msbuild." echo "Arguments can also be passed in with a single hyphen." @@ -76,9 +78,11 @@ projects='' configuration='Debug' prepare_machine=false verbosity='minimal' +runtime_source_feed='' +runtime_source_feed_key='' +use_default_dotnet_install=false properties='' - while [[ $# > 0 ]]; do opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" case "$opt" in @@ -151,6 +155,18 @@ while [[ $# > 0 ]]; do node_reuse=$2 shift ;; + -runtimesourcefeed) + runtime_source_feed=$2 + shift + ;; + -runtimesourcefeedkey) + runtime_source_feed_key=$2 + shift + ;; + -usedefaultdotnetinstall) + use_default_dotnet_install=$2 + shift + ;; *) properties="$properties $1" ;; diff --git a/eng/common/cross/armel/tizen-build-rootfs.sh b/eng/common/cross/armel/tizen-build-rootfs.sh index 25a0efa0bd..9a4438af61 100755 --- a/eng/common/cross/armel/tizen-build-rootfs.sh +++ b/eng/common/cross/armel/tizen-build-rootfs.sh @@ -30,8 +30,6 @@ rm -rf $TIZEN_TMP_DIR # Configure Tizen rootfs echo ">>Start configuring Tizen rootfs" -rm ./usr/lib/libunwind.so -ln -s libunwind.so.8 ./usr/lib/libunwind.so ln -sfn asm-arm ./usr/include/asm patch -p1 < $__TIZEN_CROSSDIR/tizen.patch echo "< - this value represents currently running OS architecture + Architecture of dotnet binaries to be installed. + Possible values are: , amd64, x64, x86, arm64, arm +.PARAMETER SharedRuntime + This parameter is obsolete and may be removed in a future version of this script. + The recommended alternative is '-Runtime dotnet'. + Installs just the shared runtime bits, not the entire SDK. +.PARAMETER Runtime + Installs just a shared runtime, not the entire SDK. + Possible values: + - dotnet - the Microsoft.NETCore.App shared runtime + - aspnetcore - the Microsoft.AspNetCore.App shared runtime + - windowsdesktop - the Microsoft.WindowsDesktop.App shared runtime +.PARAMETER DryRun + If set it will not perform installation but instead display what command line to use to consistently install + currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link + with specific version so that this command can be used deterministicly in a build script. + It also displays binaries location if you prefer to install or download it yourself. +.PARAMETER NoPath + By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder. + If set it will display binaries location but not set any environment variable. +.PARAMETER Verbose + Displays diagnostics information. +.PARAMETER AzureFeed + Default: https://dotnetcli.azureedge.net/dotnet + This parameter typically is not changed by the user. + It allows changing the URL for the Azure feed used by this installer. +.PARAMETER UncachedFeed + This parameter typically is not changed by the user. + It allows changing the URL for the Uncached feed used by this installer. +.PARAMETER FeedCredential + Used as a query string to append to the Azure feed. + It allows changing the URL to use non-public blob storage accounts. +.PARAMETER ProxyAddress + If set, the installer will use the proxy when making web requests +.PARAMETER ProxyUseDefaultCredentials + Default: false + Use default credentials, when using proxy address. +.PARAMETER ProxyBypassList + If set with ProxyAddress, will provide the list of comma separated urls that will bypass the proxy +.PARAMETER SkipNonVersionedFiles + Default: false + Skips installing non-versioned files if they already exist, such as dotnet.exe. +.PARAMETER NoCdn + Disable downloading from the Azure CDN, and use the uncached feed directly. +.PARAMETER JSonFile + Determines the SDK version from a user specified global.json file + Note: global.json must have a value for 'SDK:Version' +#> +[cmdletbinding()] +param( + [string]$Channel="LTS", + [string]$Version="Latest", + [string]$JSonFile, + [string]$InstallDir="", + [string]$Architecture="", + [ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)] + [string]$Runtime, + [Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")] + [switch]$SharedRuntime, + [switch]$DryRun, + [switch]$NoPath, + [string]$AzureFeed="https://dotnetcli.azureedge.net/dotnet", + [string]$UncachedFeed="https://dotnetcli.blob.core.windows.net/dotnet", + [string]$FeedCredential, + [string]$ProxyAddress, + [switch]$ProxyUseDefaultCredentials, + [string[]]$ProxyBypassList=@(), + [switch]$SkipNonVersionedFiles, + [switch]$NoCdn +) + +Set-StrictMode -Version Latest +$ErrorActionPreference="Stop" +$ProgressPreference="SilentlyContinue" + +if ($NoCdn) { + $AzureFeed = $UncachedFeed +} + +$BinFolderRelativePath="" + +if ($SharedRuntime -and (-not $Runtime)) { + $Runtime = "dotnet" +} + +# example path with regex: shared/1.0.0-beta-12345/somepath +$VersionRegEx="/\d+\.\d+[^/]+/" +$OverrideNonVersionedFiles = !$SkipNonVersionedFiles + +function Say($str) { + try + { + Write-Host "dotnet-install: $str" + } + catch + { + # Some platforms cannot utilize Write-Host (Azure Functions, for instance). Fall back to Write-Output + Write-Output "dotnet-install: $str" + } +} + +function Say-Verbose($str) { + try + { + Write-Verbose "dotnet-install: $str" + } + catch + { + # Some platforms cannot utilize Write-Verbose (Azure Functions, for instance). Fall back to Write-Output + Write-Output "dotnet-install: $str" + } +} + +function Say-Invocation($Invocation) { + $command = $Invocation.MyCommand; + $args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ") + Say-Verbose "$command $args" +} + +function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) { + $Attempts = 0 + + while ($true) { + try { + return $ScriptBlock.Invoke() + } + catch { + $Attempts++ + if ($Attempts -lt $MaxAttempts) { + Start-Sleep $SecondsBetweenAttempts + } + else { + throw + } + } + } +} + +function Get-Machine-Architecture() { + Say-Invocation $MyInvocation + + # On PS x86, PROCESSOR_ARCHITECTURE reports x86 even on x64 systems. + # To get the correct architecture, we need to use PROCESSOR_ARCHITEW6432. + # PS x64 doesn't define this, so we fall back to PROCESSOR_ARCHITECTURE. + # Possible values: amd64, x64, x86, arm64, arm + + if( $ENV:PROCESSOR_ARCHITEW6432 -ne $null ) + { + return $ENV:PROCESSOR_ARCHITEW6432 + } + + return $ENV:PROCESSOR_ARCHITECTURE +} + +function Get-CLIArchitecture-From-Architecture([string]$Architecture) { + Say-Invocation $MyInvocation + + switch ($Architecture.ToLower()) { + { $_ -eq "" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) } + { ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" } + { $_ -eq "x86" } { return "x86" } + { $_ -eq "arm" } { return "arm" } + { $_ -eq "arm64" } { return "arm64" } + default { throw "Architecture not supported. If you think this is a bug, report it at https://github.com/dotnet/sdk/issues" } + } +} + +# The version text returned from the feeds is a 1-line or 2-line string: +# For the SDK and the dotnet runtime (2 lines): +# Line 1: # commit_hash +# Line 2: # 4-part version +# For the aspnetcore runtime (1 line): +# Line 1: # 4-part version +function Get-Version-Info-From-Version-Text([string]$VersionText) { + Say-Invocation $MyInvocation + + $Data = -split $VersionText + + $VersionInfo = @{ + CommitHash = $(if ($Data.Count -gt 1) { $Data[0] }) + Version = $Data[-1] # last line is always the version number. + } + return $VersionInfo +} + +function Load-Assembly([string] $Assembly) { + try { + Add-Type -Assembly $Assembly | Out-Null + } + catch { + # On Nano Server, Powershell Core Edition is used. Add-Type is unable to resolve base class assemblies because they are not GAC'd. + # Loading the base class assemblies is not unnecessary as the types will automatically get resolved. + } +} + +function GetHTTPResponse([Uri] $Uri) +{ + Invoke-With-Retry( + { + + $HttpClient = $null + + try { + # HttpClient is used vs Invoke-WebRequest in order to support Nano Server which doesn't support the Invoke-WebRequest cmdlet. + Load-Assembly -Assembly System.Net.Http + + if(-not $ProxyAddress) { + try { + # Despite no proxy being explicitly specified, we may still be behind a default proxy + $DefaultProxy = [System.Net.WebRequest]::DefaultWebProxy; + if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { + $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString + $ProxyUseDefaultCredentials = $true + } + } catch { + # Eat the exception and move forward as the above code is an attempt + # at resolving the DefaultProxy that may not have been a problem. + $ProxyAddress = $null + Say-Verbose("Exception ignored: $_.Exception.Message - moving forward...") + } + } + + if($ProxyAddress) { + $HttpClientHandler = New-Object System.Net.Http.HttpClientHandler + $HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{ + Address=$ProxyAddress; + UseDefaultCredentials=$ProxyUseDefaultCredentials; + BypassList = $ProxyBypassList; + } + $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler + } + else { + + $HttpClient = New-Object System.Net.Http.HttpClient + } + # Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out + # 20 minutes allows it to work over much slower connections. + $HttpClient.Timeout = New-TimeSpan -Minutes 20 + $Response = $HttpClient.GetAsync("${Uri}${FeedCredential}").Result + if (($Response -eq $null) -or (-not ($Response.IsSuccessStatusCode))) { + # The feed credential is potentially sensitive info. Do not log FeedCredential to console output. + $ErrorMsg = "Failed to download $Uri." + if ($Response -ne $null) { + $ErrorMsg += " $Response" + } + + throw $ErrorMsg + } + + return $Response + } + finally { + if ($HttpClient -ne $null) { + $HttpClient.Dispose() + } + } + }) +} + +function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Coherent) { + Say-Invocation $MyInvocation + + $VersionFileUrl = $null + if ($Runtime -eq "dotnet") { + $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" + } + elseif ($Runtime -eq "aspnetcore") { + $VersionFileUrl = "$UncachedFeed/aspnetcore/Runtime/$Channel/latest.version" + } + # Currently, the WindowsDesktop runtime is manufactured with the .Net core runtime + elseif ($Runtime -eq "windowsdesktop") { + $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" + } + elseif (-not $Runtime) { + if ($Coherent) { + $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.coherent.version" + } + else { + $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version" + } + } + else { + throw "Invalid value for `$Runtime" + } + try { + $Response = GetHTTPResponse -Uri $VersionFileUrl + } + catch { + throw "Could not resolve version information." + } + $StringContent = $Response.Content.ReadAsStringAsync().Result + + switch ($Response.Content.Headers.ContentType) { + { ($_ -eq "application/octet-stream") } { $VersionText = $StringContent } + { ($_ -eq "text/plain") } { $VersionText = $StringContent } + { ($_ -eq "text/plain; charset=UTF-8") } { $VersionText = $StringContent } + default { throw "``$Response.Content.Headers.ContentType`` is an unknown .version file content type." } + } + + $VersionInfo = Get-Version-Info-From-Version-Text $VersionText + + return $VersionInfo +} + +function Parse-Jsonfile-For-Version([string]$JSonFile) { + Say-Invocation $MyInvocation + + If (-Not (Test-Path $JSonFile)) { + throw "Unable to find '$JSonFile'" + } + try { + $JSonContent = Get-Content($JSonFile) -Raw | ConvertFrom-Json | Select-Object -expand "sdk" -ErrorAction SilentlyContinue + } + catch { + throw "Json file unreadable: '$JSonFile'" + } + if ($JSonContent) { + try { + $JSonContent.PSObject.Properties | ForEach-Object { + $PropertyName = $_.Name + if ($PropertyName -eq "version") { + $Version = $_.Value + Say-Verbose "Version = $Version" + } + } + } + catch { + throw "Unable to parse the SDK node in '$JSonFile'" + } + } + else { + throw "Unable to find the SDK node in '$JSonFile'" + } + If ($Version -eq $null) { + throw "Unable to find the SDK:version node in '$JSonFile'" + } + return $Version +} + +function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version, [string]$JSonFile) { + Say-Invocation $MyInvocation + + if (-not $JSonFile) { + switch ($Version.ToLower()) { + { $_ -eq "latest" } { + $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False + return $LatestVersionInfo.Version + } + { $_ -eq "coherent" } { + $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True + return $LatestVersionInfo.Version + } + default { return $Version } + } + } + else { + return Parse-Jsonfile-For-Version $JSonFile + } +} + +function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) { + Say-Invocation $MyInvocation + + # If anything fails in this lookup it will default to $SpecificVersion + $SpecificProductVersion = Get-Product-Version -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion + + if ($Runtime -eq "dotnet") { + $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip" + } + elseif ($Runtime -eq "aspnetcore") { + $PayloadURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/aspnetcore-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip" + } + elseif ($Runtime -eq "windowsdesktop") { + $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip" + } + elseif (-not $Runtime) { + $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificProductVersion-win-$CLIArchitecture.zip" + } + else { + throw "Invalid value for `$Runtime" + } + + Say-Verbose "Constructed primary named payload URL: $PayloadURL" + + return $PayloadURL, $SpecificProductVersion +} + +function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) { + Say-Invocation $MyInvocation + + if (-not $Runtime) { + $PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-dev-win-$CLIArchitecture.$SpecificVersion.zip" + } + elseif ($Runtime -eq "dotnet") { + $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-win-$CLIArchitecture.$SpecificVersion.zip" + } + else { + return $null + } + + Say-Verbose "Constructed legacy named payload URL: $PayloadURL" + + return $PayloadURL +} + +function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) { + Say-Invocation $MyInvocation + + if ($Runtime -eq "dotnet") { + $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt" + } + elseif ($Runtime -eq "aspnetcore") { + $ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/productVersion.txt" + } + elseif ($Runtime -eq "windowsdesktop") { + $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt" + } + elseif (-not $Runtime) { + $ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/productVersion.txt" + } + else { + throw "Invalid value specified for `$Runtime" + } + + Say-Verbose "Checking for existence of $ProductVersionTxtURL" + + try { + $productVersionResponse = GetHTTPResponse($productVersionTxtUrl) + + if ($productVersionResponse.StatusCode -eq 200) { + $productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim() + if ($productVersion -ne $SpecificVersion) + { + Say "Using alternate version $productVersion found in $ProductVersionTxtURL" + } + + return $productVersion + } + else { + Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) trying to get productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion" + $productVersion = $SpecificVersion + } + } catch { + Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion" + $productVersion = $SpecificVersion + } + + return $productVersion +} + +function Get-User-Share-Path() { + Say-Invocation $MyInvocation + + $InstallRoot = $env:DOTNET_INSTALL_DIR + if (!$InstallRoot) { + $InstallRoot = "$env:LocalAppData\Microsoft\dotnet" + } + return $InstallRoot +} + +function Resolve-Installation-Path([string]$InstallDir) { + Say-Invocation $MyInvocation + + if ($InstallDir -eq "") { + return Get-User-Share-Path + } + return $InstallDir +} + +function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) { + Say-Invocation $MyInvocation + + $DotnetPackagePath = Join-Path -Path $InstallRoot -ChildPath $RelativePathToPackage | Join-Path -ChildPath $SpecificVersion + Say-Verbose "Is-Dotnet-Package-Installed: DotnetPackagePath=$DotnetPackagePath" + return Test-Path $DotnetPackagePath -PathType Container +} + +function Get-Absolute-Path([string]$RelativeOrAbsolutePath) { + # Too much spam + # Say-Invocation $MyInvocation + + return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($RelativeOrAbsolutePath) +} + +function Get-Path-Prefix-With-Version($path) { + $match = [regex]::match($path, $VersionRegEx) + if ($match.Success) { + return $entry.FullName.Substring(0, $match.Index + $match.Length) + } + + return $null +} + +function Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package([System.IO.Compression.ZipArchive]$Zip, [string]$OutPath) { + Say-Invocation $MyInvocation + + $ret = @() + foreach ($entry in $Zip.Entries) { + $dir = Get-Path-Prefix-With-Version $entry.FullName + if ($dir -ne $null) { + $path = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $dir) + if (-Not (Test-Path $path -PathType Container)) { + $ret += $dir + } + } + } + + $ret = $ret | Sort-Object | Get-Unique + + $values = ($ret | foreach { "$_" }) -join ";" + Say-Verbose "Directories to unpack: $values" + + return $ret +} + +# Example zip content and extraction algorithm: +# Rule: files if extracted are always being extracted to the same relative path locally +# .\ +# a.exe # file does not exist locally, extract +# b.dll # file exists locally, override only if $OverrideFiles set +# aaa\ # same rules as for files +# ... +# abc\1.0.0\ # directory contains version and exists locally +# ... # do not extract content under versioned part +# abc\asd\ # same rules as for files +# ... +# def\ghi\1.0.1\ # directory contains version and does not exist locally +# ... # extract content +function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) { + Say-Invocation $MyInvocation + + Load-Assembly -Assembly System.IO.Compression.FileSystem + Set-Variable -Name Zip + try { + $Zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath) + + $DirectoriesToUnpack = Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package -Zip $Zip -OutPath $OutPath + + foreach ($entry in $Zip.Entries) { + $PathWithVersion = Get-Path-Prefix-With-Version $entry.FullName + if (($PathWithVersion -eq $null) -Or ($DirectoriesToUnpack -contains $PathWithVersion)) { + $DestinationPath = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $entry.FullName) + $DestinationDir = Split-Path -Parent $DestinationPath + $OverrideFiles=$OverrideNonVersionedFiles -Or (-Not (Test-Path $DestinationPath)) + if ((-Not $DestinationPath.EndsWith("\")) -And $OverrideFiles) { + New-Item -ItemType Directory -Force -Path $DestinationDir | Out-Null + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $DestinationPath, $OverrideNonVersionedFiles) + } + } + } + } + finally { + if ($Zip -ne $null) { + $Zip.Dispose() + } + } +} + +function DownloadFile($Source, [string]$OutPath) { + if ($Source -notlike "http*") { + # Using System.IO.Path.GetFullPath to get the current directory + # does not work in this context - $pwd gives the current directory + if (![System.IO.Path]::IsPathRooted($Source)) { + $Source = $(Join-Path -Path $pwd -ChildPath $Source) + } + $Source = Get-Absolute-Path $Source + Say "Copying file from $Source to $OutPath" + Copy-Item $Source $OutPath + return + } + + $Stream = $null + + try { + $Response = GetHTTPResponse -Uri $Source + $Stream = $Response.Content.ReadAsStreamAsync().Result + $File = [System.IO.File]::Create($OutPath) + $Stream.CopyTo($File) + $File.Close() + } + finally { + if ($Stream -ne $null) { + $Stream.Dispose() + } + } +} + +function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolderRelativePath) { + $BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath) + if (-Not $NoPath) { + $SuffixedBinPath = "$BinPath;" + if (-Not $env:path.Contains($SuffixedBinPath)) { + Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process." + $env:path = $SuffixedBinPath + $env:path + } else { + Say-Verbose "Current process PATH already contains `"$BinPath`"" + } + } + else { + Say "Binaries of dotnet can be found in $BinPath" + } +} + +$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture +$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile +$DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture +$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture + +$InstallRoot = Resolve-Installation-Path $InstallDir +Say-Verbose "InstallRoot: $InstallRoot" +$ScriptName = $MyInvocation.MyCommand.Name + +if ($DryRun) { + Say "Payload URLs:" + Say "Primary named payload URL: $DownloadLink" + if ($LegacyDownloadLink) { + Say "Legacy named payload URL: $LegacyDownloadLink" + } + $RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`"" + if ($Runtime -eq "dotnet") { + $RepeatableCommand+=" -Runtime `"dotnet`"" + } + elseif ($Runtime -eq "aspnetcore") { + $RepeatableCommand+=" -Runtime `"aspnetcore`"" + } + foreach ($key in $MyInvocation.BoundParameters.Keys) { + if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version") -contains $key)) { + $RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`"" + } + } + Say "Repeatable invocation: $RepeatableCommand" + exit 0 +} + +if ($Runtime -eq "dotnet") { + $assetName = ".NET Core Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.NETCore.App" +} +elseif ($Runtime -eq "aspnetcore") { + $assetName = "ASP.NET Core Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.AspNetCore.App" +} +elseif ($Runtime -eq "windowsdesktop") { + $assetName = ".NET Core Windows Desktop Runtime" + $dotnetPackageRelativePath = "shared\Microsoft.WindowsDesktop.App" +} +elseif (-not $Runtime) { + $assetName = ".NET Core SDK" + $dotnetPackageRelativePath = "sdk" +} +else { + throw "Invalid value for `$Runtime" +} + +if ($SpecificVersion -ne $EffectiveVersion) +{ + Say "Performing installation checks for effective version: $EffectiveVersion" + $SpecificVersion = $EffectiveVersion +} + +# Check if the SDK version is already installed. +$isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion +if ($isAssetInstalled) { + Say "$assetName version $SpecificVersion is already installed." + Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath + exit 0 +} + +New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null + +$installDrive = $((Get-Item $InstallRoot).PSDrive.Name); +$diskInfo = Get-PSDrive -Name $installDrive +if ($diskInfo.Free / 1MB -le 100) { + Say "There is not enough disk space on drive ${installDrive}:" + exit 0 +} + +$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) +Say-Verbose "Zip path: $ZipPath" + +$DownloadFailed = $false +Say "Downloading link: $DownloadLink" +try { + DownloadFile -Source $DownloadLink -OutPath $ZipPath +} +catch { + Say "Cannot download: $DownloadLink" + if ($LegacyDownloadLink) { + $DownloadLink = $LegacyDownloadLink + $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) + Say-Verbose "Legacy zip path: $ZipPath" + Say "Downloading legacy link: $DownloadLink" + try { + DownloadFile -Source $DownloadLink -OutPath $ZipPath + } + catch { + Say "Cannot download: $DownloadLink" + $DownloadFailed = $true + } + } + else { + $DownloadFailed = $true + } +} + +if ($DownloadFailed) { + throw "Could not find/download: `"$assetName`" with version = $SpecificVersion`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" +} + +Say "Extracting zip from $DownloadLink" +Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot + +# Check if the SDK version is installed; if not, fail the installation. +$isAssetInstalled = $false + +# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. +if ($SpecificVersion -Match "rtm" -or $SpecificVersion -Match "servicing") { + $ReleaseVersion = $SpecificVersion.Split("-")[0] + Say-Verbose "Checking installation: version = $ReleaseVersion" + $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $ReleaseVersion +} + +# Check if the SDK version is installed. +if (!$isAssetInstalled) { + Say-Verbose "Checking installation: version = $SpecificVersion" + $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion +} + +if (!$isAssetInstalled) { + throw "`"$assetName`" with version = $SpecificVersion failed to install with an unknown error." +} + +Remove-Item $ZipPath + +Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath + +Say "Installation finished" +exit 0 \ No newline at end of file diff --git a/eng/common/dotnet-install-scripts/dotnet-install.sh b/eng/common/dotnet-install-scripts/dotnet-install.sh new file mode 100644 index 0000000000..92161141f6 --- /dev/null +++ b/eng/common/dotnet-install-scripts/dotnet-install.sh @@ -0,0 +1,1133 @@ +#!/usr/bin/env bash +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +# Stop script on NZEC +set -e +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u +# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success +# This is causing it to fail +set -o pipefail + +# Use in the the functions: eval $invocation +invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"' + +# standard output may be used as a return value in the functions +# we need a way to write text on the screen in the functions so that +# it won't interfere with the return value. +# Exposing stream 3 as a pipe to standard output of the script itself +exec 3>&1 + +# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors. +# See if stdout is a terminal +if [ -t 1 ] && command -v tput > /dev/null; then + # see if it supports colors + ncolors=$(tput colors) + if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then + bold="$(tput bold || echo)" + normal="$(tput sgr0 || echo)" + black="$(tput setaf 0 || echo)" + red="$(tput setaf 1 || echo)" + green="$(tput setaf 2 || echo)" + yellow="$(tput setaf 3 || echo)" + blue="$(tput setaf 4 || echo)" + magenta="$(tput setaf 5 || echo)" + cyan="$(tput setaf 6 || echo)" + white="$(tput setaf 7 || echo)" + fi +fi + +say_warning() { + printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}" +} + +say_err() { + printf "%b\n" "${red:-}dotnet_install: Error: $1${normal:-}" >&2 +} + +say() { + # using stream 3 (defined in the beginning) to not interfere with stdout of functions + # which may be used as return value + printf "%b\n" "${cyan:-}dotnet-install:${normal:-} $1" >&3 +} + +say_verbose() { + if [ "$verbose" = true ]; then + say "$1" + fi +} + +# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets, +# then and only then should the Linux distribution appear in this list. +# Adding a Linux distribution to this list does not imply distribution-specific support. +get_legacy_os_name_from_platform() { + eval $invocation + + platform="$1" + case "$platform" in + "centos.7") + echo "centos" + return 0 + ;; + "debian.8") + echo "debian" + return 0 + ;; + "debian.9") + echo "debian.9" + return 0 + ;; + "fedora.23") + echo "fedora.23" + return 0 + ;; + "fedora.24") + echo "fedora.24" + return 0 + ;; + "fedora.27") + echo "fedora.27" + return 0 + ;; + "fedora.28") + echo "fedora.28" + return 0 + ;; + "opensuse.13.2") + echo "opensuse.13.2" + return 0 + ;; + "opensuse.42.1") + echo "opensuse.42.1" + return 0 + ;; + "opensuse.42.3") + echo "opensuse.42.3" + return 0 + ;; + "rhel.7"*) + echo "rhel" + return 0 + ;; + "ubuntu.14.04") + echo "ubuntu" + return 0 + ;; + "ubuntu.16.04") + echo "ubuntu.16.04" + return 0 + ;; + "ubuntu.16.10") + echo "ubuntu.16.10" + return 0 + ;; + "ubuntu.18.04") + echo "ubuntu.18.04" + return 0 + ;; + "alpine.3.4.3") + echo "alpine" + return 0 + ;; + esac + return 1 +} + +get_linux_platform_name() { + eval $invocation + + if [ -n "$runtime_id" ]; then + echo "${runtime_id%-*}" + return 0 + else + if [ -e /etc/os-release ]; then + . /etc/os-release + echo "$ID${VERSION_ID:+.${VERSION_ID}}" + return 0 + elif [ -e /etc/redhat-release ]; then + local redhatRelease=$(&1 || true) | grep -q musl +} + +get_current_os_name() { + eval $invocation + + local uname=$(uname) + if [ "$uname" = "Darwin" ]; then + echo "osx" + return 0 + elif [ "$uname" = "FreeBSD" ]; then + echo "freebsd" + return 0 + elif [ "$uname" = "Linux" ]; then + local linux_platform_name + linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; } + + if [ "$linux_platform_name" = "rhel.6" ]; then + echo $linux_platform_name + return 0 + elif is_musl_based_distro; then + echo "linux-musl" + return 0 + else + echo "linux" + return 0 + fi + fi + + say_err "OS name could not be detected: UName = $uname" + return 1 +} + +get_legacy_os_name() { + eval $invocation + + local uname=$(uname) + if [ "$uname" = "Darwin" ]; then + echo "osx" + return 0 + elif [ -n "$runtime_id" ]; then + echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}") + return 0 + else + if [ -e /etc/os-release ]; then + . /etc/os-release + os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "") + if [ -n "$os" ]; then + echo "$os" + return 0 + fi + fi + fi + + say_verbose "Distribution specific OS name and version could not be detected: UName = $uname" + return 1 +} + +machine_has() { + eval $invocation + + hash "$1" > /dev/null 2>&1 + return $? +} + + +check_min_reqs() { + local hasMinimum=false + if machine_has "curl"; then + hasMinimum=true + elif machine_has "wget"; then + hasMinimum=true + fi + + if [ "$hasMinimum" = "false" ]; then + say_err "curl (recommended) or wget are required to download dotnet. Install missing prerequisite to proceed." + return 1 + fi + return 0 +} + +check_pre_reqs() { + eval $invocation + + if [ "${DOTNET_INSTALL_SKIP_PREREQS:-}" = "1" ]; then + return 0 + fi + + if [ "$(uname)" = "Linux" ]; then + if is_musl_based_distro; then + if ! command -v scanelf > /dev/null; then + say_warning "scanelf not found, please install pax-utils package." + return 0 + fi + LDCONFIG_COMMAND="scanelf --ldpath -BF '%f'" + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libintl)" ] && say_warning "Unable to locate libintl. Probable prerequisite missing; install libintl (or gettext)." + else + if [ ! -x "$(command -v ldconfig)" ]; then + say_verbose "ldconfig is not in PATH, trying /sbin/ldconfig." + LDCONFIG_COMMAND="/sbin/ldconfig" + else + LDCONFIG_COMMAND="ldconfig" + fi + local librarypath=${LD_LIBRARY_PATH:-} + LDCONFIG_COMMAND="$LDCONFIG_COMMAND -NXv ${librarypath//:/ }" + fi + + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep zlib)" ] && say_warning "Unable to locate zlib. Probable prerequisite missing; install zlib." + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep ssl)" ] && say_warning "Unable to locate libssl. Probable prerequisite missing; install libssl." + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libicu)" ] && say_warning "Unable to locate libicu. Probable prerequisite missing; install libicu." + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep lttng)" ] && say_warning "Unable to locate liblttng. Probable prerequisite missing; install libcurl." + [ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libcurl)" ] && say_warning "Unable to locate libcurl. Probable prerequisite missing; install libcurl." + fi + + return 0 +} + +# args: +# input - $1 +to_lowercase() { + #eval $invocation + + echo "$1" | tr '[:upper:]' '[:lower:]' + return 0 +} + +# args: +# input - $1 +remove_trailing_slash() { + #eval $invocation + + local input="${1:-}" + echo "${input%/}" + return 0 +} + +# args: +# input - $1 +remove_beginning_slash() { + #eval $invocation + + local input="${1:-}" + echo "${input#/}" + return 0 +} + +# args: +# root_path - $1 +# child_path - $2 - this parameter can be empty +combine_paths() { + eval $invocation + + # TODO: Consider making it work with any number of paths. For now: + if [ ! -z "${3:-}" ]; then + say_err "combine_paths: Function takes two parameters." + return 1 + fi + + local root_path="$(remove_trailing_slash "$1")" + local child_path="$(remove_beginning_slash "${2:-}")" + say_verbose "combine_paths: root_path=$root_path" + say_verbose "combine_paths: child_path=$child_path" + echo "$root_path/$child_path" + return 0 +} + +get_machine_architecture() { + eval $invocation + + if command -v uname > /dev/null; then + CPUName=$(uname -m) + case $CPUName in + armv7l) + echo "arm" + return 0 + ;; + aarch64) + echo "arm64" + return 0 + ;; + esac + fi + + # Always default to 'x64' + echo "x64" + return 0 +} + +# args: +# architecture - $1 +get_normalized_architecture_from_architecture() { + eval $invocation + + local architecture="$(to_lowercase "$1")" + case "$architecture" in + \) + echo "$(get_normalized_architecture_from_architecture "$(get_machine_architecture)")" + return 0 + ;; + amd64|x64) + echo "x64" + return 0 + ;; + arm) + echo "arm" + return 0 + ;; + arm64) + echo "arm64" + return 0 + ;; + esac + + say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/sdk/issues" + return 1 +} + +# The version text returned from the feeds is a 1-line or 2-line string: +# For the SDK and the dotnet runtime (2 lines): +# Line 1: # commit_hash +# Line 2: # 4-part version +# For the aspnetcore runtime (1 line): +# Line 1: # 4-part version + +# args: +# version_text - stdin +get_version_from_version_info() { + eval $invocation + + cat | tail -n 1 | sed 's/\r$//' + return 0 +} + +# args: +# install_root - $1 +# relative_path_to_package - $2 +# specific_version - $3 +is_dotnet_package_installed() { + eval $invocation + + local install_root="$1" + local relative_path_to_package="$2" + local specific_version="${3//[$'\t\r\n']}" + + local dotnet_package_path="$(combine_paths "$(combine_paths "$install_root" "$relative_path_to_package")" "$specific_version")" + say_verbose "is_dotnet_package_installed: dotnet_package_path=$dotnet_package_path" + + if [ -d "$dotnet_package_path" ]; then + return 0 + else + return 1 + fi +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# coherent - $4 +get_latest_version_info() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local coherent="$4" + + local version_file_url=null + if [[ "$runtime" == "dotnet" ]]; then + version_file_url="$uncached_feed/Runtime/$channel/latest.version" + elif [[ "$runtime" == "aspnetcore" ]]; then + version_file_url="$uncached_feed/aspnetcore/Runtime/$channel/latest.version" + elif [ -z "$runtime" ]; then + if [ "$coherent" = true ]; then + version_file_url="$uncached_feed/Sdk/$channel/latest.coherent.version" + else + version_file_url="$uncached_feed/Sdk/$channel/latest.version" + fi + else + say_err "Invalid value for \$runtime" + return 1 + fi + say_verbose "get_latest_version_info: latest url: $version_file_url" + + download "$version_file_url" + return $? +} + +# args: +# json_file - $1 +parse_jsonfile_for_version() { + eval $invocation + + local json_file="$1" + if [ ! -f "$json_file" ]; then + say_err "Unable to find \`$json_file\`" + return 1 + fi + + sdk_section=$(cat $json_file | awk '/"sdk"/,/}/') + if [ -z "$sdk_section" ]; then + say_err "Unable to parse the SDK node in \`$json_file\`" + return 1 + fi + + sdk_list=$(echo $sdk_section | awk -F"[{}]" '{print $2}') + sdk_list=${sdk_list//[\" ]/} + sdk_list=${sdk_list//,/$'\n'} + sdk_list="$(echo -e "${sdk_list}" | tr -d '[[:space:]]')" + + local version_info="" + while read -r line; do + IFS=: + while read -r key value; do + if [[ "$key" == "version" ]]; then + version_info=$value + fi + done <<< "$line" + done <<< "$sdk_list" + if [ -z "$version_info" ]; then + say_err "Unable to find the SDK:version node in \`$json_file\`" + return 1 + fi + + unset IFS; + echo "$version_info" + return 0 +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# version - $4 +# json_file - $5 +get_specific_version_from_version() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local version="$(to_lowercase "$4")" + local json_file="$5" + + if [ -z "$json_file" ]; then + case "$version" in + latest) + local version_info + version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1 + say_verbose "get_specific_version_from_version: version_info=$version_info" + echo "$version_info" | get_version_from_version_info + return 0 + ;; + coherent) + local version_info + version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" true)" || return 1 + say_verbose "get_specific_version_from_version: version_info=$version_info" + echo "$version_info" | get_version_from_version_info + return 0 + ;; + *) + echo "$version" + return 0 + ;; + esac + else + local version_info + version_info="$(parse_jsonfile_for_version "$json_file")" || return 1 + echo "$version_info" + return 0 + fi +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# specific_version - $4 +construct_download_link() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local specific_version="${4//[$'\t\r\n']}" + local specific_product_version="$(get_specific_product_version "$1" "$4")" + + local osname + osname="$(get_current_os_name)" || return 1 + + local download_link=null + if [[ "$runtime" == "dotnet" ]]; then + download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz" + elif [[ "$runtime" == "aspnetcore" ]]; then + download_link="$azure_feed/aspnetcore/Runtime/$specific_version/aspnetcore-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz" + elif [ -z "$runtime" ]; then + download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_product_version-$osname-$normalized_architecture.tar.gz" + else + return 1 + fi + + echo "$download_link" + return 0 +} + +# args: +# azure_feed - $1 +# specific_version - $2 +get_specific_product_version() { + # If we find a 'productVersion.txt' at the root of any folder, we'll use its contents + # to resolve the version of what's in the folder, superseding the specified version. + eval $invocation + + local azure_feed="$1" + local specific_version="${2//[$'\t\r\n']}" + local specific_product_version=$specific_version + + local download_link=null + if [[ "$runtime" == "dotnet" ]]; then + download_link="$azure_feed/Runtime/$specific_version/productVersion.txt${feed_credential}" + elif [[ "$runtime" == "aspnetcore" ]]; then + download_link="$azure_feed/aspnetcore/Runtime/$specific_version/productVersion.txt${feed_credential}" + elif [ -z "$runtime" ]; then + download_link="$azure_feed/Sdk/$specific_version/productVersion.txt${feed_credential}" + else + return 1 + fi + + specific_product_version=$(curl -s --fail "$download_link") + if [ $? -ne 0 ] + then + specific_product_version=$(wget -qO- "$download_link") + if [ $? -ne 0 ] + then + specific_product_version=$specific_version + fi + fi + specific_product_version="${specific_product_version//[$'\t\r\n']}" + + echo "$specific_product_version" + return 0 +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# specific_version - $4 +construct_legacy_download_link() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local specific_version="${4//[$'\t\r\n']}" + + local distro_specific_osname + distro_specific_osname="$(get_legacy_os_name)" || return 1 + + local legacy_download_link=null + if [[ "$runtime" == "dotnet" ]]; then + legacy_download_link="$azure_feed/Runtime/$specific_version/dotnet-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" + elif [ -z "$runtime" ]; then + legacy_download_link="$azure_feed/Sdk/$specific_version/dotnet-dev-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" + else + return 1 + fi + + echo "$legacy_download_link" + return 0 +} + +get_user_install_path() { + eval $invocation + + if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then + echo "$DOTNET_INSTALL_DIR" + else + echo "$HOME/.dotnet" + fi + return 0 +} + +# args: +# install_dir - $1 +resolve_installation_path() { + eval $invocation + + local install_dir=$1 + if [ "$install_dir" = "" ]; then + local user_install_path="$(get_user_install_path)" + say_verbose "resolve_installation_path: user_install_path=$user_install_path" + echo "$user_install_path" + return 0 + fi + + echo "$install_dir" + return 0 +} + +# args: +# relative_or_absolute_path - $1 +get_absolute_path() { + eval $invocation + + local relative_or_absolute_path=$1 + echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")" + return 0 +} + +# args: +# input_files - stdin +# root_path - $1 +# out_path - $2 +# override - $3 +copy_files_or_dirs_from_list() { + eval $invocation + + local root_path="$(remove_trailing_slash "$1")" + local out_path="$(remove_trailing_slash "$2")" + local override="$3" + local osname="$(get_current_os_name)" + local override_switch=$( + if [ "$override" = false ]; then + if [ "$osname" = "linux-musl" ]; then + printf -- "-u"; + else + printf -- "-n"; + fi + fi) + + cat | uniq | while read -r file_path; do + local path="$(remove_beginning_slash "${file_path#$root_path}")" + local target="$out_path/$path" + if [ "$override" = true ] || (! ([ -d "$target" ] || [ -e "$target" ])); then + mkdir -p "$out_path/$(dirname "$path")" + if [ -d "$target" ]; then + rm -rf "$target" + fi + cp -R $override_switch "$root_path/$path" "$target" + fi + done +} + +# args: +# zip_path - $1 +# out_path - $2 +extract_dotnet_package() { + eval $invocation + + local zip_path="$1" + local out_path="$2" + + local temp_out_path="$(mktemp -d "$temporary_file_template")" + + local failed=false + tar -xzf "$zip_path" -C "$temp_out_path" > /dev/null || failed=true + + local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/' + find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false + find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files" + + rm -rf "$temp_out_path" + + if [ "$failed" = true ]; then + say_err "Extraction failed" + return 1 + fi +} + +# args: +# remote_path - $1 +# [out_path] - $2 - stdout if not provided +download() { + eval $invocation + + local remote_path="$1" + local out_path="${2:-}" + + if [[ "$remote_path" != "http"* ]]; then + cp "$remote_path" "$out_path" + return $? + fi + + local failed=false + if machine_has "curl"; then + downloadcurl "$remote_path" "$out_path" || failed=true + elif machine_has "wget"; then + downloadwget "$remote_path" "$out_path" || failed=true + else + failed=true + fi + if [ "$failed" = true ]; then + say_verbose "Download failed: $remote_path" + return 1 + fi + return 0 +} + +downloadcurl() { + eval $invocation + local remote_path="$1" + local out_path="${2:-}" + + # Append feed_credential as late as possible before calling curl to avoid logging feed_credential + remote_path="${remote_path}${feed_credential}" + + local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs " + local failed=false + if [ -z "$out_path" ]; then + curl $curl_options "$remote_path" || failed=true + else + curl $curl_options -o "$out_path" "$remote_path" || failed=true + fi + if [ "$failed" = true ]; then + say_verbose "Curl download failed" + return 1 + fi + return 0 +} + +downloadwget() { + eval $invocation + local remote_path="$1" + local out_path="${2:-}" + + # Append feed_credential as late as possible before calling wget to avoid logging feed_credential + remote_path="${remote_path}${feed_credential}" + local wget_options="--tries 20 --waitretry 2 --connect-timeout 15 " + local failed=false + if [ -z "$out_path" ]; then + wget -q $wget_options -O - "$remote_path" || failed=true + else + wget $wget_options -O "$out_path" "$remote_path" || failed=true + fi + if [ "$failed" = true ]; then + say_verbose "Wget download failed" + return 1 + fi + return 0 +} + +calculate_vars() { + eval $invocation + valid_legacy_download_link=true + + normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")" + say_verbose "normalized_architecture=$normalized_architecture" + + specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version" "$json_file")" + specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version")" + say_verbose "specific_version=$specific_version" + if [ -z "$specific_version" ]; then + say_err "Could not resolve version information." + return 1 + fi + + download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" + say_verbose "Constructed primary named payload URL: $download_link" + + legacy_download_link="$(construct_legacy_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false + + if [ "$valid_legacy_download_link" = true ]; then + say_verbose "Constructed legacy named payload URL: $legacy_download_link" + else + say_verbose "Cound not construct a legacy_download_link; omitting..." + fi + + install_root="$(resolve_installation_path "$install_dir")" + say_verbose "InstallRoot: $install_root" +} + +install_dotnet() { + eval $invocation + local download_failed=false + local asset_name='' + local asset_relative_path='' + + if [[ "$runtime" == "dotnet" ]]; then + asset_relative_path="shared/Microsoft.NETCore.App" + asset_name=".NET Core Runtime" + elif [[ "$runtime" == "aspnetcore" ]]; then + asset_relative_path="shared/Microsoft.AspNetCore.App" + asset_name="ASP.NET Core Runtime" + elif [ -z "$runtime" ]; then + asset_relative_path="sdk" + asset_name=".NET Core SDK" + else + say_err "Invalid value for \$runtime" + return 1 + fi + + # Check if the SDK version is already installed. + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_version"; then + say "$asset_name version $specific_version is already installed." + return 0 + fi + + mkdir -p "$install_root" + zip_path="$(mktemp "$temporary_file_template")" + say_verbose "Zip path: $zip_path" + + say "Downloading link: $download_link" + + # Failures are normal in the non-legacy case for ultimately legacy downloads. + # Do not output to stderr, since output to stderr is considered an error. + download "$download_link" "$zip_path" 2>&1 || download_failed=true + + # if the download fails, download the legacy_download_link + if [ "$download_failed" = true ]; then + say "Cannot download: $download_link" + + if [ "$valid_legacy_download_link" = true ]; then + download_failed=false + download_link="$legacy_download_link" + zip_path="$(mktemp "$temporary_file_template")" + say_verbose "Legacy zip path: $zip_path" + say "Downloading legacy link: $download_link" + download "$download_link" "$zip_path" 2>&1 || download_failed=true + + if [ "$download_failed" = true ]; then + say "Cannot download: $download_link" + fi + fi + fi + + if [ "$download_failed" = true ]; then + say_err "Could not find/download: \`$asset_name\` with version = $specific_version" + say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" + return 1 + fi + + say "Extracting zip from $download_link" + extract_dotnet_package "$zip_path" "$install_root" + + # Check if the SDK version is installed; if not, fail the installation. + # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. + if [[ $specific_version == *"rtm"* || $specific_version == *"servicing"* ]]; then + IFS='-' + read -ra verArr <<< "$specific_version" + release_version="${verArr[0]}" + unset IFS; + say_verbose "Checking installation: version = $release_version" + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$release_version"; then + return 0 + fi + fi + + # Check if the standard SDK version is installed. + say_verbose "Checking installation: version = $specific_product_version" + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_product_version"; then + return 0 + fi + + say_err "\`$asset_name\` with version = $specific_product_version failed to install with an unknown error." + return 1 +} + +args=("$@") + +local_version_file_relative_path="/.version" +bin_folder_relative_path="" +temporary_file_template="${TMPDIR:-/tmp}/dotnet.XXXXXXXXX" + +channel="LTS" +version="Latest" +json_file="" +install_dir="" +architecture="" +dry_run=false +no_path=false +no_cdn=false +azure_feed="https://dotnetcli.azureedge.net/dotnet" +uncached_feed="https://dotnetcli.blob.core.windows.net/dotnet" +feed_credential="" +verbose=false +runtime="" +runtime_id="" +override_non_versioned_files=true +non_dynamic_parameters="" + +while [ $# -ne 0 ] +do + name="$1" + case "$name" in + -c|--channel|-[Cc]hannel) + shift + channel="$1" + ;; + -v|--version|-[Vv]ersion) + shift + version="$1" + ;; + -i|--install-dir|-[Ii]nstall[Dd]ir) + shift + install_dir="$1" + ;; + --arch|--architecture|-[Aa]rch|-[Aa]rchitecture) + shift + architecture="$1" + ;; + --shared-runtime|-[Ss]hared[Rr]untime) + say_warning "The --shared-runtime flag is obsolete and may be removed in a future version of this script. The recommended usage is to specify '--runtime dotnet'." + if [ -z "$runtime" ]; then + runtime="dotnet" + fi + ;; + --runtime|-[Rr]untime) + shift + runtime="$1" + if [[ "$runtime" != "dotnet" ]] && [[ "$runtime" != "aspnetcore" ]]; then + say_err "Unsupported value for --runtime: '$1'. Valid values are 'dotnet' and 'aspnetcore'." + if [[ "$runtime" == "windowsdesktop" ]]; then + say_err "WindowsDesktop archives are manufactured for Windows platforms only." + fi + exit 1 + fi + ;; + --dry-run|-[Dd]ry[Rr]un) + dry_run=true + ;; + --no-path|-[Nn]o[Pp]ath) + no_path=true + non_dynamic_parameters+=" $name" + ;; + --verbose|-[Vv]erbose) + verbose=true + non_dynamic_parameters+=" $name" + ;; + --no-cdn|-[Nn]o[Cc]dn) + no_cdn=true + non_dynamic_parameters+=" $name" + ;; + --azure-feed|-[Aa]zure[Ff]eed) + shift + azure_feed="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --uncached-feed|-[Uu]ncached[Ff]eed) + shift + uncached_feed="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --feed-credential|-[Ff]eed[Cc]redential) + shift + feed_credential="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --runtime-id|-[Rr]untime[Ii]d) + shift + runtime_id="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --jsonfile|-[Jj][Ss]on[Ff]ile) + shift + json_file="$1" + ;; + --skip-non-versioned-files|-[Ss]kip[Nn]on[Vv]ersioned[Ff]iles) + override_non_versioned_files=false + non_dynamic_parameters+=" $name" + ;; + -?|--?|-h|--help|-[Hh]elp) + script_name="$(basename "$0")" + echo ".NET Tools Installer" + echo "Usage: $script_name [-c|--channel ] [-v|--version ] [-p|--prefix ]" + echo " $script_name -h|-?|--help" + echo "" + echo "$script_name is a simple command line interface for obtaining dotnet cli." + echo "" + echo "Options:" + echo " -c,--channel Download from the channel specified, Defaults to \`$channel\`." + echo " -Channel" + echo " Possible values:" + echo " - Current - most current release" + echo " - LTS - most current supported release" + echo " - 2-part version in a format A.B - represents a specific release" + echo " examples: 2.0; 1.0" + echo " - Branch name" + echo " examples: release/2.0.0; Master" + echo " Note: The version parameter overrides the channel parameter." + echo " -v,--version Use specific VERSION, Defaults to \`$version\`." + echo " -Version" + echo " Possible values:" + echo " - latest - most latest build on specific channel" + echo " - coherent - most latest coherent build on specific channel" + echo " coherent applies only to SDK downloads" + echo " - 3-part version in a format A.B.C - represents specific version of build" + echo " examples: 2.0.0-preview2-006120; 1.1.0" + echo " -i,--install-dir Install under specified location (see Install Location below)" + echo " -InstallDir" + echo " --architecture Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`." + echo " --arch,-Architecture,-Arch" + echo " Possible values: x64, arm, and arm64" + echo " --runtime Installs a shared runtime only, without the SDK." + echo " -Runtime" + echo " Possible values:" + echo " - dotnet - the Microsoft.NETCore.App shared runtime" + echo " - aspnetcore - the Microsoft.AspNetCore.App shared runtime" + echo " --dry-run,-DryRun Do not perform installation. Display download link." + echo " --no-path, -NoPath Do not set PATH for the current process." + echo " --verbose,-Verbose Display diagnostics information." + echo " --azure-feed,-AzureFeed Azure feed location. Defaults to $azure_feed, This parameter typically is not changed by the user." + echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user." + echo " --feed-credential,-FeedCredential Azure feed shared access token. This parameter typically is not specified." + echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable." + echo " -SkipNonVersionedFiles" + echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly." + echo " --jsonfile Determines the SDK version from a user specified global.json file." + echo " Note: global.json must have a value for 'SDK:Version'" + echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)." + echo " -RuntimeId" + echo " -?,--?,-h,--help,-Help Shows this help message" + echo "" + echo "Obsolete parameters:" + echo " --shared-runtime The recommended alternative is '--runtime dotnet'." + echo " This parameter is obsolete and may be removed in a future version of this script." + echo " Installs just the shared runtime bits, not the entire SDK." + echo "" + echo "Install Location:" + echo " Location is chosen in following order:" + echo " - --install-dir option" + echo " - Environmental variable DOTNET_INSTALL_DIR" + echo " - $HOME/.dotnet" + exit 0 + ;; + *) + say_err "Unknown argument \`$name\`" + exit 1 + ;; + esac + + shift +done + +if [ "$no_cdn" = true ]; then + azure_feed="$uncached_feed" +fi + +check_min_reqs +calculate_vars +script_name=$(basename "$0") + +if [ "$dry_run" = true ]; then + say "Payload URLs:" + say "Primary named payload URL: $download_link" + if [ "$valid_legacy_download_link" = true ]; then + say "Legacy named payload URL: $legacy_download_link" + fi + repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\""" + if [[ "$runtime" == "dotnet" ]]; then + repeatable_command+=" --runtime "\""dotnet"\""" + elif [[ "$runtime" == "aspnetcore" ]]; then + repeatable_command+=" --runtime "\""aspnetcore"\""" + fi + repeatable_command+="$non_dynamic_parameters" + say "Repeatable invocation: $repeatable_command" + exit 0 +fi + +check_pre_reqs +install_dotnet + +bin_path="$(get_absolute_path "$(combine_paths "$install_root" "$bin_folder_relative_path")")" +if [ "$no_path" = false ]; then + say "Adding to current process PATH: \`$bin_path\`. Note: This change will be visible only when sourcing script." + export PATH="$bin_path":"$PATH" +else + say "Binaries of dotnet can be found in $bin_path" +fi + +say "Installation finished successfully." diff --git a/eng/common/performance/blazor_perf.proj b/eng/common/performance/blazor_perf.proj new file mode 100644 index 0000000000..3b25359c43 --- /dev/null +++ b/eng/common/performance/blazor_perf.proj @@ -0,0 +1,30 @@ + + + python3 + $(HelixPreCommands);chmod +x $HELIX_WORKITEM_PAYLOAD/SOD/SizeOnDisk + + + + + %(Identity) + + + + + %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\ + $(ScenarioDirectory)blazor\ + + + $HELIX_CORRELATION_PAYLOAD/performance/src/scenarios/ + $(ScenarioDirectory)blazor/ + + + + + $(WorkItemDirectory) + cd $(BlazorDirectory);$(Python) pre.py publish --msbuild %27/p:_TrimmerDumpDependencies=true%27 --msbuild-static AdditionalMonoLinkerOptions=%27"%24(AdditionalMonoLinkerOptions) --dump-dependencies"%27 --binlog %27./traces/blazor_publish.binlog%27 + $(Python) test.py sod --scenario-name "%(Identity)" + $(Python) post.py + + + \ No newline at end of file diff --git a/eng/common/performance/crossgen_perf.proj b/eng/common/performance/crossgen_perf.proj index 3c8c33d705..4264920382 100644 --- a/eng/common/performance/crossgen_perf.proj +++ b/eng/common/performance/crossgen_perf.proj @@ -1,80 +1,68 @@ - - py -3 - $(HelixPreCommands);call %HELIX_CORRELATION_PAYLOAD%\performance\tools\machine-setup.cmd;set PYTHONPATH=%HELIX_WORKITEM_PAYLOAD%\scripts%3B%HELIX_WORKITEM_PAYLOAD% - %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts - $HELIX_CORRELATION_PAYLOAD - $(BaseDirectory)/performance - - - - $(PerformanceDirectory)/scripts/benchmarks_ci.py --csproj $(PerformanceDirectory)/$(TargetCsproj) - --dotnet-versions $DOTNET_VERSION --cli-source-info args --cli-branch $PERFLAB_BRANCH --cli-commit-sha $PERFLAB_HASH --cli-repository https://github.com/$PERFLAB_REPO --cli-source-timestamp $PERFLAB_BUILDTIMESTAMP - python3 - $(BaseDirectory)/Core_Root/corerun - $(HelixPreCommands);chmod +x $(PerformanceDirectory)/tools/machine-setup.sh;. $(PerformanceDirectory)/tools/machine-setup.sh - $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts - $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts_Baseline - $(PerformanceDirectory)/src/tools/ResultsComparer/ResultsComparer.csproj - $(PerformanceDirectory)/tools/dotnet/$(Architecture)/dotnet - %25 - $HELIX_WORKITEM_ROOT/testResults.xml - - %(Identity) - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - + + + py -3 + $(HelixPreCommands) + %HELIX_CORRELATION_PAYLOAD%\Core_Root + %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\ + $(ScenarioDirectory)crossgen\ + $(ScenarioDirectory)crossgen2\ + + + python3 + $(HelixPreCommands);chmod +x $HELIX_WORKITEM_PAYLOAD/startup/Startup;chmod +x $HELIX_WORKITEM_PAYLOAD/startup/perfcollect;sudo apt update + $HELIX_CORRELATION_PAYLOAD/Core_Root + $HELIX_CORRELATION_PAYLOAD/performance/src/scenarios/ + $(ScenarioDirectory)crossgen/ + $(ScenarioDirectory)crossgen2/ + + + + + + + + + + + - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + $(WorkItemDirectory) + $(Python) $(CrossgenDirectory)test.py crossgen --core-root $(CoreRoot) --test-name %(Identity) + + + + + + $(WorkItemDirectory) + $(Python) $(Crossgen2Directory)test.py crossgen2 --core-root $(CoreRoot) --single %(Identity) + + + + + + + 4:00 - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + + 4:00 - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - - - $(WorkItemDirectory)\ScenarioCorrelation - $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --composite %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\framework-r2r.dll.rsp --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root + + $(WorkItemDirectory) + $(Python) $(Crossgen2Directory)test.py crossgen2 --core-root $(CoreRoot) --composite $(Crossgen2Directory)framework-r2r.dll.rsp 1:00 diff --git a/eng/common/performance/microbenchmarks.proj b/eng/common/performance/microbenchmarks.proj index 5c95ef458e..94b6efbc92 100644 --- a/eng/common/performance/microbenchmarks.proj +++ b/eng/common/performance/microbenchmarks.proj @@ -46,10 +46,10 @@ - --corerun %HELIX_CORRELATION_PAYLOAD%\dotnet-mono\shared\Microsoft.NETCore.App\5.0.0\corerun.exe + --corerun %HELIX_CORRELATION_PAYLOAD%\dotnet-mono\shared\Microsoft.NETCore.App\6.0.0\corerun.exe - --corerun $(BaseDirectory)/dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun + --corerun $(BaseDirectory)/dotnet-mono/shared/Microsoft.NETCore.App/6.0.0/corerun diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh index 65a9d8fc61..806e56c612 100755 --- a/eng/common/performance/performance-setup.sh +++ b/eng/common/performance/performance-setup.sh @@ -26,6 +26,7 @@ use_baseline_core_run=true using_mono=false wasm_runtime_loc= using_wasm=false +use_latest_dotnet=false while (($# > 0)); do lowerI="$(echo $1 | awk '{print tolower($0)}')" @@ -115,7 +116,11 @@ while (($# > 0)); do configurations=$2 shift 2 ;; - --help) + --latestdotnet) + use_latest_dotnet=true + shift 1 + ;; + *) echo "Common settings:" echo " --corerootdirectory Directory where Core_Root exists, if running perf testing with --corerun" echo " --architecture Architecture of the testing being run" @@ -137,6 +142,7 @@ while (($# > 0)); do echo " --internal If the benchmarks are running as an official job." echo " --monodotnet Pass the path to the mono dotnet for mono performance testing." echo " --wasm Path to the unpacked wasm runtime pack." + echo " --latestdotnet --dotnet-versions will not be specified. --dotnet-versions defaults to LKG version in global.json " echo "" exit 0 ;; @@ -194,28 +200,30 @@ if [[ "$internal" == true ]]; then fi fi -if [[ "$mono_dotnet" != "" ]]; then +if [[ "$mono_dotnet" != "" ]] && [[ "$monointerpreter" == "false" ]]; then configurations="$configurations LLVM=$llvm MonoInterpreter=$monointerpreter MonoAOT=$monoaot" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoMono" fi if [[ "$wasm_runtime_loc" != "" ]]; then - configurations="CompilationMode=wasm RunKind=micro" - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter NoWASM" + configurations="CompilationMode=wasm RunKind=$kind" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter NoWASM NoMono" fi -if [[ "$monointerpreter" == "true" ]]; then - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter" +if [[ "$mono_dotnet" != "" ]] && [[ "$monointerpreter" == "true" ]]; then + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter NoMono" fi common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs $configurations --architecture $architecture" setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments" -# Get the tools section from the global.json. -# This grabs the LKG version number of dotnet and passes it to our scripts -dotnet_version=`cat global.json | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["tools"]["dotnet"])'` -setup_arguments="--dotnet-versions $dotnet_version $setup_arguments" - +if [[ "$use_latest_dotnet" = false ]]; then + # Get the tools section from the global.json. + # This grabs the LKG version number of dotnet and passes it to our scripts + dotnet_version=`cat global.json | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["tools"]["dotnet"])'` + setup_arguments="--dotnet-versions $dotnet_version $setup_arguments" +fi if [[ "$run_from_perf_repo" = true ]]; then payload_directory= @@ -266,7 +274,7 @@ Write-PipelineSetVariable -name "PerformanceDirectory" -value "$performance_dire Write-PipelineSetVariable -name "WorkItemDirectory" -value "$workitem_directory" -is_multi_job_variable false Write-PipelineSetVariable -name "Queue" -value "$queue" -is_multi_job_variable false Write-PipelineSetVariable -name "SetupArguments" -value "$setup_arguments" -is_multi_job_variable false -Write-PipelineSetVariable -name "Python" -value "$python3" -is_multi_job_variable false +Write-PipelineSetVariable -name "Python" -value "python3" -is_multi_job_variable false Write-PipelineSetVariable -name "PerfLabArguments" -value "$perflab_arguments" -is_multi_job_variable false Write-PipelineSetVariable -name "ExtraBenchmarkDotNetArguments" -value "$extra_benchmark_dotnet_arguments" -is_multi_job_variable false Write-PipelineSetVariable -name "BDNCategories" -value "$run_categories" -is_multi_job_variable false diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index 055304ad89..d0c3cc2b3b 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -67,6 +67,7 @@ jobs: /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:Configuration=$(_BuildConfig) + /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} @@ -87,11 +88,6 @@ jobs: ArtifactName: ReleaseConfigs - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - task: PublishBuildArtifacts@1 - displayName: Publish Logs to VSTS - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: $(Agent.Os)_PublishBuildAssets - continueOnError: true - condition: always() + - template: /eng/common/templates/steps/publish-logs.yml + parameters: + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 030808632f..630a99d4dd 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -56,6 +56,7 @@ parameters: NetEngServicesProdChannelId: 679 Net5Preview8ChannelId: 1155 Net5RC1ChannelId: 1157 + Net5RC2ChannelId: 1329 NetCoreSDK313xxChannelId: 759 NetCoreSDK313xxInternalChannelId: 760 NetCoreSDK314xxChannelId: 921 @@ -91,7 +92,7 @@ stages: inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/check-channel-consistency.ps1 arguments: -PromoteToChannels "$(TargetChannels)" - -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.Net5Preview8ChannelId}},${{parameters.Net5RC1ChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}} + -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.Net5Preview8ChannelId}},${{parameters.Net5RC1ChannelId}},${{parameters.Net5RC2ChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}} - job: displayName: NuGet Validation @@ -329,6 +330,22 @@ stages: shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json' symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json' + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'Net5_RC2_Publish' + channelName: '.NET 5 RC 2' + akaMSChannelName: 'net5/rc2' + channelId: ${{ parameters.Net5RC2ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json' + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: BARBuildId: ${{ parameters.BARBuildId }} diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml index f91751fe78..428026d2e7 100644 --- a/eng/common/templates/steps/publish-logs.yml +++ b/eng/common/templates/steps/publish-logs.yml @@ -3,21 +3,20 @@ parameters: JobLabel: '' steps: -- task: Powershell@2 - displayName: Prepare Binlogs to Upload +- task: CopyFiles@2 + displayName: Copy Logs to $(Build.StagingDirectory)\BuildLogs inputs: - targetType: inline - script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + SourceFolder: $(Build.SourcesDirectory)\artifacts + Contents: | + **/*.log + **/*.binlog + TargetFolder: '$(Build.StagingDirectory)\BuildLogs' continueOnError: true - condition: always() - -- task: PublishBuildArtifacts@1 - displayName: Publish Logs + condition: succeededOrFailed() + +- task: PublishPipelineArtifact@1 + displayName: Publish BuildLogs inputs: - PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' - PublishLocation: Container - ArtifactName: PostBuildLogs - continueOnError: true - condition: always() + targetPath: '$(Build.StagingDirectory)\BuildLogs' + artifactName: ${{ parameters.JobLabel }} + condition: succeededOrFailed() diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 27e97a3f8a..daca90c0b6 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -57,6 +57,15 @@ set-strictmode -version 2.0 $ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +# If specified, provides an alternate path for getting .NET Core SDKs and Runtimes. This script will still try public sources first. +[string]$runtimeSourceFeed = if (Test-Path variable:runtimeSourceFeed) { $runtimeSourceFeed } else { $null } +# Base-64 encoded SAS token that has permission to storage container described by $runtimeSourceFeed +[string]$runtimeSourceFeedKey = if (Test-Path variable:runtimeSourceFeedKey) { $runtimeSourceFeedKey } else { $null } + +# If false, use copy of dotnet-install from /eng/common/dotnet-install-scripts (for custom behaviors). +# otherwise will fetch from public location. +[bool]$useDefaultDotnetInstall = if (Test-Path variable:useDefaultDotnetInstall) { $useDefaultDotnetInstall } else { $false } + function Create-Directory ([string[]] $path) { New-Item -Path $path -Force -ItemType 'Directory' | Out-Null } @@ -188,37 +197,46 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { function GetDotNetInstallScript([string] $dotnetRoot) { $installScript = Join-Path $dotnetRoot 'dotnet-install.ps1' if (!(Test-Path $installScript)) { - Create-Directory $dotnetRoot - $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit + create-directory $dotnetroot - $maxRetries = 5 - $retries = 1 + if ($useDefaultDotnetInstall) + { + $progresspreference = 'silentlycontinue' # don't display the console progress ui - it's a huge perf hit - $uri = "https://dot.net/$dotnetInstallScriptVersion/dotnet-install.ps1" + $maxretries = 5 + $retries = 1 - while($true) { - try { - Write-Host "GET $uri" - Invoke-WebRequest $uri -OutFile $installScript - break + $uri = "https://dot.net/$dotnetinstallscriptversion/dotnet-install.ps1" + + while($true) { + try { + write-host "get $uri" + invoke-webrequest $uri -outfile $installscript + break + } + catch { + write-host "failed to download '$uri'" + write-error $_.exception.message -erroraction continue + } + + if (++$retries -le $maxretries) { + $delayinseconds = [math]::pow(2, $retries) - 1 # exponential backoff + write-host "retrying. waiting for $delayinseconds seconds before next attempt ($retries of $maxretries)." + start-sleep -seconds $delayinseconds + } + else { + throw "unable to download file in $maxretries attempts." + } } - catch { - Write-Host "Failed to download '$uri'" - Write-Error $_.Exception.Message -ErrorAction Continue - } - - if (++$retries -le $maxRetries) { - $delayInSeconds = [math]::Pow(2, $retries) - 1 # Exponential backoff - Write-Host "Retrying. Waiting for $delayInSeconds seconds before next attempt ($retries of $maxRetries)." - Start-Sleep -Seconds $delayInSeconds - } - else { - throw "Unable to download file in $maxRetries attempts." - } - + } + else + { + # Use a special version of the script from eng/common that understands the existence of a "productVersion.txt" in a dotnet path. + # See https://github.com/dotnet/arcade/issues/6047 for details + $engCommonCopy = Resolve-Path (Join-Path $PSScriptRoot 'dotnet-install-scripts\dotnet-install.ps1') + Copy-Item $engCommonCopy -Destination $installScript -Force } } - return $installScript } @@ -250,10 +268,8 @@ function InstallDotNet([string] $dotnetRoot, & $installScript @installParameters } catch { - Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet runtime '$runtime' from public location." - - # Only the runtime can be installed from a custom [private] location. - if ($runtime -and ($runtimeSourceFeed -or $runtimeSourceFeedKey)) { + if ($runtimeSourceFeed -or $runtimeSourceFeedKey) { + Write-Host "Failed to install dotnet from public location. Trying from '$runtimeSourceFeed'" if ($runtimeSourceFeed) { $installParameters.AzureFeed = $runtimeSourceFeed } if ($runtimeSourceFeedKey) { @@ -266,10 +282,11 @@ function InstallDotNet([string] $dotnetRoot, & $installScript @installParameters } catch { - Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet runtime '$runtime' from custom location '$runtimeSourceFeed'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from custom location '$runtimeSourceFeed'." ExitWithExitCode 1 } } else { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from public location." ExitWithExitCode 1 } } @@ -604,11 +621,7 @@ function MSBuild() { if ($pipelinesLog) { $buildTool = InitializeBuildTool - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 if ($ci -and $buildTool.Tool -eq 'dotnet') { - dotnet nuget locals http-cache -c - $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' diff --git a/eng/common/tools.sh b/eng/common/tools.sh index e94fce22ec..c722a05853 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -64,6 +64,14 @@ else use_global_nuget_cache=${use_global_nuget_cache:-true} fi +# Used when restoring .NET SDK from alternative feeds +runtime_source_feed=${runtime_source_feed:-''} +runtime_source_feed_key=${runtime_source_feed_key:-''} + +# Determines if dotnet-install.sh comes from the eng/common folder or the internet +# (default = public version) +use_default_dotnet_install=${use_default_dotnet_install:-false} + # Resolve any symlinks in the given path. function ResolvePath { local path=$1 @@ -170,11 +178,11 @@ function InitializeDotNetCli { function InstallDotNetSdk { local root=$1 local version=$2 - local architecture="" - if [[ $# == 3 ]]; then + local architecture="unset" + if [[ $# -ge 3 ]]; then architecture=$3 fi - InstallDotNet "$root" "$version" $architecture + InstallDotNet "$root" "$version" $architecture 'sdk' 'false' $runtime_source_feed $runtime_source_feed_key } function InstallDotNet { @@ -185,50 +193,50 @@ function InstallDotNet { local install_script=$_GetDotNetInstallScript local archArg='' - if [[ -n "${3:-}" ]]; then + if [[ -n "${3:-}" ]] && [ "$3" != 'unset' ]; then archArg="--architecture $3" fi local runtimeArg='' - if [[ -n "${4:-}" ]]; then + if [[ -n "${4:-}" ]] && [ "$4" != 'sdk' ]; then runtimeArg="--runtime $4" fi - local skipNonVersionedFilesArg="" - if [[ "$#" -ge "5" ]]; then + if [[ "$#" -ge "5" ]] && [[ "$5" != 'false' ]]; then skipNonVersionedFilesArg="--skip-non-versioned-files" fi bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg || { local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." + echo "Failed to install dotnet SDK from public location (exit code '$exit_code')." - if [[ -n "$runtimeArg" ]]; then - local runtimeSourceFeed='' - if [[ -n "${6:-}" ]]; then - runtimeSourceFeed="--azure-feed $6" + local runtimeSourceFeed='' + if [[ -n "${6:-}" ]]; then + runtimeSourceFeed="--azure-feed $6" + fi + + local runtimeSourceFeedKey='' + if [[ -n "${7:-}" ]]; then + # The 'base64' binary on alpine uses '-d' and doesn't support '--decode' + # '-d'. To work around this, do a simple detection and switch the parameter + # accordingly. + decodeArg="--decode" + if base64 --help 2>&1 | grep -q "BusyBox"; then + decodeArg="-d" fi + decodedFeedKey=`echo $7 | base64 $decodeArg` + runtimeSourceFeedKey="--feed-credential $decodedFeedKey" + fi - local runtimeSourceFeedKey='' - if [[ -n "${7:-}" ]]; then - # The 'base64' binary on alpine uses '-d' and doesn't support '--decode' - # '-d'. To work around this, do a simple detection and switch the parameter - # accordingly. - decodeArg="--decode" - if base64 --help 2>&1 | grep -q "BusyBox"; then - decodeArg="-d" - fi - decodedFeedKey=`echo $7 | base64 $decodeArg` - runtimeSourceFeedKey="--feed-credential $decodedFeedKey" - fi - - if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then - bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." - ExitWithExitCode $exit_code - } - else + if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then + bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." ExitWithExitCode $exit_code + } + else + if [[ $exit_code != 0 ]]; then + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." fi + ExitWithExitCode $exit_code fi } } @@ -263,23 +271,30 @@ function GetDotNetInstallScript { if [[ ! -a "$install_script" ]]; then mkdir -p "$root" - echo "Downloading '$install_script_url'" + if [[ "$use_default_dotnet_install" == true ]]; then + echo "Downloading '$install_script_url'" - # Use curl if available, otherwise use wget - if command -v curl > /dev/null; then - with_retries curl "$install_script_url" -sSL --retry 10 --create-dirs -o "$install_script" || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." - ExitWithExitCode $exit_code - } + # Use curl if available, otherwise use wget + if command -v curl > /dev/null; then + with_retries curl "$install_script_url" -sSL --retry 10 --create-dirs -o "$install_script" || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." + ExitWithExitCode $exit_code + } + else + with_retries wget -v -O "$install_script" "$install_script_url" || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." + ExitWithExitCode $exit_code + } + fi else - with_retries wget -v -O "$install_script" "$install_script_url" || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." - ExitWithExitCode $exit_code - } + # Use a special version of the script from eng/common that understands the existence of a "productVersion.txt" in a dotnet path. + # See https://github.com/dotnet/arcade/issues/6047 for details + cp $repo_root/eng/common/dotnet-install-scripts/dotnet-install.sh $install_script fi fi + # return value _GetDotNetInstallScript="$install_script" } @@ -391,11 +406,7 @@ function MSBuild { InitializeBuildTool InitializeToolset - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 if [[ "$ci" == true ]]; then - "$_InitializeBuildTool" nuget locals http-cache -c - export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" diff --git a/eng/helix/content/RunTests/RunTestsOptions.cs b/eng/helix/content/RunTests/RunTestsOptions.cs index 9e076c9701..bd611ef46e 100644 --- a/eng/helix/content/RunTests/RunTestsOptions.cs +++ b/eng/helix/content/RunTests/RunTestsOptions.cs @@ -21,14 +21,9 @@ namespace RunTests description: "The test dll to run") { Argument = new Argument(), Required = true }, - new Option( - aliases: new string[] { "--sdk" }, - description: "The version of the sdk being used") - { Argument = new Argument(), Required = true }, - new Option( aliases: new string[] { "--runtime" }, - description: "The version of the runtime being used") + description: "The version of the ASP.NET runtime being installed and used") { Argument = new Argument(), Required = true }, new Option( @@ -70,7 +65,6 @@ namespace RunTests var parseResult = command.Parse(args); var options = new RunTestsOptions(); options.Target = parseResult.ValueForOption("--target"); - options.SdkVersion = parseResult.ValueForOption("--sdk"); options.RuntimeVersion = parseResult.ValueForOption("--runtime"); options.HelixQueue = parseResult.ValueForOption("--queue"); options.Architecture = parseResult.ValueForOption("--arch"); diff --git a/eng/helix/content/runtests.cmd b/eng/helix/content/runtests.cmd index d5d43bb8ff..dc36eedf72 100644 --- a/eng/helix/content/runtests.cmd +++ b/eng/helix/content/runtests.cmd @@ -6,14 +6,16 @@ REM Use '$' as a variable name prefix to avoid MSBuild variable collisions with set $target=%1 set $sdkVersion=%2 set $runtimeVersion=%3 -set $queue=%4 -set $arch=%5 -set $quarantined=%6 -set $ef=%7 -set $aspnetruntime=%8 -set $aspnetref=%9 +set $aspRuntimeVersion=%4 +set $queue=%5 +set $arch=%6 +set $quarantined=%7 +set $ef=%8 +set $aspnetruntime=%9 REM Batch only supports up to 9 arguments using the %# syntax, need to shift to get more shift +set $aspnetref=%9 +shift set $helixTimeout=%9 shift set $feedCred=%9 @@ -39,8 +41,8 @@ set exit_code=0 echo "Restore: dotnet restore RunTests\RunTests.csproj --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json --source https://api.nuget.org/v3/index.json --ignore-failed-sources..." dotnet restore RunTests\RunTests.csproj --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json --source https://api.nuget.org/v3/index.json --ignore-failed-sources -echo "Running tests: dotnet run --project RunTests\RunTests.csproj -- --target %$target% --sdk %$sdkVersion% --runtime %$runtimeVersion% --queue %$queue% --arch %$arch% --quarantined %$quarantined% --ef %$ef% --aspnetruntime %$aspnetruntime% --aspnetref %$aspnetref% --helixTimeout %$helixTimeout%..." -dotnet run --project RunTests\RunTests.csproj -- --target %$target% --sdk %$sdkVersion% --runtime %$runtimeVersion% --queue %$queue% --arch %$arch% --quarantined %$quarantined% --ef %$ef% --aspnetruntime %$aspnetruntime% --aspnetref %$aspnetref% --helixTimeout %$helixTimeout% +echo "Running tests: dotnet run --project RunTests\RunTests.csproj -- --target %$target% --runtime %$aspRuntimeVersion% --queue %$queue% --arch %$arch% --quarantined %$quarantined% --ef %$ef% --aspnetruntime %$aspnetruntime% --aspnetref %$aspnetref% --helixTimeout %$helixTimeout%..." +dotnet run --project RunTests\RunTests.csproj -- --target %$target% --runtime %$aspRuntimeVersion% --queue %$queue% --arch %$arch% --quarantined %$quarantined% --ef %$ef% --aspnetruntime %$aspnetruntime% --aspnetref %$aspnetref% --helixTimeout %$helixTimeout% if errorlevel neq 0 ( set exit_code=%errorlevel% ) diff --git a/eng/helix/content/runtests.sh b/eng/helix/content/runtests.sh index 90e6fca8a1..ecc58322fe 100644 --- a/eng/helix/content/runtests.sh +++ b/eng/helix/content/runtests.sh @@ -63,8 +63,8 @@ sync exit_code=0 echo "Restore: $DOTNET_ROOT/dotnet restore RunTests/RunTests.csproj --source https://api.nuget.org/v3/index.json --ignore-failed-sources..." $DOTNET_ROOT/dotnet restore RunTests/RunTests.csproj --source https://api.nuget.org/v3/index.json --ignore-failed-sources -echo "Running tests: $DOTNET_ROOT/dotnet run --project RunTests/RunTests.csproj -- --target $1 --sdk $2 --runtime $3 --queue $4 --arch $5 --quarantined $6 --ef $7 --aspnetruntime $8 --aspnetref $9 --helixTimeout ${10}..." -$DOTNET_ROOT/dotnet run --project RunTests/RunTests.csproj -- --target $1 --sdk $2 --runtime $3 --queue $4 --arch $5 --quarantined $6 --ef $7 --aspnetruntime $8 --aspnetref $9 --helixTimeout ${10} +echo "Running tests: $DOTNET_ROOT/dotnet run --project RunTests/RunTests.csproj -- --target $1 --runtime $4 --queue $5 --arch $6 --quarantined $7 --ef $8 --aspnetruntime $9 --aspnetref ${10} --helixTimeout ${11}" +$DOTNET_ROOT/dotnet run --project RunTests/RunTests.csproj -- --target $1 --runtime $4 --queue $5 --arch $6 --quarantined $7 --ef $8 --aspnetruntime $9 --aspnetref ${10} --helixTimeout ${11} exit_code=$? echo "Finished tests...exit_code=$exit_code" diff --git a/eng/scripts/InstallVisualStudio.ps1 b/eng/scripts/InstallVisualStudio.ps1 index 844da67bba..df0b0e1951 100644 --- a/eng/scripts/InstallVisualStudio.ps1 +++ b/eng/scripts/InstallVisualStudio.ps1 @@ -111,14 +111,13 @@ if (Test-path $InstallPath) { $arguments += ` '--productId', $productId, ` '--installPath', "`"$InstallPath`"", ` - '--in', "`"$responseFile`"", ` - '--norestart' + '--in', "`"$responseFile`"" if ($Passive) { - $arguments += '--passive' + $arguments += '--passive', '--norestart' } if ($Quiet) { - $arguments += '--quiet', '--wait' + $arguments += '--quiet', '--wait', '--norestart' } Write-Host diff --git a/eng/targets/CSharp.Common.targets b/eng/targets/CSharp.Common.targets index 62b7462035..f0df33c3e5 100644 --- a/eng/targets/CSharp.Common.targets +++ b/eng/targets/CSharp.Common.targets @@ -2,7 +2,7 @@ - net$(TargetFrameworkVersion.Substring(1).Replace('.','')) + net$(TargetFrameworkVersion.TrimStart('vV').Replace('.','')) .NETFramework diff --git a/eng/targets/Helix.props b/eng/targets/Helix.props index 1c6206291b..032bcd4928 100644 --- a/eng/targets/Helix.props +++ b/eng/targets/Helix.props @@ -22,7 +22,6 @@ false false 10.15.3 - 5.0.0-ci false diff --git a/eng/targets/Helix.targets b/eng/targets/Helix.targets index 188b9b01bc..9a277c0d59 100644 --- a/eng/targets/Helix.targets +++ b/eng/targets/Helix.targets @@ -16,10 +16,6 @@ - - - - @@ -100,11 +96,23 @@ Usage: dotnet msbuild /t:Helix src/MyTestProject.csproj - - + + + + + + + + + @@ -126,8 +134,8 @@ Usage: dotnet msbuild /t:Helix src/MyTestProject.csproj $(TargetFileName) @(HelixPreCommand) @(HelixPostCommand) - call runtests.cmd $(TargetFileName) $(NETCoreSdkVersion) $(MicrosoftNETCoreAppRuntimeVersion) $(_HelixFriendlyNameTargetQueue) $(TargetArchitecture) $(RunQuarantinedTests) $(DotnetEfPackageVersion) Microsoft.AspNetCore.App.Runtime.win-x64.$(AppRuntimeVersion).nupkg Microsoft.AspNetCore.App.Ref.$(AppRuntimeVersion).nupkg $(HelixTimeout) $(DotNetRuntimeSourceFeedKey) - ./runtests.sh $(TargetFileName) $(NETCoreSdkVersion) $(MicrosoftNETCoreAppRuntimeVersion) $(_HelixFriendlyNameTargetQueue) $(TargetArchitecture) $(RunQuarantinedTests) $(DotnetEfPackageVersion) Microsoft.AspNetCore.App.Runtime.win-x64.$(AppRuntimeVersion).nupkg Microsoft.AspNetCore.App.Ref.$(AppRuntimeVersion).nupkg $(HelixTimeout) $(DotNetRuntimeSourceFeedKey) + call runtests.cmd $(TargetFileName) $(NETCoreSdkVersion) $(MicrosoftNETCoreAppRuntimeVersion) $(SharedFxVersion) $(_HelixFriendlyNameTargetQueue) $(TargetArchitecture) $(RunQuarantinedTests) $(DotnetEfPackageVersion) Microsoft.AspNetCore.App.Runtime.win-x64.$(SharedFxVersion).nupkg Microsoft.AspNetCore.App.Ref.$(SharedFxVersion).nupkg $(HelixTimeout) + ./runtests.sh $(TargetFileName) $(NETCoreSdkVersion) $(MicrosoftNETCoreAppRuntimeVersion) $(SharedFxVersion) $(_HelixFriendlyNameTargetQueue) $(TargetArchitecture) $(RunQuarantinedTests) $(DotnetEfPackageVersion) Microsoft.AspNetCore.App.Runtime.win-x64.$(SharedFxVersion).nupkg Microsoft.AspNetCore.App.Ref.$(SharedFxVersion).nupkg $(HelixTimeout) $(HelixCommand) $(HelixTimeout) diff --git a/eng/targets/ResolveReferences.targets b/eng/targets/ResolveReferences.targets index 646a526c81..fe8224d198 100644 --- a/eng/targets/ResolveReferences.targets +++ b/eng/targets/ResolveReferences.targets @@ -175,9 +175,15 @@ - - + Exclude="@(Reference);@(PackageReference);@(ProjectReference->'%(Filename)')" /> + + + + + + + + + + ", "The NuGet source of packages to fetch", CommandOptionType.SingleValue); + _source = Option( + "-s|--package-source ", + "The NuGet source of packages to fetch", + CommandOptionType.SingleValue); _output = Option("-o|--output ", "The generated file output path", CommandOptionType.SingleValue); _update = Option("-u|--update", "Regenerate the input (Baseline.xml) file.", CommandOptionType.NoValue); @@ -45,9 +48,6 @@ namespace PackageBaselineGenerator private async Task Run() { - var source = _source.HasValue() - ? _source.Value().TrimEnd('/') - : "https://api.nuget.org/v3/index.json"; if (_output.HasValue() && _update.HasValue()) { await Error.WriteLineAsync("'--output' and '--update' options must not be used together."); @@ -56,6 +56,7 @@ namespace PackageBaselineGenerator var inputPath = Path.Combine(Directory.GetCurrentDirectory(), "Baseline.xml"); var input = XDocument.Load(inputPath); + var source = _source.HasValue() ? _source.Value().TrimEnd('/') : "https://api.nuget.org/v3/index.json"; var packageSource = new PackageSource(source); var providers = Repository.Provider.GetCoreV3(); // Get v2 and v3 API support var sourceRepository = new SourceRepository(packageSource, providers); @@ -89,6 +90,11 @@ namespace PackageBaselineGenerator var baselineVersion = input.Root.Attribute("Version").Value; + // Baseline and .NET Core versions always align in non-preview releases. + var parsedVersion = Version.Parse(baselineVersion); + var defaultTarget = ((parsedVersion.Major < 5) ? "netcoreapp" : "net") + + $"{parsedVersion.Major}.{parsedVersion.Minor}"; + var doc = new XDocument( new XComment(" Auto generated. Do not edit manually, use eng/tools/BaselineGenerator/ to recreate. "), new XElement("Project", @@ -136,12 +142,34 @@ namespace PackageBaselineGenerator foreach (var group in reader.NuspecReader.GetDependencyGroups()) { - var itemGroup = new XElement("ItemGroup", new XAttribute("Condition", $" '$(PackageId)' == '{id}' AND '$(TargetFramework)' == '{group.TargetFramework.GetShortFolderName()}' ")); + // Don't bother generating empty ItemGroup elements. + if (group.Packages.Count() == 0) + { + continue; + } + + // Handle changes to $(DefaultNetCoreTargetFramework) even if some projects are held back. + var targetCondition = $"'$(TargetFramework)' == '{group.TargetFramework.GetShortFolderName()}'"; + if (string.Equals( + group.TargetFramework.GetShortFolderName(), + defaultTarget, + StringComparison.OrdinalIgnoreCase)) + { + targetCondition = + $"('$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)' OR {targetCondition})"; + } + + var itemGroup = new XElement( + "ItemGroup", + new XAttribute("Condition", $" '$(PackageId)' == '{id}' AND {targetCondition} ")); doc.Root.Add(itemGroup); foreach (var dependency in group.Packages) { - itemGroup.Add(new XElement("BaselinePackageReference", new XAttribute("Include", dependency.Id), new XAttribute("Version", dependency.VersionRange.ToString()))); + itemGroup.Add( + new XElement("BaselinePackageReference", + new XAttribute("Include", dependency.Id), + new XAttribute("Version", dependency.VersionRange.ToString()))); } } } diff --git a/global.json b/global.json index 4479dd9dd0..acb77596ab 100644 --- a/global.json +++ b/global.json @@ -30,7 +30,7 @@ }, "msbuild-sdks": { "Yarn.MSBuild": "1.15.2", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20419.21", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20419.21" + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20431.1", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20431.1" } } diff --git a/src/Analyzers/Analyzers/src/PublicAPI.Shipped.txt b/src/Analyzers/Analyzers/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Analyzers/Analyzers/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Analyzers/Analyzers/src/PublicAPI.Unshipped.txt b/src/Analyzers/Analyzers/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Analyzers/Analyzers/src/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Antiforgery/src/PublicAPI.Shipped.txt b/src/Antiforgery/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Antiforgery/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Antiforgery/src/PublicAPI.Unshipped.txt b/src/Antiforgery/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..575a0a0b86 --- /dev/null +++ b/src/Antiforgery/src/PublicAPI.Unshipped.txt @@ -0,0 +1,33 @@ +#nullable enable +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.AntiforgeryOptions() -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.Cookie.get -> Microsoft.AspNetCore.Http.CookieBuilder! +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.Cookie.set -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.FormFieldName.get -> string! +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.FormFieldName.set -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.HeaderName.get -> string? +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.HeaderName.set -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.SuppressXFrameOptionsHeader.get -> bool +Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.SuppressXFrameOptionsHeader.set -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet.AntiforgeryTokenSet(string? requestToken, string? cookieToken, string! formFieldName, string? headerName) -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet.CookieToken.get -> string? +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet.FormFieldName.get -> string! +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet.HeaderName.get -> string? +Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet.RequestToken.get -> string? +Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException +Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException.AntiforgeryValidationException(string! message) -> void +Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException.AntiforgeryValidationException(string! message, System.Exception? innerException) -> void +Microsoft.AspNetCore.Antiforgery.IAntiforgery +Microsoft.AspNetCore.Antiforgery.IAntiforgery.GetAndStoreTokens(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet! +Microsoft.AspNetCore.Antiforgery.IAntiforgery.GetTokens(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet! +Microsoft.AspNetCore.Antiforgery.IAntiforgery.IsRequestValidAsync(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Antiforgery.IAntiforgery.SetCookieTokenAndHeader(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> void +Microsoft.AspNetCore.Antiforgery.IAntiforgery.ValidateRequestAsync(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Antiforgery.IAntiforgeryAdditionalDataProvider +Microsoft.AspNetCore.Antiforgery.IAntiforgeryAdditionalDataProvider.GetAdditionalData(Microsoft.AspNetCore.Http.HttpContext! context) -> string! +Microsoft.AspNetCore.Antiforgery.IAntiforgeryAdditionalDataProvider.ValidateAdditionalData(Microsoft.AspNetCore.Http.HttpContext! context, string! additionalData) -> bool +Microsoft.Extensions.DependencyInjection.AntiforgeryServiceCollectionExtensions +static Microsoft.Extensions.DependencyInjection.AntiforgeryServiceCollectionExtensions.AddAntiforgery(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.AntiforgeryServiceCollectionExtensions.AddAntiforgery(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! setupAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static readonly Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.DefaultCookiePrefix -> string! diff --git a/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Shipped.txt b/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Unshipped.txt b/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8ae5bbc1c5 --- /dev/null +++ b/src/Azure/AzureAppServices.HostingStartup/src/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +#nullable enable +Microsoft.AspNetCore.AzureAppServices.HostingStartup.AzureAppServicesHostingStartup +Microsoft.AspNetCore.AzureAppServices.HostingStartup.AzureAppServicesHostingStartup.AzureAppServicesHostingStartup() -> void +~Microsoft.AspNetCore.AzureAppServices.HostingStartup.AzureAppServicesHostingStartup.Configure(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) -> void diff --git a/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Shipped.txt b/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Unshipped.txt b/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8a21c33de6 --- /dev/null +++ b/src/Azure/AzureAppServicesIntegration/src/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +#nullable enable +Microsoft.AspNetCore.Hosting.AppServicesWebHostBuilderExtensions +~static Microsoft.AspNetCore.Hosting.AppServicesWebHostBuilderExtensions.UseAzureAppServices(this Microsoft.AspNetCore.Hosting.IWebHostBuilder hostBuilder) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder diff --git a/src/Components/Components.slnf b/src/Components/Components.slnf index 637ec1a384..bfb10dcc6f 100644 --- a/src/Components/Components.slnf +++ b/src/Components/Components.slnf @@ -101,10 +101,8 @@ "src\\Components\\benchmarkapps\\Wasm.Performance\\Driver\\Wasm.Performance.Driver.csproj", "src\\Components\\benchmarkapps\\Wasm.Performance\\TestApp\\Wasm.Performance.TestApp.csproj", "src\\Components\\Web.Extensions\\src\\Microsoft.AspNetCore.Components.Web.Extensions.csproj", - "src\\Components\\Web.Extensions\\test\\Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj", "src\\Components\\WebAssembly\\Server\\test\\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj", "src\\Components\\WebAssembly\\Authentication.Msal\\src\\Microsoft.Authentication.WebAssembly.Msal.csproj", - "src\\Components\\WebAssembly\\DebugProxy\\src\\Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj", "src\\Components\\WebAssembly\\JSInterop\\src\\Microsoft.JSInterop.WebAssembly.csproj", "src\\Components\\WebAssembly\\WebAssembly.Authentication\\src\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj", "src\\Components\\WebAssembly\\WebAssembly.Authentication\\test\\Microsoft.AspNetCore.Components.WebAssembly.Authentication.Tests.csproj", @@ -113,7 +111,9 @@ "src\\Components\\WebAssembly\\Sdk\\src\\Microsoft.NET.Sdk.BlazorWebAssembly.csproj", "src\\Components\\WebAssembly\\Sdk\\test\\Microsoft.NET.Sdk.BlazorWebAssembly.Tests.csproj", "src\\Components\\WebAssembly\\Sdk\\integrationtests\\Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj", - "src\\JSInterop\\Microsoft.JSInterop\\src\\Microsoft.JSInterop.csproj" + "src\\JSInterop\\Microsoft.JSInterop\\src\\Microsoft.JSInterop.csproj", + "src\\Components\\ProtectedBrowserStorage\\src\\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj", + "src\\Components\\ProtectedBrowserStorage\\test\\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj" ] } } diff --git a/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj b/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj index 1e7f881ed5..110ed5f7ae 100644 --- a/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj +++ b/src/Components/Components/src/Microsoft.AspNetCore.Components.csproj @@ -17,11 +17,17 @@ - + - - - + + + diff --git a/src/Components/Components/src/Properties/AssemblyInfo.cs b/src/Components/Components/src/Properties/AssemblyInfo.cs index 31d53210c5..8ff5dba844 100644 --- a/src/Components/Components/src/Properties/AssemblyInfo.cs +++ b/src/Components/Components/src/Properties/AssemblyInfo.cs @@ -7,6 +7,6 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Web.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] -[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Web.Extensions.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/Components/ComponentsNoDeps.slnf b/src/Components/ComponentsNoDeps.slnf index 861f0ce53c..b6e75d5a65 100644 --- a/src/Components/ComponentsNoDeps.slnf +++ b/src/Components/ComponentsNoDeps.slnf @@ -17,9 +17,7 @@ "src\\Components\\Server\\src\\Microsoft.AspNetCore.Components.Server.csproj", "src\\Components\\Server\\test\\Microsoft.AspNetCore.Components.Server.Tests.csproj", "src\\Components\\Web.Extensions\\src\\Microsoft.AspNetCore.Components.Web.Extensions.csproj", - "src\\Components\\Web.Extensions\\test\\Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj", "src\\Components\\WebAssembly\\Authentication.Msal\\src\\Microsoft.Authentication.WebAssembly.Msal.csproj", - "src\\Components\\WebAssembly\\DebugProxy\\src\\Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj", "src\\Components\\WebAssembly\\DevServer\\src\\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj", "src\\Components\\WebAssembly\\JSInterop\\src\\Microsoft.JSInterop.WebAssembly.csproj", "src\\Components\\WebAssembly\\Sdk\\integrationtests\\Microsoft.NET.Sdk.BlazorWebAssembly.IntegrationTests.csproj", @@ -47,7 +45,9 @@ "src\\Components\\test\\testassets\\BasicTestApp\\BasicTestApp.csproj", "src\\Components\\test\\testassets\\ComponentsApp.Server\\ComponentsApp.Server.csproj", "src\\Components\\test\\testassets\\TestContentPackage\\TestContentPackage.csproj", - "src\\Components\\test\\testassets\\TestServer\\Components.TestServer.csproj" + "src\\Components\\test\\testassets\\TestServer\\Components.TestServer.csproj", + "src\\Components\\ProtectedBrowserStorage\\src\\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj", + "src\\Components\\ProtectedBrowserStorage\\test\\Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj" ] } -} \ No newline at end of file +} diff --git a/src/Components/Ignitor/src/BlazorClient.cs b/src/Components/Ignitor/src/BlazorClient.cs index 5353659f36..b19ab8b3dd 100644 --- a/src/Components/Ignitor/src/BlazorClient.cs +++ b/src/Components/Ignitor/src/BlazorClient.cs @@ -353,7 +353,7 @@ namespace Ignitor _hubConnection = builder.Build(); HubConnection.On("JS.AttachComponent", OnAttachComponent); - HubConnection.On("JS.BeginInvokeJS", OnBeginInvokeJS); + HubConnection.On("JS.BeginInvokeJS", OnBeginInvokeJS); HubConnection.On("JS.EndInvokeDotNet", OnEndInvokeDotNet); HubConnection.On("JS.RenderBatch", OnRenderBatch); HubConnection.On("JS.Error", OnError); @@ -401,9 +401,9 @@ namespace Ignitor NextAttachComponentReceived?.Completion?.TrySetResult(call); } - private void OnBeginInvokeJS(int asyncHandle, string identifier, string argsJson) + private void OnBeginInvokeJS(int asyncHandle, string identifier, string argsJson, int resultType, long targetInstanceId) { - var call = new CapturedJSInteropCall(asyncHandle, identifier, argsJson); + var call = new CapturedJSInteropCall(asyncHandle, identifier, argsJson, resultType, targetInstanceId); Operations?.JSInteropCalls.Enqueue(call); JSInterop?.Invoke(call); diff --git a/src/Components/Ignitor/src/CapturedJSInteropCall.cs b/src/Components/Ignitor/src/CapturedJSInteropCall.cs index 4af491a58a..0dc8b0fa11 100644 --- a/src/Components/Ignitor/src/CapturedJSInteropCall.cs +++ b/src/Components/Ignitor/src/CapturedJSInteropCall.cs @@ -5,15 +5,19 @@ namespace Ignitor { public class CapturedJSInteropCall { - public CapturedJSInteropCall(int asyncHandle, string identifier, string argsJson) + public CapturedJSInteropCall(int asyncHandle, string identifier, string argsJson, int resultType, long targetInstanceId) { AsyncHandle = asyncHandle; Identifier = identifier; ArgsJson = argsJson; + ResultType = resultType; + TargetInstanceId = targetInstanceId; } public int AsyncHandle { get; } public string Identifier { get; } public string ArgsJson { get; } + public int ResultType { get; } + public long TargetInstanceId { get; } } } diff --git a/src/Components/ProtectedBrowserStorage/src/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj b/src/Components/ProtectedBrowserStorage/src/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj new file mode 100644 index 0000000000..47d821394f --- /dev/null +++ b/src/Components/ProtectedBrowserStorage/src/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.csproj @@ -0,0 +1,20 @@ + + + + $(DefaultNetCoreTargetFramework) + Provides functionality for storing protected data using the browser's localStorage and sessionStorage APIs. + true + enable + + + + + + + + + + + + + diff --git a/src/Components/ProtectedBrowserStorage/src/Properties/AssemblyInfo.cs b/src/Components/ProtectedBrowserStorage/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..6c858dd397 --- /dev/null +++ b/src/Components/ProtectedBrowserStorage/src/Properties/AssemblyInfo.cs @@ -0,0 +1,4 @@ +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs similarity index 99% rename from src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs rename to src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs index 1d2610079c..565d32574b 100644 --- a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs +++ b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.ProtectedBrowserStorage { /// diff --git a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs similarity index 74% rename from src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs rename to src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs index a666be1dc5..7fa193231f 100644 --- a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs +++ b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageResult.cs @@ -1,6 +1,9 @@ +// 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.Diagnostics.CodeAnalysis; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.ProtectedBrowserStorage { /// /// Contains the result of a protected browser storage operation. diff --git a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs similarity index 93% rename from src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs rename to src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs index 1e06de723e..8fd43a6ed8 100644 --- a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs +++ b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedBrowserStorageServiceCollectionExtensions.cs @@ -1,7 +1,7 @@ // 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 Microsoft.AspNetCore.Components.Web.Extensions; +using Microsoft.AspNetCore.Components.ProtectedBrowserStorage; namespace Microsoft.Extensions.DependencyInjection { diff --git a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs similarity index 95% rename from src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs rename to src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs index 08a529c948..badaaaea95 100644 --- a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs +++ b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedLocalStorage.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.ProtectedBrowserStorage { /// /// Provides mechanisms for storing and retrieving data in the browser's diff --git a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs similarity index 95% rename from src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs rename to src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs index 8f03d50802..35fb9d7ea4 100644 --- a/src/Components/Web.Extensions/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs +++ b/src/Components/ProtectedBrowserStorage/src/ProtectedBrowserStorage/ProtectedSessionStorage.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.ProtectedBrowserStorage { /// /// Provides mechanisms for storing and retrieving data in the browser's diff --git a/src/Components/Web.Extensions/test/Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj b/src/Components/ProtectedBrowserStorage/test/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj similarity index 77% rename from src/Components/Web.Extensions/test/Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj rename to src/Components/ProtectedBrowserStorage/test/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj index f09b7de9ec..04c21cbd13 100644 --- a/src/Components/Web.Extensions/test/Microsoft.AspNetCore.Components.Web.Extensions.Tests.csproj +++ b/src/Components/ProtectedBrowserStorage/test/Microsoft.AspNetCore.Components.ProtectedBrowserStorage.Tests.csproj @@ -2,12 +2,11 @@ $(DefaultNetCoreTargetFramework) - Microsoft.AspNetCore.Components - + diff --git a/src/Components/Web.Extensions/test/ProtectedBrowserStorageTest.cs b/src/Components/ProtectedBrowserStorage/test/ProtectedBrowserStorageTest.cs similarity index 99% rename from src/Components/Web.Extensions/test/ProtectedBrowserStorageTest.cs rename to src/Components/ProtectedBrowserStorage/test/ProtectedBrowserStorageTest.cs index 8143890de0..f5a752d9a3 100644 --- a/src/Components/Web.Extensions/test/ProtectedBrowserStorageTest.cs +++ b/src/Components/ProtectedBrowserStorage/test/ProtectedBrowserStorageTest.cs @@ -14,7 +14,7 @@ using Microsoft.AspNetCore.WebUtilities; using Microsoft.JSInterop; using Xunit; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.ProtectedBrowserStorage { public class ProtectedBrowserStorageTest { diff --git a/src/Components/Server/src/Circuits/CircuitIdFactory.cs b/src/Components/Server/src/Circuits/CircuitIdFactory.cs index 7250ee8116..61ded8c441 100644 --- a/src/Components/Server/src/Circuits/CircuitIdFactory.cs +++ b/src/Components/Server/src/Circuits/CircuitIdFactory.cs @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits return new CircuitId(Base64UrlTextEncoder.Encode(secret), Base64UrlTextEncoder.Encode(id)); } - public bool TryParseCircuitId(string text, out CircuitId circuitId) + public bool TryParseCircuitId(string? text, out CircuitId circuitId) { if (text is null) { diff --git a/src/Components/Server/src/Circuits/RemoteRenderer.cs b/src/Components/Server/src/Circuits/RemoteRenderer.cs index 0d9f862da2..59f93f6526 100644 --- a/src/Components/Server/src/Circuits/RemoteRenderer.cs +++ b/src/Components/Server/src/Circuits/RemoteRenderer.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits /// /// Notifies when a rendering exception occurred. /// - public event EventHandler UnhandledException; + public event EventHandler? UnhandledException; /// /// Creates a new . @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits pendingRender = new UnacknowledgedRenderBatch( renderId, arrayBuilder, - new TaskCompletionSource(), + new TaskCompletionSource(), ValueStopwatch.StartNew()); // Buffer the rendered batches no matter what. We'll send it down immediately when the client @@ -234,7 +234,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits // disposed. } - public Task OnRenderCompletedAsync(long incomingBatchId, string errorMessageOrNull) + public Task OnRenderCompletedAsync(long incomingBatchId, string? errorMessageOrNull) { if (_disposing) { @@ -308,7 +308,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits } } - private void ProcessPendingBatch(string errorMessageOrNull, UnacknowledgedRenderBatch entry) + private void ProcessPendingBatch(string? errorMessageOrNull, UnacknowledgedRenderBatch entry) { var elapsedTime = entry.ValueStopwatch.GetElapsedTime(); if (errorMessageOrNull == null) @@ -324,11 +324,11 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits CompleteRender(entry.CompletionSource, errorMessageOrNull); } - private void CompleteRender(TaskCompletionSource pendingRenderInfo, string errorMessageOrNull) + private void CompleteRender(TaskCompletionSource pendingRenderInfo, string? errorMessageOrNull) { if (errorMessageOrNull == null) { - pendingRenderInfo.TrySetResult(null); + pendingRenderInfo.TrySetResult(); } else { @@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits internal readonly struct UnacknowledgedRenderBatch { - public UnacknowledgedRenderBatch(long batchId, ArrayBuilder data, TaskCompletionSource completionSource, ValueStopwatch valueStopwatch) + public UnacknowledgedRenderBatch(long batchId, ArrayBuilder data, TaskCompletionSource completionSource, ValueStopwatch valueStopwatch) { BatchId = batchId; Data = data; @@ -348,7 +348,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits public long BatchId { get; } public ArrayBuilder Data { get; } - public TaskCompletionSource CompletionSource { get; } + public TaskCompletionSource CompletionSource { get; } public ValueStopwatch ValueStopwatch { get; } } diff --git a/src/Components/Shared/src/ArrayBuilder.cs b/src/Components/Shared/src/ArrayBuilder.cs index afb7b01987..206c741538 100644 --- a/src/Components/Shared/src/ArrayBuilder.cs +++ b/src/Components/Shared/src/ArrayBuilder.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree { /// /// Implements a list that uses an array of objects to store the elements. - /// + /// /// This differs from a in that /// it not only grows as required but also shrinks if cleared with significant /// excess capacity. This makes it useful for component rendering, because diff --git a/src/Components/Web.Extensions/src/InputFile/BrowserFile.cs b/src/Components/Web.Extensions/src/InputFile/BrowserFile.cs deleted file mode 100644 index ede5b7dc75..0000000000 --- a/src/Components/Web.Extensions/src/InputFile/BrowserFile.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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 System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Components.Web.Extensions -{ - internal class BrowserFile : IBrowserFile - { - internal InputFile Owner { get; set; } = default!; - - public int Id { get; set; } - - public string Name { get; set; } = string.Empty; - - public DateTime LastModified { get; set; } - - public long Size { get; set; } - - public string Type { get; set; } = string.Empty; - - public string? RelativePath { get; set; } - - public Stream OpenReadStream(CancellationToken cancellationToken = default) - => Owner.OpenReadStream(this, cancellationToken); - - public Task ToImageFileAsync(string format, int maxWidth, int maxHeight) - => Owner.ConvertToImageFileAsync(this, format, maxWidth, maxHeight); - } -} diff --git a/src/Components/Web.Extensions/src/InputFile/IBrowserFile.cs b/src/Components/Web.Extensions/src/InputFile/IBrowserFile.cs deleted file mode 100644 index 17d673e642..0000000000 --- a/src/Components/Web.Extensions/src/InputFile/IBrowserFile.cs +++ /dev/null @@ -1,54 +0,0 @@ -// 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 System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Components.Web.Extensions -{ - /// - /// Represents the data of a file selected from an component. - /// - public interface IBrowserFile - { - /// - /// Gets the name of the file. - /// - string Name { get; } - - /// - /// Gets the last modified date. - /// - DateTime LastModified { get; } - - /// - /// Gets the size of the file in bytes. - /// - long Size { get; } - - /// - /// Gets the MIME type of the file. - /// - string Type { get; } - - /// - /// Opens the stream for reading the uploaded file. - /// - /// A cancellation token to signal the cancellation of streaming file data. - Stream OpenReadStream(CancellationToken cancellationToken = default); - - /// - /// Converts the current image file to a new one of the specified file type and maximum file dimensions. - /// - /// - /// The image will be scaled to fit the specified dimensions while preserving the original aspect ratio. - /// - /// The new image format. - /// The maximum image width. - /// The maximum image height - /// A representing the completion of the operation. - Task ToImageFileAsync(string format, int maxWith, int maxHeight); - } -} diff --git a/src/Components/Web.Extensions/src/InputFile/InputFileChangeEventArgs.cs b/src/Components/Web.Extensions/src/InputFile/InputFileChangeEventArgs.cs deleted file mode 100644 index ae1dba5533..0000000000 --- a/src/Components/Web.Extensions/src/InputFile/InputFileChangeEventArgs.cs +++ /dev/null @@ -1,28 +0,0 @@ -// 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.Collections.Generic; - -namespace Microsoft.AspNetCore.Components.Web.Extensions -{ - /// - /// Supplies information about an event being raised. - /// - public class InputFileChangeEventArgs : EventArgs - { - /// - /// The updated file entries list. - /// - public IReadOnlyList Files { get; } - - /// - /// Constructs a new instance. - /// - /// The updated file entries list. - public InputFileChangeEventArgs(IReadOnlyList files) - { - Files = files; - } - } -} diff --git a/src/Components/Web.Extensions/src/Microsoft.AspNetCore.Components.Web.Extensions.csproj b/src/Components/Web.Extensions/src/Microsoft.AspNetCore.Components.Web.Extensions.csproj index 9492c3200c..852f471d38 100644 --- a/src/Components/Web.Extensions/src/Microsoft.AspNetCore.Components.Web.Extensions.csproj +++ b/src/Components/Web.Extensions/src/Microsoft.AspNetCore.Components.Web.Extensions.csproj @@ -6,11 +6,11 @@ true Microsoft.AspNetCore.Components enable + false - diff --git a/src/Components/Web.Extensions/src/wwwroot/inputFile.js b/src/Components/Web.Extensions/src/wwwroot/inputFile.js deleted file mode 100644 index 1fcec6929f..0000000000 --- a/src/Components/Web.Extensions/src/wwwroot/inputFile.js +++ /dev/null @@ -1,142 +0,0 @@ -(function () { - - // Exported functions - - function init(callbackWrapper, elem) { - elem._blazorInputFileNextFileId = 0; - - elem.addEventListener('click', function () { - // Permits replacing an existing file with a new one of the same file name. - elem.value = ''; - }); - - elem.addEventListener('change', function () { - // Reduce to purely serializable data, plus an index by ID. - elem._blazorFilesById = {}; - - const fileList = Array.prototype.map.call(elem.files, function (file) { - const result = { - id: ++elem._blazorInputFileNextFileId, - lastModified: new Date(file.lastModified).toISOString(), - name: file.name, - size: file.size, - type: file.type, - }; - - elem._blazorFilesById[result.id] = result; - - // Attach the blob data itself as a non-enumerable property so it doesn't appear in the JSON. - Object.defineProperty(result, 'blob', { value: file }); - - return result; - }); - - callbackWrapper.invokeMethodAsync('NotifyChange', fileList); - }); - } - - function toImageFile(elem, fileId, format, maxWidth, maxHeight) { - var originalFile = getFileById(elem, fileId); - - return new Promise(function (resolve) { - var originalFileImage = new Image(); - originalFileImage.onload = function () { resolve(originalFileImage); }; - originalFileImage.src = URL.createObjectURL(originalFile.blob); - }).then(function (loadedImage) { - return new Promise(function (resolve) { - var desiredWidthRatio = Math.min(1, maxWidth / loadedImage.width); - var desiredHeightRatio = Math.min(1, maxHeight / loadedImage.height); - var chosenSizeRatio = Math.min(desiredWidthRatio, desiredHeightRatio); - - var canvas = document.createElement('canvas'); - canvas.width = Math.round(loadedImage.width * chosenSizeRatio); - canvas.height = Math.round(loadedImage.height * chosenSizeRatio); - canvas.getContext('2d').drawImage(loadedImage, 0, 0, canvas.width, canvas.height); - canvas.toBlob(resolve, format); - }); - }).then(function (resizedImageBlob) { - var result = { - id: ++elem._blazorInputFileNextFileId, - lastModified: originalFile.lastModified, - name: originalFile.name, // Note: we're not changing the file extension. - size: resizedImageBlob.size, - type: format, - relativePath: originalFile.relativePath - }; - - elem._blazorFilesById[result.id] = result; - - // Attach the blob data itself as a non-enumerable property so it doesn't appear in the JSON. - Object.defineProperty(result, 'blob', { value: resizedImageBlob }); - - return result; - }); - } - - function ensureArrayBufferReadyForSharedMemoryInterop(elem, fileId) { - return getArrayBufferFromFileAsync(elem, fileId).then(function (arrayBuffer) { - getFileById(elem, fileId).arrayBuffer = arrayBuffer; - }); - } - - function readFileData(elem, fileId, startOffset, count) { - return getArrayBufferFromFileAsync(elem, fileId).then(function (arrayBuffer) { - return btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer, startOffset, count))); - }); - } - - function readFileDataSharedMemory(readRequest) { - const inputFileElementReferenceId = Blazor.platform.readStringField(readRequest, 0); - const inputFileElement = document.querySelector(`[_bl_${inputFileElementReferenceId}]`); - const fileId = Blazor.platform.readInt32Field(readRequest, 4); - const sourceOffset = Blazor.platform.readUint64Field(readRequest, 8); - const destination = Blazor.platform.readInt32Field(readRequest, 16); - const destinationOffset = Blazor.platform.readInt32Field(readRequest, 20); - const maxBytes = Blazor.platform.readInt32Field(readRequest, 24); - - const sourceArrayBuffer = getFileById(inputFileElement, fileId).arrayBuffer; - const bytesToRead = Math.min(maxBytes, sourceArrayBuffer.byteLength - sourceOffset); - const sourceUint8Array = new Uint8Array(sourceArrayBuffer, sourceOffset, bytesToRead); - - const destinationUint8Array = Blazor.platform.toUint8Array(destination); - destinationUint8Array.set(sourceUint8Array, destinationOffset); - - return bytesToRead; - } - - // Local helpers - - function getFileById(elem, fileId) { - const file = elem._blazorFilesById[fileId]; - - if (!file) { - throw new Error(`There is no file with ID ${fileId}. The file list may have changed.`); - } - - return file; - } - - function getArrayBufferFromFileAsync(elem, fileId) { - const file = getFileById(elem, fileId); - - // On the first read, convert the FileReader into a Promise. - if (!file.readPromise) { - file.readPromise = new Promise(function (resolve, reject) { - const reader = new FileReader(); - reader.onload = function () { resolve(reader.result); }; - reader.onerror = function (err) { reject(err); }; - reader.readAsArrayBuffer(file.blob); - }); - } - - return file.readPromise; - } - - window._blazorInputFile = { - init, - toImageFile, - ensureArrayBufferReadyForSharedMemoryInterop, - readFileData, - readFileDataSharedMemory, - }; -})(); diff --git a/src/Components/Web.JS/dist/Release/blazor.server.js b/src/Components/Web.JS/dist/Release/blazor.server.js index a444b4e075..4256e35b98 100644 --- a/src/Components/Web.JS/dist/Release/blazor.server.js +++ b/src/Components/Web.JS/dist/Release/blazor.server.js @@ -1,19 +1,19 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=52)}([function(e,t,n){"use strict";var r;n.d(t,"a",(function(){return r})),function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(r||(r={}))},function(e,t,n){"use strict";(function(e){n.d(t,"e",(function(){return c})),n.d(t,"a",(function(){return u})),n.d(t,"c",(function(){return l})),n.d(t,"g",(function(){return f})),n.d(t,"i",(function(){return h})),n.d(t,"j",(function(){return p})),n.d(t,"f",(function(){return d})),n.d(t,"d",(function(){return g})),n.d(t,"b",(function(){return y})),n.d(t,"h",(function(){return v}));var r=n(0),o=n(4),i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback&&this.subject.cancelCallback().catch((function(e){}))},e}(),y=function(){function e(e){this.minimumLogLevel=e,this.outputConsole=console}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:this.outputConsole.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:this.outputConsole.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:this.outputConsole.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:this.outputConsole.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}();function v(){var e="X-SignalR-User-Agent";return l.isNode&&(e="User-Agent"),[e,b(c,m(),E(),w())]}function b(e,t,n,r){var o="Microsoft SignalR/",i=e.split(".");return o+=i[0]+"."+i[1],o+=" ("+e+"; ",o+=t&&""!==t?t+"; ":"Unknown OS; ",o+=""+n,o+=r?"; "+r:"; Unknown Runtime Version",o+=")"}function m(){if(!l.isNode)return"";switch(e.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return e.platform}}function w(){if(l.isNode)return e.versions.node}function E(){return l.isNode?"NodeJS":"Browser"}}).call(this,n(13))},function(e,t,n){"use strict";n.r(t),n.d(t,"AbortError",(function(){return a})),n.d(t,"HttpError",(function(){return i})),n.d(t,"TimeoutError",(function(){return s})),n.d(t,"HttpClient",(function(){return l})),n.d(t,"HttpResponse",(function(){return u})),n.d(t,"DefaultHttpClient",(function(){return S})),n.d(t,"HubConnection",(function(){return O})),n.d(t,"HubConnectionState",(function(){return I})),n.d(t,"HubConnectionBuilder",(function(){return re})),n.d(t,"MessageType",(function(){return b})),n.d(t,"LogLevel",(function(){return f.a})),n.d(t,"HttpTransportType",(function(){return x})),n.d(t,"TransferFormat",(function(){return P})),n.d(t,"NullLogger",(function(){return $.a})),n.d(t,"JsonHubProtocol",(function(){return ee})),n.d(t,"Subject",(function(){return _})),n.d(t,"VERSION",(function(){return h.e}));var r,o=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return o(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return o(t,e),t}(Error),a=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return o(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=200&&o.status<300?n(new u(o.status,o.statusText,o.response||o.responseText)):r(new i(o.statusText,o.status))},o.onerror=function(){t.logger.log(f.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new i(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(f.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")})):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(l),E=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),S=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof fetch||h.c.isNode)n.httpClient=new v(t);else{if("undefined"==typeof XMLHttpRequest)throw new Error("No usable HttpClient found.");n.httpClient=new w(t)}return n}return E(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new a):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(l),C=n(43);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(b||(b={}));var I,_=function(){function e(){this.observers=[]}return e.prototype.next=function(e){for(var t=0,n=this.observers;t0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?[2,Promise.reject(new Error("Unable to connect to the server with any of the available transports. "+i.join(" ")))]:[2,Promise.reject(new Error("None of the transports supported by the client are supported by the server."))]}}))}))},e.prototype.constructTransport=function(e){switch(e){case x.WebSockets:if(!this.options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new J(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.WebSocket,this.options.headers||{});case x.ServerSentEvents:if(!this.options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new H(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.EventSource,this.options.withCredentials,this.options.headers||{});case x.LongPolling:return new B(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.withCredentials,this.options.headers||{});default:throw new Error("Unknown transport: "+e+".")}},e.prototype.startTransport=function(e,t){var n=this;return this.transport.onreceive=this.onreceive,this.transport.onclose=function(e){return n.stopConnection(e)},this.transport.connect(e,t)},e.prototype.resolveTransportOrError=function(e,t,n){var r=x[e.transport];if(null==r)return this.logger.log(f.a.Debug,"Skipping transport '"+e.transport+"' because it is not supported by this client."),new Error("Skipping transport '"+e.transport+"' because it is not supported by this client.");if(!function(e,t){return!e||0!=(t&e)}(t,r))return this.logger.log(f.a.Debug,"Skipping transport '"+x[r]+"' because it was disabled by the client."),new Error("'"+x[r]+"' is disabled by the client.");if(!(e.transferFormats.map((function(e){return P[e]})).indexOf(n)>=0))return this.logger.log(f.a.Debug,"Skipping transport '"+x[r]+"' because it does not support the requested transfer format '"+P[n]+"'."),new Error("'"+x[r]+"' does not support "+P[n]+".");if(r===x.WebSockets&&!this.options.WebSocket||r===x.ServerSentEvents&&!this.options.EventSource)return this.logger.log(f.a.Debug,"Skipping transport '"+x[r]+"' because it is not supported in your environment.'"),new Error("'"+x[r]+"' is not supported in your environment.");this.logger.log(f.a.Debug,"Selecting transport '"+x[r]+"'.");try{return this.constructTransport(r)}catch(e){return e}},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.stopConnection=function(e){var t=this;if(this.logger.log(f.a.Debug,"HttpConnection.stopConnection("+e+") called while in state "+this.connectionState+"."),this.transport=void 0,e=this.stopError||e,this.stopError=void 0,"Disconnected"!==this.connectionState){if("Connecting"===this.connectionState)throw this.logger.log(f.a.Warning,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is still in the connecting state."),new Error("HttpConnection.stopConnection("+e+") was called while the connection is still in the connecting state.");if("Disconnecting"===this.connectionState&&this.stopPromiseResolver(),e?this.logger.log(f.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(f.a.Information,"Connection disconnected."),this.sendQueue&&(this.sendQueue.stop().catch((function(e){t.logger.log(f.a.Error,"TransportSendQueue.stop() threw error '"+e+"'.")})),this.sendQueue=void 0),this.connectionId=void 0,this.connectionState="Disconnected",this.connectionStarted){this.connectionStarted=!1;try{this.onclose&&this.onclose(e)}catch(t){this.logger.log(f.a.Error,"HttpConnection.onclose("+e+") threw error '"+t+"'.")}}}else this.logger.log(f.a.Debug,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is already in the disconnected state.")},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!h.c.isBrowser||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(f.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",-1===(n+=-1===t?"":e.substring(t)).indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this.negotiateVersion),n},e}();var G=function(){function e(e){this.transport=e,this.buffer=[],this.executing=!0,this.sendBufferedData=new Q,this.transportResult=new Q,this.sendLoopPromise=this.sendLoop()}return e.prototype.send=function(e){return this.bufferData(e),this.transportResult||(this.transportResult=new Q),this.transportResult.promise},e.prototype.stop=function(){return this.executing=!1,this.sendBufferedData.resolve(),this.sendLoopPromise},e.prototype.bufferData=function(e){if(this.buffer.length&&typeof this.buffer[0]!=typeof e)throw new Error("Expected data to be of type "+typeof this.buffer+" but was of type "+typeof e);this.buffer.push(e),this.sendBufferedData.resolve()},e.prototype.sendLoop=function(){return V(this,void 0,void 0,(function(){var t,n,r;return K(this,(function(o){switch(o.label){case 0:return[4,this.sendBufferedData.promise];case 1:if(o.sent(),!this.executing)return this.transportResult&&this.transportResult.reject("Connection stopped."),[3,6];this.sendBufferedData=new Q,t=this.transportResult,this.transportResult=void 0,n="string"==typeof this.buffer[0]?this.buffer.join(""):e.concatBuffers(this.buffer),this.buffer.length=0,o.label=2;case 2:return o.trys.push([2,4,,5]),[4,this.transport.send(n)];case 3:return o.sent(),t.resolve(),[3,5];case 4:return r=o.sent(),t.reject(r),[3,5];case 5:return[3,0];case 6:return[2]}}))}))},e.concatBuffers=function(e){for(var t=e.map((function(e){return e.byteLength})).reduce((function(e,t){return e+t})),n=new Uint8Array(t),r=0,o=0,i=e;o0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function a(e,t,n){var i=e;if(e instanceof Comment&&(u(i)&&u(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(c(i))throw new Error("Not implemented: moving existing logical children");var s=u(t);if(n0;)e(r,0)}var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=c,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return u(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=u,t.permuteLogicalChildren=function(e,t){var n=u(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=c(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var s=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=s}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r=n(21),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(19);i.inherits=n(15);var s=n(36),a=n(41);i.inherits(f,s);for(var c=o(a.prototype),u=0;u0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback&&this.subject.cancelCallback().catch((function(e){}))},e}(),y=function(){function e(e){this.minimumLogLevel=e,this.outputConsole=console}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:this.outputConsole.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:this.outputConsole.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:this.outputConsole.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:this.outputConsole.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}();function v(){var e="X-SignalR-User-Agent";return l.isNode&&(e="User-Agent"),[e,b(c,m(),E(),w())]}function b(e,t,n,r){var o="Microsoft SignalR/",i=e.split(".");return o+=i[0]+"."+i[1],o+=" ("+e+"; ",o+=t&&""!==t?t+"; ":"Unknown OS; ",o+=""+n,o+=r?"; "+r:"; Unknown Runtime Version",o+=")"}function m(){if(!l.isNode)return"";switch(e.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return e.platform}}function w(){if(l.isNode)return e.versions.node}function E(){return l.isNode?"NodeJS":"Browser"}}).call(this,n(13))},function(e,t,n){"use strict";n.r(t),n.d(t,"AbortError",(function(){return s})),n.d(t,"HttpError",(function(){return i})),n.d(t,"TimeoutError",(function(){return a})),n.d(t,"HttpClient",(function(){return l})),n.d(t,"HttpResponse",(function(){return u})),n.d(t,"DefaultHttpClient",(function(){return S})),n.d(t,"HubConnection",(function(){return R})),n.d(t,"HubConnectionState",(function(){return I})),n.d(t,"HubConnectionBuilder",(function(){return re})),n.d(t,"MessageType",(function(){return b})),n.d(t,"LogLevel",(function(){return f.a})),n.d(t,"HttpTransportType",(function(){return P})),n.d(t,"TransferFormat",(function(){return O})),n.d(t,"NullLogger",(function(){return $.a})),n.d(t,"JsonHubProtocol",(function(){return ee})),n.d(t,"Subject",(function(){return C})),n.d(t,"VERSION",(function(){return h.e}));var r,o=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return o(t,e),t}(Error),a=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return o(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return o(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=200&&o.status<300?n(new u(o.status,o.statusText,o.response||o.responseText)):r(new i(o.statusText,o.status))},o.onerror=function(){t.logger.log(f.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new i(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(f.a.Warning,"Timeout from HTTP request."),r(new a)},o.send(e.content||"")})):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(l),E=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),S=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof fetch||h.c.isNode)n.httpClient=new v(t);else{if("undefined"==typeof XMLHttpRequest)throw new Error("No usable HttpClient found.");n.httpClient=new w(t)}return n}return E(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new s):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(l),_=n(46);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(b||(b={}));var I,C=function(){function e(){this.observers=[]}return e.prototype.next=function(e){for(var t=0,n=this.observers;t0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?[2,Promise.reject(new Error("Unable to connect to the server with any of the available transports. "+i.join(" ")))]:[2,Promise.reject(new Error("None of the transports supported by the client are supported by the server."))]}}))}))},e.prototype.constructTransport=function(e){switch(e){case P.WebSockets:if(!this.options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new J(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.WebSocket,this.options.headers||{});case P.ServerSentEvents:if(!this.options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new H(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.EventSource,this.options.withCredentials,this.options.headers||{});case P.LongPolling:return new B(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.withCredentials,this.options.headers||{});default:throw new Error("Unknown transport: "+e+".")}},e.prototype.startTransport=function(e,t){var n=this;return this.transport.onreceive=this.onreceive,this.transport.onclose=function(e){return n.stopConnection(e)},this.transport.connect(e,t)},e.prototype.resolveTransportOrError=function(e,t,n){var r=P[e.transport];if(null==r)return this.logger.log(f.a.Debug,"Skipping transport '"+e.transport+"' because it is not supported by this client."),new Error("Skipping transport '"+e.transport+"' because it is not supported by this client.");if(!function(e,t){return!e||0!=(t&e)}(t,r))return this.logger.log(f.a.Debug,"Skipping transport '"+P[r]+"' because it was disabled by the client."),new Error("'"+P[r]+"' is disabled by the client.");if(!(e.transferFormats.map((function(e){return O[e]})).indexOf(n)>=0))return this.logger.log(f.a.Debug,"Skipping transport '"+P[r]+"' because it does not support the requested transfer format '"+O[n]+"'."),new Error("'"+P[r]+"' does not support "+O[n]+".");if(r===P.WebSockets&&!this.options.WebSocket||r===P.ServerSentEvents&&!this.options.EventSource)return this.logger.log(f.a.Debug,"Skipping transport '"+P[r]+"' because it is not supported in your environment.'"),new Error("'"+P[r]+"' is not supported in your environment.");this.logger.log(f.a.Debug,"Selecting transport '"+P[r]+"'.");try{return this.constructTransport(r)}catch(e){return e}},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.stopConnection=function(e){var t=this;if(this.logger.log(f.a.Debug,"HttpConnection.stopConnection("+e+") called while in state "+this.connectionState+"."),this.transport=void 0,e=this.stopError||e,this.stopError=void 0,"Disconnected"!==this.connectionState){if("Connecting"===this.connectionState)throw this.logger.log(f.a.Warning,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is still in the connecting state."),new Error("HttpConnection.stopConnection("+e+") was called while the connection is still in the connecting state.");if("Disconnecting"===this.connectionState&&this.stopPromiseResolver(),e?this.logger.log(f.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(f.a.Information,"Connection disconnected."),this.sendQueue&&(this.sendQueue.stop().catch((function(e){t.logger.log(f.a.Error,"TransportSendQueue.stop() threw error '"+e+"'.")})),this.sendQueue=void 0),this.connectionId=void 0,this.connectionState="Disconnected",this.connectionStarted){this.connectionStarted=!1;try{this.onclose&&this.onclose(e)}catch(t){this.logger.log(f.a.Error,"HttpConnection.onclose("+e+") threw error '"+t+"'.")}}}else this.logger.log(f.a.Debug,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is already in the disconnected state.")},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!h.c.isBrowser||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(f.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",-1===(n+=-1===t?"":e.substring(t)).indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this.negotiateVersion),n},e}();var X=function(){function e(e){this.transport=e,this.buffer=[],this.executing=!0,this.sendBufferedData=new Q,this.transportResult=new Q,this.sendLoopPromise=this.sendLoop()}return e.prototype.send=function(e){return this.bufferData(e),this.transportResult||(this.transportResult=new Q),this.transportResult.promise},e.prototype.stop=function(){return this.executing=!1,this.sendBufferedData.resolve(),this.sendLoopPromise},e.prototype.bufferData=function(e){if(this.buffer.length&&typeof this.buffer[0]!=typeof e)throw new Error("Expected data to be of type "+typeof this.buffer+" but was of type "+typeof e);this.buffer.push(e),this.sendBufferedData.resolve()},e.prototype.sendLoop=function(){return V(this,void 0,void 0,(function(){var t,n,r;return G(this,(function(o){switch(o.label){case 0:return[4,this.sendBufferedData.promise];case 1:if(o.sent(),!this.executing)return this.transportResult&&this.transportResult.reject("Connection stopped."),[3,6];this.sendBufferedData=new Q,t=this.transportResult,this.transportResult=void 0,n="string"==typeof this.buffer[0]?this.buffer.join(""):e.concatBuffers(this.buffer),this.buffer.length=0,o.label=2;case 2:return o.trys.push([2,4,,5]),[4,this.transport.send(n)];case 3:return o.sent(),t.resolve(),[3,5];case 4:return r=o.sent(),t.reject(r),[3,5];case 5:return[3,0];case 6:return[2]}}))}))},e.concatBuffers=function(e){for(var t=e.map((function(e){return e.byteLength})).reduce((function(e,t){return e+t})),n=new Uint8Array(t),r=0,o=0,i=e;o0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function s(e,t,n){var i=e;if(e instanceof Comment&&(u(i)&&u(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(c(i))throw new Error("Not implemented: moving existing logical children");var a=u(t);if(n0;)e(r,0)}var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=c,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return u(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=u,t.permuteLogicalChildren=function(e,t){var n=u(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=c(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r=n(23),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(19);i.inherits=n(15);var a=n(39),s=n(44);i.inherits(f,a);for(var c=o(s.prototype),u=0;u * @license MIT */ -var r=n(53),o=n(54),i=n(55);function s(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(e,t){if(s()=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|e}function d(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return P(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return T(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return _(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function y(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function v(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,o);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,o){var i,s=1,a=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s=2,a/=2,c/=2,n/=2}function u(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(o){var l=-1;for(i=n;ia&&(n=a-c),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var s=0;s>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function _(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:u>223?3:u>191?2:1;if(o+f<=n)switch(f){case 1:u<128&&(l=u);break;case 2:128==(192&(i=e[o+1]))&&(c=(31&u)<<6|63&i)>127&&(l=c);break;case 3:i=e[o+1],s=e[o+2],128==(192&i)&&128==(192&s)&&(c=(15&u)<<12|(63&i)<<6|63&s)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:i=e[o+1],s=e[o+2],a=e[o+3],128==(192&i)&&128==(192&s)&&128==(192&a)&&(c=(15&u)<<18|(63&i)<<12|(63&s)<<6|63&a)>65535&&c<1114112&&(l=c)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},c.prototype.compare=function(e,t,n,r,o){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),a=Math.min(i,s),u=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return E(this,e,t,n);case"latin1":case"binary":return S(this,e,t,n);case"base64":return C(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function T(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function D(e,t,n,r,o,i){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function j(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function M(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function A(e,t,n,r,i){return i||M(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function B(e,t,n,r,i){return i||M(e,0,n,8),o.write(e,t,n,r,52,8),n+8}c.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},c.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||R(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},c.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||R(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},c.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),o.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),o.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),o.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return t||R(e,8,this.length),o.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||D(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},c.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,1,255,0),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):j(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):j(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);D(this,e,t,n,o-1,-o)}var i=0,s=1,a=0;for(this[t]=255&e;++i>0)-a&255;return t+n},c.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);D(this,e,t,n,o-1,-o)}var i=n-1,s=1,a=0;for(this[t+i]=255&e;--i>=0&&(s*=256);)e<0&&0===a&&0!==this[t+i+1]&&(a=1),this[t+i]=(e/s>>0)-a&255;return t+n},c.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):j(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):j(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,n){return A(this,e,t,!0,n)},c.prototype.writeFloatBE=function(e,t,n){return A(this,e,t,!1,n)},c.prototype.writeDoubleLE=function(e,t,n){return B(this,e,t,!0,n)},c.prototype.writeDoubleBE=function(e,t,n){return B(this,e,t,!1,n)},c.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!c.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(8))},function(e,t,n){"use strict";var r=n(14).Buffer,o=n(56),i=n(20),s=n(69),a=n(72),c=n(73);e.exports=function(e){var t=[],n=[];return{encode:c(t,(e=e||{forceFloat64:!1,compatibilityMode:!1,disableTimestampEncoding:!1}).forceFloat64,e.compatibilityMode,e.disableTimestampEncoding),decode:a(n),register:function(e,t,n,s){return o(t,"must have a constructor"),o(n,"must have an encode function"),o(e>=0,"must have a non-negative type"),o(s,"must have a decode function"),this.registerEncoder((function(e){return e instanceof t}),(function(t){var o=i(),s=r.allocUnsafe(1);return s.writeInt8(e,0),o.append(s),o.append(n(t)),o})),this.registerDecoder(e,s),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:s.encoder,decoder:s.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:a.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23),n(17);var r=n(24),o=n(7),i={},s=!1;function a(e,t,n){var o=i[e];o||(o=i[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=a,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");a(n||0,o.toLogicalElement(r,!0),t)},t.getRendererer=function(e){return i[e]},t.renderBatch=function(e,t){var n=i[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),a=r.values(o),c=r.count(o),u=t.referenceFrames(),l=r.values(u),f=t.diffReader,h=0;h1)for(var n=1;nthis.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,s,a=!!e,c=this._offset(n),u=r-n,l=u,f=a&&t||0,h=c[1];if(0===n&&r==this.length){if(!a)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(s=0;s(o=this._bufs[s].length-h))){this._bufs[s].copy(e,f,h,h+l);break}this._bufs[s].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},s.prototype.shallowSlice=function(e,t){e=e||0,t=t||this.length,e<0&&(e+=this.length),t<0&&(t+=this.length);var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new s(o)},s.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},s.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},s.prototype.duplicate=function(){for(var e=0,t=new s;e0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,s)}}))}),{root:o(t),rootMargin:i+"px"});s.observe(t),s.observe(n);var a=u(t),c=u(n);function u(e){var t=new MutationObserver((function(){s.unobserve(e),s.observe(e)}));return t.observe(e,{attributes:!0}),t}r[e._id]={intersectionObserver:s,mutationObserverBefore:a,mutationObserverAfter:c}},dispose:function(e){var t=r[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete r[e._id])}};var r={};function o(e){return e?"visible"!==getComputedStyle(e).overflowY?e:o(e.parentElement):null}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1].*)$/;function i(e,t){var n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r.groups&&r.groups.descriptor;if(!i)return;try{var a=function(e){var t=JSON.parse(e),n=t.type;if("server"!==n&&"webassembly"!==n)throw new Error("Invalid component type '"+n+"'.");return t}(i);switch(t){case"webassembly":return function(e,t,n){var r=e.type,o=e.assembly,i=e.typeName,a=e.parameterDefinitions,c=e.parameterValues,u=e.prerenderId;if("webassembly"!==r)return;if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(u){var l=s(u,n);if(!l)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,assembly:o,typeName:i,parameterDefinitions:a&&atob(a),parameterValues:c&&atob(c),start:t,prerenderId:u,end:l}}return{type:r,assembly:o,typeName:i,parameterDefinitions:a&&atob(a),parameterValues:c&&atob(c),start:t}}(a,n,e);case"server":return function(e,t,n){var r=e.type,o=e.descriptor,i=e.sequence,a=e.prerenderId;if("server"!==r)return;if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error("Error parsing the sequence '"+i+"' for component '"+JSON.stringify(e)+"'");if(a){var c=s(a,n);if(!c)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,sequence:i,descriptor:o,start:t,prerenderId:a,end:c}}return{type:r,sequence:i,descriptor:o,start:t}}(a,n,e)}}catch(e){throw new Error("Found malformed component comment at "+n.textContent)}}}function s(e,t){for(;t.next()&&t.currentElement;){var n=t.currentElement;if(n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r[1];if(i)return a(i,e),n}}}function a(e,t){var n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error("Invalid end of component comment: '"+e+"'");var r=n.prerenderId;if(!r)throw new Error("End of component comment must have a value for the prerendered property: '"+e+"'");if(r!==t)throw new Error("End of component comment prerendered property must match the start comment prerender id: '"+t+"', '"+r+"'")}var c=function(){function e(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}return e.prototype.next=function(){return this.currentIndex++,this.currentIndex=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}})),c=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=c),l(r,e,r.depth)}function c(e,t){var n=a.styles[t];return n?"["+a.colors[n][0]+"m"+e+"["+a.colors[n][1]+"m":e}function u(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&C(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var s=Object.keys(n),a=function(e){var t={};return e.forEach((function(e,n){t[e]=!0})),t}(s);if(e.showHidden&&(s=Object.getOwnPropertyNames(n)),S(n)&&(s.indexOf("message")>=0||s.indexOf("description")>=0))return f(n);if(0===s.length){if(C(n)){var c=n.name?": "+n.name:"";return e.stylize("[Function"+c+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var u,w="",I=!1,_=["{","}"];(p(n)&&(I=!0,_=["[","]"]),C(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==s.length||I&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),u=I?function(e,t,n,r,o){for(var i=[],s=0,a=t.length;s=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1}),0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(u,w,_)):_[0]+w+_[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var s,a,c;if((c=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?a=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(a=e.stylize("[Setter]","special")),x(r,o)||(s="["+o+"]"),a||(e.seen.indexOf(c.value)<0?(a=g(n)?l(e,c.value,null):l(e,c.value,n-1)).indexOf("\n")>-1&&(a=i?a.split("\n").map((function(e){return" "+e})).join("\n").substr(2):"\n"+a.split("\n").map((function(e){return" "+e})).join("\n")):a=e.stylize("[Circular]","special")),b(s)){if(i&&o.match(/^\d+$/))return a;(s=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+a}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===I(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===I(e)}function S(e){return w(e)&&("[object Error]"===I(e)||e instanceof Error)}function C(e){return"function"==typeof e}function I(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!s[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;s[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else s[n]=function(){};return s[n]},t.inspect=a,a.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=C,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(58);var k=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function T(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),k[e.getMonth()],t].join(" ")}function x(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){console.log("%s - %s",T(),t.format.apply(t,arguments))},t.inherits=n(59),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var P="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function O(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(P&&e[P]){var t;if("function"!=typeof(t=e[P]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,P,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise((function(e,r){t=e,n=r})),o=[],i=0;i0?("string"==typeof t||s.objectMode||Object.getPrototypeOf(t)===u.prototype||(t=function(e){return u.from(e)}(t)),r?s.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,s,t,!0):s.ended?e.emit("error",new Error("stream.push() after EOF")):(s.reading=!1,s.decoder&&!n?(t=s.decoder.write(t),s.objectMode||0!==t.length?E(e,s,t,!1):_(e,s)):E(e,s,t,!1))):r||(s.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=8388608?e=8388608:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function C(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(I,e):I(e))}function I(e){p("emit readable"),e.emit("readable"),P(e)}function _(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(k,e,t))}function k(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(s===i.length?o+=i:o+=i.slice(0,e),0===(e-=s)){s===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(s));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=u.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,s=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,s),0===(e-=s)){s===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(s));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function R(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(D,t,e))}function D(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function L(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?R(this):C(this),null;if(0===(e=S(e,t))&&t.ended)return 0===t.length&&R(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?O(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&R(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var c=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function u(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",u),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(c):n.once("end",c),e.on("unpipe",u);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&a(e,"data")&&(t.flowing=!0,P(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==L(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===a(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?s(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&s.length>o&&!s.warned){s.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=s.length,a=c,console&&console.warn&&console.warn(a)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=h.bind(r);return o.listener=n,r.wrapFn=o,o}function d(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(s=t[0]),s instanceof Error)throw s;var a=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw a.context=s,a}var c=o[e];if(void 0===c)return!1;if("function"==typeof c)i(c,this,t);else{var u=c.length,l=y(c,u);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){s=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},a.prototype.listeners=function(e){return d(this,e,!0)},a.prototype.rawListeners=function(e){return d(this,e,!1)},a.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):g.call(e,t)},a.prototype.listenerCount=g,a.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(37).EventEmitter},function(e,t,n){"use strict";var r=n(21);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return i||s?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";var r=n(65).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=c,this.end=u,t=4;break;case"utf8":this.fillLast=a,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function s(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function a(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function c(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function u(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";(function(t,r,o){var i=n(21);function s(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var a,c=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var u=n(19);u.inherits=n(15);var l={deprecate:n(68)},f=n(38),h=n(14).Buffer,p=o.Uint8Array||function(){};var d,g=n(39);function y(){}function v(e,t){a=a||n(9),e=e||{};var r=t instanceof a;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,u=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(u||0===u)?u:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(I,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),I(e,t))}(e,n,r,t,o);else{var s=S(n);s||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?c(w,e,n,s,o):w(e,n,s,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new s(this)}function b(e){if(a=a||n(9),!(d.call(b,this)||this instanceof a))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,s){t.writelen=r,t.writecb=s,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),I(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var a=0,c=!0;n;)o[a]=n,n.isBuf||(c=!1),n=n.next,a+=1;o.allBuffers=c,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new s(t),t.bufferedRequestCount=0}else{for(;n;){var u=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:u.length,u,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function C(e,t){e._final((function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),I(e,t)}))}function I(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(C,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}u.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,s=!1,a=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return a&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),a?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(a||function(e,t,n,r){var o=!0,s=!1;return null===n?s=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(s=new TypeError("Invalid non-string/buffer chunk")),s&&(e.emit("error",s),i.nextTick(r,s),o=!1),o}(this,o,e,n))&&(o.pendingcb++,s=function(e,t,n,r,o,i){if(!n){var s=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==s&&(n=!0,o="buffer",r=s)}var a=t.objectMode?1:r.length;t.length+=a;var c=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,I(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(13),n(66).setImmediate,n(8))},function(e,t,n){"use strict";e.exports=s;var r=n(9),o=n(19);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.lengtha?s.slice(a).buffer:null}else{var c,u=t;if(-1===(c=u.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");a=c+1;n=u.substring(0,a),i=u.length>a?u.substring(a):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(10).Buffer)},,,,,,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)s.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return s},s=this&&this.__spread||function(){for(var e=[],t=0;t0?s-4:s;for(n=0;n>16&255,c[l++]=t>>8&255,c[l++]=255&t;2===a&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,c[l++]=255&t);1===a&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t);return c},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],s=0,a=n-o;sa?a:s+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,c=s.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,s=[],a=t;a>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return s.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,s,a=8*o-r-1,c=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=a;l>0;i=256*i+e[t+f],f+=h,l-=8);for(s=i&(1<<-l)-1,i>>=-l,l+=r;l>0;s=256*s+e[t+f],f+=h,l-=8);if(0===i)i=1-u;else{if(i===c)return s?NaN:1/0*(p?-1:1);s+=Math.pow(2,r),i-=u}return(p?-1:1)*s*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var s,a,c,u=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-s))<1&&(s--,c*=2),(t+=s+f>=1?h/c:h*Math.pow(2,1-f))*c>=2&&(s++,c/=2),s+f>=l?(a=0,s=l):s+f>=1?(a=(t*c-1)*Math.pow(2,o),s+=f):(a=t*Math.pow(2,f-1)*Math.pow(2,o),s=0));o>=8;e[n+p]=255&a,p+=d,a/=256,o-=8);for(s=s<0;e[n+p]=255&s,p+=d,s/=256,u-=8);e[n+p-d]|=128*g}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";(function(t){var r=n(57); +var r=n(54),o=n(55),i=n(56);function a(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return O(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return T(this,t,n);case"latin1":case"binary":return P(this,t,n);case"base64":return C(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function y(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function v(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,o);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,o){var i,a=1,s=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,n/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-c),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function C(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:u>223?3:u>191?2:1;if(o+f<=n)switch(f){case 1:u<128&&(l=u);break;case 2:128==(192&(i=e[o+1]))&&(c=(31&u)<<6|63&i)>127&&(l=c);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(c=(15&u)<<12|(63&i)<<6|63&a)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(c=(15&u)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&c<1114112&&(l=c)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},c.prototype.compare=function(e,t,n,r,o){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),u=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return E(this,e,t,n);case"latin1":case"binary":return S(this,e,t,n);case"base64":return _(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function T(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function D(e,t,n,r,o,i){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function A(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function M(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function L(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function j(e,t,n,r,i){return i||L(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function B(e,t,n,r,i){return i||L(e,0,n,8),o.write(e,t,n,r,52,8),n+8}c.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},c.prototype.readUInt8=function(e,t){return t||x(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return t||x(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return t||x(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return t||x(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return t||x(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||x(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},c.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||x(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},c.prototype.readInt8=function(e,t){return t||x(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){t||x(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt16BE=function(e,t){t||x(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt32LE=function(e,t){return t||x(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return t||x(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return t||x(e,4,this.length),o.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return t||x(e,4,this.length),o.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return t||x(e,8,this.length),o.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return t||x(e,8,this.length),o.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||D(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},c.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,1,255,0),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):A(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):A(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):M(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);D(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},c.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);D(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},c.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):A(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):A(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):M(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,n){return j(this,e,t,!0,n)},c.prototype.writeFloatBE=function(e,t,n){return j(this,e,t,!1,n)},c.prototype.writeDoubleLE=function(e,t,n){return B(this,e,t,!0,n)},c.prototype.writeDoubleBE=function(e,t,n){return B(this,e,t,!1,n)},c.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!c.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function W(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(8))},function(e,t,n){"use strict";var r=n(14).Buffer,o=n(57),i=n(22),a=n(70),s=n(73),c=n(74);e.exports=function(e){var t=[],n=[];return{encode:c(t,(e=e||{forceFloat64:!1,compatibilityMode:!1,disableTimestampEncoding:!1}).forceFloat64,e.compatibilityMode,e.disableTimestampEncoding),decode:s(n),register:function(e,t,n,a){return o(t,"must have a constructor"),o(n,"must have an encode function"),o(e>=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder((function(e){return e instanceof t}),(function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o})),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(17);var r=n(26),o=n(7),i={},a=!1;function s(e,t,n){var o=i[e];o||(o=i[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=s,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");s(n||0,o.toLogicalElement(r,!0),t)},t.getRendererer=function(e){return i[e]},t.renderBatch=function(e,t){var n=i[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),s=r.values(o),c=r.count(o),u=t.referenceFrames(),l=r.values(u),f=t.diffReader,h=0;h1)for(var n=1;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var u,l;s.attachDebuggerHotkey(e),window.Browser={init:function(){}},u=function(){window.Module=function(e,t,n){var u=this,l=e.bootConfig.resources,f=window.Module||{},h=["DEBUGGING ENABLED"];f.print=function(e){return h.indexOf(e)<0&&console.log(e)},f.printErr=function(e){console.error(e),c.showErrorNotification()},f.preRun=f.preRun||[],f.postRun=f.postRun||[],f.preloadPlugins=[];var d,b,m=e.loadResources(l.assembly,(function(e){return"_framework/"+e}),"assembly"),w=e.loadResources(l.pdb||{},(function(e){return"_framework/"+e}),"pdb"),E=e.loadResource("dotnet.wasm","_framework/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.blat")&&(d=e.loadResource("dotnet.timezones.blat","_framework/dotnet.timezones.blat",e.bootConfig.resources.runtime["dotnet.timezones.blat"],"globalization")),e.bootConfig.resources.runtime.hasOwnProperty("icudt.dat")&&(b=e.loadResource("icudt.dat","_framework/icudt.dat",e.bootConfig.resources.runtime["icudt.dat"],"globalization")),f.instantiateWasm=function(e,t){return r(u,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,E];case 1:return[4,y(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),f.printErr(r),r;case 4:return t(n),[2]}}))})),[]},f.preRun.push((function(){i=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),MONO.loaded_files=[],d&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),Module.FS_createPath("/","usr",!0,!0),Module.FS_createPath("/usr/","share",!0,!0),Module.FS_createPath("/usr/share/","zoneinfo",!0,!0),MONO.mono_wasm_load_data_archive(new Uint8Array(n),"/usr/share/zoneinfo/"),removeRunDependency(t),[2]}}))}))}(d),b?function(e){r(this,void 0,void 0,(function(){var t,n,r,i,a;return o(this,(function(o){switch(o.label){case 0:return t="blazor:icudata",addRunDependency(t),[4,e.response];case 1:return n=o.sent(),i=Uint8Array.bind,[4,n.arrayBuffer()];case 2:if(r=new(i.apply(Uint8Array,[void 0,o.sent()])),a=MONO.mono_wasm_load_bytes_into_heap(r),!MONO.mono_wasm_load_icu_data(a))throw new Error("Error loading ICU asset.");return removeRunDependency(t),[2]}}))}))}(b):MONO.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT","1"),m.forEach((function(e){return S(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),w.forEach((function(e){return S(e,e.name)})),window.Blazor._internal.dotNetCriticalError=function(e){f.printErr(BINDING.conv_string(e)||"(null)")},window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),i=e.bootConfig.resources.satelliteResources;if(i){var a=Promise.all(n.filter((function(e){return i.hasOwnProperty(e)})).map((function(t){return e.loadResources(i[t],(function(e){return"_framework/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(u,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(a.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n>1];var n},readInt32Field:function(e,t){return h(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>l)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*u+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return h(e+(t||0))},readStringField:function(e,t,n){var r,o=h(e+(t||0));if(0===o)return null;if(n){var i=BINDING.unbox_mono_obj(o);return"boolean"==typeof i?i?"":null:i}return f?void 0===(r=f.stringCache.get(o))&&(r=BINDING.conv_string(o),f.stringCache.set(o,r)):r=BINDING.conv_string(o),r},readStructField:function(e,t){return e+(t||0)},beginHeapLock:function(){return v(),f=new b},invokeWhenHeapUnlocked:function(e){f?f.enqueuePostReleaseAction(e):e()}};var p=document.createElement("a");function d(e){return e+12}function g(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function y(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}function v(){if(f)throw new Error("Assertion failed - heap is currently locked")}var b=function(){function e(){this.stringCache=new Map}return e.prototype.enqueuePostReleaseAction=function(e){this.postReleaseActions||(this.postReleaseActions=[]),this.postReleaseActions.push(e)},e.prototype.release=function(){var e;if(f!==this)throw new Error("Trying to release a lock which isn't current");for(f=null;null===(e=this.postReleaseActions)||void 0===e?void 0:e.length;){this.postReleaseActions.shift()(),v()}},e}()},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,c=this._offset(n),u=r-n,l=u,f=s&&t||0,h=c[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){e=e||0,t=t||this.length,e<0&&(e+=this.length),t<0&&(t+=this.length);var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;e0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,a)}}))}),{root:o(t),rootMargin:i+"px"});a.observe(t),a.observe(n);var s=u(t),c=u(n);function u(e){var t=new MutationObserver((function(){a.unobserve(e),a.observe(e)}));return t.observe(e,{attributes:!0}),t}r[e._id]={intersectionObserver:a,mutationObserverBefore:s,mutationObserverAfter:c}},dispose:function(e){var t=r[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete r[e._id])}};var r={};function o(e){return e?"visible"!==getComputedStyle(e).overflowY?e:o(e.parentElement):null}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1].*)$/;function i(e,t){var n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r.groups&&r.groups.descriptor;if(!i)return;try{var s=function(e){var t=JSON.parse(e),n=t.type;if("server"!==n&&"webassembly"!==n)throw new Error("Invalid component type '"+n+"'.");return t}(i);switch(t){case"webassembly":return function(e,t,n){var r=e.type,o=e.assembly,i=e.typeName,s=e.parameterDefinitions,c=e.parameterValues,u=e.prerenderId;if("webassembly"!==r)return;if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(u){var l=a(u,n);if(!l)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:c&&atob(c),start:t,prerenderId:u,end:l}}return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:c&&atob(c),start:t}}(s,n,e);case"server":return function(e,t,n){var r=e.type,o=e.descriptor,i=e.sequence,s=e.prerenderId;if("server"!==r)return;if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error("Error parsing the sequence '"+i+"' for component '"+JSON.stringify(e)+"'");if(s){var c=a(s,n);if(!c)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,sequence:i,descriptor:o,start:t,prerenderId:s,end:c}}return{type:r,sequence:i,descriptor:o,start:t}}(s,n,e)}}catch(e){throw new Error("Found malformed component comment at "+n.textContent)}}}function a(e,t){for(;t.next()&&t.currentElement;){var n=t.currentElement;if(n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r[1];if(i)return s(i,e),n}}}function s(e,t){var n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error("Invalid end of component comment: '"+e+"'");var r=n.prerenderId;if(!r)throw new Error("End of component comment must have a value for the prerendered property: '"+e+"'");if(r!==t)throw new Error("End of component comment prerendered property must match the start comment prerender id: '"+t+"', '"+r+"'")}var c=function(){function e(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}return e.prototype.next=function(){return this.currentIndex++,this.currentIndex=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}})),c=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=c),l(r,e,r.depth)}function c(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function u(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach((function(e,n){t[e]=!0})),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var c=n.name?": "+n.name:"";return e.stylize("[Function"+c+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var u,w="",I=!1,C=["{","}"];(p(n)&&(I=!0,C=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||I&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),u=I?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1}),0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(u,w,C)):C[0]+w+C[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,c;if((c=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),P(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(c.value)<0?(s=g(n)?l(e,c.value,null):l(e,c.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map((function(e){return" "+e})).join("\n").substr(2):"\n"+s.split("\n").map((function(e){return" "+e})).join("\n")):s=e.stylize("[Circular]","special")),b(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===I(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===I(e)}function S(e){return w(e)&&("[object Error]"===I(e)||e instanceof Error)}function _(e){return"function"==typeof e}function I(e){return Object.prototype.toString.call(e)}function C(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(59);var k=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function T(){var e=new Date,t=[C(e.getHours()),C(e.getMinutes()),C(e.getSeconds())].join(":");return[e.getDate(),k[e.getMonth()],t].join(" ")}function P(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){console.log("%s - %s",T(),t.format.apply(t,arguments))},t.inherits=n(60),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var O="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(O&&e[O]){var t;if("function"!=typeof(t=e[O]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,O,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise((function(e,r){t=e,n=r})),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===u.prototype||(t=function(e){return u.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=8388608?e=8388608:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function _(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(I,e):I(e))}function I(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(k,e,t))}function k(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=u.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function x(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(D,t,e))}function D(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?x(this):_(this),null;if(0===(e=S(e,t))&&t.ended)return 0===t.length&&x(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?R(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&x(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var c=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function u(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",u),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(c):n.once("end",c),e.on("unpipe",u);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=a.length,s=c,console&&console.warn&&console.warn(s)}return e}function h(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=h.bind(r);return o.listener=n,r.wrapFn=o,o}function d(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var c=o[e];if(void 0===c)return!1;if("function"==typeof c)i(c,this,t);else{var u=c.length,l=y(c,u);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return d(this,e,!0)},s.prototype.rawListeners=function(e){return d(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):g.call(e,t)},s.prototype.listenerCount=g,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(40).EventEmitter},function(e,t,n){"use strict";var r=n(23);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";var r=n(66).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=c,this.end=u,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function c(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function u(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";(function(t,r,o){var i=n(23);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var s,c=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var u=n(19);u.inherits=n(15);var l={deprecate:n(69)},f=n(41),h=n(14).Buffer,p=o.Uint8Array||function(){};var d,g=n(42);function y(){}function v(e,t){s=s||n(9),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,u=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(u||0===u)?u:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(I,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),I(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?c(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function b(e){if(s=s||n(9),!(d.call(b,this)||this instanceof s))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),I(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,c=!0;n;)o[s]=n,n.isBuf||(c=!1),n=n.next,s+=1;o.allBuffers=c,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var u=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:u.length,u,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final((function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),I(e,t)}))}function I(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}u.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var c=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,I(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(13),n(67).setImmediate,n(8))},function(e,t,n){"use strict";e.exports=a;var r=n(9),o=n(19);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.lengths?a.slice(s).buffer:null}else{var c,u=t;if(-1===(c=u.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=c+1;n=u.substring(0,s),i=u.length>s?u.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(10).Buffer)},,,,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a},a=this&&this.__spread||function(){for(var e=[],t=0;t0?a-4:a;for(n=0;n>16&255,c[l++]=t>>8&255,c[l++]=255&t;2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,c[l++]=255&t);1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t);return c},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,c=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,c=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-u;else{if(i===c)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=u}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,c,u=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-a))<1&&(a--,c*=2),(t+=a+f>=1?h/c:h*Math.pow(2,1-f))*c>=2&&(a++,c/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*c-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,u-=8);e[n+p-d]|=128*g}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";(function(t){var r=n(58); /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT - */function o(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;u--)if(l[u]!==f[u])return!1;for(u=l.length-1;u>=0;u--)if(a=l[u],!m(e[a],t[a],n,r))return!1;return!0}(e,t,n,r))}return n?e===t:e==t}function w(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function E(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function S(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&v(o,n,"Missing expected exception"+r);var i="string"==typeof r,a=!e&&o&&!n;if((!e&&s.isError(o)&&i&&E(o,n)||a)&&v(o,n,"Got unwanted exception"+r),e&&o&&n&&!E(o,n)||!e&&o)throw o}h.AssertionError=function(e){this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=function(e){return g(y(e.actual),128)+" "+e.operator+" "+g(y(e.expected),128)}(this),this.generatedMessage=!0);var t=e.stackStartFunction||v;if(Error.captureStackTrace)Error.captureStackTrace(this,t);else{var n=new Error;if(n.stack){var r=n.stack,o=d(t),i=r.indexOf("\n"+o);if(i>=0){var s=r.indexOf("\n",i+1);r=r.substring(s+1)}this.stack=r}}},s.inherits(h.AssertionError,Error),h.fail=v,h.ok=b,h.equal=function(e,t,n){e!=t&&v(e,t,n,"==",h.equal)},h.notEqual=function(e,t,n){e==t&&v(e,t,n,"!=",h.notEqual)},h.deepEqual=function(e,t,n){m(e,t,!1)||v(e,t,n,"deepEqual",h.deepEqual)},h.deepStrictEqual=function(e,t,n){m(e,t,!0)||v(e,t,n,"deepStrictEqual",h.deepStrictEqual)},h.notDeepEqual=function(e,t,n){m(e,t,!1)&&v(e,t,n,"notDeepEqual",h.notDeepEqual)},h.notDeepStrictEqual=function e(t,n,r){m(t,n,!0)&&v(t,n,r,"notDeepStrictEqual",e)},h.strictEqual=function(e,t,n){e!==t&&v(e,t,n,"===",h.strictEqual)},h.notStrictEqual=function(e,t,n){e===t&&v(e,t,n,"!==",h.notStrictEqual)},h.throws=function(e,t,n){S(!0,e,t,n)},h.doesNotThrow=function(e,t,n){S(!1,e,t,n)},h.ifError=function(e){if(e)throw e},h.strict=r((function e(t,n){t||v(t,!0,n,"==",e)}),h,{equal:h.strictEqual,deepEqual:h.deepStrictEqual,notEqual:h.notStrictEqual,notDeepEqual:h.notDeepStrictEqual}),h.strict.strict=h.strict;var C=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(8))},function(e,t,n){"use strict"; + */function o(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;u--)if(l[u]!==f[u])return!1;for(u=l.length-1;u>=0;u--)if(s=l[u],!m(e[s],t[s],n,r))return!1;return!0}(e,t,n,r))}return n?e===t:e==t}function w(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function E(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function S(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&v(o,n,"Missing expected exception"+r);var i="string"==typeof r,s=!e&&o&&!n;if((!e&&a.isError(o)&&i&&E(o,n)||s)&&v(o,n,"Got unwanted exception"+r),e&&o&&n&&!E(o,n)||!e&&o)throw o}h.AssertionError=function(e){this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=function(e){return g(y(e.actual),128)+" "+e.operator+" "+g(y(e.expected),128)}(this),this.generatedMessage=!0);var t=e.stackStartFunction||v;if(Error.captureStackTrace)Error.captureStackTrace(this,t);else{var n=new Error;if(n.stack){var r=n.stack,o=d(t),i=r.indexOf("\n"+o);if(i>=0){var a=r.indexOf("\n",i+1);r=r.substring(a+1)}this.stack=r}}},a.inherits(h.AssertionError,Error),h.fail=v,h.ok=b,h.equal=function(e,t,n){e!=t&&v(e,t,n,"==",h.equal)},h.notEqual=function(e,t,n){e==t&&v(e,t,n,"!=",h.notEqual)},h.deepEqual=function(e,t,n){m(e,t,!1)||v(e,t,n,"deepEqual",h.deepEqual)},h.deepStrictEqual=function(e,t,n){m(e,t,!0)||v(e,t,n,"deepStrictEqual",h.deepStrictEqual)},h.notDeepEqual=function(e,t,n){m(e,t,!1)&&v(e,t,n,"notDeepEqual",h.notDeepEqual)},h.notDeepStrictEqual=function e(t,n,r){m(t,n,!0)&&v(t,n,r,"notDeepStrictEqual",e)},h.strictEqual=function(e,t,n){e!==t&&v(e,t,n,"===",h.strictEqual)},h.notStrictEqual=function(e,t,n){e===t&&v(e,t,n,"!==",h.notStrictEqual)},h.throws=function(e,t,n){S(!0,e,t,n)},h.doesNotThrow=function(e,t,n){S(!1,e,t,n)},h.ifError=function(e){if(e)throw e},h.strict=r((function e(t,n){t||v(t,!0,n,"==",e)}),h,{equal:h.strictEqual,deepEqual:h.deepStrictEqual,notEqual:h.notStrictEqual,notDeepEqual:h.notDeepStrictEqual}),h.strict.strict=h.strict;var _=Object.keys||function(e){var t=[];for(var n in e)s.call(e,n)&&t.push(n);return t}}).call(this,n(8))},function(e,t,n){"use strict"; /* object-assign (c) Sindre Sorhus @license MIT -*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function s(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,a,c=s(e),u=1;u0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),s=this.head,a=0;s;)t=s.data,n=i,o=a,t.copy(n,o),a+=s.data.length,s=s.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){var r=n(10),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function s(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=s),s.prototype=Object.create(o.prototype),i(o,s),s.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},s.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},s.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},s.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout((function(){e._onTimeout&&e._onTimeout()}),t))},n(67),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(8))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,s,a,c=1,u={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick((function(){d(e)}))}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(s="setImmediate$"+Math.random()+"$",a=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(s)&&d(+t.data.slice(s.length))},e.addEventListener?e.addEventListener("message",a,!1):e.attachEvent("onmessage",a),r=function(t){e.postMessage(s+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=c,e.exports.encoder=a},function(e,t,n){(t=e.exports=n(36)).Stream=t,t.Readable=t,t.Writable=n(41),t.Duplex=n(9),t.Transform=n(42),t.PassThrough=n(71)},function(e,t,n){"use strict";e.exports=i;var r=n(42),o=n(19);function i(e){if(!(this instanceof i))return new i(e);r.call(this,e)}o.inherits=n(15),o.inherits(i,r),i.prototype._transform=function(e,t,n){n(null,e)}},function(e,t,n){var r=n(20);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(35).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var s=e.readUInt32BE(t+0),a=e.readUInt32BE(t+4);return(4294967296*s+a)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),s(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),s(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),a(e,r,i,3);case 223:throw new Error("map too big to decode in JS");case 212:return c(e,r,1);case 213:return c(e,r,2);case 214:return c(e,r,4);case 215:return c(e,r,8);case 216:return c(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?u(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?u(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?u(e,r,l,i,6):null}if(144==(240&h))return s(e,r,i=15&h,1);if(128==(240&h))return a(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function s(e,t,r,o){var s,a=[],c=0;for(t+=o,s=0;s.1)&&((n=r.allocUnsafe(9))[0]=203,n.writeDoubleBE(e,1)),n}e.exports=function(e,t,n,s){function a(c,u){var l,f,h;if(void 0===c)throw new Error("undefined is not encodable in msgpack!");if(null===c)(l=r.allocUnsafe(1))[0]=192;else if(!0===c)(l=r.allocUnsafe(1))[0]=195;else if(!1===c)(l=r.allocUnsafe(1))[0]=194;else if("string"==typeof c)(f=r.byteLength(c))<32?((l=r.allocUnsafe(1+f))[0]=160|f,f>0&&l.write(c,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(c,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(c,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(c,5));else if(c&&(c.readUInt32LE||c instanceof Uint8Array))c instanceof Uint8Array&&(c=r.from(c)),c.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=c.length):c.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(c.length,1)),l=o([l,c]);else if(Array.isArray(c))c.length<16?(l=r.allocUnsafe(1))[0]=144|c.length:c.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(c.length,1)),l=c.reduce((function(e,t){return e.append(a(t,!0)),e}),o().append(l));else{if(!s&&"function"==typeof c.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),s=1e6*(n-1e3*i);if(s||i>4294967295){(t=new r(10))[0]=215,t[1]=-1;var a=4*s,c=i/Math.pow(2,32),u=a+c&4294967295,l=4294967295&i;t.writeInt32BE(u,2),t.writeInt32BE(l,6)}else(t=new r(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(c);if("object"==typeof c)l=function(t){var n,i,s,a=[];for(n=0;n>8),a.push(255&s)):(a.push(201),a.push(s>>24),a.push(s>>16&255),a.push(s>>8&255),a.push(255&s));return o().append(r.from(a)).append(i)}(c)||function(e){var t,n,i=[],s=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++s,i.push(a(t,!0)),i.push(a(e[t],!0)));s<16?(n=r.allocUnsafe(1))[0]=128|s:((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(s,1));return i.unshift(n),i.reduce((function(e,t){return e.append(t)}),o())}(c);else if("number"==typeof c){if((h=c)!==Math.floor(h))return i(c,t);if(c>=0)if(c<128)(l=r.allocUnsafe(1))[0]=c;else if(c<256)(l=r.allocUnsafe(2))[0]=204,l[1]=c;else if(c<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(c,1);else if(c<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(c,1);else{if(!(c<=9007199254740991))return i(c,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,c)}else if(c>=-32)(l=r.allocUnsafe(1))[0]=256+c;else if(c>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(c,1);else if(c>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(c,1);else if(c>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(c,1);else{if(!(c>=-9007199254740991))return i(c,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var s=1,a=t+7;a>=t;a--){var c=(255^e[a])+s;e[a]=255&c,s=c>>8}}(l,1,c)}}}if(!l)throw new Error("not implemented yet");return u?l:l.slice()}return a}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId?this.fatalError?(this.logger.log(a.LogLevel.Debug,"Received a new batch "+e+" but errored out on a previous batch "+(this.nextBatchId-1)),[4,n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())]):[3,4]:[3,5];case 3:return o.sent(),[2];case 4:return this.logger.log(a.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed."),[2];case 5:return o.trys.push([5,7,,8]),this.nextBatchId++,this.logger.log(a.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new s.OutOfProcessRenderBatch(t)),[4,this.completeBatch(n,e)];case 6:return o.sent(),[3,8];case 7:throw r=o.sent(),this.fatalError=r.toString(),this.logger.log(a.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,r.toString()),r;case 8:return[2]}}))}))},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(a.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}}))}))},e}();t.RenderQueue=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(76),o=n(77),i=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new l(e),this.arrayBuilderSegmentReader=new f(e),this.diffReader=new s(e),this.editReader=new a(e,t),this.frameReader=new c(e,t)}return e.prototype.updatedComponents=function(){return o.readInt32LE(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return o.readInt32LE(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return o.readInt32LE(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return o.readInt32LE(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return o.readInt32LE(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+20*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return o.readInt32LE(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+8*t;return o.readUint64LE(this.batchData,n)},e}();t.OutOfProcessRenderBatch=i;var s=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),a=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),c=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return o.readInt32LE(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=o.readInt32LE(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return o.readUint64LE(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=o.readInt32LE(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t=o.readInt32LE(this.batchDataUint8,this.stringTableStartIndex+4*e),n=o.readLEB128(this.batchDataUint8,t),i=t+o.numLEB128Bytes(n),s=new Uint8Array(this.batchDataUint8.buffer,this.batchDataUint8.byteOffset+i,n);return r.decodeUtf8(s)},e}(),l=function(){function e(e){this.batchDataUint8=e}return e.prototype.count=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.values=function(e){return e+4},e}(),f=function(){function e(e){this.batchDataUint8=e}return e.prototype.offset=function(e){return 0},e.prototype.count=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.values=function(e){return e+4},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Math.pow(2,32),o=Math.pow(2,21)-1;function i(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=i,t.readUint64LE=function(e,t){var n=i(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+i(e,t)},t.readLEB128=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]e.MaximumFirstRetryInterval?e.MaximumFirstRetryInterval:t.retryIntervalMilliseconds,[4,this.delay(r)]):[3,7];case 2:if(o.sent(),this.isDisposed)return[3,7];o.label=3;case 3:return o.trys.push([3,5,,6]),[4,this.reconnectCallback()];case 4:return o.sent()||this.reconnectDisplay.rejected(),[2];case 5:return i=o.sent(),this.logger.log(a.LogLevel.Error,i),[3,6];case 6:return n++,[3,1];case 7:return this.reconnectDisplay.failed(),[2]}}))}))},e.prototype.delay=function(e){return new Promise((function(t){return setTimeout(t,e)}))},e.MaximumFirstRetryInterval=3e3,e}()},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",(function(){return location.reload()}))},e.prototype.rejected=function(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",(function(){return location.reload()}))},e.prototype.getLoader=function(){var e=this.document.createElement("div");return e.style.cssText=["border: 0.3em solid #f3f3f3","border-top: 0.3em solid #3498db","border-radius: 50%","width: 2em","height: 2em","display: inline-block"].join(";"),e.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:2e3,iterations:1/0}),e},e}();t.DefaultReconnectDisplay=s},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(t,n,r){this.dialog=t,this.maxRetries=n,this.document=r,this.document=r;var o=this.document.getElementById(e.MaxRetriesId);o&&(o.innerText=this.maxRetries.toString())}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.update=function(t){var n=this.document.getElementById(e.CurrentAttemptId);n&&(n.innerText=t.toString())},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.rejected=function(){this.removeClasses(),this.dialog.classList.add(e.RejectedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName,e.RejectedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e.RejectedClassName="components-reconnect-rejected",e.MaxRetriesId="components-reconnect-max-retries",e.CurrentAttemptId="components-reconnect-current-attempt",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";n.r(t),n.d(t,"VERSION",(function(){return l})),n.d(t,"MessagePackHubProtocol",(function(){return u}));var r=n(10),o=n(11),i=n(2),s=function(){function e(){}return e.write=function(e){var t=e.byteLength||e.length,n=[];do{var r=127&t;(t>>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+s))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+s):n.subarray(o+i,o+i+s)),o=o+i+s}return t},e}();var a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=3?e[2]:void 0,error:e[1],type:i.MessageType.Close}},e.prototype.createPingMessage=function(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:i.MessageType.Ping}},e.prototype.createInvocationMessage=function(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");var n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:i.MessageType.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:i.MessageType.Invocation}},e.prototype.createStreamItemMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:i.MessageType.StreamItem}},e.prototype.createCompletionMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");var n,r,o=t[3];if(o!==this.voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");switch(o){case this.errorResult:n=t[4];break;case this.nonVoidResult:r=t[4]}return{error:n,headers:e,invocationId:t[2],result:r,type:i.MessageType.Completion}},e.prototype.writeInvocation=function(e){var t,n=o(this.messagePackOptions);return t=e.streamIds?n.encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]):n.encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments]),s.write(t.slice())},e.prototype.writeStreamInvocation=function(e){var t,n=o(this.messagePackOptions);return t=e.streamIds?n.encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]):n.encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments]),s.write(t.slice())},e.prototype.writeStreamItem=function(e){var t=o(this.messagePackOptions).encode([i.MessageType.StreamItem,e.headers||{},e.invocationId,e.item]);return s.write(t.slice())},e.prototype.writeCompletion=function(e){var t,n=o(this.messagePackOptions),r=e.error?this.errorResult:e.result?this.nonVoidResult:this.voidResult;switch(r){case this.errorResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.error]);break;case this.voidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r]);break;case this.nonVoidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.result])}return s.write(t.slice())},e.prototype.writeCancelInvocation=function(e){var t=o(this.messagePackOptions).encode([i.MessageType.CancelInvocation,e.headers||{},e.invocationId]);return s.write(t.slice())},e.prototype.readHeaders=function(e){var t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t},e}(),l="5.0.0-dev"}]); \ No newline at end of file +*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,c=a(e),u=1;u0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){var r=n(10),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=a),a.prototype=Object.create(o.prototype),i(o,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout((function(){e._onTimeout&&e._onTimeout()}),t))},n(68),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(8))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,c=1,u={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick((function(){d(e)}))}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=c,e.exports.encoder=s},function(e,t,n){(t=e.exports=n(39)).Stream=t,t.Readable=t,t.Writable=n(44),t.Duplex=n(9),t.Transform=n(45),t.PassThrough=n(72)},function(e,t,n){"use strict";e.exports=i;var r=n(45),o=n(19);function i(e){if(!(this instanceof i))return new i(e);r.call(this,e)}o.inherits=n(15),o.inherits(i,r),i.prototype._transform=function(e,t,n){n(null,e)}},function(e,t,n){var r=n(22);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(38).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:throw new Error("map too big to decode in JS");case 212:return c(e,r,1);case 213:return c(e,r,2);case 214:return c(e,r,4);case 215:return c(e,r,8);case 216:return c(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?u(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?u(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?u(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],c=0;for(t+=o,a=0;a.1)&&((n=r.allocUnsafe(9))[0]=203,n.writeDoubleBE(e,1)),n}e.exports=function(e,t,n,a){function s(c,u){var l,f,h;if(void 0===c)throw new Error("undefined is not encodable in msgpack!");if(null===c)(l=r.allocUnsafe(1))[0]=192;else if(!0===c)(l=r.allocUnsafe(1))[0]=195;else if(!1===c)(l=r.allocUnsafe(1))[0]=194;else if("string"==typeof c)(f=r.byteLength(c))<32?((l=r.allocUnsafe(1+f))[0]=160|f,f>0&&l.write(c,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(c,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(c,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(c,5));else if(c&&(c.readUInt32LE||c instanceof Uint8Array))c instanceof Uint8Array&&(c=r.from(c)),c.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=c.length):c.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(c.length,1)),l=o([l,c]);else if(Array.isArray(c))c.length<16?(l=r.allocUnsafe(1))[0]=144|c.length:c.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(c.length,1)),l=c.reduce((function(e,t){return e.append(s(t,!0)),e}),o().append(l));else{if(!a&&"function"==typeof c.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=new r(10))[0]=215,t[1]=-1;var s=4*a,c=i/Math.pow(2,32),u=s+c&4294967295,l=4294967295&i;t.writeInt32BE(u,2),t.writeInt32BE(l,6)}else(t=new r(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(c);if("object"==typeof c)l=function(t){var n,i,a,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(c)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1));return i.unshift(n),i.reduce((function(e,t){return e.append(t)}),o())}(c);else if("number"==typeof c){if((h=c)!==Math.floor(h))return i(c,t);if(c>=0)if(c<128)(l=r.allocUnsafe(1))[0]=c;else if(c<256)(l=r.allocUnsafe(2))[0]=204,l[1]=c;else if(c<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(c,1);else if(c<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(c,1);else{if(!(c<=9007199254740991))return i(c,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,c)}else if(c>=-32)(l=r.allocUnsafe(1))[0]=256+c;else if(c>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(c,1);else if(c>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(c,1);else if(c>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(c,1);else{if(!(c>=-9007199254740991))return i(c,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var c=(255^e[s])+a;e[s]=255&c,a=c>>8}}(l,1,c)}}}if(!l)throw new Error("not implemented yet");return u?l:l.slice()}return s}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId?this.fatalError?(this.logger.log(s.LogLevel.Debug,"Received a new batch "+e+" but errored out on a previous batch "+(this.nextBatchId-1)),[4,n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())]):[3,4]:[3,5];case 3:return o.sent(),[2];case 4:return this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed."),[2];case 5:return o.trys.push([5,7,,8]),this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),[4,this.completeBatch(n,e)];case 6:return o.sent(),[3,8];case 7:throw r=o.sent(),this.fatalError=r.toString(),this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,r.toString()),r;case 8:return[2]}}))}))},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}}))}))},e}();t.RenderQueue=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(77),o=n(78),i=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new l(e),this.arrayBuilderSegmentReader=new f(e),this.diffReader=new a(e),this.editReader=new s(e,t),this.frameReader=new c(e,t)}return e.prototype.updatedComponents=function(){return o.readInt32LE(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return o.readInt32LE(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return o.readInt32LE(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return o.readInt32LE(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return o.readInt32LE(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+20*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return o.readInt32LE(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+8*t;return o.readUint64LE(this.batchData,n)},e}();t.OutOfProcessRenderBatch=i;var a=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),s=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),c=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return o.readInt32LE(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return o.readInt32LE(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=o.readInt32LE(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=o.readInt32LE(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return o.readUint64LE(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=o.readInt32LE(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t=o.readInt32LE(this.batchDataUint8,this.stringTableStartIndex+4*e),n=o.readLEB128(this.batchDataUint8,t),i=t+o.numLEB128Bytes(n),a=new Uint8Array(this.batchDataUint8.buffer,this.batchDataUint8.byteOffset+i,n);return r.decodeUtf8(a)},e}(),l=function(){function e(e){this.batchDataUint8=e}return e.prototype.count=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.values=function(e){return e+4},e}(),f=function(){function e(e){this.batchDataUint8=e}return e.prototype.offset=function(e){return 0},e.prototype.count=function(e){return o.readInt32LE(this.batchDataUint8,e)},e.prototype.values=function(e){return e+4},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Math.pow(2,32),o=Math.pow(2,21)-1;function i(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=i,t.readUint64LE=function(e,t){var n=i(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+i(e,t)},t.readLEB128=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]e.MaximumFirstRetryInterval?e.MaximumFirstRetryInterval:t.retryIntervalMilliseconds,[4,this.delay(r)]):[3,7];case 2:if(o.sent(),this.isDisposed)return[3,7];o.label=3;case 3:return o.trys.push([3,5,,6]),[4,this.reconnectCallback()];case 4:return o.sent()||this.reconnectDisplay.rejected(),[2];case 5:return i=o.sent(),this.logger.log(s.LogLevel.Error,i),[3,6];case 6:return n++,[3,1];case 7:return this.reconnectDisplay.failed(),[2]}}))}))},e.prototype.delay=function(e){return new Promise((function(t){return setTimeout(t,e)}))},e.MaximumFirstRetryInterval=3e3,e}()},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}c((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",(function(){return location.reload()}))},e.prototype.rejected=function(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.loader.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",(function(){return location.reload()}))},e.prototype.getLoader=function(){var e=this.document.createElement("div");return e.style.cssText=["border: 0.3em solid #f3f3f3","border-top: 0.3em solid #3498db","border-radius: 50%","width: 2em","height: 2em","display: inline-block"].join(";"),e.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:2e3,iterations:1/0}),e},e}();t.DefaultReconnectDisplay=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(t,n,r){this.dialog=t,this.maxRetries=n,this.document=r,this.document=r;var o=this.document.getElementById(e.MaxRetriesId);o&&(o.innerText=this.maxRetries.toString())}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.update=function(t){var n=this.document.getElementById(e.CurrentAttemptId);n&&(n.innerText=t.toString())},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.rejected=function(){this.removeClasses(),this.dialog.classList.add(e.RejectedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName,e.RejectedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e.RejectedClassName="components-reconnect-rejected",e.MaxRetriesId="components-reconnect-max-retries",e.CurrentAttemptId="components-reconnect-current-attempt",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";n.r(t),n.d(t,"VERSION",(function(){return l})),n.d(t,"MessagePackHubProtocol",(function(){return u}));var r=n(10),o=n(11),i=n(2),a=function(){function e(){}return e.write=function(e){var t=e.byteLength||e.length,n=[];do{var r=127&t;(t>>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=3?e[2]:void 0,error:e[1],type:i.MessageType.Close}},e.prototype.createPingMessage=function(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:i.MessageType.Ping}},e.prototype.createInvocationMessage=function(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");var n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:i.MessageType.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:i.MessageType.Invocation}},e.prototype.createStreamItemMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:i.MessageType.StreamItem}},e.prototype.createCompletionMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");var n,r,o=t[3];if(o!==this.voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");switch(o){case this.errorResult:n=t[4];break;case this.nonVoidResult:r=t[4]}return{error:n,headers:e,invocationId:t[2],result:r,type:i.MessageType.Completion}},e.prototype.writeInvocation=function(e){var t,n=o(this.messagePackOptions);return t=e.streamIds?n.encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]):n.encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments]),a.write(t.slice())},e.prototype.writeStreamInvocation=function(e){var t,n=o(this.messagePackOptions);return t=e.streamIds?n.encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]):n.encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments]),a.write(t.slice())},e.prototype.writeStreamItem=function(e){var t=o(this.messagePackOptions).encode([i.MessageType.StreamItem,e.headers||{},e.invocationId,e.item]);return a.write(t.slice())},e.prototype.writeCompletion=function(e){var t,n=o(this.messagePackOptions),r=e.error?this.errorResult:e.result?this.nonVoidResult:this.voidResult;switch(r){case this.errorResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.error]);break;case this.voidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r]);break;case this.nonVoidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.result])}return a.write(t.slice())},e.prototype.writeCancelInvocation=function(e){var t=o(this.messagePackOptions).encode([i.MessageType.CancelInvocation,e.headers||{},e.invocationId]);return a.write(t.slice())},e.prototype.readHeaders=function(e){var t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t},e}(),l="5.0.0-dev"}]); \ No newline at end of file diff --git a/src/Components/Web.JS/dist/Release/blazor.webassembly.js b/src/Components/Web.JS/dist/Release/blazor.webassembly.js index df469f8e58..a16c6c4abb 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Web.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=44)}([,,,function(e,t,n){"use strict";var r;n.r(t),n.d(t,"DotNet",(function(){return r})),function(e){var t;window.DotNet=e;var n=[],r=function(){function e(e){this._jsObject=e,this._cachedFunctions=new Map}return e.prototype.findFunction=function(e){var t=this._cachedFunctions.get(e);if(t)return t;var n,r=this._jsObject;if(e.split(".").forEach((function(t){if(!(t in r))throw new Error("Could not find '"+e+"' ('"+t+"' was undefined).");n=r,r=r[t]})),r instanceof Function)return r=r.bind(n),this._cachedFunctions.set(e,r),r;throw new Error("The value '"+e+"' is not a function.")},e.prototype.getWrappedObject=function(){return this._jsObject},e}(),o={},i=((t={})[0]=new r(window),t);i[0]._cachedFunctions.set("import",(function(e){return"string"==typeof e&&e.startsWith("./")&&(e=document.baseURI+e.substr(2)),import(e)}));var a,s=1,u=1,c=null;function l(e){n.push(e)}function f(e){var t;if(e&&"object"==typeof e){i[u]=new r(e);var n=((t={}).__jsObjectId=u,t);return u++,n}throw new Error("Cannot create a JSObjectReference from the value '"+e+"'.")}function d(e){return e?JSON.parse(e,(function(e,t){return n.reduce((function(t,n){return n(e,t)}),t)})):null}function p(e,t,n,r){var o=m();if(o.invokeDotNetFromJS){var i=JSON.stringify(r,_),a=o.invokeDotNetFromJS(e,t,n,i);return a?d(a):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function h(e,t,n,r){if(e&&n)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=s++,a=new Promise((function(e,t){o[i]={resolve:e,reject:t}}));try{var u=JSON.stringify(r,_);m().beginInvokeDotNetFromJS(i,e,t,n,u)}catch(e){v(i,!1,e)}return a}function m(){if(null!==c)return c;throw new Error("No .NET call dispatcher has been set.")}function v(e,t,n){if(!o.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var r=o[e];delete o[e],t?r.resolve(n):r.reject(n)}function y(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function b(e,t){var n=i[t];if(n)return n.findFunction(e);throw new Error("JS object instance with ID "+t+" does not exist (has it been disposed?).")}function g(e){delete i[e]}e.attachDispatcher=function(e){c=e},e.attachReviver=l,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0)}var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23),n(17);var r=n(24),o=n(7),i={},a=!1;function s(e,t,n){var o=i[e];o||(o=i[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=s,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");s(n||0,o.toLogicalElement(r,!0),t)},t.getRendererer=function(e){return i[e]},t.renderBatch=function(e,t){var n=i[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),s=r.values(o),u=r.count(o),c=t.referenceFrames(),l=r.values(c),f=t.diffReader,d=0;d0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,a)}}))}),{root:o(t),rootMargin:i+"px"});a.observe(t),a.observe(n);var s=c(t),u=c(n);function c(e){var t=new MutationObserver((function(){a.unobserve(e),a.observe(e)}));return t.observe(e,{attributes:!0}),t}r[e._id]={intersectionObserver:a,mutationObserverBefore:s,mutationObserverAfter:u}},dispose:function(e){var t=r[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete r[e._id])}};var r={};function o(e){return e?"visible"!==getComputedStyle(e).overflowY?e:o(e.parentElement):null}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1].*)$/;function i(e,t){var n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r.groups&&r.groups.descriptor;if(!i)return;try{var s=function(e){var t=JSON.parse(e),n=t.type;if("server"!==n&&"webassembly"!==n)throw new Error("Invalid component type '"+n+"'.");return t}(i);switch(t){case"webassembly":return function(e,t,n){var r=e.type,o=e.assembly,i=e.typeName,s=e.parameterDefinitions,u=e.parameterValues,c=e.prerenderId;if("webassembly"!==r)return;if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(c){var l=a(c,n);if(!l)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:u&&atob(u),start:t,prerenderId:c,end:l}}return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:u&&atob(u),start:t}}(s,n,e);case"server":return function(e,t,n){var r=e.type,o=e.descriptor,i=e.sequence,s=e.prerenderId;if("server"!==r)return;if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error("Error parsing the sequence '"+i+"' for component '"+JSON.stringify(e)+"'");if(s){var u=a(s,n);if(!u)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,sequence:i,descriptor:o,start:t,prerenderId:s,end:u}}return{type:r,sequence:i,descriptor:o,start:t}}(s,n,e)}}catch(e){throw new Error("Found malformed component comment at "+n.textContent)}}}function a(e,t){for(;t.next()&&t.currentElement;){var n=t.currentElement;if(n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r[1];if(i)return s(i,e),n}}}function s(e,t){var n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error("Invalid end of component comment: '"+e+"'");var r=n.prerenderId;if(!r)throw new Error("End of component comment must have a value for the prerendered property: '"+e+"'");if(r!==t)throw new Error("End of component comment prerendered property must match the start comment prerender id: '"+t+"', '"+r+"'")}var u=function(){function e(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}return e.prototype.next=function(){return this.currentIndex++,this.currentIndex0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var a=n(3);n(22);var s=n(17),u=n(45),c=n(12),l=n(47),f=n(33),d=n(18),p=n(48),h=n(49),m=n(50),v=n(51),y=n(34),b=!1;function g(e){return r(this,void 0,void 0,(function(){var t,n,f,g,E,_,I,C,N,A,S,k=this;return o(this,(function(O){switch(O.label){case 0:if(b)throw new Error("Blazor has already started.");return b=!0,d.setEventDispatcher((function(e,t){c.getRendererer(e.browserRendererId).eventDelegator.getHandler(e.eventHandlerId)&&u.monoPlatform.invokeWhenHeapUnlocked((function(){return a.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))}))})),window.Blazor._internal.invokeJSFromDotNet=w,t=s.setPlatform(u.monoPlatform),window.Blazor.platform=t,window.Blazor._internal.renderBatch=function(e,t){var n=u.monoPlatform.beginHeapLock();try{c.renderBatch(e,new l.SharedMemoryRenderBatch(t))}finally{n.release()}},n=window.Blazor._internal.navigationManager.getBaseURI,f=window.Blazor._internal.navigationManager.getLocationHref,window.Blazor._internal.navigationManager.getUnmarshalledBaseURI=function(){return BINDING.js_string_to_mono_string(n())},window.Blazor._internal.navigationManager.getUnmarshalledLocationHref=function(){return BINDING.js_string_to_mono_string(f())},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(k,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,a.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),g=null==e?void 0:e.environment,E=m.BootConfigResult.initAsync(g),_=y.discoverComponents(document,"webassembly"),I=new v.WebAssemblyComponentAttacher(_),window.Blazor._internal.registeredComponents={getRegisteredComponentsCount:function(){return I.getCount()},getId:function(e){return I.getId(e)},getAssembly:function(e){return BINDING.js_string_to_mono_string(I.getAssembly(e))},getTypeName:function(e){return BINDING.js_string_to_mono_string(I.getTypeName(e))},getParameterDefinitions:function(e){return BINDING.js_string_to_mono_string(I.getParameterDefinitions(e)||"")},getParameterValues:function(e){return BINDING.js_string_to_mono_string(I.getParameterValues(e)||"")}},window.Blazor._internal.attachRootComponentToElement=function(e,t,n){var r=I.resolveRegisteredElement(e);r?c.attachRootComponentToLogicalElement(n,r,t):c.attachRootComponentToElement(e,t,n)},[4,E];case 1:return C=O.sent(),[4,Promise.all([p.WebAssemblyResourceLoader.initAsync(C.bootConfig,e||{}),h.WebAssemblyConfigLoader.initAsync(C)])];case 2:N=i.apply(void 0,[O.sent(),1]),A=N[0],O.label=3;case 3:return O.trys.push([3,5,,6]),[4,t.start(A)];case 4:return O.sent(),[3,6];case 5:throw S=O.sent(),new Error("Failed to start platform. Reason: "+S);case 6:return t.callEntryPoint(A.bootConfig.entryAssembly),[2]}}))}))}function w(e,t,n,r){var o=u.monoPlatform.readStringField(e,0),i=u.monoPlatform.readInt32Field(e,4),s=u.monoPlatform.readStringField(e,8),c=u.monoPlatform.readUint64Field(e,20);if(null!==s){var l=u.monoPlatform.readUint64Field(e,12);if(0!==l)return a.DotNet.jsCallDispatcher.beginInvokeJSFromDotNet(l,o,s,i,c),0;var f=a.DotNet.jsCallDispatcher.invokeJSFromDotNet(o,s,i,c);return null===f?0:BINDING.js_string_to_mono_string(f)}return a.DotNet.jsCallDispatcher.findJSFunction(o,c).call(null,t,n,r)}window.Blazor.start=g,f.shouldAutoStart()&&g().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var c,l;s.attachDebuggerHotkey(e),window.Browser={init:function(){}},c=function(){window.Module=function(e,t,n){var c=this,l=e.bootConfig.resources,f=window.Module||{},d=["DEBUGGING ENABLED"];f.print=function(e){return d.indexOf(e)<0&&console.log(e)},f.printErr=function(e){console.error(e),u.showErrorNotification()},f.preRun=f.preRun||[],f.postRun=f.postRun||[],f.preloadPlugins=[];var h,b,g=e.loadResources(l.assembly,(function(e){return"_framework/"+e}),"assembly"),w=e.loadResources(l.pdb||{},(function(e){return"_framework/"+e}),"pdb"),E=e.loadResource("dotnet.wasm","_framework/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.blat")&&(h=e.loadResource("dotnet.timezones.blat","_framework/dotnet.timezones.blat",e.bootConfig.resources.runtime["dotnet.timezones.blat"],"globalization")),e.bootConfig.resources.runtime.hasOwnProperty("icudt.dat")&&(b=e.loadResource("icudt.dat","_framework/icudt.dat",e.bootConfig.resources.runtime["icudt.dat"],"globalization")),f.instantiateWasm=function(e,t){return r(c,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,E];case 1:return[4,v(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),f.printErr(r),r;case 4:return t(n),[2]}}))})),[]},f.preRun.push((function(){i=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),MONO.loaded_files=[],h&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),Module.FS_createPath("/","usr",!0,!0),Module.FS_createPath("/usr/","share",!0,!0),Module.FS_createPath("/usr/share/","zoneinfo",!0,!0),MONO.mono_wasm_load_data_archive(new Uint8Array(n),"/usr/share/zoneinfo/"),removeRunDependency(t),[2]}}))}))}(h),b?function(e){r(this,void 0,void 0,(function(){var t,n,r,i,a;return o(this,(function(o){switch(o.label){case 0:return t="blazor:icudata",addRunDependency(t),[4,e.response];case 1:return n=o.sent(),i=Uint8Array.bind,[4,n.arrayBuffer()];case 2:if(r=new(i.apply(Uint8Array,[void 0,o.sent()])),a=MONO.mono_wasm_load_bytes_into_heap(r),!MONO.mono_wasm_load_icu_data(a))throw new Error("Error loading ICU asset.");return removeRunDependency(t),[2]}}))}))}(b):MONO.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT","1"),g.forEach((function(e){return _(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),w.forEach((function(e){return _(e,e.name)})),window.Blazor._internal.dotNetCriticalError=function(e){f.printErr(BINDING.conv_string(e)||"(null)")},window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),i=e.bootConfig.resources.satelliteResources;if(i){var a=Promise.all(n.filter((function(e){return i.hasOwnProperty(e)})).map((function(t){return e.loadResources(i[t],(function(e){return"_framework/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(c,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(a.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n>1];var n},readInt32Field:function(e,t){return d(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>l)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*c+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return d(e+(t||0))},readStringField:function(e,t,n){var r,o=d(e+(t||0));if(0===o)return null;if(n){var i=BINDING.unbox_mono_obj(o);return"boolean"==typeof i?i?"":null:i}return f?void 0===(r=f.stringCache.get(o))&&(r=BINDING.conv_string(o),f.stringCache.set(o,r)):r=BINDING.conv_string(o),r},readStructField:function(e,t){return e+(t||0)},beginHeapLock:function(){return y(),f=new b},invokeWhenHeapUnlocked:function(e){f?f.enqueuePostReleaseAction(e):e()}};var p=document.createElement("a");function h(e){return e+12}function m(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function v(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}function y(){if(f)throw new Error("Assertion failed - heap is currently locked")}var b=function(){function e(){this.stringCache=new Map}return e.prototype.enqueuePostReleaseAction=function(e){this.postReleaseActions||(this.postReleaseActions=[]),this.postReleaseActions.push(e)},e.prototype.release=function(){var e;if(f!==this)throw new Error("Trying to release a lock which isn't current");for(f=null;null===(e=this.postReleaseActions)||void 0===e?void 0:e.length;){this.postReleaseActions.shift()(),y()}},e}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=window.chrome&&navigator.userAgent.indexOf("Edge")<0,o=!0;window.addEventListener("load",(function(){var e=new URLSearchParams(window.location.search);o="true"===e.get("_blazor_debug")}));var i=!1;function a(){return o&&i&&r}t.hasDebuggingEnabled=a,t.attachDebuggerHotkey=function(e){i=!!e.bootConfig.resources.pdb;var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";a()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",(function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(i?r?o?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("_blazor_debug query parameter must be set to enable debugging. To enable debugging, go to "+location.href+"?_blazor_debug=true."):console.error("Currently, only Microsoft Edge (80+), or Google Chrome, are supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=i,this.arrayBuilderSegmentReader=a,this.diffReader=s,this.editReader=u,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,i.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*i.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*i.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,s.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var i={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},a={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},s={structLength:4+a.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,u.structLength)}},u={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0)}var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(17);var r=n(26),o=n(7),i={},a=!1;function s(e,t,n){var o=i[e];o||(o=i[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=s,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");s(n||0,o.toLogicalElement(r,!0),t)},t.getRendererer=function(e){return i[e]},t.renderBatch=function(e,t){var n=i[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),s=r.values(o),u=r.count(o),c=t.referenceFrames(),l=r.values(c),f=t.diffReader,d=0;d0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var c,l;s.attachDebuggerHotkey(e),window.Browser={init:function(){}},c=function(){window.Module=function(e,t,n){var c=this,l=e.bootConfig.resources,f=window.Module||{},d=["DEBUGGING ENABLED"];f.print=function(e){return d.indexOf(e)<0&&console.log(e)},f.printErr=function(e){console.error(e),u.showErrorNotification()},f.preRun=f.preRun||[],f.postRun=f.postRun||[],f.preloadPlugins=[];var h,b,g=e.loadResources(l.assembly,(function(e){return"_framework/"+e}),"assembly"),w=e.loadResources(l.pdb||{},(function(e){return"_framework/"+e}),"pdb"),E=e.loadResource("dotnet.wasm","_framework/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.blat")&&(h=e.loadResource("dotnet.timezones.blat","_framework/dotnet.timezones.blat",e.bootConfig.resources.runtime["dotnet.timezones.blat"],"globalization")),e.bootConfig.resources.runtime.hasOwnProperty("icudt.dat")&&(b=e.loadResource("icudt.dat","_framework/icudt.dat",e.bootConfig.resources.runtime["icudt.dat"],"globalization")),f.instantiateWasm=function(e,t){return r(c,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,E];case 1:return[4,v(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),f.printErr(r),r;case 4:return t(n),[2]}}))})),[]},f.preRun.push((function(){i=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),MONO.loaded_files=[],h&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),Module.FS_createPath("/","usr",!0,!0),Module.FS_createPath("/usr/","share",!0,!0),Module.FS_createPath("/usr/share/","zoneinfo",!0,!0),MONO.mono_wasm_load_data_archive(new Uint8Array(n),"/usr/share/zoneinfo/"),removeRunDependency(t),[2]}}))}))}(h),b?function(e){r(this,void 0,void 0,(function(){var t,n,r,i,a;return o(this,(function(o){switch(o.label){case 0:return t="blazor:icudata",addRunDependency(t),[4,e.response];case 1:return n=o.sent(),i=Uint8Array.bind,[4,n.arrayBuffer()];case 2:if(r=new(i.apply(Uint8Array,[void 0,o.sent()])),a=MONO.mono_wasm_load_bytes_into_heap(r),!MONO.mono_wasm_load_icu_data(a))throw new Error("Error loading ICU asset.");return removeRunDependency(t),[2]}}))}))}(b):MONO.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT","1"),g.forEach((function(e){return _(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),w.forEach((function(e){return _(e,e.name)})),window.Blazor._internal.dotNetCriticalError=function(e){f.printErr(BINDING.conv_string(e)||"(null)")},window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),i=e.bootConfig.resources.satelliteResources;if(i){var a=Promise.all(n.filter((function(e){return i.hasOwnProperty(e)})).map((function(t){return e.loadResources(i[t],(function(e){return"_framework/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(c,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(a.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n>1];var n},readInt32Field:function(e,t){return d(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>l)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*c+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return d(e+(t||0))},readStringField:function(e,t,n){var r,o=d(e+(t||0));if(0===o)return null;if(n){var i=BINDING.unbox_mono_obj(o);return"boolean"==typeof i?i?"":null:i}return f?void 0===(r=f.stringCache.get(o))&&(r=BINDING.conv_string(o),f.stringCache.set(o,r)):r=BINDING.conv_string(o),r},readStructField:function(e,t){return e+(t||0)},beginHeapLock:function(){return y(),f=new b},invokeWhenHeapUnlocked:function(e){f?f.enqueuePostReleaseAction(e):e()}};var p=document.createElement("a");function h(e){return e+12}function m(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function v(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}function y(){if(f)throw new Error("Assertion failed - heap is currently locked")}var b=function(){function e(){this.stringCache=new Map}return e.prototype.enqueuePostReleaseAction=function(e){this.postReleaseActions||(this.postReleaseActions=[]),this.postReleaseActions.push(e)},e.prototype.release=function(){var e;if(f!==this)throw new Error("Trying to release a lock which isn't current");for(f=null;null===(e=this.postReleaseActions)||void 0===e?void 0:e.length;){this.postReleaseActions.shift()(),y()}},e}()},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&e.invokeMethodAsync("OnSpacerAfterVisible",r.boundingClientRect.bottom-r.intersectionRect.bottom,i,a)}}))}),{root:o(t),rootMargin:i+"px"});a.observe(t),a.observe(n);var s=c(t),u=c(n);function c(e){var t=new MutationObserver((function(){a.unobserve(e),a.observe(e)}));return t.observe(e,{attributes:!0}),t}r[e._id]={intersectionObserver:a,mutationObserverBefore:s,mutationObserverAfter:u}},dispose:function(e){var t=r[e._id];t&&(t.intersectionObserver.disconnect(),t.mutationObserverBefore.disconnect(),t.mutationObserverAfter.disconnect(),e.dispose(),delete r[e._id])}};var r={};function o(e){return e?"visible"!==getComputedStyle(e).overflowY?e:o(e.parentElement):null}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1].*)$/;function i(e,t){var n=e.currentElement;if(n&&n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r.groups&&r.groups.descriptor;if(!i)return;try{var s=function(e){var t=JSON.parse(e),n=t.type;if("server"!==n&&"webassembly"!==n)throw new Error("Invalid component type '"+n+"'.");return t}(i);switch(t){case"webassembly":return function(e,t,n){var r=e.type,o=e.assembly,i=e.typeName,s=e.parameterDefinitions,u=e.parameterValues,c=e.prerenderId;if("webassembly"!==r)return;if(!o)throw new Error("assembly must be defined when using a descriptor.");if(!i)throw new Error("typeName must be defined when using a descriptor.");if(c){var l=a(c,n);if(!l)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:u&&atob(u),start:t,prerenderId:c,end:l}}return{type:r,assembly:o,typeName:i,parameterDefinitions:s&&atob(s),parameterValues:u&&atob(u),start:t}}(s,n,e);case"server":return function(e,t,n){var r=e.type,o=e.descriptor,i=e.sequence,s=e.prerenderId;if("server"!==r)return;if(!o)throw new Error("descriptor must be defined when using a descriptor.");if(void 0===i)throw new Error("sequence must be defined when using a descriptor.");if(!Number.isInteger(i))throw new Error("Error parsing the sequence '"+i+"' for component '"+JSON.stringify(e)+"'");if(s){var u=a(s,n);if(!u)throw new Error("Could not find an end component comment for '"+t+"'");return{type:r,sequence:i,descriptor:o,start:t,prerenderId:s,end:u}}return{type:r,sequence:i,descriptor:o,start:t}}(s,n,e)}}catch(e){throw new Error("Found malformed component comment at "+n.textContent)}}}function a(e,t){for(;t.next()&&t.currentElement;){var n=t.currentElement;if(n.nodeType===Node.COMMENT_NODE&&n.textContent){var r=new RegExp(o).exec(n.textContent),i=r&&r[1];if(i)return s(i,e),n}}}function s(e,t){var n=JSON.parse(e);if(1!==Object.keys(n).length)throw new Error("Invalid end of component comment: '"+e+"'");var r=n.prerenderId;if(!r)throw new Error("End of component comment must have a value for the prerendered property: '"+e+"'");if(r!==t)throw new Error("End of component comment prerendered property must match the start comment prerender id: '"+t+"', '"+r+"'")}var u=function(){function e(e){this.childNodes=e,this.currentIndex=-1,this.length=e.length}return e.prototype.next=function(){return this.currentIndex++,this.currentIndex0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var a=n(3);n(24);var s=n(17),u=n(20),c=n(12),l=n(48),f=n(36),d=n(18),p=n(49),h=n(50),m=n(51),v=n(52),y=n(37),b=!1;function g(e){return r(this,void 0,void 0,(function(){var t,n,f,g,E,_,I,C,N,A,S,k=this;return o(this,(function(F){switch(F.label){case 0:if(b)throw new Error("Blazor has already started.");return b=!0,d.setEventDispatcher((function(e,t){c.getRendererer(e.browserRendererId).eventDelegator.getHandler(e.eventHandlerId)&&u.monoPlatform.invokeWhenHeapUnlocked((function(){return a.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))}))})),window.Blazor._internal.invokeJSFromDotNet=w,t=s.setPlatform(u.monoPlatform),window.Blazor.platform=t,window.Blazor._internal.renderBatch=function(e,t){var n=u.monoPlatform.beginHeapLock();try{c.renderBatch(e,new l.SharedMemoryRenderBatch(t))}finally{n.release()}},n=window.Blazor._internal.navigationManager.getBaseURI,f=window.Blazor._internal.navigationManager.getLocationHref,window.Blazor._internal.navigationManager.getUnmarshalledBaseURI=function(){return BINDING.js_string_to_mono_string(n())},window.Blazor._internal.navigationManager.getUnmarshalledLocationHref=function(){return BINDING.js_string_to_mono_string(f())},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(k,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,a.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),g=null==e?void 0:e.environment,E=m.BootConfigResult.initAsync(g),_=y.discoverComponents(document,"webassembly"),I=new v.WebAssemblyComponentAttacher(_),window.Blazor._internal.registeredComponents={getRegisteredComponentsCount:function(){return I.getCount()},getId:function(e){return I.getId(e)},getAssembly:function(e){return BINDING.js_string_to_mono_string(I.getAssembly(e))},getTypeName:function(e){return BINDING.js_string_to_mono_string(I.getTypeName(e))},getParameterDefinitions:function(e){return BINDING.js_string_to_mono_string(I.getParameterDefinitions(e)||"")},getParameterValues:function(e){return BINDING.js_string_to_mono_string(I.getParameterValues(e)||"")}},window.Blazor._internal.attachRootComponentToElement=function(e,t,n){var r=I.resolveRegisteredElement(e);r?c.attachRootComponentToLogicalElement(n,r,t):c.attachRootComponentToElement(e,t,n)},[4,E];case 1:return C=F.sent(),[4,Promise.all([p.WebAssemblyResourceLoader.initAsync(C.bootConfig,e||{}),h.WebAssemblyConfigLoader.initAsync(C)])];case 2:N=i.apply(void 0,[F.sent(),1]),A=N[0],F.label=3;case 3:return F.trys.push([3,5,,6]),[4,t.start(A)];case 4:return F.sent(),[3,6];case 5:throw S=F.sent(),new Error("Failed to start platform. Reason: "+S);case 6:return t.callEntryPoint(A.bootConfig.entryAssembly),[2]}}))}))}function w(e,t,n,r){var o=u.monoPlatform.readStringField(e,0),i=u.monoPlatform.readInt32Field(e,4),s=u.monoPlatform.readStringField(e,8),c=u.monoPlatform.readUint64Field(e,20);if(null!==s){var l=u.monoPlatform.readUint64Field(e,12);if(0!==l)return a.DotNet.jsCallDispatcher.beginInvokeJSFromDotNet(l,o,s,i,c),0;var f=a.DotNet.jsCallDispatcher.invokeJSFromDotNet(o,s,i,c);return null===f?0:BINDING.js_string_to_mono_string(f)}return a.DotNet.jsCallDispatcher.findJSFunction(o,c).call(null,t,n,r)}window.Blazor.start=g,f.shouldAutoStart()&&g().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=i,this.arrayBuilderSegmentReader=a,this.diffReader=s,this.editReader=u,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,i.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*i.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*i.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,s.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var i={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},a={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},s={structLength:4+a.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,u.structLength)}},u={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,s)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1] | undefined; + arrayBuffer: ArrayBuffer | undefined; +} + +interface InputElement extends HTMLInputElement { + _blazorInputFileNextFileId: number; + _blazorFilesById: { [id: number]: BrowserFile }; +} + +function init(callbackWrapper: any, elem: InputElement): void { + elem._blazorInputFileNextFileId = 0; + + elem.addEventListener('click', function(): void { + // Permits replacing an existing file with a new one of the same file name. + elem.value = ''; + }); + + elem.addEventListener('change', function(): void { + // Reduce to purely serializable data, plus an index by ID. + elem._blazorFilesById = {}; + + const fileList = Array.prototype.map.call(elem.files, function(file): BrowserFile { + const result = { + id: ++elem._blazorInputFileNextFileId, + lastModified: new Date(file.lastModified).toISOString(), + name: file.name, + size: file.size, + type: file.type, + readPromise: undefined, + arrayBuffer: undefined, + }; + + elem._blazorFilesById[result.id] = result; + + // Attach the blob data itself as a non-enumerable property so it doesn't appear in the JSON. + Object.defineProperty(result, 'blob', { value: file }); + + return result; + }); + + callbackWrapper.invokeMethodAsync('NotifyChange', fileList); + }); +} + +async function toImageFile(elem: InputElement, fileId: number, format: string, maxWidth: number, maxHeight: number): Promise { + const originalFile = getFileById(elem, fileId); + + const loadedImage = await new Promise(function(resolve: (loadedImage: HTMLImageElement) => void): void { + const originalFileImage = new Image(); + originalFileImage.onload = function(): void { + resolve(originalFileImage); + }; + originalFileImage.src = URL.createObjectURL(originalFile['blob']); + }); + + const resizedImageBlob = await new Promise(function(resolve: BlobCallback): void { + const desiredWidthRatio = Math.min(1, maxWidth / loadedImage.width); + const desiredHeightRatio = Math.min(1, maxHeight / loadedImage.height); + const chosenSizeRatio = Math.min(desiredWidthRatio, desiredHeightRatio); + + const canvas = document.createElement('canvas'); + canvas.width = Math.round(loadedImage.width * chosenSizeRatio); + canvas.height = Math.round(loadedImage.height * chosenSizeRatio); + canvas.getContext('2d')?.drawImage(loadedImage, 0, 0, canvas.width, canvas.height); + canvas.toBlob(resolve, format); + }); + const result: BrowserFile = { + id: ++elem._blazorInputFileNextFileId, + lastModified: originalFile.lastModified, + name: originalFile.name, + size: resizedImageBlob?.size || 0, + type: format, + readPromise: undefined, + arrayBuffer: undefined, + }; + + elem._blazorFilesById[result.id] = result; + + // Attach the blob data itself as a non-enumerable property so it doesn't appear in the JSON. + Object.defineProperty(result, 'blob', { value: resizedImageBlob }); + + return result; +} + +async function ensureArrayBufferReadyForSharedMemoryInterop(elem: InputElement, fileId: number): Promise { + const arrayBuffer = await getArrayBufferFromFileAsync(elem, fileId); + getFileById(elem, fileId).arrayBuffer = arrayBuffer; +} + +async function readFileData(elem: InputElement, fileId: number, startOffset: number, count: number): Promise { + const arrayBuffer = await getArrayBufferFromFileAsync(elem, fileId); + return btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer, startOffset, count) as unknown as number[])); +} + +function readFileDataSharedMemory(readRequest: any): number { + const inputFileElementReferenceId = monoPlatform.readStringField(readRequest, 0); + const inputFileElement = document.querySelector(`[_bl_${inputFileElementReferenceId}]`); + const fileId = monoPlatform.readInt32Field(readRequest, 4); + const sourceOffset = monoPlatform.readUint64Field(readRequest, 8); + const destination = monoPlatform.readInt32Field(readRequest, 16) as unknown as System_Array; + const destinationOffset = monoPlatform.readInt32Field(readRequest, 20); + const maxBytes = monoPlatform.readInt32Field(readRequest, 24); + + const sourceArrayBuffer = getFileById(inputFileElement as InputElement, fileId).arrayBuffer as ArrayBuffer; + const bytesToRead = Math.min(maxBytes, sourceArrayBuffer.byteLength - sourceOffset); + const sourceUint8Array = new Uint8Array(sourceArrayBuffer, sourceOffset, bytesToRead); + + const destinationUint8Array = monoPlatform.toUint8Array(destination); + destinationUint8Array.set(sourceUint8Array, destinationOffset); + + return bytesToRead; +} + +function getFileById(elem: InputElement, fileId: number): BrowserFile { + const file = elem._blazorFilesById[fileId]; + + if (!file) { + throw new Error(`There is no file with ID ${fileId}. The file list may have changed.`); + } + + return file; +} + +function getArrayBufferFromFileAsync(elem: InputElement, fileId: number): Promise { + const file = getFileById(elem, fileId); + + // On the first read, convert the FileReader into a Promise. + if (!file.readPromise) { + file.readPromise = new Promise(function(resolve: (buffer: ArrayBuffer) => void, reject): void { + const reader = new FileReader(); + reader.onload = function(): void { + resolve(reader.result as ArrayBuffer); + }; + reader.onerror = function(err): void { + reject(err); + }; + reader.readAsArrayBuffer(file['blob']); + }); + } + + return file.readPromise; +} \ No newline at end of file diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoDebugger.ts b/src/Components/Web.JS/src/Platform/Mono/MonoDebugger.ts index 51cb0d94f1..55514e0a3b 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoDebugger.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoDebugger.ts @@ -3,17 +3,11 @@ import { WebAssemblyResourceLoader } from '../WebAssemblyResourceLoader'; const currentBrowserIsChrome = (window as any).chrome && navigator.userAgent.indexOf('Edge') < 0; // Edge pretends to be Chrome -let isDebugging = true; - -window.addEventListener('load', () => { - const params = new URLSearchParams(window.location.search); - isDebugging = params.get('_blazor_debug') === 'true'; -}) let hasReferencedPdbs = false; export function hasDebuggingEnabled() { - return isDebugging && hasReferencedPdbs && currentBrowserIsChrome; + return hasReferencedPdbs && currentBrowserIsChrome; } export function attachDebuggerHotkey(resourceLoader: WebAssemblyResourceLoader) { @@ -33,8 +27,6 @@ export function attachDebuggerHotkey(resourceLoader: WebAssemblyResourceLoader) console.error('Cannot start debugging, because the application was not compiled with debugging enabled.'); } else if (!currentBrowserIsChrome) { console.error('Currently, only Microsoft Edge (80+), or Google Chrome, are supported for debugging.'); - } else if (!isDebugging) { - console.error(`_blazor_debug query parameter must be set to enable debugging. To enable debugging, go to ${location.href}?_blazor_debug=true.`); } else { launchDebugger(); } diff --git a/src/Components/Web.Extensions/src/InputFile/InputFile.cs b/src/Components/Web/src/Forms/InputFile.cs similarity index 91% rename from src/Components/Web.Extensions/src/InputFile/InputFile.cs rename to src/Components/Web/src/Forms/InputFile.cs index 1f73eb2d6a..ada1a96f10 100644 --- a/src/Components/Web.Extensions/src/InputFile/InputFile.cs +++ b/src/Components/Web/src/Forms/InputFile.cs @@ -10,10 +10,10 @@ using Microsoft.AspNetCore.Components.Rendering; using Microsoft.Extensions.Options; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { /// - /// A component that wraps the HTML file input element and exposes a for each file's contents. + /// A component that wraps the HTML file input element and supplies a for each file's contents. /// public class InputFile : ComponentBase, IInputFileJsCallbacks, IDisposable { @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Components.Web.Extensions (Stream)new SharedBrowserFileStream(JSRuntime, _jsUnmarshalledRuntime, _inputFileElement, file) : new RemoteBrowserFileStream(JSRuntime, _inputFileElement, file, Options.Value, cancellationToken); - internal async Task ConvertToImageFileAsync(BrowserFile file, string format, int maxWidth, int maxHeight) + internal async ValueTask ConvertToImageFileAsync(BrowserFile file, string format, int maxWidth, int maxHeight) { var imageFile = await JSRuntime.InvokeAsync(InputFileInterop.ToImageFile, _inputFileElement, file.Id, format, maxWidth, maxHeight); diff --git a/src/Components/Web/src/Forms/InputFile/BrowserFile.cs b/src/Components/Web/src/Forms/InputFile/BrowserFile.cs new file mode 100644 index 0000000000..09b7a54283 --- /dev/null +++ b/src/Components/Web/src/Forms/InputFile/BrowserFile.cs @@ -0,0 +1,50 @@ +// 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 System.Threading; + +namespace Microsoft.AspNetCore.Components.Forms +{ + internal sealed class BrowserFile : IBrowserFile + { + private long _size; + + internal InputFile Owner { get; set; } = default!; + + public int Id { get; set; } + + public string Name { get; set; } = string.Empty; + + public DateTimeOffset LastModified { get; set; } + + public long Size + { + get => _size; + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(Size), $"Size must be a non-negative value. Value provided: {value}."); + } + + _size = value; + } + } + + public string ContentType { get; set; } = string.Empty; + + public string? RelativePath { get; set; } + + public Stream OpenReadStream(long maxAllowedSize = 512000, CancellationToken cancellationToken = default) + { + if (Size > maxAllowedSize) + { + throw new IOException($"Supplied file with size {Size} bytes exceeds the maximum of {maxAllowedSize} bytes."); + } + + return Owner.OpenReadStream(this, cancellationToken); + } + } +} diff --git a/src/Components/Web/src/Forms/InputFile/BrowserFileExtensions.cs b/src/Components/Web/src/Forms/InputFile/BrowserFileExtensions.cs new file mode 100644 index 0000000000..c2797ca053 --- /dev/null +++ b/src/Components/Web/src/Forms/InputFile/BrowserFileExtensions.cs @@ -0,0 +1,40 @@ +// 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.Threading.Tasks; + +namespace Microsoft.AspNetCore.Components.Forms +{ + /// + /// Contains helper methods for . + /// + public static class BrowserFileExtensions + { + /// + /// Attempts to convert the current image file to a new one of the specified file type and maximum file dimensions. + /// + /// Caution: there is no guarantee that the file will be converted, or will even be a valid image file at all, either + /// before or after conversion. The conversion is requested within the browser before it is transferred to .NET + /// code, so the resulting data should be treated as untrusted. + /// + /// + /// + /// The image will be scaled to fit the specified dimensions while preserving the original aspect ratio. + /// + /// The to convert to a new image file. + /// The new image format. + /// The maximum image width. + /// The maximum image height + /// A representing the completion of the operation. + public static ValueTask RequestImageFileAsync(this IBrowserFile browserFile, string format, int maxWith, int maxHeight) + { + if (browserFile is BrowserFile browserFileInternal) + { + return browserFileInternal.Owner.ConvertToImageFileAsync(browserFileInternal, format, maxWith, maxHeight); + } + + throw new InvalidOperationException($"Cannot perform this operation on custom {typeof(IBrowserFile)} implementations."); + } + } +} diff --git a/src/Components/Web.Extensions/src/InputFile/BrowserFileStream.cs b/src/Components/Web/src/Forms/InputFile/BrowserFileStream.cs similarity index 97% rename from src/Components/Web.Extensions/src/InputFile/BrowserFileStream.cs rename to src/Components/Web/src/Forms/InputFile/BrowserFileStream.cs index 539e0c1d34..214e0ee831 100644 --- a/src/Components/Web.Extensions/src/InputFile/BrowserFileStream.cs +++ b/src/Components/Web/src/Forms/InputFile/BrowserFileStream.cs @@ -6,7 +6,7 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal abstract class BrowserFileStream : Stream { diff --git a/src/Components/Web/src/Forms/InputFile/IBrowserFile.cs b/src/Components/Web/src/Forms/InputFile/IBrowserFile.cs new file mode 100644 index 0000000000..44d7e53275 --- /dev/null +++ b/src/Components/Web/src/Forms/InputFile/IBrowserFile.cs @@ -0,0 +1,62 @@ +// 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 System.Threading; + +namespace Microsoft.AspNetCore.Components.Forms +{ + /// + /// Represents the data of a file selected from an component. + /// + /// Note: Metadata is provided by the client and is untrusted. + /// + /// + public interface IBrowserFile + { + /// + /// Gets the name of the file as specified by the browser. + /// + string Name { get; } + + /// + /// Gets the last modified date as specified by the browser. + /// + DateTimeOffset LastModified { get; } + + /// + /// Gets the size of the file in bytes as specified by the browser. + /// + long Size { get; } + + /// + /// Gets the MIME type of the file as specified by the browser. + /// + string ContentType { get; } + + /// + /// Opens the stream for reading the uploaded file. + /// + /// + /// The maximum number of bytes that can be supplied by the Stream. Defaults to 500 KB. + /// + /// Calling + /// will throw if the file's size, as specified by is larger than + /// . By default, if the user supplies a file larger than 500 KB, this method will throw an exception. + /// + /// + /// It is valuable to choose a size limit that corresponds to your use case. If you allow excessively large files, this + /// may result in excessive consumption of memory or disk/database space, depending on what your code does + /// with the supplied . + /// + /// + /// For Blazor Server in particular, beware of reading the entire stream into a memory buffer unless you have + /// passed a suitably low size limit, since you will be consuming that memory on the server. + /// + /// + /// A cancellation token to signal the cancellation of streaming file data. + /// Thrown if the file's length exceeds the value. + Stream OpenReadStream(long maxAllowedSize = 500 * 1024, CancellationToken cancellationToken = default); + } +} diff --git a/src/Components/Web.Extensions/src/InputFile/IInputFileJsCallbacks.cs b/src/Components/Web/src/Forms/InputFile/IInputFileJsCallbacks.cs similarity index 84% rename from src/Components/Web.Extensions/src/InputFile/IInputFileJsCallbacks.cs rename to src/Components/Web/src/Forms/InputFile/IInputFileJsCallbacks.cs index 853a44a0c2..5e23a58036 100644 --- a/src/Components/Web.Extensions/src/InputFile/IInputFileJsCallbacks.cs +++ b/src/Components/Web/src/Forms/InputFile/IInputFileJsCallbacks.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal interface IInputFileJsCallbacks { diff --git a/src/Components/Web/src/Forms/InputFile/InputFileChangeEventArgs.cs b/src/Components/Web/src/Forms/InputFile/InputFileChangeEventArgs.cs new file mode 100644 index 0000000000..fed0c50489 --- /dev/null +++ b/src/Components/Web/src/Forms/InputFile/InputFileChangeEventArgs.cs @@ -0,0 +1,57 @@ +// 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.Collections.Generic; + +namespace Microsoft.AspNetCore.Components.Forms +{ + /// + /// Supplies information about an event being raised. + /// + public sealed class InputFileChangeEventArgs : EventArgs + { + private readonly IReadOnlyList _files; + + /// + /// Constructs a new instance. + /// + /// The list of . + public InputFileChangeEventArgs(IReadOnlyList files) + { + _files = files ?? throw new ArgumentNullException(nameof(files)); + } + + /// + /// Gets the number of supplied files. + /// + public int FileCount => _files.Count; + + /// + /// Gets the supplied file. Note that if the input accepts multiple files, then instead of + /// reading this property, you should call . + /// + public IBrowserFile File => _files.Count switch + { + 0 => throw new InvalidOperationException("No file was supplied."), + 1 => _files[0], + _ => throw new InvalidOperationException($"More than one file was supplied. Call {nameof(GetMultipleFiles)} to receive multiple files."), + }; + + /// + /// Gets the file entries list. This method should be used for inputs that accept multiple + /// files. If the input accepts only a single file, then use the property + /// instead. + /// + /// The maximum number of files to accept. If the number of files exceeds this value, this method will throw an exception. + public IReadOnlyList GetMultipleFiles(int maximumFileCount = 10) + { + if (_files.Count > maximumFileCount) + { + throw new InvalidOperationException($"The maximum number of files accepted is {maximumFileCount}, but {_files.Count} were supplied."); + } + + return _files; + } + } +} diff --git a/src/Components/Web.Extensions/src/InputFile/InputFileInterop.cs b/src/Components/Web/src/Forms/InputFile/InputFileInterop.cs similarity index 84% rename from src/Components/Web.Extensions/src/InputFile/InputFileInterop.cs rename to src/Components/Web/src/Forms/InputFile/InputFileInterop.cs index 15fba058d4..d0162a3d22 100644 --- a/src/Components/Web.Extensions/src/InputFile/InputFileInterop.cs +++ b/src/Components/Web/src/Forms/InputFile/InputFileInterop.cs @@ -1,11 +1,11 @@ // 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. -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal static class InputFileInterop { - private const string JsFunctionsPrefix = "_blazorInputFile."; + private const string JsFunctionsPrefix = "Blazor._internal.InputFile."; public const string Init = JsFunctionsPrefix + "init"; diff --git a/src/Components/Web.Extensions/src/InputFile/InputFileJsCallbacksRelay.cs b/src/Components/Web/src/Forms/InputFile/InputFileJsCallbacksRelay.cs similarity index 93% rename from src/Components/Web.Extensions/src/InputFile/InputFileJsCallbacksRelay.cs rename to src/Components/Web/src/Forms/InputFile/InputFileJsCallbacksRelay.cs index c2d4a0aadd..56a48a4337 100644 --- a/src/Components/Web.Extensions/src/InputFile/InputFileJsCallbacksRelay.cs +++ b/src/Components/Web/src/Forms/InputFile/InputFileJsCallbacksRelay.cs @@ -5,7 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal class InputFileJsCallbacksRelay : IDisposable { diff --git a/src/Components/Web.Extensions/src/InputFile/ReadRequest.cs b/src/Components/Web/src/Forms/InputFile/ReadRequest.cs similarity index 92% rename from src/Components/Web.Extensions/src/InputFile/ReadRequest.cs rename to src/Components/Web/src/Forms/InputFile/ReadRequest.cs index 206667eb96..4c24e7dcae 100644 --- a/src/Components/Web.Extensions/src/InputFile/ReadRequest.cs +++ b/src/Components/Web/src/Forms/InputFile/ReadRequest.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { [StructLayout(LayoutKind.Explicit)] internal struct ReadRequest diff --git a/src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStream.cs b/src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStream.cs similarity index 97% rename from src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStream.cs rename to src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStream.cs index cb22b6ac8c..8f712ad3de 100644 --- a/src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStream.cs +++ b/src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStream.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal class RemoteBrowserFileStream : BrowserFileStream { @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Components.Web.Extensions { _jsRuntime = jsRuntime; _inputFileElement = inputFileElement; - _maxSegmentSize = options.SegmentSize; + _maxSegmentSize = options.MaxSegmentSize; _segmentFetchTimeout = options.SegmentFetchTimeout; var pipe = new Pipe(new PipeOptions(pauseWriterThreshold: options.MaxBufferSize, resumeWriterThreshold: options.MaxBufferSize)); diff --git a/src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStreamOptions.cs b/src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStreamOptions.cs similarity index 89% rename from src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStreamOptions.cs rename to src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStreamOptions.cs index b594f29d04..52955393df 100644 --- a/src/Components/Web.Extensions/src/InputFile/RemoteBrowserFileStreamOptions.cs +++ b/src/Components/Web/src/Forms/InputFile/RemoteBrowserFileStreamOptions.cs @@ -4,7 +4,7 @@ using System; using System.Runtime.Versioning; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { /// /// Repesents configurable options for . @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Components.Web.Extensions /// This only has an effect when using Blazor Server. /// /// - public int SegmentSize { get; set; } = 20 * 1024; // SignalR limit is 32K. + public int MaxSegmentSize { get; set; } = 20 * 1024; // SignalR limit is 32K. /// /// Gets or sets the maximum internal buffer size for unread data sent over a SignalR circuit. @@ -35,6 +35,6 @@ namespace Microsoft.AspNetCore.Components.Web.Extensions /// This only has an effect when using Blazor Server. /// /// - public TimeSpan SegmentFetchTimeout { get; set; } = TimeSpan.FromSeconds(3); + public TimeSpan SegmentFetchTimeout { get; set; } = TimeSpan.FromMinutes(1); } } diff --git a/src/Components/Web.Extensions/src/InputFile/SharedBrowserFileStream.cs b/src/Components/Web/src/Forms/InputFile/SharedBrowserFileStream.cs similarity index 97% rename from src/Components/Web.Extensions/src/InputFile/SharedBrowserFileStream.cs rename to src/Components/Web/src/Forms/InputFile/SharedBrowserFileStream.cs index bf7e50984c..f3e6d196e8 100644 --- a/src/Components/Web.Extensions/src/InputFile/SharedBrowserFileStream.cs +++ b/src/Components/Web/src/Forms/InputFile/SharedBrowserFileStream.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.JSInterop; -namespace Microsoft.AspNetCore.Components.Web.Extensions +namespace Microsoft.AspNetCore.Components.Forms { internal class SharedBrowserFileStream : BrowserFileStream { diff --git a/src/Components/Web/test/Forms/BrowserFileTest.cs b/src/Components/Web/test/Forms/BrowserFileTest.cs new file mode 100644 index 0000000000..ceb894924c --- /dev/null +++ b/src/Components/Web/test/Forms/BrowserFileTest.cs @@ -0,0 +1,33 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.Components.Forms +{ + public class BrowserFileTest + { + [Fact] + public void SetSize_ThrowsIfSizeIsNegative() + { + // Arrange + var file = new BrowserFile(); + + // Act & Assert + var ex = Assert.Throws(() => file.Size = -7); + } + + [Fact] + public void OpenReadStream_ThrowsIfFileSizeIsLargerThanAllowedSize() + { + // Arrange + var file = new BrowserFile { Size = 100 }; + + // Act & Assert + var ex = Assert.Throws(() => file.OpenReadStream(80)); + Assert.Equal("Supplied file with size 100 bytes exceeds the maximum of 80 bytes.", ex.Message); + } + } +} diff --git a/src/Components/Web/test/Forms/InputFileChangeEventArgsTest.cs b/src/Components/Web/test/Forms/InputFileChangeEventArgsTest.cs new file mode 100644 index 0000000000..8dcdfcc18e --- /dev/null +++ b/src/Components/Web/test/Forms/InputFileChangeEventArgsTest.cs @@ -0,0 +1,69 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.Components.Forms +{ + public class InputFileChangeEventArgsTest + { + [Fact] + public void SuppliesNumberOfFiles() + { + var emptySet = new InputFileChangeEventArgs(Array.Empty()); + Assert.Equal(0, emptySet.FileCount); + + var twoItemSet = new InputFileChangeEventArgs(new[] { new BrowserFile(), new BrowserFile() }); + Assert.Equal(2, twoItemSet.FileCount); + } + + [Fact] + public void File_CanSupplySingle() + { + var file = new BrowserFile(); + var instance = new InputFileChangeEventArgs(new[] { file }); + Assert.Same(file, instance.File); + } + + [Fact] + public void File_ThrowsIfZeroFiles() + { + var instance = new InputFileChangeEventArgs(Array.Empty()); + var ex = Assert.Throws(() => instance.File); + Assert.StartsWith("No file was supplied", ex.Message); + } + + [Fact] + public void File_ThrowsIfMultipleFiles() + { + var instance = new InputFileChangeEventArgs(new[] { new BrowserFile(), new BrowserFile() }); + var ex = Assert.Throws(() => instance.File); + Assert.StartsWith("More than one file was supplied", ex.Message); + } + + [Fact] + public void GetMultipleFiles_CanSupplyEmpty() + { + var instance = new InputFileChangeEventArgs(Array.Empty()); + Assert.Empty(instance.GetMultipleFiles()); + } + + [Fact] + public void GetMultipleFiles_CanSupplyFiles() + { + var files = new[] { new BrowserFile(), new BrowserFile() }; + var instance = new InputFileChangeEventArgs(files); + Assert.Same(files, instance.GetMultipleFiles()); + } + + [Fact] + public void GetMultipleFiles_ThrowsIfTooManyFiles() + { + var files = new[] { new BrowserFile(), new BrowserFile() }; + var instance = new InputFileChangeEventArgs(files); + var ex = Assert.Throws(() => instance.GetMultipleFiles(1)); + Assert.Equal($"The maximum number of files accepted is 1, but 2 were supplied.", ex.Message); + } + } +} diff --git a/src/Components/WebAssembly/DebugProxy/src/DebugProxyOptions.cs b/src/Components/WebAssembly/DebugProxy/src/DebugProxyOptions.cs deleted file mode 100644 index 70a76258c6..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/DebugProxyOptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy -{ - public class DebugProxyOptions - { - public string BrowserHost { get; set; } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/Hosting/DebugProxyHost.cs b/src/Components/WebAssembly/DebugProxy/src/Hosting/DebugProxyHost.cs deleted file mode 100644 index 4edbddc2f5..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/Hosting/DebugProxyHost.cs +++ /dev/null @@ -1,65 +0,0 @@ -// 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.Collections.Generic; -using System.IO; -using System.Text; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.Hosting -{ - public static class DebugProxyHost - { - /// - /// Creates a custom HostBuilder for the DebugProxyLauncher so that we can inject - /// only the needed configurations. - /// - /// Command line arguments passed in - /// Host where browser is listening for debug connections - /// - public static IHostBuilder CreateDefaultBuilder(string[] args, string browserHost) - { - var builder = new HostBuilder(); - - builder.ConfigureAppConfiguration((hostingContext, config) => - { - if (args != null) - { - config.AddCommandLine(args); - } - config.SetBasePath(Directory.GetCurrentDirectory()); - config.AddJsonFile("blazor-debugproxysettings.json", optional: true, reloadOnChange: true); - }) - .ConfigureLogging((hostingContext, logging) => - { - logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); - logging.AddConsole(); - logging.AddDebug(); - logging.AddEventSourceLogger(); - }) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - - // By default we bind to a dyamic port - // This can be overridden using an option like "--urls http://localhost:9500" - webBuilder.UseUrls("http://127.0.0.1:0"); - }) - .ConfigureServices(serviceCollection => - { - serviceCollection.AddSingleton(new DebugProxyOptions - { - BrowserHost = browserHost - }); - }); - - return builder; - - } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj b/src/Components/WebAssembly/DebugProxy/src/Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj deleted file mode 100644 index 4a727c739d..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - Exe - Microsoft.AspNetCore.Components.WebAssembly.DebugProxy - true - Debug proxy for use when building Blazor applications. - - false - $(NoWarn);CS0649 - true - - - - - - - - - - - - - - - - - - diff --git a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DebugStore.cs b/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DebugStore.cs deleted file mode 100644 index 1b9568de80..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DebugStore.cs +++ /dev/null @@ -1,843 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; -using System.Linq; -using Newtonsoft.Json.Linq; -using System.Net.Http; -using Mono.Cecil.Pdb; -using Newtonsoft.Json; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Threading; -using Microsoft.Extensions.Logging; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; - -namespace WebAssembly.Net.Debugging { - internal class BreakpointRequest { - public string Id { get; private set; } - public string Assembly { get; private set; } - public string File { get; private set; } - public int Line { get; private set; } - public int Column { get; private set; } - public MethodInfo Method { get; private set; } - - JObject request; - - public bool IsResolved => Assembly != null; - public List Locations { get; } = new List (); - - public override string ToString () - => $"BreakpointRequest Assembly: {Assembly} File: {File} Line: {Line} Column: {Column}"; - - public object AsSetBreakpointByUrlResponse (IEnumerable jsloc) - => new { breakpointId = Id, locations = Locations.Select(l => l.Location.AsLocation ()).Concat (jsloc) }; - - public BreakpointRequest () { - } - - public BreakpointRequest (string id, MethodInfo method) { - Id = id; - Method = method; - } - - public BreakpointRequest (string id, JObject request) { - Id = id; - this.request = request; - } - - public static BreakpointRequest Parse (string id, JObject args) - { - return new BreakpointRequest (id, args); - } - - public BreakpointRequest Clone () - => new BreakpointRequest { Id = Id, request = request }; - - public bool IsMatch (SourceFile sourceFile) - { - var url = request? ["url"]?.Value (); - if (url == null) { - var urlRegex = request?["urlRegex"].Value(); - var regex = new Regex (urlRegex); - return regex.IsMatch (sourceFile.Url.ToString ()) || regex.IsMatch (sourceFile.DocUrl); - } - - return sourceFile.Url.ToString () == url || sourceFile.DotNetUrl == url; - } - - public bool TryResolve (SourceFile sourceFile) - { - if (!IsMatch (sourceFile)) - return false; - - var line = request? ["lineNumber"]?.Value (); - var column = request? ["columnNumber"]?.Value (); - - if (line == null || column == null) - return false; - - Assembly = sourceFile.AssemblyName; - File = sourceFile.DebuggerFileName; - Line = line.Value; - Column = column.Value; - return true; - } - - public bool TryResolve (DebugStore store) - { - if (request == null || store == null) - return false; - - return store.AllSources().FirstOrDefault (source => TryResolve (source)) != null; - } - } - - internal class VarInfo { - public VarInfo (VariableDebugInformation v) - { - this.Name = v.Name; - this.Index = v.Index; - } - - public VarInfo (ParameterDefinition p) - { - this.Name = p.Name; - this.Index = (p.Index + 1) * -1; - } - - public string Name { get; } - public int Index { get; } - - public override string ToString () - => $"(var-info [{Index}] '{Name}')"; - } - - internal class CliLocation { - public CliLocation (MethodInfo method, int offset) - { - Method = method; - Offset = offset; - } - - public MethodInfo Method { get; } - public int Offset { get; } - } - - internal class SourceLocation { - SourceId id; - int line; - int column; - CliLocation cliLoc; - - public SourceLocation (SourceId id, int line, int column) - { - this.id = id; - this.line = line; - this.column = column; - } - - public SourceLocation (MethodInfo mi, SequencePoint sp) - { - this.id = mi.SourceId; - this.line = sp.StartLine - 1; - this.column = sp.StartColumn - 1; - this.cliLoc = new CliLocation (mi, sp.Offset); - } - - public SourceId Id { get => id; } - public int Line { get => line; } - public int Column { get => column; } - public CliLocation CliLocation => this.cliLoc; - - public override string ToString () - => $"{id}:{Line}:{Column}"; - - public static SourceLocation Parse (JObject obj) - { - if (obj == null) - return null; - - if (!SourceId.TryParse (obj ["scriptId"]?.Value (), out var id)) - return null; - - var line = obj ["lineNumber"]?.Value (); - var column = obj ["columnNumber"]?.Value (); - if (id == null || line == null || column == null) - return null; - - return new SourceLocation (id, line.Value, column.Value); - } - - - internal class LocationComparer : EqualityComparer - { - public override bool Equals (SourceLocation l1, SourceLocation l2) - { - if (l1 == null && l2 == null) - return true; - else if (l1 == null || l2 == null) - return false; - - return (l1.Line == l2.Line && - l1.Column == l2.Column && - l1.Id == l2.Id); - } - - public override int GetHashCode (SourceLocation loc) - { - int hCode = loc.Line ^ loc.Column; - return loc.Id.GetHashCode () ^ hCode.GetHashCode (); - } - } - - internal object AsLocation () - => new { - scriptId = id.ToString (), - lineNumber = line, - columnNumber = column - }; - } - - internal class SourceId { - const string Scheme = "dotnet://"; - - readonly int assembly, document; - - public int Assembly => assembly; - public int Document => document; - - internal SourceId (int assembly, int document) - { - this.assembly = assembly; - this.document = document; - } - - public SourceId (string id) - { - if (!TryParse (id, out assembly, out document)) - throw new ArgumentException ("invalid source identifier", nameof (id)); - } - - public static bool TryParse (string id, out SourceId source) - { - source = null; - if (!TryParse (id, out var assembly, out var document)) - return false; - - source = new SourceId (assembly, document); - return true; - } - - static bool TryParse (string id, out int assembly, out int document) - { - assembly = document = 0; - if (id == null || !id.StartsWith (Scheme, StringComparison.Ordinal)) - return false; - - var sp = id.Substring (Scheme.Length).Split ('_'); - if (sp.Length != 2) - return false; - - if (!int.TryParse (sp [0], out assembly)) - return false; - - if (!int.TryParse (sp [1], out document)) - return false; - - return true; - } - - public override string ToString () - => $"{Scheme}{assembly}_{document}"; - - public override bool Equals (object obj) - { - if (obj == null) - return false; - SourceId that = obj as SourceId; - return that.assembly == this.assembly && that.document == this.document; - } - - public override int GetHashCode () - => assembly.GetHashCode () ^ document.GetHashCode (); - - public static bool operator == (SourceId a, SourceId b) - => ((object)a == null) ? (object)b == null : a.Equals (b); - - public static bool operator != (SourceId a, SourceId b) - => !a.Equals (b); - } - - internal class MethodInfo { - MethodDefinition methodDef; - SourceFile source; - - public SourceId SourceId => source.SourceId; - - public string Name => methodDef.Name; - public MethodDebugInformation DebugInformation => methodDef.DebugInformation; - - public SourceLocation StartLocation { get; } - public SourceLocation EndLocation { get; } - public AssemblyInfo Assembly { get; } - public uint Token => methodDef.MetadataToken.RID; - - public MethodInfo (AssemblyInfo assembly, MethodDefinition methodDef, SourceFile source) - { - this.Assembly = assembly; - this.methodDef = methodDef; - this.source = source; - - var sps = DebugInformation.SequencePoints; - if (sps == null || sps.Count() < 1) - return; - - SequencePoint start = sps [0]; - SequencePoint end = sps [0]; - - foreach (var sp in sps) { - if (sp.StartLine < start.StartLine) - start = sp; - else if (sp.StartLine == start.StartLine && sp.StartColumn < start.StartColumn) - start = sp; - - if (sp.EndLine > end.EndLine) - end = sp; - else if (sp.EndLine == end.EndLine && sp.EndColumn > end.EndColumn) - end = sp; - } - - StartLocation = new SourceLocation (this, start); - EndLocation = new SourceLocation (this, end); - } - - public SourceLocation GetLocationByIl (int pos) - { - SequencePoint prev = null; - foreach (var sp in DebugInformation.SequencePoints) { - if (sp.Offset > pos) - break; - prev = sp; - } - - if (prev != null) - return new SourceLocation (this, prev); - - return null; - } - - public VarInfo [] GetLiveVarsAt (int offset) - { - var res = new List (); - - res.AddRange (methodDef.Parameters.Select (p => new VarInfo (p))); - res.AddRange (methodDef.DebugInformation.GetScopes () - .Where (s => s.Start.Offset <= offset && (s.End.IsEndOfMethod || s.End.Offset > offset)) - .SelectMany (s => s.Variables) - .Where (v => !v.IsDebuggerHidden) - .Select (v => new VarInfo (v))); - - return res.ToArray (); - } - - public override string ToString () => "MethodInfo(" + methodDef.FullName + ")"; - } - - internal class TypeInfo { - AssemblyInfo assembly; - TypeDefinition type; - List methods; - - public TypeInfo (AssemblyInfo assembly, TypeDefinition type) { - this.assembly = assembly; - this.type = type; - methods = new List (); - } - - public string Name => type.Name; - public string FullName => type.FullName; - public List Methods => methods; - - public override string ToString () => "TypeInfo('" + FullName + "')"; - } - - class AssemblyInfo { - static int next_id; - ModuleDefinition image; - readonly int id; - readonly ILogger logger; - Dictionary methods = new Dictionary (); - Dictionary sourceLinkMappings = new Dictionary(); - Dictionary typesByName = new Dictionary (); - readonly List sources = new List(); - internal string Url { get; } - - public AssemblyInfo (string url, byte[] assembly, byte[] pdb) - { - this.id = Interlocked.Increment (ref next_id); - - try { - Url = url; - ReaderParameters rp = new ReaderParameters (/*ReadingMode.Immediate*/); - - // set ReadSymbols = true unconditionally in case there - // is an embedded pdb then handle ArgumentException - // and assume that if pdb == null that is the cause - rp.ReadSymbols = true; - rp.SymbolReaderProvider = new PdbReaderProvider (); - if (pdb != null) - rp.SymbolStream = new MemoryStream (pdb); - rp.ReadingMode = ReadingMode.Immediate; - rp.InMemory = true; - - this.image = ModuleDefinition.ReadModule (new MemoryStream (assembly), rp); - } catch (BadImageFormatException ex) { - logger.LogWarning ($"Failed to read assembly as portable PDB: {ex.Message}"); - } catch (ArgumentException) { - // if pdb == null this is expected and we - // read the assembly without symbols below - if (pdb != null) - throw; - } - - if (this.image == null) { - ReaderParameters rp = new ReaderParameters (/*ReadingMode.Immediate*/); - if (pdb != null) { - rp.ReadSymbols = true; - rp.SymbolReaderProvider = new PdbReaderProvider (); - rp.SymbolStream = new MemoryStream (pdb); - } - - rp.ReadingMode = ReadingMode.Immediate; - rp.InMemory = true; - - this.image = ModuleDefinition.ReadModule (new MemoryStream (assembly), rp); - } - - Populate (); - } - - public AssemblyInfo (ILogger logger) - { - this.logger = logger; - } - - void Populate () - { - ProcessSourceLink(); - - var d2s = new Dictionary (); - - SourceFile FindSource (Document doc) - { - if (doc == null) - return null; - - if (d2s.TryGetValue (doc, out var source)) - return source; - - var src = new SourceFile (this, sources.Count, doc, GetSourceLinkUrl (doc.Url)); - sources.Add (src); - d2s [doc] = src; - return src; - }; - - foreach (var type in image.GetTypes()) { - var typeInfo = new TypeInfo (this, type); - typesByName [type.FullName] = typeInfo; - - foreach (var method in type.Methods) { - foreach (var sp in method.DebugInformation.SequencePoints) { - var source = FindSource (sp.Document); - var methodInfo = new MethodInfo (this, method, source); - methods [method.MetadataToken.RID] = methodInfo; - if (source != null) - source.AddMethod (methodInfo); - - typeInfo.Methods.Add (methodInfo); - } - } - } - } - - private void ProcessSourceLink () - { - var sourceLinkDebugInfo = image.CustomDebugInformations.FirstOrDefault (i => i.Kind == CustomDebugInformationKind.SourceLink); - - if (sourceLinkDebugInfo != null) { - var sourceLinkContent = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content; - - if (sourceLinkContent != null) { - var jObject = JObject.Parse (sourceLinkContent) ["documents"]; - sourceLinkMappings = JsonConvert.DeserializeObject> (jObject.ToString ()); - } - } - } - - private Uri GetSourceLinkUrl (string document) - { - if (sourceLinkMappings.TryGetValue (document, out string url)) - return new Uri (url); - - foreach (var sourceLinkDocument in sourceLinkMappings) { - string key = sourceLinkDocument.Key; - - if (Path.GetFileName (key) != "*") { - continue; - } - - var keyTrim = key.TrimEnd ('*'); - - if (document.StartsWith(keyTrim, StringComparison.OrdinalIgnoreCase)) { - var docUrlPart = document.Replace (keyTrim, ""); - return new Uri (sourceLinkDocument.Value.TrimEnd ('*') + docUrlPart); - } - } - - return null; - } - - private static string GetRelativePath (string relativeTo, string path) - { - var uri = new Uri (relativeTo, UriKind.RelativeOrAbsolute); - var rel = Uri.UnescapeDataString (uri.MakeRelativeUri (new Uri (path, UriKind.RelativeOrAbsolute)).ToString ()).Replace (Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - if (rel.Contains (Path.DirectorySeparatorChar.ToString ()) == false) { - rel = $".{ Path.DirectorySeparatorChar }{ rel }"; - } - return rel; - } - - public IEnumerable Sources - => this.sources; - - public int Id => id; - public string Name => image.Name; - - public SourceFile GetDocById (int document) - { - return sources.FirstOrDefault (s => s.SourceId.Document == document); - } - - public MethodInfo GetMethodByToken (uint token) - { - methods.TryGetValue (token, out var value); - return value; - } - - public TypeInfo GetTypeByName (string name) { - typesByName.TryGetValue (name, out var res); - return res; - } - } - - internal class SourceFile { - Dictionary methods; - AssemblyInfo assembly; - int id; - Document doc; - - internal SourceFile (AssemblyInfo assembly, int id, Document doc, Uri sourceLinkUri) - { - this.methods = new Dictionary (); - this.SourceLinkUri = sourceLinkUri; - this.assembly = assembly; - this.id = id; - this.doc = doc; - this.DebuggerFileName = doc.Url.Replace ("\\", "/").Replace (":", ""); - - this.SourceUri = new Uri ((Path.IsPathRooted (doc.Url) ? "file://" : "") + doc.Url, UriKind.RelativeOrAbsolute); - if (SourceUri.IsFile && File.Exists (SourceUri.LocalPath)) { - this.Url = this.SourceUri.ToString (); - } else { - this.Url = DotNetUrl; - } - } - - internal void AddMethod (MethodInfo mi) - { - if (!this.methods.ContainsKey (mi.Token)) - this.methods [mi.Token] = mi; - } - - public string DebuggerFileName { get; } - public string Url { get; } - public string AssemblyName => assembly.Name; - public string DotNetUrl => $"dotnet://{assembly.Name}/{DebuggerFileName}"; - - public SourceId SourceId => new SourceId (assembly.Id, this.id); - public Uri SourceLinkUri { get; } - public Uri SourceUri { get; } - - public IEnumerable Methods => this.methods.Values; - - public string DocUrl => doc.Url; - - public (int startLine, int startColumn, int endLine, int endColumn) GetExtents () - { - var start = Methods.OrderBy (m => m.StartLocation.Line).ThenBy (m => m.StartLocation.Column).First (); - var end = Methods.OrderByDescending (m => m.EndLocation.Line).ThenByDescending (m => m.EndLocation.Column).First (); - return (start.StartLocation.Line, start.StartLocation.Column, end.EndLocation.Line, end.EndLocation.Column); - } - - async Task GetDataAsync (Uri uri, CancellationToken token) - { - var mem = new MemoryStream (); - try { - if (uri.IsFile && File.Exists (uri.LocalPath)) { - using (var file = File.Open (SourceUri.LocalPath, FileMode.Open)) { - await file.CopyToAsync (mem, token); - mem.Position = 0; - } - } else if (uri.Scheme == "http" || uri.Scheme == "https") { - var client = new HttpClient (); - using (var stream = await client.GetStreamAsync (uri)) { - await stream.CopyToAsync (mem, token); - mem.Position = 0; - } - } - } catch (Exception) { - return null; - } - return mem; - } - - static HashAlgorithm GetHashAlgorithm (DocumentHashAlgorithm algorithm) - { - switch (algorithm) { - case DocumentHashAlgorithm.SHA1: return SHA1.Create (); - case DocumentHashAlgorithm.SHA256: return SHA256.Create (); - case DocumentHashAlgorithm.MD5: return MD5.Create (); - } - return null; - } - - bool CheckPdbHash (byte [] computedHash) - { - if (computedHash.Length != doc.Hash.Length) - return false; - - for (var i = 0; i < computedHash.Length; i++) - if (computedHash[i] != doc.Hash[i]) - return false; - - return true; - } - - byte[] ComputePdbHash (Stream sourceStream) - { - var algorithm = GetHashAlgorithm (doc.HashAlgorithm); - if (algorithm != null) - using (algorithm) - return algorithm.ComputeHash (sourceStream); - - return Array.Empty (); - } - - public async Task GetSourceAsync (bool checkHash, CancellationToken token = default(CancellationToken)) - { - if (doc.EmbeddedSource.Length > 0) - return new MemoryStream (doc.EmbeddedSource, false); - - MemoryStream mem; - - mem = await GetDataAsync (SourceUri, token); - if (mem != null && (!checkHash || CheckPdbHash (ComputePdbHash (mem)))) { - mem.Position = 0; - return mem; - } - - mem = await GetDataAsync (SourceLinkUri, token); - if (mem != null && (!checkHash || CheckPdbHash (ComputePdbHash (mem)))) { - mem.Position = 0; - return mem; - } - - return MemoryStream.Null; - } - - public object ToScriptSource (int executionContextId, object executionContextAuxData) - { - return new { - scriptId = SourceId.ToString (), - url = Url, - executionContextId, - executionContextAuxData, - //hash: should be the v8 hash algo, managed implementation is pending - dotNetUrl = DotNetUrl, - }; - } - } - - internal class DebugStore { - List assemblies = new List (); - readonly HttpClient client; - readonly ILogger logger; - - public DebugStore (ILogger logger, HttpClient client) { - this.client = client; - this.logger = logger; - } - - public DebugStore (ILogger logger) : this (logger, new HttpClient ()) - { - } - - class DebugItem { - public string Url { get; set; } - public Task Data { get; set; } - } - - public async IAsyncEnumerable Load (SessionId sessionId, string [] loaded_files, [EnumeratorCancellation] CancellationToken token) - { - static bool MatchPdb (string asm, string pdb) - => Path.ChangeExtension (asm, "pdb") == pdb; - - var asm_files = new List (); - var pdb_files = new List (); - foreach (var file_name in loaded_files) { - if (file_name.EndsWith (".pdb", StringComparison.OrdinalIgnoreCase)) - pdb_files.Add (file_name); - else - asm_files.Add (file_name); - } - - List steps = new List (); - foreach (var url in asm_files) { - try { - var pdb = pdb_files.FirstOrDefault (n => MatchPdb (url, n)); - steps.Add ( - new DebugItem { - Url = url, - Data = Task.WhenAll (client.GetByteArrayAsync (url), pdb != null ? client.GetByteArrayAsync (pdb) : Task.FromResult (null)) - }); - } catch (Exception e) { - logger.LogDebug ($"Failed to read {url} ({e.Message})"); - } - } - - foreach (var step in steps) { - AssemblyInfo assembly = null; - try { - var bytes = await step.Data; - assembly = new AssemblyInfo (step.Url, bytes [0], bytes [1]); - } catch (Exception e) { - logger.LogDebug ($"Failed to load {step.Url} ({e.Message})"); - } - if (assembly == null) - continue; - - assemblies.Add (assembly); - foreach (var source in assembly.Sources) - yield return source; - } - } - - public IEnumerable AllSources () - => assemblies.SelectMany (a => a.Sources); - - public SourceFile GetFileById (SourceId id) - => AllSources ().SingleOrDefault (f => f.SourceId.Equals (id)); - - public AssemblyInfo GetAssemblyByName (string name) - => assemblies.FirstOrDefault (a => a.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase)); - - /* - V8 uses zero based indexing for both line and column. - PPDBs uses one based indexing for both line and column. - */ - static bool Match (SequencePoint sp, SourceLocation start, SourceLocation end) - { - var spStart = (Line: sp.StartLine - 1, Column: sp.StartColumn - 1); - var spEnd = (Line: sp.EndLine - 1, Column: sp.EndColumn - 1); - - if (start.Line > spEnd.Line) - return false; - - if (start.Column > spEnd.Column && start.Line == spEnd.Line) - return false; - - if (end.Line < spStart.Line) - return false; - - if (end.Column < spStart.Column && end.Line == spStart.Line) - return false; - - return true; - } - - public List FindPossibleBreakpoints (SourceLocation start, SourceLocation end) - { - //XXX FIXME no idea what todo with locations on different files - if (start.Id != end.Id) { - logger.LogDebug ($"FindPossibleBreakpoints: documents differ (start: {start.Id}) (end {end.Id}"); - return null; - } - - var sourceId = start.Id; - - var doc = GetFileById (sourceId); - - var res = new List (); - if (doc == null) { - logger.LogDebug ($"Could not find document {sourceId}"); - return res; - } - - foreach (var method in doc.Methods) { - foreach (var sequencePoint in method.DebugInformation.SequencePoints) { - if (!sequencePoint.IsHidden && Match (sequencePoint, start, end)) - res.Add (new SourceLocation (method, sequencePoint)); - } - } - return res; - } - - /* - V8 uses zero based indexing for both line and column. - PPDBs uses one based indexing for both line and column. - */ - static bool Match (SequencePoint sp, int line, int column) - { - var bp = (line: line + 1, column: column + 1); - - if (sp.StartLine > bp.line || sp.EndLine < bp.line) - return false; - - //Chrome sends a zero column even if getPossibleBreakpoints say something else - if (column == 0) - return true; - - if (sp.StartColumn > bp.column && sp.StartLine == bp.line) - return false; - - if (sp.EndColumn < bp.column && sp.EndLine == bp.line) - return false; - - return true; - } - - public IEnumerable FindBreakpointLocations (BreakpointRequest request) - { - request.TryResolve (this); - - var asm = assemblies.FirstOrDefault (a => a.Name.Equals (request.Assembly, StringComparison.OrdinalIgnoreCase)); - var sourceFile = asm?.Sources?.SingleOrDefault (s => s.DebuggerFileName.Equals (request.File, StringComparison.OrdinalIgnoreCase)); - - if (sourceFile == null) - yield break; - - foreach (var method in sourceFile.Methods) { - foreach (var sequencePoint in method.DebugInformation.SequencePoints) { - if (!sequencePoint.IsHidden && Match (sequencePoint, request.Line, request.Column)) - yield return new SourceLocation (method, sequencePoint); - } - } - } - - public string ToUrl (SourceLocation location) - => location != null ? GetFileById (location.Id).Url : ""; - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsHelper.cs b/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsHelper.cs deleted file mode 100644 index 871c10de9b..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsHelper.cs +++ /dev/null @@ -1,298 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Newtonsoft.Json.Linq; - -using System.Threading; -using System.IO; -using System.Collections.Generic; -using System.Net; -using Microsoft.Extensions.Logging; - -namespace WebAssembly.Net.Debugging { - - internal struct SessionId { - public readonly string sessionId; - - public SessionId (string sessionId) - { - this.sessionId = sessionId; - } - - // hashset treats 0 as unset - public override int GetHashCode () - => sessionId?.GetHashCode () ?? -1; - - public override bool Equals (object obj) - => (obj is SessionId) ? ((SessionId) obj).sessionId == sessionId : false; - - public static bool operator == (SessionId a, SessionId b) - => a.sessionId == b.sessionId; - - public static bool operator != (SessionId a, SessionId b) - => a.sessionId != b.sessionId; - - public static SessionId Null { get; } = new SessionId (); - - public override string ToString () - => $"session-{sessionId}"; - } - - internal struct MessageId { - public readonly string sessionId; - public readonly int id; - - public MessageId (string sessionId, int id) - { - this.sessionId = sessionId; - this.id = id; - } - - public static implicit operator SessionId (MessageId id) - => new SessionId (id.sessionId); - - public override string ToString () - => $"msg-{sessionId}:::{id}"; - - public override int GetHashCode () - => (sessionId?.GetHashCode () ?? 0) ^ id.GetHashCode (); - - public override bool Equals (object obj) - => (obj is MessageId) ? ((MessageId) obj).sessionId == sessionId && ((MessageId) obj).id == id : false; - } - - internal class DotnetObjectId { - public string Scheme { get; } - public string Value { get; } - - public static bool TryParse (JToken jToken, out DotnetObjectId objectId) - => TryParse (jToken?.Value(), out objectId); - - public static bool TryParse (string id, out DotnetObjectId objectId) - { - objectId = null; - if (id == null) - return false; - - if (!id.StartsWith ("dotnet:")) - return false; - - var parts = id.Split (":", 3); - - if (parts.Length < 3) - return false; - - objectId = new DotnetObjectId (parts[1], parts[2]); - - return true; - } - - public DotnetObjectId (string scheme, string value) - { - Scheme = scheme; - Value = value; - } - - public override string ToString () - => $"dotnet:{Scheme}:{Value}"; - } - - internal struct Result { - public JObject Value { get; private set; } - public JObject Error { get; private set; } - - public bool IsOk => Value != null; - public bool IsErr => Error != null; - - Result (JObject result, JObject error) - { - if (result != null && error != null) - throw new ArgumentException ($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null."); - - bool resultHasError = String.Compare ((result? ["result"] as JObject)? ["subtype"]?. Value (), "error") == 0; - if (result != null && resultHasError) { - this.Value = null; - this.Error = result; - } else { - this.Value = result; - this.Error = error; - } - } - - public static Result FromJson (JObject obj) - { - //Log ("protocol", $"from result: {obj}"); - return new Result (obj ["result"] as JObject, obj ["error"] as JObject); - } - - public static Result Ok (JObject ok) - => new Result (ok, null); - - public static Result OkFromObject (object ok) - => Ok (JObject.FromObject(ok)); - - public static Result Err (JObject err) - => new Result (null, err); - - public static Result Err (string msg) - => new Result (null, JObject.FromObject (new { message = msg })); - - public static Result Exception (Exception e) - => new Result (null, JObject.FromObject (new { message = e.Message })); - - public JObject ToJObject (MessageId target) { - if (IsOk) { - return JObject.FromObject (new { - target.id, - target.sessionId, - result = Value - }); - } else { - return JObject.FromObject (new { - target.id, - target.sessionId, - error = Error - }); - } - } - - public override string ToString () - { - return $"[Result: IsOk: {IsOk}, IsErr: {IsErr}, Value: {Value?.ToString ()}, Error: {Error?.ToString ()} ]"; - } - } - - internal class MonoCommands { - public string expression { get; set; } - public string objectGroup { get; set; } = "mono-debugger"; - public bool includeCommandLineAPI { get; set; } = false; - public bool silent { get; set; } = false; - public bool returnByValue { get; set; } = true; - - public MonoCommands (string expression) - => this.expression = expression; - - public static MonoCommands GetCallStack () - => new MonoCommands ("MONO.mono_wasm_get_call_stack()"); - - public static MonoCommands IsRuntimeReady () - => new MonoCommands ("MONO.mono_wasm_runtime_is_ready"); - - public static MonoCommands StartSingleStepping (StepKind kind) - => new MonoCommands ($"MONO.mono_wasm_start_single_stepping ({(int)kind})"); - - public static MonoCommands GetLoadedFiles () - => new MonoCommands ("MONO.mono_wasm_get_loaded_files()"); - - public static MonoCommands ClearAllBreakpoints () - => new MonoCommands ("MONO.mono_wasm_clear_all_breakpoints()"); - - public static MonoCommands GetDetails (DotnetObjectId objectId, JToken args = null) - => new MonoCommands ($"MONO.mono_wasm_get_details ('{objectId}', {(args ?? "{}")})"); - - public static MonoCommands GetScopeVariables (int scopeId, params int[] vars) - => new MonoCommands ($"MONO.mono_wasm_get_variables({scopeId}, [ {string.Join (",", vars)} ])"); - - public static MonoCommands SetBreakpoint (string assemblyName, uint methodToken, int ilOffset) - => new MonoCommands ($"MONO.mono_wasm_set_breakpoint (\"{assemblyName}\", {methodToken}, {ilOffset})"); - - public static MonoCommands RemoveBreakpoint (int breakpointId) - => new MonoCommands ($"MONO.mono_wasm_remove_breakpoint({breakpointId})"); - - public static MonoCommands ReleaseObject (DotnetObjectId objectId) - => new MonoCommands ($"MONO.mono_wasm_release_object('{objectId}')"); - - public static MonoCommands CallFunctionOn (JToken args) - => new MonoCommands ($"MONO.mono_wasm_call_function_on ({args.ToString ()})"); - } - - internal enum MonoErrorCodes { - BpNotFound = 100000, - } - - internal class MonoConstants { - public const string RUNTIME_IS_READY = "mono_wasm_runtime_ready"; - } - - class Frame { - public Frame (MethodInfo method, SourceLocation location, int id) - { - this.Method = method; - this.Location = location; - this.Id = id; - } - - public MethodInfo Method { get; private set; } - public SourceLocation Location { get; private set; } - public int Id { get; private set; } - } - - class Breakpoint { - public SourceLocation Location { get; private set; } - public int RemoteId { get; set; } - public BreakpointState State { get; set; } - public string StackId { get; private set; } - - public static bool TryParseId (string stackId, out int id) - { - id = -1; - if (stackId?.StartsWith ("dotnet:", StringComparison.Ordinal) != true) - return false; - - return int.TryParse (stackId.Substring ("dotnet:".Length), out id); - } - - public Breakpoint (string stackId, SourceLocation loc, BreakpointState state) - { - this.StackId = stackId; - this.Location = loc; - this.State = state; - } - } - - enum BreakpointState { - Active, - Disabled, - Pending - } - - enum StepKind { - Into, - Out, - Over - } - - internal class ExecutionContext { - public string DebuggerId { get; set; } - public Dictionary BreakpointRequests { get; } = new Dictionary (); - - public TaskCompletionSource ready = null; - public bool IsRuntimeReady => ready != null && ready.Task.IsCompleted; - - public int Id { get; set; } - public object AuxData { get; set; } - - public List CallStack { get; set; } - - internal DebugStore store; - public TaskCompletionSource Source { get; } = new TaskCompletionSource (); - - public Dictionary LocalsCache = new Dictionary (); - - public DebugStore Store { - get { - if (store == null || !Source.Task.IsCompleted) - return null; - - return store; - } - } - - public void ClearState () - { - CallStack = null; - LocalsCache.Clear (); - } - - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsProxy.cs b/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsProxy.cs deleted file mode 100644 index 5eac86d124..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsProxy.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -using System.Net.WebSockets; -using System.Threading; -using System.IO; -using System.Text; -using System.Collections.Generic; -using Microsoft.Extensions.Logging; - -namespace WebAssembly.Net.Debugging { - - class DevToolsQueue { - Task current_send; - List pending; - - public WebSocket Ws { get; private set; } - public Task CurrentSend { get { return current_send; } } - public DevToolsQueue (WebSocket sock) - { - this.Ws = sock; - pending = new List (); - } - - public Task Send (byte [] bytes, CancellationToken token) - { - pending.Add (bytes); - if (pending.Count == 1) { - if (current_send != null) - throw new Exception ("current_send MUST BE NULL IF THERE'S no pending send"); - //logger.LogTrace ("sending {0} bytes", bytes.Length); - current_send = Ws.SendAsync (new ArraySegment (bytes), WebSocketMessageType.Text, true, token); - return current_send; - } - return null; - } - - public Task Pump (CancellationToken token) - { - current_send = null; - pending.RemoveAt (0); - - if (pending.Count > 0) { - if (current_send != null) - throw new Exception ("current_send MUST BE NULL IF THERE'S no pending send"); - - current_send = Ws.SendAsync (new ArraySegment (pending [0]), WebSocketMessageType.Text, true, token); - return current_send; - } - return null; - } - } - - internal class DevToolsProxy { - TaskCompletionSource side_exception = new TaskCompletionSource (); - TaskCompletionSource client_initiated_close = new TaskCompletionSource (); - Dictionary> pending_cmds = new Dictionary> (); - ClientWebSocket browser; - WebSocket ide; - int next_cmd_id; - List pending_ops = new List (); - List queues = new List (); - - protected readonly ILogger logger; - - public DevToolsProxy (ILoggerFactory loggerFactory) - { - logger = loggerFactory.CreateLogger(); - } - - protected virtual Task AcceptEvent (SessionId sessionId, string method, JObject args, CancellationToken token) - { - return Task.FromResult (false); - } - - protected virtual Task AcceptCommand (MessageId id, string method, JObject args, CancellationToken token) - { - return Task.FromResult (false); - } - - async Task ReadOne (WebSocket socket, CancellationToken token) - { - byte [] buff = new byte [4000]; - var mem = new MemoryStream (); - while (true) { - - if (socket.State != WebSocketState.Open) { - Log ("error", $"DevToolsProxy: Socket is no longer open."); - client_initiated_close.TrySetResult (true); - return null; - } - - var result = await socket.ReceiveAsync (new ArraySegment (buff), token); - if (result.MessageType == WebSocketMessageType.Close) { - client_initiated_close.TrySetResult (true); - return null; - } - - mem.Write (buff, 0, result.Count); - - if (result.EndOfMessage) - return Encoding.UTF8.GetString (mem.GetBuffer (), 0, (int)mem.Length); - } - } - - DevToolsQueue GetQueueForSocket (WebSocket ws) - { - return queues.FirstOrDefault (q => q.Ws == ws); - } - - DevToolsQueue GetQueueForTask (Task task) - { - return queues.FirstOrDefault (q => q.CurrentSend == task); - } - - void Send (WebSocket to, JObject o, CancellationToken token) - { - var sender = browser == to ? "Send-browser" : "Send-ide"; - - var method = o ["method"]?.ToString (); - //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") - Log ("protocol", $"{sender}: " + JsonConvert.SerializeObject (o)); - var bytes = Encoding.UTF8.GetBytes (o.ToString ()); - - var queue = GetQueueForSocket (to); - - var task = queue.Send (bytes, token); - if (task != null) - pending_ops.Add (task); - } - - async Task OnEvent (SessionId sessionId, string method, JObject args, CancellationToken token) - { - try { - if (!await AcceptEvent (sessionId, method, args, token)) { - //logger.LogDebug ("proxy browser: {0}::{1}",method, args); - SendEventInternal (sessionId, method, args, token); - } - } catch (Exception e) { - side_exception.TrySetException (e); - } - } - - async Task OnCommand (MessageId id, string method, JObject args, CancellationToken token) - { - try { - if (!await AcceptCommand (id, method, args, token)) { - var res = await SendCommandInternal (id, method, args, token); - SendResponseInternal (id, res, token); - } - } catch (Exception e) { - side_exception.TrySetException (e); - } - } - - void OnResponse (MessageId id, Result result) - { - //logger.LogTrace ("got id {0} res {1}", id, result); - // Fixme - if (pending_cmds.Remove (id, out var task)) { - task.SetResult (result); - return; - } - logger.LogError ("Cannot respond to command: {id} with result: {result} - command is not pending", id, result); - } - - void ProcessBrowserMessage (string msg, CancellationToken token) - { - var res = JObject.Parse (msg); - - var method = res ["method"]?.ToString (); - //if (method != "Debugger.scriptParsed" && method != "Runtime.consoleAPICalled") - Log ("protocol", $"browser: {msg}"); - - if (res ["id"] == null) - pending_ops.Add (OnEvent (new SessionId (res ["sessionId"]?.Value ()), res ["method"].Value (), res ["params"] as JObject, token)); - else - OnResponse (new MessageId (res ["sessionId"]?.Value (), res ["id"].Value ()), Result.FromJson (res)); - } - - void ProcessIdeMessage (string msg, CancellationToken token) - { - Log ("protocol", $"ide: {msg}"); - if (!string.IsNullOrEmpty (msg)) { - var res = JObject.Parse (msg); - pending_ops.Add (OnCommand ( - new MessageId (res ["sessionId"]?.Value (), res ["id"].Value ()), - res ["method"].Value (), - res ["params"] as JObject, token)); - } - } - - internal async Task SendCommand (SessionId id, string method, JObject args, CancellationToken token) { - //Log ("verbose", $"sending command {method}: {args}"); - return await SendCommandInternal (id, method, args, token); - } - - Task SendCommandInternal (SessionId sessionId, string method, JObject args, CancellationToken token) - { - int id = Interlocked.Increment (ref next_cmd_id); - - var o = JObject.FromObject (new { - id, - method, - @params = args - }); - if (sessionId.sessionId != null) - o["sessionId"] = sessionId.sessionId; - var tcs = new TaskCompletionSource (); - - var msgId = new MessageId (sessionId.sessionId, id); - //Log ("verbose", $"add cmd id {sessionId}-{id}"); - pending_cmds[msgId] = tcs; - - Send (this.browser, o, token); - return tcs.Task; - } - - public void SendEvent (SessionId sessionId, string method, JObject args, CancellationToken token) - { - //Log ("verbose", $"sending event {method}: {args}"); - SendEventInternal (sessionId, method, args, token); - } - - void SendEventInternal (SessionId sessionId, string method, JObject args, CancellationToken token) - { - var o = JObject.FromObject (new { - method, - @params = args - }); - if (sessionId.sessionId != null) - o["sessionId"] = sessionId.sessionId; - - Send (this.ide, o, token); - } - - internal void SendResponse (MessageId id, Result result, CancellationToken token) - { - SendResponseInternal (id, result, token); - } - - void SendResponseInternal (MessageId id, Result result, CancellationToken token) - { - JObject o = result.ToJObject (id); - if (result.IsErr) - logger.LogError ($"sending error response for id: {id} -> {result}"); - - Send (this.ide, o, token); - } - - // , HttpContext context) - public async Task Run (Uri browserUri, WebSocket ideSocket) - { - Log ("info", $"DevToolsProxy: Starting on {browserUri}"); - using (this.ide = ideSocket) { - Log ("verbose", $"DevToolsProxy: IDE waiting for connection on {browserUri}"); - queues.Add (new DevToolsQueue (this.ide)); - using (this.browser = new ClientWebSocket ()) { - this.browser.Options.KeepAliveInterval = Timeout.InfiniteTimeSpan; - await this.browser.ConnectAsync (browserUri, CancellationToken.None); - queues.Add (new DevToolsQueue (this.browser)); - - Log ("verbose", $"DevToolsProxy: Client connected on {browserUri}"); - var x = new CancellationTokenSource (); - - pending_ops.Add (ReadOne (browser, x.Token)); - pending_ops.Add (ReadOne (ide, x.Token)); - pending_ops.Add (side_exception.Task); - pending_ops.Add (client_initiated_close.Task); - - try { - while (!x.IsCancellationRequested) { - var task = await Task.WhenAny (pending_ops.ToArray ()); - //logger.LogTrace ("pump {0} {1}", task, pending_ops.IndexOf (task)); - if (task == pending_ops [0]) { - var msg = ((Task)task).Result; - if (msg != null) { - pending_ops [0] = ReadOne (browser, x.Token); //queue next read - ProcessBrowserMessage (msg, x.Token); - } - } else if (task == pending_ops [1]) { - var msg = ((Task)task).Result; - if (msg != null) { - pending_ops [1] = ReadOne (ide, x.Token); //queue next read - ProcessIdeMessage (msg, x.Token); - } - } else if (task == pending_ops [2]) { - var res = ((Task)task).Result; - throw new Exception ("side task must always complete with an exception, what's going on???"); - } else if (task == pending_ops [3]) { - var res = ((Task)task).Result; - Log ("verbose", $"DevToolsProxy: Client initiated close from {browserUri}"); - x.Cancel (); - } else { - //must be a background task - pending_ops.Remove (task); - var queue = GetQueueForTask (task); - if (queue != null) { - var tsk = queue.Pump (x.Token); - if (tsk != null) - pending_ops.Add (tsk); - } - } - } - } catch (Exception e) { - Log ("error", $"DevToolsProxy::Run: Exception {e}"); - //throw; - } finally { - if (!x.IsCancellationRequested) - x.Cancel (); - } - } - } - } - - protected void Log (string priority, string msg) - { - switch (priority) { - case "protocol": - logger.LogTrace (msg); - break; - case "verbose": - logger.LogDebug (msg); - break; - case "info": - case "warning": - case "error": - default: - logger.LogDebug (msg); - break; - } - } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/EvaluateExpression.cs b/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/EvaluateExpression.cs deleted file mode 100644 index fb7e776ed9..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/EvaluateExpression.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Newtonsoft.Json.Linq; - -using System.Threading; -using System.IO; -using System.Collections.Generic; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Emit; -using System.Reflection; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace WebAssembly.Net.Debugging { - - internal class EvaluateExpression { - - class FindThisExpression : CSharpSyntaxWalker { - public List thisExpressions = new List (); - public SyntaxTree syntaxTree; - public FindThisExpression (SyntaxTree syntax) - { - syntaxTree = syntax; - } - public override void Visit (SyntaxNode node) - { - if (node is ThisExpressionSyntax) { - if (node.Parent is MemberAccessExpressionSyntax thisParent && thisParent.Name is IdentifierNameSyntax) { - IdentifierNameSyntax var = thisParent.Name as IdentifierNameSyntax; - thisExpressions.Add(var.Identifier.Text); - var newRoot = syntaxTree.GetRoot ().ReplaceNode (node.Parent, thisParent.Name); - syntaxTree = syntaxTree.WithRootAndOptions (newRoot, syntaxTree.Options); - this.Visit (GetExpressionFromSyntaxTree(syntaxTree)); - } - } - else - base.Visit (node); - } - - public async Task CheckIfIsProperty (MonoProxy proxy, MessageId msg_id, int scope_id, CancellationToken token) - { - foreach (var var in thisExpressions) { - JToken value = await proxy.TryGetVariableValue (msg_id, scope_id, var, true, token); - if (value == null) - throw new Exception ($"The property {var} does not exist in the current context"); - } - } - } - - class FindVariableNMethodCall : CSharpSyntaxWalker { - public List variables = new List (); - public List thisList = new List (); - public List methodCall = new List (); - public List values = new List (); - - public override void Visit (SyntaxNode node) - { - if (node is IdentifierNameSyntax identifier && !variables.Any (x => x.Identifier.Text == identifier.Identifier.Text)) - variables.Add (identifier); - if (node is InvocationExpressionSyntax) { - methodCall.Add (node as InvocationExpressionSyntax); - throw new Exception ("Method Call is not implemented yet"); - } - if (node is AssignmentExpressionSyntax) - throw new Exception ("Assignment is not implemented yet"); - base.Visit (node); - } - public async Task ReplaceVars (SyntaxTree syntaxTree, MonoProxy proxy, MessageId msg_id, int scope_id, CancellationToken token) - { - CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot (); - foreach (var var in variables) { - ClassDeclarationSyntax classDeclaration = root.Members.ElementAt (0) as ClassDeclarationSyntax; - MethodDeclarationSyntax method = classDeclaration.Members.ElementAt (0) as MethodDeclarationSyntax; - - JToken value = await proxy.TryGetVariableValue (msg_id, scope_id, var.Identifier.Text, false, token); - - if (value == null) - throw new Exception ($"The name {var.Identifier.Text} does not exist in the current context"); - - values.Add (ConvertJSToCSharpType (value ["value"] ["value"].ToString (), value ["value"] ["type"].ToString ())); - - var updatedMethod = method.AddParameterListParameters ( - SyntaxFactory.Parameter ( - SyntaxFactory.Identifier (var.Identifier.Text)) - .WithType (SyntaxFactory.ParseTypeName (GetTypeFullName(value["value"]["type"].ToString())))); - root = root.ReplaceNode (method, updatedMethod); - } - syntaxTree = syntaxTree.WithRootAndOptions (root, syntaxTree.Options); - return syntaxTree; - } - - private object ConvertJSToCSharpType (string v, string type) - { - switch (type) { - case "number": - return Convert.ChangeType (v, typeof (int)); - case "string": - return v; - } - - throw new Exception ($"Evaluate of this datatype {type} not implemented yet"); - } - - private string GetTypeFullName (string type) - { - switch (type) { - case "number": - return typeof (int).FullName; - case "string": - return typeof (string).FullName; - } - - throw new Exception ($"Evaluate of this datatype {type} not implemented yet"); - } - } - static SyntaxNode GetExpressionFromSyntaxTree (SyntaxTree syntaxTree) - { - CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot (); - ClassDeclarationSyntax classDeclaration = root.Members.ElementAt (0) as ClassDeclarationSyntax; - MethodDeclarationSyntax methodDeclaration = classDeclaration.Members.ElementAt (0) as MethodDeclarationSyntax; - BlockSyntax blockValue = methodDeclaration.Body; - ReturnStatementSyntax returnValue = blockValue.Statements.ElementAt (0) as ReturnStatementSyntax; - InvocationExpressionSyntax expressionInvocation = returnValue.Expression as InvocationExpressionSyntax; - MemberAccessExpressionSyntax expressionMember = expressionInvocation.Expression as MemberAccessExpressionSyntax; - ParenthesizedExpressionSyntax expressionParenthesized = expressionMember.Expression as ParenthesizedExpressionSyntax; - return expressionParenthesized.Expression; - } - internal static async Task CompileAndRunTheExpression (MonoProxy proxy, MessageId msg_id, int scope_id, string expression, CancellationToken token) - { - FindVariableNMethodCall findVarNMethodCall = new FindVariableNMethodCall (); - string retString; - SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText (@" - using System; - public class CompileAndRunTheExpression - { - public string Evaluate() - { - return (" + expression + @").ToString(); - } - }"); - - FindThisExpression findThisExpression = new FindThisExpression (syntaxTree); - var expressionTree = GetExpressionFromSyntaxTree(syntaxTree); - findThisExpression.Visit (expressionTree); - await findThisExpression.CheckIfIsProperty (proxy, msg_id, scope_id, token); - syntaxTree = findThisExpression.syntaxTree; - - expressionTree = GetExpressionFromSyntaxTree (syntaxTree); - findVarNMethodCall.Visit (expressionTree); - - syntaxTree = await findVarNMethodCall.ReplaceVars (syntaxTree, proxy, msg_id, scope_id, token); - - MetadataReference [] references = new MetadataReference [] - { - MetadataReference.CreateFromFile(typeof(object).Assembly.Location), - MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location) - }; - - CSharpCompilation compilation = CSharpCompilation.Create ( - "compileAndRunTheExpression", - syntaxTrees: new [] { syntaxTree }, - references: references, - options: new CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary)); - using (var ms = new MemoryStream ()) { - EmitResult result = compilation.Emit (ms); - ms.Seek (0, SeekOrigin.Begin); - Assembly assembly = Assembly.Load (ms.ToArray ()); - Type type = assembly.GetType ("CompileAndRunTheExpression"); - object obj = Activator.CreateInstance (type); - var ret = type.InvokeMember ("Evaluate", - BindingFlags.Default | BindingFlags.InvokeMethod, - null, - obj, - //new object [] { 10 } - findVarNMethodCall.values.ToArray ()); - retString = ret.ToString (); - } - return retString; - } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/MonoProxy.cs b/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/MonoProxy.cs deleted file mode 100644 index 1b26dd93fd..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/MonoProxy.cs +++ /dev/null @@ -1,885 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Newtonsoft.Json.Linq; - -using System.Threading; -using System.IO; -using System.Collections.Generic; -using System.Net; -using Microsoft.Extensions.Logging; -using Microsoft.CodeAnalysis; - - -namespace WebAssembly.Net.Debugging { - - internal class MonoProxy : DevToolsProxy { - HashSet sessions = new HashSet (); - Dictionary contexts = new Dictionary (); - - public MonoProxy (ILoggerFactory loggerFactory, bool hideWebDriver = true) : base(loggerFactory) { this.hideWebDriver = hideWebDriver; } - - readonly bool hideWebDriver; - - internal ExecutionContext GetContext (SessionId sessionId) - { - if (contexts.TryGetValue (sessionId, out var context)) - return context; - - throw new ArgumentException ($"Invalid Session: \"{sessionId}\"", nameof (sessionId)); - } - - bool UpdateContext (SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext) - { - var previous = contexts.TryGetValue (sessionId, out previousExecutionContext); - contexts[sessionId] = executionContext; - return previous; - } - - internal Task SendMonoCommand (SessionId id, MonoCommands cmd, CancellationToken token) - => SendCommand (id, "Runtime.evaluate", JObject.FromObject (cmd), token); - - protected override async Task AcceptEvent (SessionId sessionId, string method, JObject args, CancellationToken token) - { - switch (method) { - case "Runtime.consoleAPICalled": { - var type = args["type"]?.ToString (); - if (type == "debug") { - if (args["args"]?[0]?["value"]?.ToString () == MonoConstants.RUNTIME_IS_READY && args["args"]?[1]?["value"]?.ToString () == "fe00e07a-5519-4dfe-b35a-f867dbaf2e28") - await RuntimeReady (sessionId, token); - } - break; - } - - case "Runtime.executionContextCreated": { - SendEvent (sessionId, method, args, token); - var ctx = args? ["context"]; - var aux_data = ctx? ["auxData"] as JObject; - var id = ctx ["id"].Value (); - if (aux_data != null) { - var is_default = aux_data ["isDefault"]?.Value (); - if (is_default == true) { - await OnDefaultContext (sessionId, new ExecutionContext { Id = id, AuxData = aux_data }, token); - } - } - return true; - } - - case "Debugger.paused": { - //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack - var top_func = args? ["callFrames"]? [0]? ["functionName"]?.Value (); - - if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") { - return await OnBreakpointHit (sessionId, args, token); - } - break; - } - - case "Debugger.breakpointResolved": { - break; - } - - case "Debugger.scriptParsed": { - var url = args? ["url"]?.Value () ?? ""; - - switch (url) { - case var _ when url == "": - case var _ when url.StartsWith ("wasm://", StringComparison.Ordinal): { - Log ("verbose", $"ignoring wasm: Debugger.scriptParsed {url}"); - return true; - } - } - Log ("verbose", $"proxying Debugger.scriptParsed ({sessionId.sessionId}) {url} {args}"); - break; - } - - case "Target.attachedToTarget": { - if (args["targetInfo"]["type"]?.ToString() == "page") - await DeleteWebDriver (new SessionId (args["sessionId"]?.ToString ()), token); - break; - } - - } - - return false; - } - - async Task IsRuntimeAlreadyReadyAlready (SessionId sessionId, CancellationToken token) - { - var res = await SendMonoCommand (sessionId, MonoCommands.IsRuntimeReady (), token); - return res.Value? ["result"]? ["value"]?.Value () ?? false; - } - - static int bpIdGenerator; - - protected override async Task AcceptCommand (MessageId id, string method, JObject args, CancellationToken token) - { - // Inspector doesn't use the Target domain or sessions - // so we try to init immediately - if (hideWebDriver && id == SessionId.Null) - await DeleteWebDriver (id, token); - - if (!contexts.TryGetValue (id, out var context)) - return false; - - switch (method) { - case "Target.attachToTarget": { - var resp = await SendCommand (id, method, args, token); - await DeleteWebDriver (new SessionId (resp.Value ["sessionId"]?.ToString ()), token); - break; - } - - case "Debugger.enable": { - var resp = await SendCommand (id, method, args, token); - - context.DebuggerId = resp.Value ["debuggerId"]?.ToString (); - - if (await IsRuntimeAlreadyReadyAlready (id, token)) - await RuntimeReady (id, token); - - SendResponse (id,resp,token); - return true; - } - - case "Debugger.getScriptSource": { - var script = args? ["scriptId"]?.Value (); - return await OnGetScriptSource (id, script, token); - } - - case "Runtime.compileScript": { - var exp = args? ["expression"]?.Value (); - if (exp.StartsWith ("//dotnet:", StringComparison.Ordinal)) { - OnCompileDotnetScript (id, token); - return true; - } - break; - } - - case "Debugger.getPossibleBreakpoints": { - var resp = await SendCommand (id, method, args, token); - if (resp.IsOk && resp.Value["locations"].HasValues) { - SendResponse (id, resp, token); - return true; - } - - var start = SourceLocation.Parse (args? ["start"] as JObject); - //FIXME support variant where restrictToFunction=true and end is omitted - var end = SourceLocation.Parse (args? ["end"] as JObject); - if (start != null && end != null && await GetPossibleBreakpoints (id, start, end, token)) - return true; - - SendResponse (id, resp, token); - return true; - } - - case "Debugger.setBreakpoint": { - break; - } - - case "Debugger.setBreakpointByUrl": { - var resp = await SendCommand (id, method, args, token); - if (!resp.IsOk) { - SendResponse (id, resp, token); - return true; - } - - var bpid = resp.Value["breakpointId"]?.ToString (); - var locations = resp.Value["locations"]?.Values(); - var request = BreakpointRequest.Parse (bpid, args); - - // is the store done loading? - var loaded = context.Source.Task.IsCompleted; - if (!loaded) { - // Send and empty response immediately if not - // and register the breakpoint for resolution - context.BreakpointRequests [bpid] = request; - SendResponse (id, resp, token); - } - - if (await IsRuntimeAlreadyReadyAlready (id, token)) { - var store = await RuntimeReady (id, token); - - Log ("verbose", $"BP req {args}"); - await SetBreakpoint (id, store, request, !loaded, token); - } - - if (loaded) { - // we were already loaded so we should send a response - // with the locations included and register the request - context.BreakpointRequests [bpid] = request; - var result = Result.OkFromObject (request.AsSetBreakpointByUrlResponse (locations)); - SendResponse (id, result, token); - - } - return true; - } - - case "Debugger.removeBreakpoint": { - await RemoveBreakpoint (id, args, token); - break; - } - - case "Debugger.resume": { - await OnResume (id, token); - break; - } - - case "Debugger.stepInto": { - return await Step (id, StepKind.Into, token); - } - - case "Debugger.stepOut": { - return await Step (id, StepKind.Out, token); - } - - case "Debugger.stepOver": { - return await Step (id, StepKind.Over, token); - } - - case "Debugger.evaluateOnCallFrame": { - if (!DotnetObjectId.TryParse (args? ["callFrameId"], out var objectId)) - return false; - - switch (objectId.Scheme) { - case "scope": - return await OnEvaluateOnCallFrame (id, - int.Parse (objectId.Value), - args? ["expression"]?.Value (), token); - default: - return false; - } - } - - case "Runtime.getProperties": { - if (!DotnetObjectId.TryParse (args? ["objectId"], out var objectId)) - break; - - var result = await RuntimeGetProperties (id, objectId, args, token); - SendResponse (id, result, token); - return true; - } - - case "Runtime.releaseObject": { - if (!(DotnetObjectId.TryParse (args ["objectId"], out var objectId) && objectId.Scheme == "cfo_res")) - break; - - await SendMonoCommand (id, MonoCommands.ReleaseObject (objectId), token); - SendResponse (id, Result.OkFromObject (new{}), token); - return true; - } - - // Protocol extensions - case "Dotnet-test.setBreakpointByMethod": { - Console.WriteLine ("set-breakpoint-by-method: " + id + " " + args); - - var store = await RuntimeReady (id, token); - string aname = args ["assemblyName"]?.Value (); - string typeName = args ["typeName"]?.Value (); - string methodName = args ["methodName"]?.Value (); - if (aname == null || typeName == null || methodName == null) { - SendResponse (id, Result.Err ("Invalid protocol message '" + args + "'."), token); - return true; - } - - // GetAssemblyByName seems to work on file names - var assembly = store.GetAssemblyByName (aname); - if (assembly == null) - assembly = store.GetAssemblyByName (aname + ".exe"); - if (assembly == null) - assembly = store.GetAssemblyByName (aname + ".dll"); - if (assembly == null) { - SendResponse (id, Result.Err ("Assembly '" + aname + "' not found."), token); - return true; - } - - var type = assembly.GetTypeByName (typeName); - if (type == null) { - SendResponse (id, Result.Err ($"Type '{typeName}' not found."), token); - return true; - } - - var methodInfo = type.Methods.FirstOrDefault (m => m.Name == methodName); - if (methodInfo == null) { - SendResponse (id, Result.Err ($"Method '{typeName}:{methodName}' not found."), token); - return true; - } - - bpIdGenerator ++; - string bpid = "by-method-" + bpIdGenerator.ToString (); - var request = new BreakpointRequest (bpid, methodInfo); - context.BreakpointRequests[bpid] = request; - - var loc = methodInfo.StartLocation; - var bp = await SetMonoBreakpoint (id, bpid, loc, token); - if (bp.State != BreakpointState.Active) { - // FIXME: - throw new NotImplementedException (); - } - - var resolvedLocation = new { - breakpointId = bpid, - location = loc.AsLocation () - }; - - SendEvent (id, "Debugger.breakpointResolved", JObject.FromObject (resolvedLocation), token); - - SendResponse (id, Result.OkFromObject (new { - result = new { breakpointId = bpid, locations = new object [] { loc.AsLocation () }} - }), token); - - return true; - } - case "Runtime.callFunctionOn": { - if (!DotnetObjectId.TryParse (args ["objectId"], out var objectId)) - return false; - - var silent = args ["silent"]?.Value () ?? false; - if (objectId.Scheme == "scope") { - var fail = silent ? Result.OkFromObject (new { result = new { } }) : Result.Exception (new ArgumentException ($"Runtime.callFunctionOn not supported with scope ({objectId}).")); - - SendResponse (id, fail, token); - return true; - } - - var returnByValue = args ["returnByValue"]?.Value () ?? false; - var res = await SendMonoCommand (id, MonoCommands.CallFunctionOn (args), token); - - if (!returnByValue && - DotnetObjectId.TryParse (res.Value?["result"]?["value"]?["objectId"], out var resultObjectId) && - resultObjectId.Scheme == "cfo_res") - res = Result.OkFromObject (new { result = res.Value ["result"]["value"] }); - - if (res.IsErr && silent) - res = Result.OkFromObject (new { result = new { } }); - - SendResponse (id, res, token); - return true; - } - } - - return false; - } - - async Task RuntimeGetProperties (MessageId id, DotnetObjectId objectId, JToken args, CancellationToken token) - { - if (objectId.Scheme == "scope") - return await GetScopeProperties (id, int.Parse (objectId.Value), token); - - var res = await SendMonoCommand (id, MonoCommands.GetDetails (objectId, args), token); - if (res.IsErr) - return res; - - if (objectId.Scheme == "cfo_res") { - // Runtime.callFunctionOn result object - var value_json_str = res.Value ["result"]?["value"]?["__value_as_json_string__"]?.Value (); - if (value_json_str != null) { - res = Result.OkFromObject (new { - result = JArray.Parse (value_json_str.Replace (@"\""", "\"")) - }); - } else { - res = Result.OkFromObject (new { result = new {} }); - } - } else { - res = Result.Ok (JObject.FromObject (new { result = res.Value ["result"] ["value"] })); - } - - return res; - } - - //static int frame_id=0; - async Task OnBreakpointHit (SessionId sessionId, JObject args, CancellationToken token) - { - //FIXME we should send release objects every now and then? Or intercept those we inject and deal in the runtime - var res = await SendMonoCommand (sessionId, MonoCommands.GetCallStack(), token); - var orig_callframes = args? ["callFrames"]?.Values (); - var context = GetContext (sessionId); - - if (res.IsErr) { - //Give up and send the original call stack - return false; - } - - //step one, figure out where did we hit - var res_value = res.Value? ["result"]? ["value"]; - if (res_value == null || res_value is JValue) { - //Give up and send the original call stack - return false; - } - - Log ("verbose", $"call stack (err is {res.Error} value is:\n{res.Value}"); - var bp_id = res_value? ["breakpoint_id"]?.Value (); - Log ("verbose", $"We just hit bp {bp_id}"); - if (!bp_id.HasValue) { - //Give up and send the original call stack - return false; - } - - var bp = context.BreakpointRequests.Values.SelectMany (v => v.Locations).FirstOrDefault (b => b.RemoteId == bp_id.Value); - - var callFrames = new List (); - foreach (var frame in orig_callframes) { - var function_name = frame ["functionName"]?.Value (); - var url = frame ["url"]?.Value (); - if ("mono_wasm_fire_bp" == function_name || "_mono_wasm_fire_bp" == function_name) { - var frames = new List (); - int frame_id = 0; - var the_mono_frames = res.Value? ["result"]? ["value"]? ["frames"]?.Values (); - - foreach (var mono_frame in the_mono_frames) { - ++frame_id; - var il_pos = mono_frame ["il_pos"].Value (); - var method_token = mono_frame ["method_token"].Value (); - var assembly_name = mono_frame ["assembly_name"].Value (); - - // This can be different than `method.Name`, like in case of generic methods - var method_name = mono_frame ["method_name"]?.Value (); - - var store = await LoadStore (sessionId, token); - var asm = store.GetAssemblyByName (assembly_name); - if (asm == null) { - Log ("info",$"Unable to find assembly: {assembly_name}"); - continue; - } - - var method = asm.GetMethodByToken (method_token); - - if (method == null) { - Log ("info", $"Unable to find il offset: {il_pos} in method token: {method_token} assembly name: {assembly_name}"); - continue; - } - - var location = method?.GetLocationByIl (il_pos); - - // When hitting a breakpoint on the "IncrementCount" method in the standard - // Blazor project template, one of the stack frames is inside mscorlib.dll - // and we get location==null for it. It will trigger a NullReferenceException - // if we don't skip over that stack frame. - if (location == null) { - continue; - } - - Log ("info", $"frame il offset: {il_pos} method token: {method_token} assembly name: {assembly_name}"); - Log ("info", $"\tmethod {method_name} location: {location}"); - frames.Add (new Frame (method, location, frame_id-1)); - - callFrames.Add (new { - functionName = method_name, - callFrameId = $"dotnet:scope:{frame_id-1}", - functionLocation = method.StartLocation.AsLocation (), - - location = location.AsLocation (), - - url = store.ToUrl (location), - - scopeChain = new [] { - new { - type = "local", - @object = new { - @type = "object", - className = "Object", - description = "Object", - objectId = $"dotnet:scope:{frame_id-1}", - }, - name = method_name, - startLocation = method.StartLocation.AsLocation (), - endLocation = method.EndLocation.AsLocation (), - }} - }); - - context.CallStack = frames; - - } - } else if (!(function_name.StartsWith ("wasm-function", StringComparison.Ordinal) - || url.StartsWith ("wasm://wasm/", StringComparison.Ordinal))) { - callFrames.Add (frame); - } - } - - var bp_list = new string [bp == null ? 0 : 1]; - if (bp != null) - bp_list [0] = bp.StackId; - - var o = JObject.FromObject (new { - callFrames, - reason = "other", //other means breakpoint - hitBreakpoints = bp_list, - }); - - SendEvent (sessionId, "Debugger.paused", o, token); - return true; - } - - async Task OnDefaultContext (SessionId sessionId, ExecutionContext context, CancellationToken token) - { - Log ("verbose", "Default context created, clearing state and sending events"); - if (UpdateContext (sessionId, context, out var previousContext)) { - foreach (var kvp in previousContext.BreakpointRequests) { - context.BreakpointRequests[kvp.Key] = kvp.Value.Clone(); - } - } - - if (await IsRuntimeAlreadyReadyAlready (sessionId, token)) - await RuntimeReady (sessionId, token); - } - - async Task OnResume (MessageId msd_id, CancellationToken token) - { - //discard managed frames - GetContext (msd_id).ClearState (); - await Task.CompletedTask; - } - - async Task Step (MessageId msg_id, StepKind kind, CancellationToken token) - { - var context = GetContext (msg_id); - if (context.CallStack == null) - return false; - - if (context.CallStack.Count <= 1 && kind == StepKind.Out) - return false; - - var res = await SendMonoCommand (msg_id, MonoCommands.StartSingleStepping (kind), token); - - var ret_code = res.Value? ["result"]? ["value"]?.Value (); - - if (ret_code.HasValue && ret_code.Value == 0) { - context.ClearState (); - await SendCommand (msg_id, "Debugger.stepOut", new JObject (), token); - return false; - } - - SendResponse (msg_id, Result.Ok (new JObject ()), token); - - context.ClearState (); - - await SendCommand (msg_id, "Debugger.resume", new JObject (), token); - return true; - } - - internal bool TryFindVariableValueInCache(ExecutionContext ctx, string expression, bool only_search_on_this, out JToken obj) - { - if (ctx.LocalsCache.TryGetValue (expression, out obj)) { - if (only_search_on_this && obj["fromThis"] == null) - return false; - return true; - } - return false; - } - - internal async Task TryGetVariableValue (MessageId msg_id, int scope_id, string expression, bool only_search_on_this, CancellationToken token) - { - JToken thisValue = null; - var context = GetContext (msg_id); - if (context.CallStack == null) - return null; - - if (TryFindVariableValueInCache(context, expression, only_search_on_this, out JToken obj)) - return obj; - - var scope = context.CallStack.FirstOrDefault (s => s.Id == scope_id); - var live_vars = scope.Method.GetLiveVarsAt (scope.Location.CliLocation.Offset); - //get_this - var res = await SendMonoCommand (msg_id, MonoCommands.GetScopeVariables (scope.Id, live_vars.Select (lv => lv.Index).ToArray ()), token); - - var scope_values = res.Value? ["result"]? ["value"]?.Values ()?.ToArray (); - thisValue = scope_values?.FirstOrDefault (v => v ["name"]?.Value () == "this"); - - if (!only_search_on_this) { - if (thisValue != null && expression == "this") - return thisValue; - - var value = scope_values.SingleOrDefault (sv => sv ["name"]?.Value () == expression); - if (value != null) - return value; - } - - //search in scope - if (thisValue != null) { - if (!DotnetObjectId.TryParse (thisValue ["value"] ["objectId"], out var objectId)) - return null; - - res = await SendMonoCommand (msg_id, MonoCommands.GetDetails (objectId), token); - scope_values = res.Value? ["result"]? ["value"]?.Values ().ToArray (); - var foundValue = scope_values.FirstOrDefault (v => v ["name"].Value () == expression); - if (foundValue != null) { - foundValue["fromThis"] = true; - context.LocalsCache[foundValue ["name"].Value ()] = foundValue; - return foundValue; - } - } - return null; - } - - async Task OnEvaluateOnCallFrame (MessageId msg_id, int scope_id, string expression, CancellationToken token) - { - try { - var context = GetContext (msg_id); - if (context.CallStack == null) - return false; - - var varValue = await TryGetVariableValue (msg_id, scope_id, expression, false, token); - - if (varValue != null) { - SendResponse (msg_id, Result.OkFromObject (new { - result = varValue ["value"] - }), token); - return true; - } - - string retValue = await EvaluateExpression.CompileAndRunTheExpression (this, msg_id, scope_id, expression, token); - SendResponse (msg_id, Result.OkFromObject (new { - result = new { - value = retValue - } - }), token); - return true; - } catch (Exception e) { - logger.LogDebug (e, $"Error in EvaluateOnCallFrame for expression '{expression}."); - } - return false; - } - - async Task GetScopeProperties (MessageId msg_id, int scope_id, CancellationToken token) - { - try { - var ctx = GetContext (msg_id); - var scope = ctx.CallStack.FirstOrDefault (s => s.Id == scope_id); - if (scope == null) - return Result.Err (JObject.FromObject (new { message = $"Could not find scope with id #{scope_id}" })); - - var vars = scope.Method.GetLiveVarsAt (scope.Location.CliLocation.Offset); - - var var_ids = vars.Select (v => v.Index).ToArray (); - var res = await SendMonoCommand (msg_id, MonoCommands.GetScopeVariables (scope.Id, var_ids), token); - - //if we fail we just buble that to the IDE (and let it panic over it) - if (res.IsErr) - return res; - - var values = res.Value? ["result"]? ["value"]?.Values ().ToArray (); - - if(values == null) - return Result.OkFromObject (new { result = Array.Empty () }); - - var var_list = new List (); - int i = 0; - for (; i < vars.Length && i < values.Length; i ++) { - // For async methods, we get locals with names, unlike non-async methods - // and the order may not match the var_ids, so, use the names that they - // come with - if (values [i]["name"] != null) - continue; - - ctx.LocalsCache[vars [i].Name] = values [i]; - var_list.Add (new { name = vars [i].Name, value = values [i]["value"] }); - } - for (; i < values.Length; i ++) { - ctx.LocalsCache[values [i]["name"].ToString()] = values [i]; - var_list.Add (values [i]); - } - - return Result.OkFromObject (new { result = var_list }); - } catch (Exception exception) { - Log ("verbose", $"Error resolving scope properties {exception.Message}"); - return Result.Exception (exception); - } - } - - async Task SetMonoBreakpoint (SessionId sessionId, string reqId, SourceLocation location, CancellationToken token) - { - var bp = new Breakpoint (reqId, location, BreakpointState.Pending); - var asm_name = bp.Location.CliLocation.Method.Assembly.Name; - var method_token = bp.Location.CliLocation.Method.Token; - var il_offset = bp.Location.CliLocation.Offset; - - var res = await SendMonoCommand (sessionId, MonoCommands.SetBreakpoint (asm_name, method_token, il_offset), token); - var ret_code = res.Value? ["result"]? ["value"]?.Value (); - - if (ret_code.HasValue) { - bp.RemoteId = ret_code.Value; - bp.State = BreakpointState.Active; - //Log ("verbose", $"BP local id {bp.LocalId} enabled with remote id {bp.RemoteId}"); - } - - return bp; - } - - async Task LoadStore (SessionId sessionId, CancellationToken token) - { - var context = GetContext (sessionId); - - if (Interlocked.CompareExchange (ref context.store, new DebugStore (logger), null) != null) - return await context.Source.Task; - - try { - var loaded_pdbs = await SendMonoCommand (sessionId, MonoCommands.GetLoadedFiles(), token); - var the_value = loaded_pdbs.Value? ["result"]? ["value"]; - var the_pdbs = the_value?.ToObject (); - - await foreach (var source in context.store.Load(sessionId, the_pdbs, token).WithCancellation (token)) { - var scriptSource = JObject.FromObject (source.ToScriptSource (context.Id, context.AuxData)); - Log ("verbose", $"\tsending {source.Url} {context.Id} {sessionId.sessionId}"); - - SendEvent (sessionId, "Debugger.scriptParsed", scriptSource, token); - - foreach (var req in context.BreakpointRequests.Values) { - if (req.TryResolve (source)) { - await SetBreakpoint (sessionId, context.store, req, true, token); - } - } - } - } catch (Exception e) { - context.Source.SetException (e); - } - - if (!context.Source.Task.IsCompleted) - context.Source.SetResult (context.store); - return context.store; - } - - async Task RuntimeReady (SessionId sessionId, CancellationToken token) - { - var context = GetContext (sessionId); - if (Interlocked.CompareExchange (ref context.ready, new TaskCompletionSource (), null) != null) - return await context.ready.Task; - - var clear_result = await SendMonoCommand (sessionId, MonoCommands.ClearAllBreakpoints (), token); - if (clear_result.IsErr) { - Log ("verbose", $"Failed to clear breakpoints due to {clear_result}"); - } - - var store = await LoadStore (sessionId, token); - - context.ready.SetResult (store); - SendEvent (sessionId, "Mono.runtimeReady", new JObject (), token); - return store; - } - - async Task RemoveBreakpoint(MessageId msg_id, JObject args, CancellationToken token) { - var bpid = args? ["breakpointId"]?.Value (); - - var context = GetContext (msg_id); - if (!context.BreakpointRequests.TryGetValue (bpid, out var breakpointRequest)) - return; - - foreach (var bp in breakpointRequest.Locations) { - var res = await SendMonoCommand (msg_id, MonoCommands.RemoveBreakpoint (bp.RemoteId), token); - var ret_code = res.Value? ["result"]? ["value"]?.Value (); - - if (ret_code.HasValue) { - bp.RemoteId = -1; - bp.State = BreakpointState.Disabled; - } - } - breakpointRequest.Locations.Clear (); - } - - async Task SetBreakpoint (SessionId sessionId, DebugStore store, BreakpointRequest req, bool sendResolvedEvent, CancellationToken token) - { - var context = GetContext (sessionId); - if (req.Locations.Any ()) { - Log ("debug", $"locations already loaded for {req.Id}"); - return; - } - - var comparer = new SourceLocation.LocationComparer (); - // if column is specified the frontend wants the exact matches - // and will clear the bp if it isn't close enoug - var locations = store.FindBreakpointLocations (req) - .Distinct (comparer) - .Where (l => l.Line == req.Line && (req.Column == 0 || l.Column == req.Column)) - .OrderBy (l => l.Column) - .GroupBy (l => l.Id); - - logger.LogDebug ("BP request for '{req}' runtime ready {context.RuntimeReady}", req, GetContext (sessionId).IsRuntimeReady); - - var breakpoints = new List (); - - foreach (var sourceId in locations) { - var loc = sourceId.First (); - var bp = await SetMonoBreakpoint (sessionId, req.Id, loc, token); - - // If we didn't successfully enable the breakpoint - // don't add it to the list of locations for this id - if (bp.State != BreakpointState.Active) - continue; - - breakpoints.Add (bp); - - var resolvedLocation = new { - breakpointId = req.Id, - location = loc.AsLocation () - }; - - if (sendResolvedEvent) - SendEvent (sessionId, "Debugger.breakpointResolved", JObject.FromObject (resolvedLocation), token); - } - - req.Locations.AddRange (breakpoints); - return; - } - - async Task GetPossibleBreakpoints (MessageId msg, SourceLocation start, SourceLocation end, CancellationToken token) - { - var bps = (await RuntimeReady (msg, token)).FindPossibleBreakpoints (start, end); - - if (bps == null) - return false; - - var response = new { locations = bps.Select (b => b.AsLocation ()) }; - - SendResponse (msg, Result.OkFromObject (response), token); - return true; - } - - void OnCompileDotnetScript (MessageId msg_id, CancellationToken token) - { - SendResponse (msg_id, Result.OkFromObject (new { }), token); - } - - async Task OnGetScriptSource (MessageId msg_id, string script_id, CancellationToken token) - { - if (!SourceId.TryParse (script_id, out var id)) - return false; - - var src_file = (await LoadStore (msg_id, token)).GetFileById (id); - - try { - var uri = new Uri (src_file.Url); - string source = $"// Unable to find document {src_file.SourceUri}"; - - using (var data = await src_file.GetSourceAsync (checkHash: false, token: token)) { - if (data.Length == 0) - return false; - - using (var reader = new StreamReader (data)) - source = await reader.ReadToEndAsync (); - } - SendResponse (msg_id, Result.OkFromObject (new { scriptSource = source }), token); - } catch (Exception e) { - var o = new { - scriptSource = $"// Unable to read document ({e.Message})\n" + - $"Local path: {src_file?.SourceUri}\n" + - $"SourceLink path: {src_file?.SourceLinkUri}\n" - }; - - SendResponse (msg_id, Result.OkFromObject (o), token); - } - return true; - } - - async Task DeleteWebDriver (SessionId sessionId, CancellationToken token) - { - // see https://github.com/mono/mono/issues/19549 for background - if (hideWebDriver && sessions.Add (sessionId)) { - var res = await SendCommand (sessionId, - "Page.addScriptToEvaluateOnNewDocument", - JObject.FromObject (new { source = "delete navigator.constructor.prototype.webdriver"}), - token); - - if (sessionId != SessionId.Null && !res.IsOk) - sessions.Remove (sessionId); - } - } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/Program.cs b/src/Components/WebAssembly/DebugProxy/src/Program.cs deleted file mode 100644 index ce67276e6e..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/Program.cs +++ /dev/null @@ -1,71 +0,0 @@ -// 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 Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.Hosting; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; - -namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy -{ - public class Program - { - static int Main(string[] args) - { - var app = new CommandLineApplication(throwOnUnexpectedArg: false) - { - Name = "webassembly-debugproxy" - }; - app.HelpOption("-?|-h|--help"); - - var browserHostOption = new CommandOption("-b|--browser-host", CommandOptionType.SingleValue) - { - Description = "Host on which the browser is listening for debug connections. Example: http://localhost:9300" - }; - - var ownerPidOption = new CommandOption("-op|--owner-pid", CommandOptionType.SingleValue) - { - Description = "ID of the owner process. The debug proxy will shut down if this process exits." - }; - - app.Options.Add(browserHostOption); - app.Options.Add(ownerPidOption); - - app.OnExecute(() => - { - var browserHost = browserHostOption.HasValue() ? browserHostOption.Value(): "http://127.0.0.1:9222"; - var host = DebugProxyHost.CreateDefaultBuilder(args, browserHost).Build(); - - if (ownerPidOption.HasValue()) - { - var ownerProcess = Process.GetProcessById(int.Parse(ownerPidOption.Value())); - ownerProcess.EnableRaisingEvents = true; - ownerProcess.Exited += async (sender, eventArgs) => - { - Console.WriteLine("Exiting because parent process has exited"); - await host.StopAsync(); - }; - } - - host.Run(); - - return 0; - }); - - try - { - return app.Execute(args); - } - catch (CommandParsingException cex) - { - app.Error.WriteLine(cex.Message); - app.ShowHelp(); - return 1; - } - } - } -} diff --git a/src/Components/WebAssembly/DebugProxy/src/Startup.cs b/src/Components/WebAssembly/DebugProxy/src/Startup.cs deleted file mode 100644 index 9a80b2a252..0000000000 --- a/src/Components/WebAssembly/DebugProxy/src/Startup.cs +++ /dev/null @@ -1,45 +0,0 @@ -// 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.Net; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using WebAssembly.Net.Debugging; - -namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy -{ - public class Startup - { - public void Configure(IApplicationBuilder app, DebugProxyOptions debugProxyOptions) - { - app.UseDeveloperExceptionPage(); - app.UseWebSockets(); - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - // At the homepage, we check whether we can uniquely identify the target tab - // - If yes, we redirect directly to the debug tools, proxying to that tab - // - If no, we present a list of available tabs for the user to pick from - endpoints.MapGet("/", new TargetPickerUi(debugProxyOptions).Display); - - // At this URL, we wire up the actual WebAssembly proxy - endpoints.MapGet("/ws-proxy", async (context) => - { - if (!context.WebSockets.IsWebSocketRequest) - { - context.Response.StatusCode = (int)HttpStatusCode.BadRequest; - return; - } - - var loggerFactory = context.RequestServices.GetRequiredService(); - var browserUri = new Uri(context.Request.Query["browser"]); - var ideSocket = await context.WebSockets.AcceptWebSocketAsync(); - await new MonoProxy(loggerFactory).Run(browserUri, ideSocket); - }); - }); - } - } -} diff --git a/src/Components/WebAssembly/Sdk/src/Microsoft.NET.Sdk.BlazorWebAssembly.csproj b/src/Components/WebAssembly/Sdk/src/Microsoft.NET.Sdk.BlazorWebAssembly.csproj index 404f147f92..ca1baca263 100644 --- a/src/Components/WebAssembly/Sdk/src/Microsoft.NET.Sdk.BlazorWebAssembly.csproj +++ b/src/Components/WebAssembly/Sdk/src/Microsoft.NET.Sdk.BlazorWebAssembly.csproj @@ -12,6 +12,8 @@ $(NoWarn);NU5100 false + + false diff --git a/src/Components/WebAssembly/Sdk/src/targets/BlazorWasm.web.config b/src/Components/WebAssembly/Sdk/src/targets/BlazorWasm.web.config index c16575f751..c461dc0b3d 100644 --- a/src/Components/WebAssembly/Sdk/src/targets/BlazorWasm.web.config +++ b/src/Components/WebAssembly/Sdk/src/targets/BlazorWasm.web.config @@ -9,6 +9,7 @@ + diff --git a/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs b/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs index a8351af106..2b294ac8a6 100644 --- a/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs +++ b/src/Components/WebAssembly/Server/src/DebugProxyLauncher.cs @@ -10,7 +10,9 @@ using System.Reflection; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using System.Web; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; @@ -24,20 +26,20 @@ namespace Microsoft.AspNetCore.Builder private static readonly Regex NowListeningRegex = new Regex(@"^\s*Now listening on: (?.*)$", RegexOptions.None, TimeSpan.FromSeconds(10)); private static readonly Regex ApplicationStartedRegex = new Regex(@"^\s*Application started\. Press Ctrl\+C to shut down\.$", RegexOptions.None, TimeSpan.FromSeconds(10)); - public static Task EnsureLaunchedAndGetUrl(IServiceProvider serviceProvider) + public static Task EnsureLaunchedAndGetUrl(IServiceProvider serviceProvider, string devToolsHost) { lock (LaunchLock) { if (LaunchedDebugProxyUrl == null) { - LaunchedDebugProxyUrl = LaunchAndGetUrl(serviceProvider); + LaunchedDebugProxyUrl = LaunchAndGetUrl(serviceProvider, devToolsHost); } return LaunchedDebugProxyUrl; } } - private static async Task LaunchAndGetUrl(IServiceProvider serviceProvider) + private static async Task LaunchAndGetUrl(IServiceProvider serviceProvider, string devToolsHost) { var tcs = new TaskCompletionSource(); @@ -45,10 +47,11 @@ namespace Microsoft.AspNetCore.Builder var executablePath = LocateDebugProxyExecutable(environment); var muxerPath = DotNetMuxer.MuxerPathOrDefault(); var ownerPid = Process.GetCurrentProcess().Id; + var processStartInfo = new ProcessStartInfo { FileName = muxerPath, - Arguments = $"exec \"{executablePath}\" --owner-pid {ownerPid}", + Arguments = $"exec \"{executablePath}\" --owner-pid {ownerPid} --DevToolsUrl {devToolsHost}", UseShellExecute = false, RedirectStandardOutput = true, }; @@ -87,7 +90,7 @@ namespace Microsoft.AspNetCore.Builder var debugProxyPath = Path.Combine( Path.GetDirectoryName(assembly.Location), "BlazorDebugProxy", - "Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.dll"); + "BrowserDebugHost.dll"); if (!File.Exists(debugProxyPath)) { @@ -114,6 +117,12 @@ namespace Microsoft.AspNetCore.Builder void OnOutputDataReceived(object sender, DataReceivedEventArgs eventArgs) { + if (String.IsNullOrEmpty(eventArgs.Data)) + { + taskCompletionSource.TrySetException(new InvalidOperationException( + "No output has been recevied from the application.")); + } + if (ApplicationStartedRegex.IsMatch(eventArgs.Data)) { aspNetProcess.OutputDataReceived -= OnOutputDataReceived; diff --git a/src/Components/WebAssembly/Server/src/Microsoft.AspNetCore.Components.WebAssembly.Server.csproj b/src/Components/WebAssembly/Server/src/Microsoft.AspNetCore.Components.WebAssembly.Server.csproj index 0b94d5c6e8..f332792a19 100644 --- a/src/Components/WebAssembly/Server/src/Microsoft.AspNetCore.Components.WebAssembly.Server.csproj +++ b/src/Components/WebAssembly/Server/src/Microsoft.AspNetCore.Components.WebAssembly.Server.csproj @@ -12,6 +12,7 @@ + @@ -22,38 +23,15 @@ - - - - - - - + + - - diff --git a/src/Components/WebAssembly/DebugProxy/src/TargetPickerUi.cs b/src/Components/WebAssembly/Server/src/TargetPickerUi.cs similarity index 91% rename from src/Components/WebAssembly/DebugProxy/src/TargetPickerUi.cs rename to src/Components/WebAssembly/Server/src/TargetPickerUi.cs index 249e2e5f37..538086f29c 100644 --- a/src/Components/WebAssembly/DebugProxy/src/TargetPickerUi.cs +++ b/src/Components/WebAssembly/Server/src/TargetPickerUi.cs @@ -12,7 +12,7 @@ using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy +namespace Microsoft.AspNetCore.Components.WebAssembly.Server { public class TargetPickerUi { @@ -23,11 +23,13 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy IgnoreNullValues = true }; - private readonly DebugProxyOptions _options; + private string _browserHost; + private string _debugProxyUrl; - public TargetPickerUi(DebugProxyOptions options) + public TargetPickerUi(string debugProxyUrl, string devToolsHost) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + _debugProxyUrl = debugProxyUrl; + _browserHost = devToolsHost; } public async Task Display(HttpContext context) @@ -37,7 +39,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy var request = context.Request; var targetApplicationUrl = request.Query["url"]; - var debuggerTabsListUrl = $"{_options.BrowserHost}/json"; + var debuggerTabsListUrl = $"{_browserHost}/json"; IEnumerable availableTabs; try @@ -134,17 +136,17 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy private string GetDevToolsUrlWithProxy(HttpRequest request, BrowserTab tabToDebug) { - var underlyingV8Endpoint = tabToDebug.WebSocketDebuggerUrl; - var proxyEndpoint = GetProxyEndpoint(request, underlyingV8Endpoint); - var devToolsUrlAbsolute = new Uri(_options.BrowserHost + tabToDebug.DevtoolsFrontendUrl); - var devToolsUrlWithProxy = $"{devToolsUrlAbsolute.Scheme}://{devToolsUrlAbsolute.Authority}{devToolsUrlAbsolute.AbsolutePath}?{proxyEndpoint.Scheme}={proxyEndpoint.Authority}{proxyEndpoint.PathAndQuery}"; + var underlyingV8Endpoint = new Uri(tabToDebug.WebSocketDebuggerUrl); + var proxyEndpoint = new Uri(_debugProxyUrl); + var devToolsUrlAbsolute = new Uri(_browserHost + tabToDebug.DevtoolsFrontendUrl); + var devToolsUrlWithProxy = $"{devToolsUrlAbsolute.Scheme}://{devToolsUrlAbsolute.Authority}{devToolsUrlAbsolute.AbsolutePath}?{underlyingV8Endpoint.Scheme}={proxyEndpoint.Authority}{underlyingV8Endpoint.PathAndQuery}"; return devToolsUrlWithProxy; } private string GetLaunchChromeInstructions(string targetApplicationUrl) { var profilePath = Path.Combine(Path.GetTempPath(), "blazor-chrome-debug"); - var debuggerPort = new Uri(_options.BrowserHost).Port; + var debuggerPort = new Uri(_browserHost).Port; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -170,7 +172,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy private string GetLaunchEdgeInstructions(string targetApplicationUrl) { var profilePath = Path.Combine(Path.GetTempPath(), "blazor-edge-debug"); - var debuggerPort = new Uri(_options.BrowserHost).Port; + var debuggerPort = new Uri(_browserHost).Port; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -209,7 +211,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DebugProxy private async Task> GetOpenedBrowserTabs() { using var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }; - var jsonResponse = await httpClient.GetStringAsync($"{_options.BrowserHost}/json"); + var jsonResponse = await httpClient.GetStringAsync($"{_browserHost}/json"); return JsonSerializer.Deserialize(jsonResponse, JsonOptions); } diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyNetDebugProxyAppBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyNetDebugProxyAppBuilderExtensions.cs index 6d51d4ff9b..81eb09641b 100644 --- a/src/Components/WebAssembly/Server/src/WebAssemblyNetDebugProxyAppBuilderExtensions.cs +++ b/src/Components/WebAssembly/Server/src/WebAssemblyNetDebugProxyAppBuilderExtensions.cs @@ -1,7 +1,10 @@ // 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.Net; +using System.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Server; namespace Microsoft.AspNetCore.Builder { @@ -20,20 +23,31 @@ namespace Microsoft.AspNetCore.Builder { app.Use(async (context, next) => { - var debugProxyBaseUrl = await DebugProxyLauncher.EnsureLaunchedAndGetUrl(context.RequestServices); + var queryParams = HttpUtility.ParseQueryString(context.Request.QueryString.Value); + var browserParam = queryParams.Get("browser"); + Uri browserUrl = null; + var devToolsHost = "http://localhost:9222"; + if (browserParam != null) + { + browserUrl = new Uri(browserParam); + devToolsHost = $"http://{browserUrl.Host}:{browserUrl.Port}"; + } + + var debugProxyBaseUrl = await DebugProxyLauncher.EnsureLaunchedAndGetUrl(context.RequestServices, devToolsHost); var requestPath = context.Request.Path.ToString(); if (requestPath == string.Empty) { requestPath = "/"; } - // Although we could redirect for every URL we see here, we filter the allowed set - // to ensure this doesn't get misused as some kind of more general redirector switch (requestPath) { case "/": + var targetPickerUi = new TargetPickerUi(debugProxyBaseUrl, devToolsHost); + await targetPickerUi.Display(context); + break; case "/ws-proxy": - context.Response.Redirect($"{debugProxyBaseUrl}{requestPath}{context.Request.QueryString}"); + context.Response.Redirect($"{debugProxyBaseUrl}{browserUrl.PathAndQuery}"); break; default: context.Response.StatusCode = (int)HttpStatusCode.NotFound; diff --git a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj index 906e03fe82..cf30c9c9e2 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj +++ b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -15,9 +15,13 @@ - - - + diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs index 1224ee978f..038e01f0c7 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -57,6 +58,11 @@ namespace Wasm.Authentication.Server app.UseWebAssemblyDebugging(); } + app.UseCookiePolicy(new CookiePolicyOptions + { + MinimumSameSitePolicy = SameSiteMode.Lax + }); + app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj index 142bfe2145..8daf509266 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj @@ -10,10 +10,12 @@ + + diff --git a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj index a2fe529a19..4a363519fb 100644 --- a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj +++ b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj @@ -14,6 +14,9 @@ true false + + true + diff --git a/src/Components/test/E2ETest/ServerExecutionTests/TestSubclasses.cs b/src/Components/test/E2ETest/ServerExecutionTests/TestSubclasses.cs index c418d9e7b5..8de1d8a7c6 100644 --- a/src/Components/test/E2ETest/ServerExecutionTests/TestSubclasses.cs +++ b/src/Components/test/E2ETest/ServerExecutionTests/TestSubclasses.cs @@ -75,4 +75,12 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests { } } + + public class ServerInputFileTest : InputFileTest + { + public ServerInputFileTest(BrowserFixture browserFixture, ToggleExecutionModeServerFixture serverFixture, ITestOutputHelper output) + : base(browserFixture, serverFixture.WithServerExecution(), output) + { + } + } } diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs index 9c4f840dcf..d974ace64f 100644 --- a/src/Components/test/E2ETest/Tests/FormsTest.cs +++ b/src/Components/test/E2ETest/Tests/FormsTest.cs @@ -303,47 +303,43 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests } [Fact] + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/24850")] public void InputRadioGroupWithoutNameInteractsWithEditContext() { var appElement = MountTypicalValidationComponent(); - var airlineInputs = FindAirlineInputs(appElement); - var unknownAirlineInput = FindUnknownAirlineInput(airlineInputs); - var bestAirlineInput = FindBestAirlineInput(airlineInputs); var messagesAccessor = CreateValidationMessagesAccessor(appElement); - // Validate unselected inputs - Assert.All(airlineInputs.Where(i => i != unknownAirlineInput), i => Browser.False(() => i.Selected)); - // Validate selected inputs - Browser.True(() => unknownAirlineInput.Selected); + Browser.True(() => FindUnknownAirlineInput().Selected); + Browser.False(() => FindBestAirlineInput().Selected); // InputRadio emits additional attributes - Browser.True(() => unknownAirlineInput.GetAttribute("extra").Equals("additional")); + Browser.True(() => FindUnknownAirlineInput().GetAttribute("extra").Equals("additional")); // Validates on edit - Assert.All(airlineInputs, i => Browser.Equal("valid", () => i.GetAttribute("class"))); + Browser.Equal("valid", () => FindUnknownAirlineInput().GetAttribute("class")); + Browser.Equal("valid", () => FindBestAirlineInput().GetAttribute("class")); - bestAirlineInput.Click(); - airlineInputs = FindAirlineInputs(appElement); + FindBestAirlineInput().Click(); - Assert.All(airlineInputs, i => Browser.Equal("modified valid", () => i.GetAttribute("class"))); + Browser.Equal("modified valid", () => FindUnknownAirlineInput().GetAttribute("class")); + Browser.Equal("modified valid", () => FindBestAirlineInput().GetAttribute("class")); // Can become invalid - unknownAirlineInput = FindUnknownAirlineInput(airlineInputs); - unknownAirlineInput.Click(); - airlineInputs = FindAirlineInputs(appElement); + FindUnknownAirlineInput().Click(); - Assert.All(airlineInputs, i => Browser.Equal("modified invalid", () => i.GetAttribute("class"))); + Browser.Equal("modified invalid", () => FindUnknownAirlineInput().GetAttribute("class")); + Browser.Equal("modified invalid", () => FindBestAirlineInput().GetAttribute("class")); Browser.Equal(new[] { "Pick a valid airline." }, messagesAccessor); - static IReadOnlyCollection FindAirlineInputs(IWebElement appElement) + IReadOnlyCollection FindAirlineInputs() => appElement.FindElement(By.ClassName("airline")).FindElements(By.TagName("input")); - static IWebElement FindUnknownAirlineInput(IReadOnlyCollection airlineInputs) - => airlineInputs.First(i => i.GetAttribute("value").Equals("Unknown")); + IWebElement FindUnknownAirlineInput() + => FindAirlineInputs().First(i => string.Equals("Unknown", i.GetAttribute("value"))); - static IWebElement FindBestAirlineInput(IReadOnlyCollection airlineInputs) - => airlineInputs.First(i => i.GetAttribute("value").Equals("BestAirline")); + IWebElement FindBestAirlineInput() + => FindAirlineInputs().First(i => string.Equals("BestAirline", i.GetAttribute("value"))); } [Fact] @@ -353,40 +349,29 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var appElement = MountTypicalValidationComponent(); var submitButton = appElement.FindElement(By.CssSelector("button[type=submit]")); var group = appElement.FindElement(By.ClassName("nested-radio-group")); - var countryInputs = FindCountryInputs(); - var colorInputs = FindColorInputs(); - - // Validate group counts - Assert.Equal(3, countryInputs.Count); - Assert.Equal(4, colorInputs.Count); // Validate unselected inputs - Assert.All(countryInputs, i => Browser.False(() => i.Selected)); - Assert.All(colorInputs, i => Browser.False(() => i.Selected)); + Browser.True(() => FindCountryInputs().All(i => !i.Selected)); + Browser.True(() => FindColorInputs().All(i => !i.Selected)); // Invalidates on submit - Assert.All(countryInputs, i => Browser.Equal("valid", () => i.GetAttribute("class"))); - Assert.All(colorInputs, i => Browser.Equal("valid", () => i.GetAttribute("class"))); + Browser.True(() => FindCountryInputs().All(i => string.Equals("valid", i.GetAttribute("class")))); + Browser.True(() => FindColorInputs().All(i => string.Equals("valid", i.GetAttribute("class")))); submitButton.Click(); - countryInputs = FindCountryInputs(); - colorInputs = FindColorInputs(); - Assert.All(countryInputs, i => Browser.Equal("invalid", () => i.GetAttribute("class"))); - Assert.All(colorInputs, i => Browser.Equal("invalid", () => i.GetAttribute("class"))); + Browser.True(() => FindCountryInputs().All(i => string.Equals("invalid", i.GetAttribute("class")))); + Browser.True(() => FindColorInputs().All(i => string.Equals("invalid", i.GetAttribute("class")))); // Validates on edit - countryInputs.First().Click(); - countryInputs = FindCountryInputs(); - colorInputs = FindColorInputs(); + FindCountryInputs().First().Click(); - Assert.All(countryInputs, i => Browser.Equal("modified valid", () => i.GetAttribute("class"))); - Assert.All(colorInputs, i => Browser.Equal("invalid", () => i.GetAttribute("class"))); + Browser.True(() => FindCountryInputs().All(i => string.Equals("modified valid", i.GetAttribute("class")))); + Browser.True(() => FindColorInputs().All(i => string.Equals("invalid", i.GetAttribute("class")))); - colorInputs.First().Click(); - colorInputs = FindColorInputs(); + FindColorInputs().First().Click(); - Assert.All(colorInputs, i => Browser.Equal("modified valid", () => i.GetAttribute("class"))); + Browser.True(() => FindColorInputs().All(i => string.Equals("modified valid", i.GetAttribute("class")))); IReadOnlyCollection FindCountryInputs() => group.FindElements(By.Name("country")); diff --git a/src/Components/test/E2ETest/Tests/InputFileTest.cs b/src/Components/test/E2ETest/Tests/InputFileTest.cs index d96d4358dc..c140f996c6 100644 --- a/src/Components/test/E2ETest/Tests/InputFileTest.cs +++ b/src/Components/test/E2ETest/Tests/InputFileTest.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text; using BasicTestApp; +using BasicTestApp.FormsTest; using Microsoft.AspNetCore.Components.E2ETest; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; @@ -15,7 +16,7 @@ using OpenQA.Selenium.Support.Extensions; using Xunit; using Xunit.Abstractions; -namespace Microsoft.AspNetCore.Components.E2ETests.Tests +namespace Microsoft.AspNetCore.Components.E2ETest.Tests { public class InputFileTest : ServerTestBase>, IDisposable { @@ -139,6 +140,45 @@ namespace Microsoft.AspNetCore.Components.E2ETests.Tests Browser.Equal(480, () => uploadedImage.Size.Height); } + [Fact] + public void ThrowsWhenTooManyFilesAreSelected() + { + var maxAllowedFilesElement = Browser.FindElement(By.Id("max-allowed-files")); + maxAllowedFilesElement.Clear(); + maxAllowedFilesElement.SendKeys("1\n"); + + // Save two files locally + var file1 = TempFile.Create(_tempDirectory, "txt", "This is file 1."); + var file2 = TempFile.Create(_tempDirectory, "txt", "This is file 2."); + + // Select both files + var inputFile = Browser.FindElement(By.Id("input-file")); + inputFile.SendKeys($"{file1.Path}\n{file2.Path}"); + + // Validate that the proper exception is thrown + var exceptionMessage = Browser.FindElement(By.Id("exception-message")); + Browser.Equal("The maximum number of files accepted is 1, but 2 were supplied.", () => exceptionMessage.Text); + } + + [Fact] + public void ThrowsWhenOversizedFileIsSelected() + { + var maxFileSizeElement = Browser.FindElement(By.Id("max-file-size")); + maxFileSizeElement.Clear(); + maxFileSizeElement.SendKeys("10\n"); + + // Save a file that exceeds the specified file size limit + var file = TempFile.Create(_tempDirectory, "txt", "This file is over 10 bytes long."); + + // Select the file + var inputFile = Browser.FindElement(By.Id("input-file")); + inputFile.SendKeys(file.Path); + + // Validate that the proper exception is thrown + var exceptionMessage = Browser.FindElement(By.Id("exception-message")); + Browser.Equal("Supplied file with size 32 bytes exceeds the maximum of 10 bytes.", () => exceptionMessage.Text); + } + public void Dispose() { Directory.Delete(_tempDirectory, recursive: true); diff --git a/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj b/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj index 13f08442bf..d25ab75795 100644 --- a/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj +++ b/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor b/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor new file mode 100644 index 0000000000..44a555fe4f --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/FormsTest/InputFileComponent.razor @@ -0,0 +1,102 @@ +@using System.IO; +@using Microsoft.AspNetCore.Components.Forms + +

File preview

+ +Max file size: +
+ +
+ +Max allowed files: +
+ +
+ + +
+ +@exceptionMessage + +@if (isLoading) +{ +

Loading...

+
+} + +@foreach (var (file, content) in loadedFiles) +{ +

+ File name: @(file.Name)
+ File size (bytes): @(file.Size)
+ File content: @content
+

+} + +

Image upload

+ + +
+ +@if (imageDataUri != null) +{ +

+ Uploaded image:
+ +

+} + +

+ Source image:
+ +

+ +@code { + Dictionary loadedFiles = new Dictionary(); + + long maxFileSize = 1024 * 1024 * 15; + int maxAllowedFiles = 3; + + bool isLoading; + + string imageDataUri; + + string exceptionMessage; + + async Task LoadFiles(InputFileChangeEventArgs e) + { + isLoading = true; + loadedFiles.Clear(); + exceptionMessage = string.Empty; + + try + { + foreach (var file in e.GetMultipleFiles(maxAllowedFiles)) + { + StateHasChanged(); + + using var reader = new StreamReader(file.OpenReadStream(maxFileSize)); + + loadedFiles.Add(file, await reader.ReadToEndAsync()); + } + } + catch (Exception ex) + { + exceptionMessage = ex.Message; + } + + isLoading = false; + } + + async Task LoadImage(InputFileChangeEventArgs e) + { + var format = "image/jpeg"; + var imageFile = await e.File.RequestImageFileAsync(format, 640, 480); + + using var fileStream = imageFile.OpenReadStream(maxFileSize); + using var memoryStream = new MemoryStream(); + await fileStream.CopyToAsync(memoryStream); + + imageDataUri = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}"; + } +} diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index db232b3aa4..f2abaa1ba9 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -36,6 +36,7 @@ + @@ -46,7 +47,6 @@ - diff --git a/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor b/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor deleted file mode 100644 index e9f7dbd301..0000000000 --- a/src/Components/test/testassets/BasicTestApp/InputFileComponent.razor +++ /dev/null @@ -1,80 +0,0 @@ -@using System.IO; -@using Microsoft.AspNetCore.Components.Web.Extensions - -

File preview

- -
- -@if (isLoading) -{ -

Loading...


-} - -@foreach (var (file, content) in loadedFiles) -{ -

- File name: @(file.Name)
- File size (bytes): @(file.Size)
- File content: @content
-

-} - -

Image upload

- -
- -@if (imageDataUri != null) -{ -

- Uploaded image:
- -

-} - -

- Source image:
- -

- -@code { - Dictionary loadedFiles = new Dictionary(); - - bool isLoading; - - string imageDataUri; - - async Task LoadFiles(InputFileChangeEventArgs e) - { - isLoading = true; - loadedFiles.Clear(); - - foreach (var file in e.Files) - { - StateHasChanged(); - - using var reader = new StreamReader(file.OpenReadStream()); - - loadedFiles.Add(file, await reader.ReadToEndAsync()); - } - - isLoading = false; - } - - async Task LoadImage(InputFileChangeEventArgs e) - { - var file = e.Files.SingleOrDefault(); - - if (file != null) - { - var format = "image/jpeg"; - var imageFile = await file.ToImageFileAsync(format, 640, 480); - - using var fileStream = imageFile.OpenReadStream(); - using var memoryStream = new MemoryStream(); - await fileStream.CopyToAsync(memoryStream); - - imageDataUri = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}"; - StateHasChanged(); - } - } -} diff --git a/src/Components/test/testassets/BasicTestApp/Program.cs b/src/Components/test/testassets/BasicTestApp/Program.cs index 1e640b59dc..09f652e62e 100644 --- a/src/Components/test/testassets/BasicTestApp/Program.cs +++ b/src/Components/test/testassets/BasicTestApp/Program.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Configuration; using Microsoft.JSInterop; +using Microsoft.AspNetCore.Components.ProtectedBrowserStorage; namespace BasicTestApp { diff --git a/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageInjectionComponent.razor b/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageInjectionComponent.razor index db55ea6bc2..1fc1b40c0d 100644 --- a/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageInjectionComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageInjectionComponent.razor @@ -1,5 +1,6 @@ @using Microsoft.Extensions.DependencyInjection @using Microsoft.AspNetCore.Components.Web.Extensions +@using Microsoft.AspNetCore.Components.ProtectedBrowserStorage @inject IServiceProvider ServiceProvider diff --git a/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageUsageComponent.razor b/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageUsageComponent.razor index 8a1f70fa08..fd9c65d4c9 100644 --- a/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageUsageComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/ProtectedBrowserStorageUsageComponent.razor @@ -1,4 +1,5 @@ @using Microsoft.AspNetCore.Components.Web.Extensions +@using Microsoft.AspNetCore.Components.ProtectedBrowserStorage @inject ProtectedLocalStorage ProtectedLocalStore @inject ProtectedSessionStorage ProtectedSessionStore diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html index f387c50b57..20c78f34f2 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html @@ -45,8 +45,6 @@ - - diff --git a/src/Configuration.KeyPerFile/src/Microsoft.Extensions.Configuration.KeyPerFile.csproj b/src/Configuration.KeyPerFile/src/Microsoft.Extensions.Configuration.KeyPerFile.csproj index aeffe0a751..68b2d70729 100644 --- a/src/Configuration.KeyPerFile/src/Microsoft.Extensions.Configuration.KeyPerFile.csproj +++ b/src/Configuration.KeyPerFile/src/Microsoft.Extensions.Configuration.KeyPerFile.csproj @@ -2,7 +2,7 @@ Configuration provider that uses files in a directory for Microsoft.Extensions.Configuration. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true true diff --git a/src/Configuration.KeyPerFile/src/PublicAPI.Shipped.txt b/src/Configuration.KeyPerFile/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Configuration.KeyPerFile/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Configuration.KeyPerFile/src/PublicAPI.Unshipped.txt b/src/Configuration.KeyPerFile/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..481cdb9395 --- /dev/null +++ b/src/Configuration.KeyPerFile/src/PublicAPI.Unshipped.txt @@ -0,0 +1,26 @@ +#nullable enable +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider.Dispose() -> void +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.KeyPerFileConfigurationSource() -> void +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.Optional.get -> bool +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.Optional.set -> void +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.ReloadDelay.get -> int +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.ReloadDelay.set -> void +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.ReloadOnChange.get -> bool +Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.ReloadOnChange.set -> void +Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions +override Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider.Load() -> void +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider.KeyPerFileConfigurationProvider(Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource source) -> void +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.Build(Microsoft.Extensions.Configuration.IConfigurationBuilder builder) -> Microsoft.Extensions.Configuration.IConfigurationProvider +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.FileProvider.get -> Microsoft.Extensions.FileProviders.IFileProvider +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.FileProvider.set -> void +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.IgnoreCondition.get -> System.Func +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.IgnoreCondition.set -> void +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.IgnorePrefix.get -> string +~Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationSource.IgnorePrefix.set -> void +~override Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider.ToString() -> string +~static Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions.AddKeyPerFile(this Microsoft.Extensions.Configuration.IConfigurationBuilder builder, System.Action configureSource) -> Microsoft.Extensions.Configuration.IConfigurationBuilder +~static Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions.AddKeyPerFile(this Microsoft.Extensions.Configuration.IConfigurationBuilder builder, string directoryPath) -> Microsoft.Extensions.Configuration.IConfigurationBuilder +~static Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions.AddKeyPerFile(this Microsoft.Extensions.Configuration.IConfigurationBuilder builder, string directoryPath, bool optional) -> Microsoft.Extensions.Configuration.IConfigurationBuilder +~static Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions.AddKeyPerFile(this Microsoft.Extensions.Configuration.IConfigurationBuilder builder, string directoryPath, bool optional, bool reloadOnChange) -> Microsoft.Extensions.Configuration.IConfigurationBuilder diff --git a/src/Configuration.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj b/src/Configuration.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj index 053553b984..0912054743 100644 --- a/src/Configuration.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj +++ b/src/Configuration.KeyPerFile/test/Microsoft.Extensions.Configuration.KeyPerFile.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) diff --git a/src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj b/src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj index 160fff97e3..55e687fa18 100644 --- a/src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj +++ b/src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj @@ -5,7 +5,7 @@ Commonly used types: Microsoft.AspNetCore.DataProtection.IDataProtectionProvider Microsoft.AspNetCore.DataProtection.IDataProtector - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) true true aspnetcore;dataprotection diff --git a/src/DataProtection/Abstractions/src/PublicAPI.Shipped.txt b/src/DataProtection/Abstractions/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/Abstractions/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/Abstractions/src/PublicAPI.Unshipped.txt b/src/DataProtection/Abstractions/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..63c7b2b5d6 --- /dev/null +++ b/src/DataProtection/Abstractions/src/PublicAPI.Unshipped.txt @@ -0,0 +1,16 @@ +#nullable enable +Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions +Microsoft.AspNetCore.DataProtection.IDataProtectionProvider +Microsoft.AspNetCore.DataProtection.IDataProtectionProvider.CreateProtector(string! purpose) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +Microsoft.AspNetCore.DataProtection.IDataProtector +Microsoft.AspNetCore.DataProtection.IDataProtector.Protect(byte[]! plaintext) -> byte[]! +Microsoft.AspNetCore.DataProtection.IDataProtector.Unprotect(byte[]! protectedData) -> byte[]! +Microsoft.AspNetCore.DataProtection.Infrastructure.IApplicationDiscriminator +Microsoft.AspNetCore.DataProtection.Infrastructure.IApplicationDiscriminator.Discriminator.get -> string! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.CreateProtector(this Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! provider, System.Collections.Generic.IEnumerable! purposes) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.CreateProtector(this Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! provider, string! purpose, params string![]! subPurposes) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.GetDataProtectionProvider(this System.IServiceProvider! services) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.GetDataProtector(this System.IServiceProvider! services, System.Collections.Generic.IEnumerable! purposes) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.GetDataProtector(this System.IServiceProvider! services, string! purpose, params string![]! subPurposes) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Protect(this Microsoft.AspNetCore.DataProtection.IDataProtector! protector, string! plaintext) -> string! +static Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(this Microsoft.AspNetCore.DataProtection.IDataProtector! protector, string! protectedData) -> string! diff --git a/src/DataProtection/Abstractions/test/Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj b/src/DataProtection/Abstractions/test/Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj index a6eeb69ec8..d4566743b2 100644 --- a/src/DataProtection/Abstractions/test/Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj +++ b/src/DataProtection/Abstractions/test/Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) diff --git a/src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj b/src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj index b23c38e9e5..9c9458698e 100644 --- a/src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj +++ b/src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj @@ -2,7 +2,7 @@ Infrastructure for ASP.NET Core cryptographic packages. Applications and libraries should not reference this package directly. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) true $(NoWarn);CS1591 true diff --git a/src/DataProtection/Cryptography.Internal/src/PublicAPI.Shipped.txt b/src/DataProtection/Cryptography.Internal/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/Cryptography.Internal/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/Cryptography.Internal/src/PublicAPI.Unshipped.txt b/src/DataProtection/Cryptography.Internal/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/Cryptography.Internal/src/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/Cryptography.Internal/test/Microsoft.AspNetCore.Cryptography.Internal.Tests.csproj b/src/DataProtection/Cryptography.Internal/test/Microsoft.AspNetCore.Cryptography.Internal.Tests.csproj index 2bce1bc391..159332b178 100644 --- a/src/DataProtection/Cryptography.Internal/test/Microsoft.AspNetCore.Cryptography.Internal.Tests.csproj +++ b/src/DataProtection/Cryptography.Internal/test/Microsoft.AspNetCore.Cryptography.Internal.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) true diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj b/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj index 48e0bf5f5f..6d36d60b5a 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj +++ b/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj @@ -2,7 +2,7 @@ ASP.NET Core utilities for key derivation. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) true true true diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs index a3340b13b2..bc4d7efdc2 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs +++ b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2 } else { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 return new ManagedPbkdf2Provider(); #elif NETCOREAPP // fastest implementation on .NET Core for Linux/macOS. diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Shipped.txt b/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Unshipped.txt b/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..168d785bec --- /dev/null +++ b/src/DataProtection/Cryptography.KeyDerivation/src/PublicAPI.Unshipped.txt @@ -0,0 +1,7 @@ +#nullable enable +Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivation +Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf +Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf.HMACSHA1 = 0 -> Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf +Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf.HMACSHA256 = 1 -> Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf +Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf.HMACSHA512 = 2 -> Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf +static Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivation.Pbkdf2(string! password, byte[]! salt, Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf prf, int iterationCount, int numBytesRequested) -> byte[]! diff --git a/src/DataProtection/Cryptography.KeyDerivation/test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj b/src/DataProtection/Cryptography.KeyDerivation/test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj index c0d90626fb..f650905dd7 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj +++ b/src/DataProtection/Cryptography.KeyDerivation/test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) true diff --git a/src/DataProtection/Cryptography.KeyDerivation/test/Pbkdf2Tests.cs b/src/DataProtection/Cryptography.KeyDerivation/test/Pbkdf2Tests.cs index aa96359dc8..0f088c1a51 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/test/Pbkdf2Tests.cs +++ b/src/DataProtection/Cryptography.KeyDerivation/test/Pbkdf2Tests.cs @@ -37,7 +37,13 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation } // Act & assert +#if NET461 + TestProvider(password, salt, prf, iterationCount, numBytesRequested, expectedValueAsBase64); +#elif NETCOREAPP TestProvider(password, salt, prf, iterationCount, numBytesRequested, expectedValueAsBase64); +#else +#error Update target frameworks +#endif } [Fact] @@ -47,7 +53,13 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation byte[] salt = Encoding.UTF8.GetBytes("salt"); const string expectedDerivedKeyBase64 = "Sc+V/c3fiZq5Z5qH3iavAiojTsW97FAp2eBNmCQAwCNzA8hfhFFYyQLIMK65qPnBFHOHXQPwAxNQNhaEAH9hzfiaNBSRJpF9V4rpl02d5ZpI6cZbsQFF7TJW7XJzQVpYoPDgJlg0xVmYLhn1E9qMtUVUuXsBjOOdd7K1M+ZI00c="; +#if NET461 + RunTest_WithLongPassword_Impl(salt, expectedDerivedKeyBase64); +#elif NETCOREAPP RunTest_WithLongPassword_Impl(salt, expectedDerivedKeyBase64); +#else +#error Update target frameworks +#endif } [Fact] @@ -55,7 +67,14 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation { // salt longer than 8 bytes var salt = Encoding.UTF8.GetBytes("abcdefghijkl"); + +#if NET461 + RunTest_WithLongPassword_Impl(salt, "NGJtFzYUaaSxu+3ZsMeZO5d/qPJDUYW4caLkFlaY0cLSYdh1PN4+nHUVp4pUUubJWu3UeXNMnHKNDfnn8GMfnDVrAGTv1lldszsvUJ0JQ6p4+daQEYBc//Tj/ejuB3luwW0IinyE7U/ViOQKbfi5pCZFMQ0FFx9I+eXRlyT+I74="); +#elif NETCOREAPP RunTest_WithLongPassword_Impl(salt, "NGJtFzYUaaSxu+3ZsMeZO5d/qPJDUYW4caLkFlaY0cLSYdh1PN4+nHUVp4pUUubJWu3UeXNMnHKNDfnn8GMfnDVrAGTv1lldszsvUJ0JQ6p4+daQEYBc//Tj/ejuB3luwW0IinyE7U/ViOQKbfi5pCZFMQ0FFx9I+eXRlyT+I74="); +#else +#error Update target frameworks +#endif } // The 'numBytesRequested' parameters below are chosen to exercise code paths where diff --git a/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs b/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs index 1a96268960..c94c2f21f5 100644 --- a/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs +++ b/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.DataProtection.Managed { internal unsafe sealed class ManagedGenRandomImpl : IManagedGenRandom { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); #endif public static readonly ManagedGenRandomImpl Instance = new ManagedGenRandomImpl(); @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.DataProtection.Managed public byte[] GenRandom(int numBytes) { var bytes = new byte[numBytes]; -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 _rng.GetBytes(bytes); #else RandomNumberGenerator.Fill(bytes); diff --git a/src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj b/src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj index de50517328..8f16e33480 100644 --- a/src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj +++ b/src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj @@ -2,7 +2,7 @@ ASP.NET Core logic to protect and unprotect data, similar to DPAPI. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true $(NoWarn);CS1591 @@ -29,7 +29,10 @@ - + + + + diff --git a/src/DataProtection/DataProtection/src/PublicAPI.Shipped.txt b/src/DataProtection/DataProtection/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/DataProtection/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/DataProtection/src/PublicAPI.Unshipped.txt b/src/DataProtection/DataProtection/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..5cbadc6095 --- /dev/null +++ b/src/DataProtection/DataProtection/src/PublicAPI.Unshipped.txt @@ -0,0 +1,276 @@ +#nullable enable +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptorFactory +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptorFactory.AuthenticatedEncryptorFactory(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptorFactory.CreateEncryptorInstance(Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! key) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngCbcAuthenticatedEncryptorFactory +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngCbcAuthenticatedEncryptorFactory.CngCbcAuthenticatedEncryptorFactory(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngCbcAuthenticatedEncryptorFactory.CreateEncryptorInstance(Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! key) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CngGcmAuthenticatedEncryptorFactory(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CreateEncryptorInstance(Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! key) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration.AlgorithmConfiguration() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.AuthenticatedEncryptorConfiguration() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.EncryptionAlgorithm.get -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.EncryptionAlgorithm.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.ValidationAlgorithm.get -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.ValidationAlgorithm.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptor.AuthenticatedEncryptorDescriptor(Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration! configuration, Microsoft.AspNetCore.DataProtection.ISecret! masterKey) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptor.ExportToXml() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer.AuthenticatedEncryptorDescriptorDeserializer() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer.ImportFromXml(System.Xml.Linq.XElement! element) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.CngCbcAuthenticatedEncryptorConfiguration() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithm.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithm.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.get -> int +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithmProvider.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.EncryptionAlgorithmProvider.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.HashAlgorithm.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.HashAlgorithm.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.HashAlgorithmProvider.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.HashAlgorithmProvider.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptor.CngCbcAuthenticatedEncryptorDescriptor(Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration! configuration, Microsoft.AspNetCore.DataProtection.ISecret! masterKey) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptor.ExportToXml() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptorDeserializer +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptorDeserializer.CngCbcAuthenticatedEncryptorDescriptorDeserializer() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorDescriptorDeserializer.ImportFromXml(System.Xml.Linq.XElement! element) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.CngGcmAuthenticatedEncryptorConfiguration() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithm.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithm.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.get -> int +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmProvider.get -> string! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.EncryptionAlgorithmProvider.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptor.CngGcmAuthenticatedEncryptorDescriptor(Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration! configuration, Microsoft.AspNetCore.DataProtection.ISecret! masterKey) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptor.ExportToXml() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptorDeserializer +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptorDeserializer.CngGcmAuthenticatedEncryptorDescriptorDeserializer() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorDescriptorDeserializer.ImportFromXml(System.Xml.Linq.XElement! element) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor.ExportToXml() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptorDeserializer +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptorDeserializer.ImportFromXml(System.Xml.Linq.XElement! element) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.get -> int +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmType.get -> System.Type! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmType.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.ManagedAuthenticatedEncryptorConfiguration() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.ValidationAlgorithmType.get -> System.Type! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.ValidationAlgorithmType.set -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptor.ExportToXml() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptor.ManagedAuthenticatedEncryptorDescriptor(Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration! configuration, Microsoft.AspNetCore.DataProtection.ISecret! masterKey) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptorDeserializer +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptorDeserializer.ImportFromXml(System.Xml.Linq.XElement! element) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorDescriptorDeserializer.ManagedAuthenticatedEncryptorDescriptorDeserializer() -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlExtensions +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo.DeserializerType.get -> System.Type! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo.SerializedDescriptorElement.get -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlSerializedDescriptorInfo.XmlSerializedDescriptorInfo(System.Xml.Linq.XElement! serializedDescriptorElement, System.Type! deserializerType) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_128_CBC = 0 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_128_GCM = 3 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_192_CBC = 1 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_192_GCM = 4 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC = 2 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_GCM = 5 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor.Decrypt(System.ArraySegment ciphertext, System.ArraySegment additionalAuthenticatedData) -> byte[]! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor.Encrypt(System.ArraySegment plaintext, System.ArraySegment additionalAuthenticatedData) -> byte[]! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptorFactory +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptorFactory.CreateEncryptorInstance(Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! key) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ManagedAuthenticatedEncryptorFactory +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ManagedAuthenticatedEncryptorFactory.CreateEncryptorInstance(Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! key) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ManagedAuthenticatedEncryptorFactory.ManagedAuthenticatedEncryptorFactory(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256 = 0 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm +Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA512 = 1 -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm +Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions +Microsoft.AspNetCore.DataProtection.DataProtectionOptions +Microsoft.AspNetCore.DataProtection.DataProtectionOptions.ApplicationDiscriminator.get -> string! +Microsoft.AspNetCore.DataProtection.DataProtectionOptions.ApplicationDiscriminator.set -> void +Microsoft.AspNetCore.DataProtection.DataProtectionOptions.DataProtectionOptions() -> void +Microsoft.AspNetCore.DataProtection.DataProtectionUtilityExtensions +Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider +Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider.CreateProtector(string! purpose) -> Microsoft.AspNetCore.DataProtection.IDataProtector! +Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider.EphemeralDataProtectionProvider() -> void +Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider.EphemeralDataProtectionProvider(Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder +Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +Microsoft.AspNetCore.DataProtection.IPersistedDataProtector +Microsoft.AspNetCore.DataProtection.IPersistedDataProtector.DangerousUnprotect(byte[]! protectedData, bool ignoreRevocationErrors, out bool requiresMigration, out bool wasRevoked) -> byte[]! +Microsoft.AspNetCore.DataProtection.ISecret +Microsoft.AspNetCore.DataProtection.ISecret.Length.get -> int +Microsoft.AspNetCore.DataProtection.ISecret.WriteSecretIntoBuffer(System.ArraySegment buffer) -> void +Microsoft.AspNetCore.DataProtection.Internal.IActivator +Microsoft.AspNetCore.DataProtection.Internal.IActivator.CreateInstance(System.Type! expectedBaseType, string! implementationTypeName) -> object! +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.ActivationDate.get -> System.DateTimeOffset +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.CreateEncryptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.CreationDate.get -> System.DateTimeOffset +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.Descriptor.get -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.ExpirationDate.get -> System.DateTimeOffset +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.IsRevoked.get -> bool +Microsoft.AspNetCore.DataProtection.KeyManagement.IKey.KeyId.get -> System.Guid +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyEscrowSink +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyEscrowSink.Store(System.Guid keyId, System.Xml.Linq.XElement! element) -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager.CreateNewKey(System.DateTimeOffset activationDate, System.DateTimeOffset expirationDate) -> Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager.GetAllKeys() -> System.Collections.Generic.IReadOnlyCollection! +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager.GetCacheExpirationToken() -> System.Threading.CancellationToken +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager.RevokeAllKeys(System.DateTimeOffset revocationDate, string! reason = null) -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager.RevokeKey(System.Guid keyId, string! reason = null) -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.CacheableKeyRing +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution.DefaultKey -> Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution.DefaultKeyResolution() -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution.FallbackKey -> Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution.ShouldGenerateNewKey -> bool +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider.GetCacheableKeyRing(System.DateTimeOffset now) -> Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.CacheableKeyRing! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IDefaultKeyResolver +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IDefaultKeyResolver.ResolveDefaultKeyPolicy(System.DateTimeOffset now, System.Collections.Generic.IEnumerable! allKeys) -> Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.DefaultKeyResolution +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.CreateNewKey(System.Guid keyId, System.DateTimeOffset creationDate, System.DateTimeOffset activationDate, System.DateTimeOffset expirationDate) -> Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(System.Xml.Linq.XElement! keyElement) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.RevokeSingleKey(System.Guid keyId, System.DateTimeOffset revocationDate, string! reason) -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRing +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRing.DefaultAuthenticatedEncryptor.get -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRing.DefaultKeyId.get -> System.Guid +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRing.GetAuthenticatedEncryptorByKeyId(System.Guid keyId, out bool isRevoked) -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRingProvider +Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRingProvider.GetCurrentKeyRing() -> Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IKeyRing! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.AuthenticatedEncryptorConfiguration.get -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.AuthenticatedEncryptorConfiguration.set -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.AuthenticatedEncryptorFactories.get -> System.Collections.Generic.IList! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.AutoGenerateKeys.get -> bool +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.AutoGenerateKeys.set -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.KeyEscrowSinks.get -> System.Collections.Generic.IList! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.KeyManagementOptions() -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.NewKeyLifetime.get -> System.TimeSpan +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.NewKeyLifetime.set -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.XmlEncryptor.get -> Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.XmlEncryptor.set -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.XmlRepository.get -> Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository! +Microsoft.AspNetCore.DataProtection.KeyManagement.KeyManagementOptions.XmlRepository.set -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.CreateNewKey(System.DateTimeOffset activationDate, System.DateTimeOffset expirationDate) -> Microsoft.AspNetCore.DataProtection.KeyManagement.IKey! +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.GetAllKeys() -> System.Collections.Generic.IReadOnlyCollection! +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.GetCacheExpirationToken() -> System.Threading.CancellationToken +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.RevokeAllKeys(System.DateTimeOffset revocationDate, string! reason = null) -> void +Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.RevokeKey(System.Guid keyId, string! reason = null) -> void +Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository +Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.Directory.get -> System.IO.DirectoryInfo! +Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.FileSystemXmlRepository(System.IO.DirectoryInfo! directory, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository +Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository.GetAllElements() -> System.Collections.Generic.IReadOnlyCollection! +Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository.StoreElement(System.Xml.Linq.XElement! element, string! friendlyName) -> void +Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository +Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository.RegistryKey.get -> Microsoft.Win32.RegistryKey! +Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository.RegistryXmlRepository(Microsoft.Win32.RegistryKey! registryKey, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.Secret +Microsoft.AspNetCore.DataProtection.Secret.Dispose() -> void +Microsoft.AspNetCore.DataProtection.Secret.Length.get -> int +Microsoft.AspNetCore.DataProtection.Secret.Secret(Microsoft.AspNetCore.DataProtection.ISecret! secret) -> void +Microsoft.AspNetCore.DataProtection.Secret.Secret(System.ArraySegment value) -> void +Microsoft.AspNetCore.DataProtection.Secret.Secret(byte* secret, int secretLength) -> void +Microsoft.AspNetCore.DataProtection.Secret.Secret(byte[]! value) -> void +Microsoft.AspNetCore.DataProtection.Secret.WriteSecretIntoBuffer(System.ArraySegment buffer) -> void +Microsoft.AspNetCore.DataProtection.Secret.WriteSecretIntoBuffer(byte* buffer, int bufferLength) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateResolver +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateResolver.CertificateResolver() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateXmlEncryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateXmlEncryptor.CertificateXmlEncryptor(System.Security.Cryptography.X509Certificates.X509Certificate2! certificate, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateXmlEncryptor.CertificateXmlEncryptor(string! thumbprint, Microsoft.AspNetCore.DataProtection.XmlEncryption.ICertificateResolver! certificateResolver, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateXmlEncryptor.Encrypt(System.Xml.Linq.XElement! plaintextElement) -> Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo! +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.MachineKey = 32 -> Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.NamedDescriptor = 1 -> Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags.None = 0 -> Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlDecryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlDecryptor.Decrypt(System.Xml.Linq.XElement! encryptedElement) -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlDecryptor.DpapiNGXmlDecryptor() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlDecryptor.DpapiNGXmlDecryptor(System.IServiceProvider! services) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlEncryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlEncryptor.DpapiNGXmlEncryptor(string! protectionDescriptorRule, Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags flags, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGXmlEncryptor.Encrypt(System.Xml.Linq.XElement! plaintextElement) -> Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo! +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor.Decrypt(System.Xml.Linq.XElement! encryptedElement) -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor.DpapiXmlDecryptor() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor.DpapiXmlDecryptor(System.IServiceProvider! services) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlEncryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlEncryptor.DpapiXmlEncryptor(bool protectToLocalMachine, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlEncryptor.Encrypt(System.Xml.Linq.XElement! plaintextElement) -> Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo! +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(System.Xml.Linq.XElement! encryptedElement) -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlDecryptor() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlDecryptor(System.IServiceProvider! services) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo.DecryptorType.get -> System.Type! +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo.EncryptedElement.get -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo.EncryptedXmlInfo(System.Xml.Linq.XElement! encryptedElement, System.Type! decryptorType) -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.ICertificateResolver +Microsoft.AspNetCore.DataProtection.XmlEncryption.ICertificateResolver.ResolveCertificate(string! thumbprint) -> System.Security.Cryptography.X509Certificates.X509Certificate2! +Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlDecryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlDecryptor.Decrypt(System.Xml.Linq.XElement! encryptedElement) -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor.Encrypt(System.Xml.Linq.XElement! plaintextElement) -> Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo! +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlDecryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlDecryptor.Decrypt(System.Xml.Linq.XElement! encryptedElement) -> System.Xml.Linq.XElement! +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlDecryptor.NullXmlDecryptor() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlEncryptor +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlEncryptor.Encrypt(System.Xml.Linq.XElement! plaintextElement) -> Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlInfo! +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlEncryptor.NullXmlEncryptor() -> void +Microsoft.AspNetCore.DataProtection.XmlEncryption.NullXmlEncryptor.NullXmlEncryptor(System.IServiceProvider! services) -> void +Microsoft.Extensions.DependencyInjection.DataProtectionServiceCollectionExtensions +abstract Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration.CreateNewDescriptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration.CreateNewDescriptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration.CreateNewDescriptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration.CreateNewDescriptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration.CreateNewDescriptor() -> Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor! +static Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.XmlExtensions.MarkAsRequiresEncryption(this System.Xml.Linq.XElement! element) -> void +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.AddKeyEscrowSink(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyEscrowSink! sink) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.AddKeyEscrowSink(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Func! factory) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.AddKeyEscrowSink(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.AddKeyManagementOptions(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Action! setupAction) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.DisableAutomaticKeyGeneration(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.PersistKeysToFileSystem(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.IO.DirectoryInfo! directory) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.PersistKeysToRegistry(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.Win32.RegistryKey! registryKey) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithCertificate(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Security.Cryptography.X509Certificates.X509Certificate2! certificate) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithCertificate(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, string! thumbprint) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithDpapi(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithDpapi(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, bool protectToLocalMachine) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithDpapiNG(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.ProtectKeysWithDpapiNG(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, string! protectionDescriptorRule, Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiNGProtectionDescriptorFlags flags) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.SetApplicationName(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, string! applicationName) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.SetDefaultKeyLifetime(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.TimeSpan lifetime) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UnprotectKeysWithAnyCertificate(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, params System.Security.Cryptography.X509Certificates.X509Certificate2![]! certificates) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UseCryptographicAlgorithms(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration! configuration) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UseCustomCryptographicAlgorithms(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngCbcAuthenticatedEncryptorConfiguration! configuration) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UseCustomCryptographicAlgorithms(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.CngGcmAuthenticatedEncryptorConfiguration! configuration) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UseCustomCryptographicAlgorithms(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.ManagedAuthenticatedEncryptorConfiguration! configuration) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionBuilderExtensions.UseEphemeralDataProtectionProvider(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.DataProtectionUtilityExtensions.GetApplicationUniqueIdentifier(this System.IServiceProvider! services) -> string! +static Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.DefaultKeyStorageDirectory.get -> System.IO.DirectoryInfo! +static Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository.DefaultRegistryKey.get -> Microsoft.Win32.RegistryKey! +static Microsoft.AspNetCore.DataProtection.Secret.Random(int numBytes) -> Microsoft.AspNetCore.DataProtection.Secret! +static Microsoft.Extensions.DependencyInjection.DataProtectionServiceCollectionExtensions.AddDataProtection(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.Extensions.DependencyInjection.DataProtectionServiceCollectionExtensions.AddDataProtection(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! setupAction) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +virtual Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.GetAllElements() -> System.Collections.Generic.IReadOnlyCollection! +virtual Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository.StoreElement(System.Xml.Linq.XElement! element, string! friendlyName) -> void +virtual Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository.GetAllElements() -> System.Collections.Generic.IReadOnlyCollection! +virtual Microsoft.AspNetCore.DataProtection.Repositories.RegistryXmlRepository.StoreElement(System.Xml.Linq.XElement! element, string! friendlyName) -> void +virtual Microsoft.AspNetCore.DataProtection.XmlEncryption.CertificateResolver.ResolveCertificate(string! thumbprint) -> System.Security.Cryptography.X509Certificates.X509Certificate2! +~Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.XmlKeyManager(Microsoft.Extensions.Options.IOptions! keyManagementOptions, Microsoft.AspNetCore.DataProtection.Internal.IActivator! activator) -> void +~Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.XmlKeyManager(Microsoft.Extensions.Options.IOptions! keyManagementOptions, Microsoft.AspNetCore.DataProtection.Internal.IActivator! activator, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void diff --git a/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Shipped.txt b/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Unshipped.txt b/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..3158631350 --- /dev/null +++ b/src/DataProtection/EntityFrameworkCore/src/PublicAPI.Unshipped.txt @@ -0,0 +1,17 @@ +#nullable enable +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.DataProtectionKey() -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.FriendlyName.get -> string? +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.FriendlyName.set -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.Id.get -> int +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.Id.set -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.Xml.get -> string? +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey.Xml.set -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.EntityFrameworkCoreXmlRepository +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.EntityFrameworkCoreXmlRepository.EntityFrameworkCoreXmlRepository(System.IServiceProvider! services, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory) -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.EntityFrameworkCoreXmlRepository.StoreElement(System.Xml.Linq.XElement! element, string! friendlyName) -> void +Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.IDataProtectionKeyContext +Microsoft.AspNetCore.DataProtection.EntityFrameworkCoreDataProtectionExtensions +static Microsoft.AspNetCore.DataProtection.EntityFrameworkCoreDataProtectionExtensions.PersistKeysToDbContext(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +virtual Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.EntityFrameworkCoreXmlRepository.GetAllElements() -> System.Collections.Generic.IReadOnlyCollection! +~Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.IDataProtectionKeyContext.DataProtectionKeys.get -> Microsoft.EntityFrameworkCore.DbSet! diff --git a/src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj b/src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj index a8947d0584..35624976d7 100644 --- a/src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj +++ b/src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj @@ -2,7 +2,7 @@ Additional APIs for ASP.NET Core data protection. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true true diff --git a/src/DataProtection/Extensions/src/PublicAPI.Shipped.txt b/src/DataProtection/Extensions/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/Extensions/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/Extensions/src/PublicAPI.Unshipped.txt b/src/DataProtection/Extensions/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..b10e5dadba --- /dev/null +++ b/src/DataProtection/Extensions/src/PublicAPI.Unshipped.txt @@ -0,0 +1,18 @@ +#nullable enable +Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions +Microsoft.AspNetCore.DataProtection.DataProtectionProvider +Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector +Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector.CreateProtector(string! purpose) -> Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! +Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector.Protect(byte[]! plaintext, System.DateTimeOffset expiration) -> byte[]! +Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector.Unprotect(byte[]! protectedData, out System.DateTimeOffset expiration) -> byte[]! +static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.Protect(this Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! protector, byte[]! plaintext, System.TimeSpan lifetime) -> byte[]! +static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.Protect(this Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! protector, string! plaintext, System.DateTimeOffset expiration) -> string! +static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.Protect(this Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! protector, string! plaintext, System.TimeSpan lifetime) -> string! +static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.ToTimeLimitedDataProtector(this Microsoft.AspNetCore.DataProtection.IDataProtector! protector) -> Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! +static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.Unprotect(this Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! protector, string! protectedData, out System.DateTimeOffset expiration) -> string! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(System.IO.DirectoryInfo! keyDirectory) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(System.IO.DirectoryInfo! keyDirectory, System.Action! setupAction) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(System.IO.DirectoryInfo! keyDirectory, System.Action! setupAction, System.Security.Cryptography.X509Certificates.X509Certificate2! certificate) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(System.IO.DirectoryInfo! keyDirectory, System.Security.Cryptography.X509Certificates.X509Certificate2! certificate) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(string! applicationName) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! +static Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create(string! applicationName, System.Security.Cryptography.X509Certificates.X509Certificate2! certificate) -> Microsoft.AspNetCore.DataProtection.IDataProtectionProvider! diff --git a/src/DataProtection/Extensions/test/Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj b/src/DataProtection/Extensions/test/Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj index 6d8f3d313a..d8b1cfa103 100644 --- a/src/DataProtection/Extensions/test/Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj +++ b/src/DataProtection/Extensions/test/Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) diff --git a/src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj b/src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj index 499e6be9ca..ec7a580b6e 100644 --- a/src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj +++ b/src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj @@ -2,7 +2,7 @@ Support for storing data protection keys in Redis. - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 true true aspnetcore;dataprotection;redis diff --git a/src/DataProtection/StackExchangeRedis/src/PublicAPI.Shipped.txt b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..6e73346214 --- /dev/null +++ b/src/DataProtection/StackExchangeRedis/src/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +#nullable enable +Microsoft.AspNetCore.DataProtection.StackExchangeRedis.RedisXmlRepository +Microsoft.AspNetCore.DataProtection.StackExchangeRedis.RedisXmlRepository.GetAllElements() -> System.Collections.Generic.IReadOnlyCollection! +Microsoft.AspNetCore.DataProtection.StackExchangeRedis.RedisXmlRepository.RedisXmlRepository(System.Func! databaseFactory, StackExchange.Redis.RedisKey key) -> void +Microsoft.AspNetCore.DataProtection.StackExchangeRedis.RedisXmlRepository.StoreElement(System.Xml.Linq.XElement! element, string! friendlyName) -> void +Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions +static Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions.PersistKeysToStackExchangeRedis(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connectionMultiplexer) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions.PersistKeysToStackExchangeRedis(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connectionMultiplexer, StackExchange.Redis.RedisKey key) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! +static Microsoft.AspNetCore.DataProtection.StackExchangeRedisDataProtectionBuilderExtensions.PersistKeysToStackExchangeRedis(this Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! builder, System.Func! databaseFactory, StackExchange.Redis.RedisKey key) -> Microsoft.AspNetCore.DataProtection.IDataProtectionBuilder! diff --git a/src/DataProtection/StackExchangeRedis/test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Tests.csproj b/src/DataProtection/StackExchangeRedis/test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Tests.csproj index 149d2fff52..5a457b9c90 100644 --- a/src/DataProtection/StackExchangeRedis/test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Tests.csproj +++ b/src/DataProtection/StackExchangeRedis/test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) diff --git a/src/DefaultBuilder/src/PublicAPI.Shipped.txt b/src/DefaultBuilder/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/DefaultBuilder/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/DefaultBuilder/src/PublicAPI.Unshipped.txt b/src/DefaultBuilder/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..3484c65bff --- /dev/null +++ b/src/DefaultBuilder/src/PublicAPI.Unshipped.txt @@ -0,0 +1,13 @@ +#nullable enable +Microsoft.AspNetCore.WebHost +Microsoft.Extensions.Hosting.GenericHostBuilderExtensions +static Microsoft.AspNetCore.WebHost.CreateDefaultBuilder() -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.WebHost.CreateDefaultBuilder(string![]! args) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.WebHost.CreateDefaultBuilder(string![]! args) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.WebHost.Start(Microsoft.AspNetCore.Http.RequestDelegate! app) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.WebHost.Start(System.Action! routeBuilder) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.WebHost.Start(string! url, Microsoft.AspNetCore.Http.RequestDelegate! app) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.WebHost.Start(string! url, System.Action! routeBuilder) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.WebHost.StartWith(System.Action! app) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.WebHost.StartWith(string! url, System.Action! app) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.Extensions.Hosting.GenericHostBuilderExtensions.ConfigureWebHostDefaults(this Microsoft.Extensions.Hosting.IHostBuilder! builder, System.Action! configure) -> Microsoft.Extensions.Hosting.IHostBuilder! diff --git a/src/DefaultBuilder/src/WebHost.cs b/src/DefaultBuilder/src/WebHost.cs index ff79107d32..45617c693f 100644 --- a/src/DefaultBuilder/src/WebHost.cs +++ b/src/DefaultBuilder/src/WebHost.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore /// A delegate that handles requests to the application. /// A started that hosts the application. public static IWebHost Start(RequestDelegate app) => - Start(url: null, app: app); + Start(url: null!, app: app); /// /// Initializes and starts a new with pre-configured defaults. @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore /// The URL the hosted application will listen on. /// A delegate that handles requests to the application. /// A started that hosts the application. - public static IWebHost Start(string? url, RequestDelegate app) + public static IWebHost Start(string url, RequestDelegate app) { var startupAssemblyName = app.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name; return StartWith(url: url, configureServices: null, app: appBuilder => appBuilder.Run(app), applicationName: startupAssemblyName); @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore /// A delegate that configures the router for handling requests to the application. /// A started that hosts the application. public static IWebHost Start(Action routeBuilder) => - Start(url: null, routeBuilder: routeBuilder); + Start(url: null!, routeBuilder: routeBuilder); /// /// Initializes and starts a new with pre-configured defaults. @@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore /// The URL the hosted application will listen on. /// A delegate that configures the router for handling requests to the application. /// A started that hosts the application. - public static IWebHost Start(string? url, Action routeBuilder) + public static IWebHost Start(string url, Action routeBuilder) { var startupAssemblyName = routeBuilder.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name; return StartWith(url, services => services.AddRouting(), appBuilder => appBuilder.UseRouter(routeBuilder), applicationName: startupAssemblyName); @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore /// The delegate that configures the . /// A started that hosts the application. public static IWebHost StartWith(Action app) => - StartWith(url: null, app: app); + StartWith(url: null!, app: app); /// /// Initializes and starts a new with pre-configured defaults. @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore /// The URL the hosted application will listen on. /// The delegate that configures the . /// A started that hosts the application. - public static IWebHost StartWith(string? url, Action app) => + public static IWebHost StartWith(string url, Action app) => StartWith(url: url, configureServices: null, app: app, applicationName: null); private static IWebHost StartWith(string? url, Action? configureServices, Action app, string? applicationName) @@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore /// /// The initialized . public static IWebHostBuilder CreateDefaultBuilder() => - CreateDefaultBuilder(args: null); + CreateDefaultBuilder(args: null!); /// /// Initializes a new instance of the class with pre-configured defaults. @@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore /// /// The command line args. /// The initialized . - public static IWebHostBuilder CreateDefaultBuilder(string[]? args) + public static IWebHostBuilder CreateDefaultBuilder(string[] args) { var builder = new WebHostBuilder(); diff --git a/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj b/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj index f6f11fd3b3..54ac89b43f 100644 --- a/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj +++ b/src/Features/JsonPatch/src/Microsoft.AspNetCore.JsonPatch.csproj @@ -2,7 +2,7 @@ ASP.NET Core support for JSON PATCH. - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 $(NoWarn);CS1591 true aspnetcore;json;jsonpatch diff --git a/src/Features/JsonPatch/src/PublicAPI.Shipped.txt b/src/Features/JsonPatch/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Features/JsonPatch/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt b/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..17eb40088c --- /dev/null +++ b/src/Features/JsonPatch/src/PublicAPI.Unshipped.txt @@ -0,0 +1,228 @@ +#nullable enable +Microsoft.AspNetCore.JsonPatch.Adapters.AdapterFactory +Microsoft.AspNetCore.JsonPatch.Adapters.AdapterFactory.AdapterFactory() -> void +Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory +Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter +Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapterWithTest +Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter +Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter +Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter.JsonPatchDocumentConverter() -> void +Microsoft.AspNetCore.JsonPatch.Converters.TypedJsonPatchDocumentConverter +Microsoft.AspNetCore.JsonPatch.Converters.TypedJsonPatchDocumentConverter.TypedJsonPatchDocumentConverter() -> void +Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException +Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.JsonPatchException() -> void +Microsoft.AspNetCore.JsonPatch.Helpers.GetValueResult +Microsoft.AspNetCore.JsonPatch.Helpers.GetValueResult.HasError.get -> bool +Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument +Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult +Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult.CanBeConverted.get -> bool +Microsoft.AspNetCore.JsonPatch.Internal.ConversionResultProvider +Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter +Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.DictionaryAdapter() -> void +Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter +Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.DynamicObjectAdapter() -> void +Microsoft.AspNetCore.JsonPatch.Internal.IAdapter +Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter +Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.JObjectAdapter() -> void +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.ListAdapter() -> void +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType.Add = 0 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType.Get = 2 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType.Remove = 1 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType.Replace = 3 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionInfo +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionInfo.Index.get -> int +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionInfo.PositionInfo(Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType type, int index) -> void +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionInfo.Type.get -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType.EndOfList = 1 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType.Index = 0 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType.Invalid = 2 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType.OutOfBounds = 3 -> Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType +Microsoft.AspNetCore.JsonPatch.Internal.ObjectVisitor +Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath +Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter +Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.PocoAdapter() -> void +Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.JsonPatchDocument() -> void +Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.JsonPatchDocument() -> void +Microsoft.AspNetCore.JsonPatch.JsonPatchError +Microsoft.AspNetCore.JsonPatch.JsonPatchProperty +Microsoft.AspNetCore.JsonPatch.Operations.Operation +Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation() -> void +Microsoft.AspNetCore.JsonPatch.Operations.Operation.ShouldSerializevalue() -> bool +Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation() -> void +Microsoft.AspNetCore.JsonPatch.Operations.OperationBase +Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.OperationBase() -> void +Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.OperationType.get -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.ShouldSerializefrom() -> bool +Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Add = 0 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Copy = 4 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Invalid = 6 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Move = 3 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Remove = 1 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Replace = 2 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +Microsoft.AspNetCore.JsonPatch.Operations.OperationType.Test = 5 -> Microsoft.AspNetCore.JsonPatch.Operations.OperationType +~Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory.Create(object target, Newtonsoft.Json.Serialization.IContractResolver contractResolver) -> Microsoft.AspNetCore.JsonPatch.Internal.IAdapter +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter.Add(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter.Copy(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter.Move(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter.Remove(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter.Replace(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapterWithTest.Test(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.AdapterFactory.get -> Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Add(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.ContractResolver.get -> Newtonsoft.Json.Serialization.IContractResolver +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Copy(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.LogErrorAction.get -> System.Action +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Move(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.ObjectAdapter(Newtonsoft.Json.Serialization.IContractResolver contractResolver, System.Action logErrorAction) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.ObjectAdapter(Newtonsoft.Json.Serialization.IContractResolver contractResolver, System.Action logErrorAction, Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory adapterFactory) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Remove(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Replace(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Adapters.ObjectAdapter.Test(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.AffectedObject.get -> object +~Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.FailedOperation.get -> Microsoft.AspNetCore.JsonPatch.Operations.Operation +~Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.JsonPatchException(Microsoft.AspNetCore.JsonPatch.JsonPatchError jsonPatchError) -> void +~Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.JsonPatchException(Microsoft.AspNetCore.JsonPatch.JsonPatchError jsonPatchError, System.Exception innerException) -> void +~Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException.JsonPatchException(string message, System.Exception innerException) -> void +~Microsoft.AspNetCore.JsonPatch.Helpers.GetValueResult.GetValueResult(object propertyValue, bool hasError) -> void +~Microsoft.AspNetCore.JsonPatch.Helpers.GetValueResult.PropertyValue.get -> object +~Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument.ContractResolver.get -> Newtonsoft.Json.Serialization.IContractResolver +~Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument.ContractResolver.set -> void +~Microsoft.AspNetCore.JsonPatch.IJsonPatchDocument.GetOperations() -> System.Collections.Generic.IList +~Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult.ConversionResult(bool canBeConverted, object convertedInstance) -> void +~Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult.ConvertedInstance.get -> object +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.IAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.ObjectVisitor.ObjectVisitor(Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath path, Newtonsoft.Json.Serialization.IContractResolver contractResolver) -> void +~Microsoft.AspNetCore.JsonPatch.Internal.ObjectVisitor.ObjectVisitor(Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath path, Newtonsoft.Json.Serialization.IContractResolver contractResolver, Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory adapterFactory) -> void +~Microsoft.AspNetCore.JsonPatch.Internal.ObjectVisitor.TryVisit(ref object target, out Microsoft.AspNetCore.JsonPatch.Internal.IAdapter adapter, out string errorMessage) -> bool +~Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath.LastSegment.get -> string +~Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath.ParsedPath(string path) -> void +~Microsoft.AspNetCore.JsonPatch.Internal.ParsedPath.Segments.get -> System.Collections.Generic.IReadOnlyList +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Add(string path, object value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(object objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(object objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(object objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter, System.Action logErrorAction) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(object objectToApplyTo, System.Action logErrorAction) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ContractResolver.get -> Newtonsoft.Json.Serialization.IContractResolver +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ContractResolver.set -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(string from, string path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.JsonPatchDocument(System.Collections.Generic.List operations, Newtonsoft.Json.Serialization.IContractResolver contractResolver) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(string from, string path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Operations.get -> System.Collections.Generic.List +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Remove(string path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Replace(string path, object value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Test(string path, object value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Add(System.Linq.Expressions.Expression>> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Add(System.Linq.Expressions.Expression>> path, TProp value, int position) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Add(System.Linq.Expressions.Expression> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(TModel objectToApplyTo) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(TModel objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(TModel objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter, System.Action logErrorAction) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ApplyTo(TModel objectToApplyTo, System.Action logErrorAction) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ContractResolver.get -> Newtonsoft.Json.Serialization.IContractResolver +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.ContractResolver.set -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression>> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression>> path, int positionTo) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression>> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression>> path, int positionTo) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Copy(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.JsonPatchDocument(System.Collections.Generic.List> operations, Newtonsoft.Json.Serialization.IContractResolver contractResolver) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression>> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression>> path, int positionTo) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression>> from, int positionFrom, System.Linq.Expressions.Expression> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression>> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression>> path, int positionTo) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Move(System.Linq.Expressions.Expression> from, System.Linq.Expressions.Expression> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Operations.get -> System.Collections.Generic.List> +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Remove(System.Linq.Expressions.Expression>> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Remove(System.Linq.Expressions.Expression>> path, int position) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Remove(System.Linq.Expressions.Expression> path) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Replace(System.Linq.Expressions.Expression>> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Replace(System.Linq.Expressions.Expression>> path, TProp value, int position) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Replace(System.Linq.Expressions.Expression> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Test(System.Linq.Expressions.Expression>> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Test(System.Linq.Expressions.Expression>> path, TProp value, int position) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchDocument.Test(System.Linq.Expressions.Expression> path, TProp value) -> Microsoft.AspNetCore.JsonPatch.JsonPatchDocument +~Microsoft.AspNetCore.JsonPatch.JsonPatchError.AffectedObject.get -> object +~Microsoft.AspNetCore.JsonPatch.JsonPatchError.ErrorMessage.get -> string +~Microsoft.AspNetCore.JsonPatch.JsonPatchError.JsonPatchError(object affectedObject, Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, string errorMessage) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchError.Operation.get -> Microsoft.AspNetCore.JsonPatch.Operations.Operation +~Microsoft.AspNetCore.JsonPatch.JsonPatchProperty.JsonPatchProperty(Newtonsoft.Json.Serialization.JsonProperty property, object parent) -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchProperty.Parent.get -> object +~Microsoft.AspNetCore.JsonPatch.JsonPatchProperty.Parent.set -> void +~Microsoft.AspNetCore.JsonPatch.JsonPatchProperty.Property.get -> Newtonsoft.Json.Serialization.JsonProperty +~Microsoft.AspNetCore.JsonPatch.JsonPatchProperty.Property.set -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Apply(object objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation(string op, string path, string from) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation(string op, string path, string from, object value) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.value.get -> object +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.value.set -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Apply(TModel objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation(string op, string path, string from) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.Operation.Operation(string op, string path, string from, object value) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.OperationBase(string op, string path, string from) -> void +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.from.get -> string +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.from.set -> void +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.op.get -> string +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.op.set -> void +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.path.get -> string +~Microsoft.AspNetCore.JsonPatch.Operations.OperationBase.path.set -> void +~override Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter.CanConvert(System.Type objectType) -> bool +~override Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter.ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) -> object +~override Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter.WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) -> void +~override Microsoft.AspNetCore.JsonPatch.Converters.TypedJsonPatchDocumentConverter.ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) -> object +~static Microsoft.AspNetCore.JsonPatch.Internal.ConversionResultProvider.ConvertTo(object value, System.Type typeToConvertTo) -> Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult +~static Microsoft.AspNetCore.JsonPatch.Internal.ConversionResultProvider.CopyTo(object value, System.Type typeToConvertTo) -> Microsoft.AspNetCore.JsonPatch.Internal.ConversionResult +~virtual Microsoft.AspNetCore.JsonPatch.Adapters.AdapterFactory.Create(object target, Newtonsoft.Json.Serialization.IContractResolver contractResolver) -> Microsoft.AspNetCore.JsonPatch.Internal.IAdapter +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryConvertKey(string key, out TKey convertedKey, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryConvertValue(object value, out TValue convertedValue, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DictionaryAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryConvertValue(object value, System.Type propertyType, out object convertedValue) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryGetDynamicObjectProperty(object target, Newtonsoft.Json.Serialization.IContractResolver contractResolver, string segment, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TrySetDynamicObjectProperty(object target, Newtonsoft.Json.Serialization.IContractResolver contractResolver, string segment, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.DynamicObjectAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.JObjectAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryConvertValue(object originalValue, System.Type listTypeArgument, string segment, out object convertedValue, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryGetListTypeArgument(System.Collections.IList list, out System.Type listTypeArgument, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryGetPositionInfo(System.Collections.IList list, string segment, Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.OperationType operationType, out Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionInfo positionInfo, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryConvertValue(object value, System.Type propertyType, out object convertedValue) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryGetJsonProperty(object target, Newtonsoft.Json.Serialization.IContractResolver contractResolver, string segment, out Newtonsoft.Json.Serialization.JsonProperty jsonProperty) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) -> bool +~virtual Microsoft.AspNetCore.JsonPatch.Internal.PocoAdapter.TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) -> bool diff --git a/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj b/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj index d378a4e876..2afab5ce0a 100644 --- a/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj +++ b/src/Features/JsonPatch/test/Microsoft.AspNetCore.JsonPatch.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) diff --git a/src/FileProviders/Embedded/src/Microsoft.Extensions.FileProviders.Embedded.csproj b/src/FileProviders/Embedded/src/Microsoft.Extensions.FileProviders.Embedded.csproj index 459a9973b9..5802aee040 100644 --- a/src/FileProviders/Embedded/src/Microsoft.Extensions.FileProviders.Embedded.csproj +++ b/src/FileProviders/Embedded/src/Microsoft.Extensions.FileProviders.Embedded.csproj @@ -3,7 +3,7 @@ Microsoft.Extensions.FileProviders File provider for files in embedded resources for Microsoft.Extensions.FileProviders. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(MSBuildProjectName).multitarget.nuspec $(DefaultNetCoreTargetFramework) $(MSBuildProjectName).netcoreapp.nuspec diff --git a/src/FileProviders/Embedded/src/PublicAPI.Shipped.txt b/src/FileProviders/Embedded/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/FileProviders/Embedded/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/FileProviders/Embedded/src/PublicAPI.Unshipped.txt b/src/FileProviders/Embedded/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..2faf94f741 --- /dev/null +++ b/src/FileProviders/Embedded/src/PublicAPI.Unshipped.txt @@ -0,0 +1,25 @@ +#nullable enable +Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo +Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.Exists.get -> bool +Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.IsDirectory.get -> bool +Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.LastModified.get -> System.DateTimeOffset +Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.Length.get -> long +Microsoft.Extensions.FileProviders.EmbeddedFileProvider +Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider +~Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.CreateReadStream() -> System.IO.Stream +~Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.EmbeddedResourceFileInfo(System.Reflection.Assembly assembly, string resourcePath, string name, System.DateTimeOffset lastModified) -> void +~Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.Name.get -> string +~Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo.PhysicalPath.get -> string +~Microsoft.Extensions.FileProviders.EmbeddedFileProvider.EmbeddedFileProvider(System.Reflection.Assembly assembly) -> void +~Microsoft.Extensions.FileProviders.EmbeddedFileProvider.EmbeddedFileProvider(System.Reflection.Assembly assembly, string baseNamespace) -> void +~Microsoft.Extensions.FileProviders.EmbeddedFileProvider.GetDirectoryContents(string subpath) -> Microsoft.Extensions.FileProviders.IDirectoryContents +~Microsoft.Extensions.FileProviders.EmbeddedFileProvider.GetFileInfo(string subpath) -> Microsoft.Extensions.FileProviders.IFileInfo +~Microsoft.Extensions.FileProviders.EmbeddedFileProvider.Watch(string pattern) -> Microsoft.Extensions.Primitives.IChangeToken +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.Assembly.get -> System.Reflection.Assembly +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.GetDirectoryContents(string subpath) -> Microsoft.Extensions.FileProviders.IDirectoryContents +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.GetFileInfo(string subpath) -> Microsoft.Extensions.FileProviders.IFileInfo +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.ManifestEmbeddedFileProvider(System.Reflection.Assembly assembly) -> void +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.ManifestEmbeddedFileProvider(System.Reflection.Assembly assembly, string root) -> void +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.ManifestEmbeddedFileProvider(System.Reflection.Assembly assembly, string root, System.DateTimeOffset lastModified) -> void +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.ManifestEmbeddedFileProvider(System.Reflection.Assembly assembly, string root, string manifestName, System.DateTimeOffset lastModified) -> void +~Microsoft.Extensions.FileProviders.ManifestEmbeddedFileProvider.Watch(string filter) -> Microsoft.Extensions.Primitives.IChangeToken diff --git a/src/FileProviders/Embedded/test/Microsoft.Extensions.FileProviders.Embedded.Tests.csproj b/src/FileProviders/Embedded/test/Microsoft.Extensions.FileProviders.Embedded.Tests.csproj index a199e43837..052d44225d 100644 --- a/src/FileProviders/Embedded/test/Microsoft.Extensions.FileProviders.Embedded.Tests.csproj +++ b/src/FileProviders/Embedded/test/Microsoft.Extensions.FileProviders.Embedded.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) diff --git a/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Shipped.txt b/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Unshipped.txt b/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/FileProviders/Manifest.MSBuildTask/src/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Framework/test/SharedFxTests.cs b/src/Framework/test/SharedFxTests.cs index 35955630c8..52d89ea938 100644 --- a/src/Framework/test/SharedFxTests.cs +++ b/src/Framework/test/SharedFxTests.cs @@ -2,8 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; using Newtonsoft.Json.Linq; using Xunit; using Xunit.Abstractions; @@ -81,7 +85,7 @@ namespace Microsoft.AspNetCore } [Fact] - public void ItContainsValidRuntimeConfigFile() + public void SharedFrameworkContainsValidRuntimeConfigFile() { var runtimeConfigFilePath = Path.Combine(_sharedFxRoot, "Microsoft.AspNetCore.App.runtimeconfig.json"); @@ -98,7 +102,7 @@ namespace Microsoft.AspNetCore } [Fact] - public void ItContainsValidDepsJson() + public void SharedFrameworkContainsValidDepsJson() { var depsFilePath = Path.Combine(_sharedFxRoot, "Microsoft.AspNetCore.App.deps.json"); @@ -155,6 +159,46 @@ namespace Microsoft.AspNetCore } } + [Fact] + public void SharedFrameworkAssembliesHaveExpectedAssemblyVersions() + { + // Only test managed assemblies + IEnumerable dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories).Where(i => !i.Contains("aspnetcorev2_inprocess")); + Assert.NotEmpty(dlls); + + Assert.All(dlls, path => + { + using var fileStream = File.OpenRead(path); + using var peReader = new PEReader(fileStream, PEStreamOptions.Default); + var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default); + var assemblyDefinition = reader.GetAssemblyDefinition(); + + // Assembly versions should all match Major.Minor.0.0 + Assert.Equal(0, assemblyDefinition.Version.Build); + Assert.Equal(0, assemblyDefinition.Version.Revision); + }); + } + + [Fact] + public void SharedFrameworkAssemblyReferencesHaveExpectedAssemblyVersions() + { + IEnumerable dlls = Directory.GetFiles(_sharedFxRoot, "*.dll", SearchOption.AllDirectories).Where(i => !i.Contains("aspnetcorev2_inprocess") && !i.Contains("System.Security.Cryptography.Xml", StringComparison.OrdinalIgnoreCase)); + Assert.NotEmpty(dlls); + + Assert.All(dlls, path => + { + using var fileStream = File.OpenRead(path); + using var peReader = new PEReader(fileStream, PEStreamOptions.Default); + var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default); + + Assert.All(reader.AssemblyReferences, handle => + { + var reference = reader.GetAssemblyReference(handle); + Assert.Equal(0, reference.Version.Revision); + }); + }); + } + [Fact] public void ItContainsVersionFile() { diff --git a/src/Framework/test/TargetingPackTests.cs b/src/Framework/test/TargetingPackTests.cs index d039631492..519681e80c 100644 --- a/src/Framework/test/TargetingPackTests.cs +++ b/src/Framework/test/TargetingPackTests.cs @@ -89,6 +89,31 @@ namespace Microsoft.AspNetCore }); } + [Fact] + public void RefAssemblyReferencesHaveExpectedAssemblyVersions() + { + if (!_isTargetingPackBuilding) + { + return; + } + + IEnumerable dlls = Directory.GetFiles(Path.Combine(_targetingPackRoot, "ref", _targetingPackTfm), "*.dll", SearchOption.AllDirectories); + Assert.NotEmpty(dlls); + + Assert.All(dlls, path => + { + using var fileStream = File.OpenRead(path); + using var peReader = new PEReader(fileStream, PEStreamOptions.Default); + var reader = peReader.GetMetadataReader(MetadataReaderOptions.Default); + + Assert.All(reader.AssemblyReferences, handle => + { + var reference = reader.GetAssemblyReference(handle); + Assert.Equal(0, reference.Version.Revision); + }); + }); + } + [Fact] public void PackageOverridesContainsCorrectEntries() { diff --git a/src/HealthChecks/Abstractions/src/Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj b/src/HealthChecks/Abstractions/src/Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj index 93fda5d4de..aa4c8c0098 100644 --- a/src/HealthChecks/Abstractions/src/Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj +++ b/src/HealthChecks/Abstractions/src/Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj @@ -7,7 +7,7 @@ Commonly Used Types Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck Microsoft.Extensions.Diagnostics.HealthChecks - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true diff --git a/src/HealthChecks/Abstractions/src/PublicAPI.Shipped.txt b/src/HealthChecks/Abstractions/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/HealthChecks/Abstractions/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/HealthChecks/Abstractions/src/PublicAPI.Unshipped.txt b/src/HealthChecks/Abstractions/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..03e65dd8f7 --- /dev/null +++ b/src/HealthChecks/Abstractions/src/PublicAPI.Unshipped.txt @@ -0,0 +1,51 @@ +#nullable enable +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext.HealthCheckContext() -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext.Registration.get -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext.Registration.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Factory.get -> System.Func! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Factory.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.FailureStatus.get -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.FailureStatus.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.HealthCheckRegistration(string! name, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck! instance, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable? tags) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.HealthCheckRegistration(string! name, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck! instance, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable? tags, System.TimeSpan? timeout) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.HealthCheckRegistration(string! name, System.Func! factory, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable? tags) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.HealthCheckRegistration(string! name, System.Func! factory, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable? tags, System.TimeSpan? timeout) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Name.get -> string! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Name.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Tags.get -> System.Collections.Generic.ISet! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Timeout.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration.Timeout.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Data.get -> System.Collections.Generic.IReadOnlyDictionary! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Description.get -> string? +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Exception.get -> System.Exception? +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.HealthCheckResult(Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus status, string? description = null, System.Exception? exception = null, System.Collections.Generic.IReadOnlyDictionary? data = null) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Status.get -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport.Entries.get -> System.Collections.Generic.IReadOnlyDictionary! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport.HealthReport(System.Collections.Generic.IReadOnlyDictionary! entries, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus status, System.TimeSpan totalDuration) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport.HealthReport(System.Collections.Generic.IReadOnlyDictionary! entries, System.TimeSpan totalDuration) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport.Status.get -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport.TotalDuration.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Data.get -> System.Collections.Generic.IReadOnlyDictionary! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Description.get -> string? +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Duration.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Exception.get -> System.Exception? +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.HealthReportEntry(Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus status, string? description, System.TimeSpan duration, System.Exception? exception, System.Collections.Generic.IReadOnlyDictionary? data) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.HealthReportEntry(Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus status, string? description, System.TimeSpan duration, System.Exception? exception, System.Collections.Generic.IReadOnlyDictionary? data, System.Collections.Generic.IEnumerable? tags = null) -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Status.get -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthReportEntry.Tags.get -> System.Collections.Generic.IEnumerable! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Degraded = 1 -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Healthy = 2 -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus.Unhealthy = 0 -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus +Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck +Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck.CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext! context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckPublisher +Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckPublisher.PublishAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthReport! report, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +static Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Degraded(string? description = null, System.Exception? exception = null, System.Collections.Generic.IReadOnlyDictionary? data = null) -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult +static Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Healthy(string? description = null, System.Collections.Generic.IReadOnlyDictionary? data = null) -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult +static Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult.Unhealthy(string? description = null, System.Exception? exception = null, System.Collections.Generic.IReadOnlyDictionary? data = null) -> Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult diff --git a/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderAddCheckExtensions.cs b/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderAddCheckExtensions.cs index 0f280d9b68..c9ecfc49ab 100644 --- a/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderAddCheckExtensions.cs +++ b/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderAddCheckExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace Microsoft.Extensions.DependencyInjection @@ -48,6 +49,7 @@ namespace Microsoft.Extensions.DependencyInjection /// A list of tags that can be used to filter health checks. /// An optional representing the timeout of the check. /// The . + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddCheck( this IHealthChecksBuilder builder, string name, @@ -121,6 +123,7 @@ namespace Microsoft.Extensions.DependencyInjection /// with any lifetime it will be used. Otherwise an instance of type will be constructed with /// access to services from the dependency injection container. /// + [SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddCheck( this IHealthChecksBuilder builder, string name, diff --git a/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderDelegateExtensions.cs b/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderDelegateExtensions.cs index 0419d0c3b2..3abe442567 100644 --- a/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderDelegateExtensions.cs +++ b/src/HealthChecks/HealthChecks/src/DependencyInjection/HealthChecksBuilderDelegateExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -41,6 +42,7 @@ namespace Microsoft.Extensions.DependencyInjection /// A delegate that provides the health check implementation. /// An optional representing the timeout of the check. /// The . + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddCheck( this IHealthChecksBuilder builder, string name, @@ -94,6 +96,7 @@ namespace Microsoft.Extensions.DependencyInjection /// A delegate that provides the health check implementation. /// An optional representing the timeout of the check. /// The . + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddCheck( this IHealthChecksBuilder builder, string name, @@ -147,6 +150,7 @@ namespace Microsoft.Extensions.DependencyInjection /// A delegate that provides the health check implementation. /// An optional representing the timeout of the check. /// The . + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddAsyncCheck( this IHealthChecksBuilder builder, string name, @@ -200,6 +204,7 @@ namespace Microsoft.Extensions.DependencyInjection /// A delegate that provides the health check implementation. /// An optional representing the timeout of the check. /// The . + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IHealthChecksBuilder AddAsyncCheck( this IHealthChecksBuilder builder, string name, diff --git a/src/HealthChecks/HealthChecks/src/HealthCheckService.cs b/src/HealthChecks/HealthChecks/src/HealthCheckService.cs index 7ef29cc961..4809350459 100644 --- a/src/HealthChecks/HealthChecks/src/HealthCheckService.cs +++ b/src/HealthChecks/HealthChecks/src/HealthCheckService.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; @@ -38,6 +39,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks /// A which will complete when all the health checks have been run, /// yielding a containing the results. /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public Task CheckHealthAsync(CancellationToken cancellationToken = default) { return CheckHealthAsync(predicate: null, cancellationToken); @@ -54,6 +56,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks /// A which will complete when all the health checks have been run, /// yielding a containing the results. /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public abstract Task CheckHealthAsync( Func? predicate, CancellationToken cancellationToken = default); diff --git a/src/HealthChecks/HealthChecks/src/Microsoft.Extensions.Diagnostics.HealthChecks.csproj b/src/HealthChecks/HealthChecks/src/Microsoft.Extensions.Diagnostics.HealthChecks.csproj index 7b000f9657..dfcd59db0e 100644 --- a/src/HealthChecks/HealthChecks/src/Microsoft.Extensions.Diagnostics.HealthChecks.csproj +++ b/src/HealthChecks/HealthChecks/src/Microsoft.Extensions.Diagnostics.HealthChecks.csproj @@ -6,7 +6,7 @@ Commonly Used Types: Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true diff --git a/src/HealthChecks/HealthChecks/src/PublicAPI.Shipped.txt b/src/HealthChecks/HealthChecks/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/HealthChecks/HealthChecks/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/HealthChecks/HealthChecks/src/PublicAPI.Unshipped.txt b/src/HealthChecks/HealthChecks/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..335f4292a1 --- /dev/null +++ b/src/HealthChecks/HealthChecks/src/PublicAPI.Unshipped.txt @@ -0,0 +1,41 @@ +#nullable enable +Microsoft.Extensions.DependencyInjection.HealthCheckServiceCollectionExtensions +Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions +Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions +Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder +Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder.Add(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckRegistration! registration) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Delay.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Delay.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.HealthCheckPublisherOptions() -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Period.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Period.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Predicate.get -> System.Func? +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Predicate.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Timeout.get -> System.TimeSpan +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherOptions.Timeout.set -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService.CheckHealthAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService.HealthCheckService() -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckServiceOptions +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckServiceOptions.HealthCheckServiceOptions() -> void +Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckServiceOptions.Registrations.get -> System.Collections.Generic.ICollection! +abstract Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService.CheckHealthAsync(System.Func? predicate, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +static Microsoft.Extensions.DependencyInjection.HealthCheckServiceCollectionExtensions.AddHealthChecks(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck! instance, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = null, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck! instance, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable! tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = null, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable! tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddTypeActivatedCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable! tags, System.TimeSpan timeout, params object![]! args) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddTypeActivatedCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, System.Collections.Generic.IEnumerable? tags, params object![]! args) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddTypeActivatedCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus, params object![]! args) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions.AddTypeActivatedCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, params object![]! args) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddAsyncCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func!>! check, System.Collections.Generic.IEnumerable! tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddAsyncCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func!>! check, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddAsyncCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func!>! check, System.Collections.Generic.IEnumerable! tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddAsyncCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func!>! check, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func! check, System.Collections.Generic.IEnumerable! tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func! check, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func! check, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = null) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! +static Microsoft.Extensions.DependencyInjection.HealthChecksBuilderDelegateExtensions.AddCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! builder, string! name, System.Func! check, System.Collections.Generic.IEnumerable? tags) -> Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder! diff --git a/src/HealthChecks/HealthChecks/test/Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj b/src/HealthChecks/HealthChecks/test/Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj index b58da42031..8b62bed115 100644 --- a/src/HealthChecks/HealthChecks/test/Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj +++ b/src/HealthChecks/HealthChecks/test/Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) Microsoft.Extensions.Diagnostics.HealthChecks enable diff --git a/src/Hosting/Abstractions/src/PublicAPI.Shipped.txt b/src/Hosting/Abstractions/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Hosting/Abstractions/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a1842d9239 --- /dev/null +++ b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt @@ -0,0 +1,95 @@ +#nullable enable +Microsoft.AspNetCore.Hosting.EnvironmentName +Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions +Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions +Microsoft.AspNetCore.Hosting.HostingStartupAttribute +Microsoft.AspNetCore.Hosting.HostingStartupAttribute.HostingStartupAttribute(System.Type! hostingStartupType) -> void +Microsoft.AspNetCore.Hosting.HostingStartupAttribute.HostingStartupType.get -> System.Type! +Microsoft.AspNetCore.Hosting.IApplicationLifetime +Microsoft.AspNetCore.Hosting.IApplicationLifetime.ApplicationStarted.get -> System.Threading.CancellationToken +Microsoft.AspNetCore.Hosting.IApplicationLifetime.ApplicationStopped.get -> System.Threading.CancellationToken +Microsoft.AspNetCore.Hosting.IApplicationLifetime.ApplicationStopping.get -> System.Threading.CancellationToken +Microsoft.AspNetCore.Hosting.IApplicationLifetime.StopApplication() -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ApplicationName.get -> string! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ApplicationName.set -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ContentRootFileProvider.get -> Microsoft.Extensions.FileProviders.IFileProvider! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ContentRootFileProvider.set -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ContentRootPath.get -> string! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.ContentRootPath.set -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment.EnvironmentName.get -> string! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.EnvironmentName.set -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment.WebRootFileProvider.get -> Microsoft.Extensions.FileProviders.IFileProvider! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.WebRootFileProvider.set -> void +Microsoft.AspNetCore.Hosting.IHostingEnvironment.WebRootPath.get -> string! +Microsoft.AspNetCore.Hosting.IHostingEnvironment.WebRootPath.set -> void +Microsoft.AspNetCore.Hosting.IHostingStartup +Microsoft.AspNetCore.Hosting.IHostingStartup.Configure(Microsoft.AspNetCore.Hosting.IWebHostBuilder! builder) -> void +Microsoft.AspNetCore.Hosting.IStartup +Microsoft.AspNetCore.Hosting.IStartup.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder! app) -> void +Microsoft.AspNetCore.Hosting.IStartup.ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> System.IServiceProvider! +Microsoft.AspNetCore.Hosting.IStartupConfigureContainerFilter +Microsoft.AspNetCore.Hosting.IStartupConfigureContainerFilter.ConfigureContainer(System.Action! container) -> System.Action! +Microsoft.AspNetCore.Hosting.IStartupConfigureServicesFilter +Microsoft.AspNetCore.Hosting.IStartupConfigureServicesFilter.ConfigureServices(System.Action! next) -> System.Action! +Microsoft.AspNetCore.Hosting.IStartupFilter +Microsoft.AspNetCore.Hosting.IStartupFilter.Configure(System.Action! next) -> System.Action! +Microsoft.AspNetCore.Hosting.IWebHost +Microsoft.AspNetCore.Hosting.IWebHost.ServerFeatures.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection! +Microsoft.AspNetCore.Hosting.IWebHost.Services.get -> System.IServiceProvider! +Microsoft.AspNetCore.Hosting.IWebHost.Start() -> void +Microsoft.AspNetCore.Hosting.IWebHost.StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Hosting.IWebHost.StopAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Hosting.IWebHostBuilder +Microsoft.AspNetCore.Hosting.IWebHostBuilder.Build() -> Microsoft.AspNetCore.Hosting.IWebHost! +Microsoft.AspNetCore.Hosting.IWebHostBuilder.ConfigureAppConfiguration(System.Action! configureDelegate) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.IWebHostBuilder.ConfigureServices(System.Action! configureServices) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.IWebHostBuilder.ConfigureServices(System.Action! configureServices) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.IWebHostBuilder.GetSetting(string! key) -> string? +Microsoft.AspNetCore.Hosting.IWebHostBuilder.UseSetting(string! key, string? value) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.IWebHostEnvironment +Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootFileProvider.get -> Microsoft.Extensions.FileProviders.IFileProvider! +Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootFileProvider.set -> void +Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootPath.get -> string! +Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootPath.set -> void +Microsoft.AspNetCore.Hosting.WebHostBuilderContext +Microsoft.AspNetCore.Hosting.WebHostBuilderContext.Configuration.get -> Microsoft.Extensions.Configuration.IConfiguration! +Microsoft.AspNetCore.Hosting.WebHostBuilderContext.Configuration.set -> void +Microsoft.AspNetCore.Hosting.WebHostBuilderContext.HostingEnvironment.get -> Microsoft.AspNetCore.Hosting.IWebHostEnvironment! +Microsoft.AspNetCore.Hosting.WebHostBuilderContext.HostingEnvironment.set -> void +Microsoft.AspNetCore.Hosting.WebHostBuilderContext.WebHostBuilderContext() -> void +Microsoft.AspNetCore.Hosting.WebHostDefaults +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.CaptureStartupErrors(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, bool captureStartupErrors) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.PreferHostingUrls(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, bool preferHostingUrls) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.Start(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, params string![]! urls) -> Microsoft.AspNetCore.Hosting.IWebHost! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.SuppressStatusMessages(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, bool suppressStatusMessages) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseContentRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, string! contentRoot) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseEnvironment(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, string! environment) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseServer(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, Microsoft.AspNetCore.Hosting.Server.IServer! server) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseShutdownTimeout(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.TimeSpan timeout) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseStartup(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, string! startupAssemblyName) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseUrls(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, params string![]! urls) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseWebRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, string! webRoot) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions.IsDevelopment(this Microsoft.AspNetCore.Hosting.IHostingEnvironment! hostingEnvironment) -> bool +static Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions.IsEnvironment(this Microsoft.AspNetCore.Hosting.IHostingEnvironment! hostingEnvironment, string! environmentName) -> bool +static Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions.IsProduction(this Microsoft.AspNetCore.Hosting.IHostingEnvironment! hostingEnvironment) -> bool +static Microsoft.AspNetCore.Hosting.HostingEnvironmentExtensions.IsStaging(this Microsoft.AspNetCore.Hosting.IHostingEnvironment! hostingEnvironment) -> bool +static readonly Microsoft.AspNetCore.Hosting.EnvironmentName.Development -> string! +static readonly Microsoft.AspNetCore.Hosting.EnvironmentName.Production -> string! +static readonly Microsoft.AspNetCore.Hosting.EnvironmentName.Staging -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.ApplicationKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.CaptureStartupErrorsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.ContentRootKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.DetailedErrorsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.EnvironmentKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HostingStartupAssembliesKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HostingStartupExcludeAssembliesKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.PreferHostingUrlsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.PreventHostingStartupKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.ServerUrlsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.ShutdownTimeoutKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.StartupAssemblyKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.StaticWebAssetsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.SuppressStatusMessagesKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.WebRootKey -> string! diff --git a/src/Hosting/Hosting/src/PublicAPI.Shipped.txt b/src/Hosting/Hosting/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Hosting/Hosting/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Hosting/Hosting/src/PublicAPI.Unshipped.txt b/src/Hosting/Hosting/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..d736c993ab --- /dev/null +++ b/src/Hosting/Hosting/src/PublicAPI.Unshipped.txt @@ -0,0 +1,63 @@ +#nullable enable +Microsoft.AspNetCore.Hosting.Builder.ApplicationBuilderFactory +Microsoft.AspNetCore.Hosting.Builder.ApplicationBuilderFactory.ApplicationBuilderFactory(System.IServiceProvider! serviceProvider) -> void +Microsoft.AspNetCore.Hosting.Builder.ApplicationBuilderFactory.CreateBuilder(Microsoft.AspNetCore.Http.Features.IFeatureCollection! serverFeatures) -> Microsoft.AspNetCore.Builder.IApplicationBuilder! +Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory +Microsoft.AspNetCore.Hosting.DelegateStartup +Microsoft.AspNetCore.Hosting.DelegateStartup.DelegateStartup(Microsoft.Extensions.DependencyInjection.IServiceProviderFactory! factory, System.Action! configureApp) -> void +Microsoft.AspNetCore.Hosting.Server.Features.ServerAddressesFeature +Microsoft.AspNetCore.Hosting.Server.Features.ServerAddressesFeature.Addresses.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Hosting.Server.Features.ServerAddressesFeature.PreferHostingUrls.get -> bool +Microsoft.AspNetCore.Hosting.Server.Features.ServerAddressesFeature.PreferHostingUrls.set -> void +Microsoft.AspNetCore.Hosting.Server.Features.ServerAddressesFeature.ServerAddressesFeature() -> void +Microsoft.AspNetCore.Hosting.StartupBase +Microsoft.AspNetCore.Hosting.StartupBase.StartupBase() -> void +Microsoft.AspNetCore.Hosting.StartupBase +Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader +Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader.StaticWebAssetsLoader() -> void +Microsoft.AspNetCore.Hosting.WebHostBuilder +Microsoft.AspNetCore.Hosting.WebHostBuilder.Build() -> Microsoft.AspNetCore.Hosting.IWebHost! +Microsoft.AspNetCore.Hosting.WebHostBuilder.ConfigureAppConfiguration(System.Action! configureDelegate) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.WebHostBuilder.ConfigureServices(System.Action! configureServices) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.WebHostBuilder.ConfigureServices(System.Action! configureServices) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.WebHostBuilder.GetSetting(string! key) -> string! +Microsoft.AspNetCore.Hosting.WebHostBuilder.UseSetting(string! key, string? value) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +Microsoft.AspNetCore.Hosting.WebHostBuilder.WebHostBuilder() -> void +Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions +Microsoft.AspNetCore.Hosting.WebHostExtensions +Microsoft.AspNetCore.Http.DefaultHttpContextFactory +Microsoft.AspNetCore.Http.DefaultHttpContextFactory.Create(Microsoft.AspNetCore.Http.Features.IFeatureCollection! featureCollection) -> Microsoft.AspNetCore.Http.HttpContext! +Microsoft.AspNetCore.Http.DefaultHttpContextFactory.DefaultHttpContextFactory(System.IServiceProvider! serviceProvider) -> void +Microsoft.AspNetCore.Http.DefaultHttpContextFactory.Dispose(Microsoft.AspNetCore.Http.HttpContext! httpContext) -> void +Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions +Microsoft.Extensions.Hosting.WebHostBuilderOptions +Microsoft.Extensions.Hosting.WebHostBuilderOptions.SuppressEnvironmentConfiguration.get -> bool +Microsoft.Extensions.Hosting.WebHostBuilderOptions.SuppressEnvironmentConfiguration.set -> void +Microsoft.Extensions.Hosting.WebHostBuilderOptions.WebHostBuilderOptions() -> void +override Microsoft.AspNetCore.Hosting.DelegateStartup.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder! app) -> void +static Microsoft.AspNetCore.Hosting.StaticWebAssets.StaticWebAssetsLoader.UseStaticWebAssets(Microsoft.AspNetCore.Hosting.IWebHostEnvironment! environment, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> void +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.Configure(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configureApp) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.Configure(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configureApp) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.ConfigureAppConfiguration(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configureDelegate) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.ConfigureLogging(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configureLogging) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.ConfigureLogging(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configureLogging) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseDefaultServiceProvider(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configure) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseDefaultServiceProvider(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Action! configure) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseStartup(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Type! startupType) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseStartup(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseStartup(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! hostBuilder, System.Func! startupFactory) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseStaticWebAssets(this Microsoft.AspNetCore.Hosting.IWebHostBuilder! builder) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder! +static Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(this Microsoft.AspNetCore.Hosting.IWebHost! host) -> void +static Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(this Microsoft.AspNetCore.Hosting.IWebHost! host, System.Threading.CancellationToken token = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +static Microsoft.AspNetCore.Hosting.WebHostExtensions.StopAsync(this Microsoft.AspNetCore.Hosting.IWebHost! host, System.TimeSpan timeout) -> System.Threading.Tasks.Task! +static Microsoft.AspNetCore.Hosting.WebHostExtensions.WaitForShutdown(this Microsoft.AspNetCore.Hosting.IWebHost! host) -> void +static Microsoft.AspNetCore.Hosting.WebHostExtensions.WaitForShutdownAsync(this Microsoft.AspNetCore.Hosting.IWebHost! host, System.Threading.CancellationToken token = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! +virtual Microsoft.AspNetCore.Hosting.StartupBase.ConfigureContainer(TBuilder builder) -> void +~Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory.CreateBuilder(Microsoft.AspNetCore.Http.Features.IFeatureCollection serverFeatures) -> Microsoft.AspNetCore.Builder.IApplicationBuilder +~Microsoft.AspNetCore.Hosting.StartupBase.StartupBase(Microsoft.Extensions.DependencyInjection.IServiceProviderFactory factory) -> void +~abstract Microsoft.AspNetCore.Hosting.StartupBase.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder app) -> void +~override Microsoft.AspNetCore.Hosting.StartupBase.CreateServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> System.IServiceProvider +~static Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions.ConfigureWebHost(this Microsoft.Extensions.Hosting.IHostBuilder builder, System.Action configure) -> Microsoft.Extensions.Hosting.IHostBuilder +~static Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions.ConfigureWebHost(this Microsoft.Extensions.Hosting.IHostBuilder builder, System.Action configure, System.Action configureWebHostBuilder) -> Microsoft.Extensions.Hosting.IHostBuilder +~virtual Microsoft.AspNetCore.Hosting.StartupBase.ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> void +~virtual Microsoft.AspNetCore.Hosting.StartupBase.CreateServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> System.IServiceProvider diff --git a/src/Hosting/Server.Abstractions/src/IServerIntegratedAuth.cs b/src/Hosting/Server.Abstractions/src/IServerIntegratedAuth.cs index 218b461b0a..d099656ac4 100644 --- a/src/Hosting/Server.Abstractions/src/IServerIntegratedAuth.cs +++ b/src/Hosting/Server.Abstractions/src/IServerIntegratedAuth.cs @@ -16,6 +16,6 @@ namespace Microsoft.AspNetCore.Hosting.Server /// /// The name of the authentication scheme for the server authentication handler. /// - string? AuthenticationScheme { get; } + string AuthenticationScheme { get; } } } diff --git a/src/Hosting/Server.Abstractions/src/PublicAPI.Shipped.txt b/src/Hosting/Server.Abstractions/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Hosting/Server.Abstractions/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Hosting/Server.Abstractions/src/PublicAPI.Unshipped.txt b/src/Hosting/Server.Abstractions/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7342849c84 --- /dev/null +++ b/src/Hosting/Server.Abstractions/src/PublicAPI.Unshipped.txt @@ -0,0 +1,25 @@ +#nullable enable +Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer +Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer.HostContext.get -> TContext +Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer.HostContext.set -> void +Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature +Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.Addresses.get -> System.Collections.Generic.ICollection! +Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.PreferHostingUrls.get -> bool +Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.PreferHostingUrls.set -> void +Microsoft.AspNetCore.Hosting.Server.IHttpApplication +Microsoft.AspNetCore.Hosting.Server.IHttpApplication.CreateContext(Microsoft.AspNetCore.Http.Features.IFeatureCollection! contextFeatures) -> TContext +Microsoft.AspNetCore.Hosting.Server.IHttpApplication.DisposeContext(TContext context, System.Exception! exception) -> void +Microsoft.AspNetCore.Hosting.Server.IHttpApplication.ProcessRequestAsync(TContext context) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Hosting.Server.IServer +Microsoft.AspNetCore.Hosting.Server.IServer.Features.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection! +Microsoft.AspNetCore.Hosting.Server.IServer.StartAsync(Microsoft.AspNetCore.Hosting.Server.IHttpApplication! application, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Hosting.Server.IServer.StopAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +Microsoft.AspNetCore.Hosting.Server.IServerIntegratedAuth +Microsoft.AspNetCore.Hosting.Server.IServerIntegratedAuth.AuthenticationScheme.get -> string! +Microsoft.AspNetCore.Hosting.Server.IServerIntegratedAuth.IsEnabled.get -> bool +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth.AuthenticationScheme.get -> string! +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth.AuthenticationScheme.set -> void +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth.IsEnabled.get -> bool +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth.IsEnabled.set -> void +Microsoft.AspNetCore.Hosting.Server.ServerIntegratedAuth.ServerIntegratedAuth() -> void diff --git a/src/Hosting/Server.Abstractions/src/ServerIntegratedAuth.cs b/src/Hosting/Server.Abstractions/src/ServerIntegratedAuth.cs index 0ab301cfaf..547dff5c95 100644 --- a/src/Hosting/Server.Abstractions/src/ServerIntegratedAuth.cs +++ b/src/Hosting/Server.Abstractions/src/ServerIntegratedAuth.cs @@ -16,6 +16,6 @@ namespace Microsoft.AspNetCore.Hosting.Server /// /// The name of the authentication scheme for the server authentication handler. /// - public string? AuthenticationScheme { get; set; } + public string AuthenticationScheme { get; set; } = default!; } } diff --git a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj index b4465d4958..45f833b2f3 100644 --- a/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj +++ b/src/Hosting/TestHost/src/Microsoft.AspNetCore.TestHost.csproj @@ -13,4 +13,9 @@ + + + + + diff --git a/src/Hosting/TestHost/src/PublicAPI.Shipped.txt b/src/Hosting/TestHost/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Hosting/TestHost/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt b/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..b30f6d3f2f --- /dev/null +++ b/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt @@ -0,0 +1,52 @@ +#nullable enable +Microsoft.AspNetCore.TestHost.ClientHandler +Microsoft.AspNetCore.TestHost.HostBuilderTestServerExtensions +Microsoft.AspNetCore.TestHost.HttpResetTestException +Microsoft.AspNetCore.TestHost.HttpResetTestException.ErrorCode.get -> int +Microsoft.AspNetCore.TestHost.HttpResetTestException.HttpResetTestException(int errorCode) -> void +Microsoft.AspNetCore.TestHost.RequestBuilder +Microsoft.AspNetCore.TestHost.TestServer +Microsoft.AspNetCore.TestHost.TestServer.AllowSynchronousIO.get -> bool +Microsoft.AspNetCore.TestHost.TestServer.AllowSynchronousIO.set -> void +Microsoft.AspNetCore.TestHost.TestServer.Dispose() -> void +Microsoft.AspNetCore.TestHost.TestServer.PreserveExecutionContext.get -> bool +Microsoft.AspNetCore.TestHost.TestServer.PreserveExecutionContext.set -> void +Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions +Microsoft.AspNetCore.TestHost.WebHostBuilderFactory +Microsoft.AspNetCore.TestHost.WebSocketClient +~Microsoft.AspNetCore.TestHost.RequestBuilder.AddHeader(string name, string value) -> Microsoft.AspNetCore.TestHost.RequestBuilder +~Microsoft.AspNetCore.TestHost.RequestBuilder.And(System.Action configure) -> Microsoft.AspNetCore.TestHost.RequestBuilder +~Microsoft.AspNetCore.TestHost.RequestBuilder.GetAsync() -> System.Threading.Tasks.Task +~Microsoft.AspNetCore.TestHost.RequestBuilder.PostAsync() -> System.Threading.Tasks.Task +~Microsoft.AspNetCore.TestHost.RequestBuilder.RequestBuilder(Microsoft.AspNetCore.TestHost.TestServer server, string path) -> void +~Microsoft.AspNetCore.TestHost.RequestBuilder.SendAsync(string method) -> System.Threading.Tasks.Task +~Microsoft.AspNetCore.TestHost.RequestBuilder.TestServer.get -> Microsoft.AspNetCore.TestHost.TestServer +~Microsoft.AspNetCore.TestHost.TestServer.BaseAddress.get -> System.Uri +~Microsoft.AspNetCore.TestHost.TestServer.BaseAddress.set -> void +~Microsoft.AspNetCore.TestHost.TestServer.CreateClient() -> System.Net.Http.HttpClient +~Microsoft.AspNetCore.TestHost.TestServer.CreateHandler() -> System.Net.Http.HttpMessageHandler +~Microsoft.AspNetCore.TestHost.TestServer.CreateRequest(string path) -> Microsoft.AspNetCore.TestHost.RequestBuilder +~Microsoft.AspNetCore.TestHost.TestServer.CreateWebSocketClient() -> Microsoft.AspNetCore.TestHost.WebSocketClient +~Microsoft.AspNetCore.TestHost.TestServer.Features.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection +~Microsoft.AspNetCore.TestHost.TestServer.Host.get -> Microsoft.AspNetCore.Hosting.IWebHost +~Microsoft.AspNetCore.TestHost.TestServer.SendAsync(System.Action configureContext, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +~Microsoft.AspNetCore.TestHost.TestServer.Services.get -> System.IServiceProvider +~Microsoft.AspNetCore.TestHost.TestServer.TestServer(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) -> void +~Microsoft.AspNetCore.TestHost.TestServer.TestServer(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, Microsoft.AspNetCore.Http.Features.IFeatureCollection featureCollection) -> void +~Microsoft.AspNetCore.TestHost.TestServer.TestServer(System.IServiceProvider services) -> void +~Microsoft.AspNetCore.TestHost.TestServer.TestServer(System.IServiceProvider services, Microsoft.AspNetCore.Http.Features.IFeatureCollection featureCollection) -> void +~Microsoft.AspNetCore.TestHost.WebSocketClient.ConfigureRequest.get -> System.Action +~Microsoft.AspNetCore.TestHost.WebSocketClient.ConfigureRequest.set -> void +~Microsoft.AspNetCore.TestHost.WebSocketClient.ConnectAsync(System.Uri uri, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +~Microsoft.AspNetCore.TestHost.WebSocketClient.SubProtocols.get -> System.Collections.Generic.IList +~static Microsoft.AspNetCore.TestHost.HostBuilderTestServerExtensions.GetTestClient(this Microsoft.Extensions.Hosting.IHost host) -> System.Net.Http.HttpClient +~static Microsoft.AspNetCore.TestHost.HostBuilderTestServerExtensions.GetTestServer(this Microsoft.Extensions.Hosting.IHost host) -> Microsoft.AspNetCore.TestHost.TestServer +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.ConfigureTestContainer(this Microsoft.AspNetCore.Hosting.IWebHostBuilder webHostBuilder, System.Action servicesConfiguration) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.ConfigureTestServices(this Microsoft.AspNetCore.Hosting.IWebHostBuilder webHostBuilder, System.Action servicesConfiguration) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.GetTestClient(this Microsoft.AspNetCore.Hosting.IWebHost host) -> System.Net.Http.HttpClient +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.GetTestServer(this Microsoft.AspNetCore.Hosting.IWebHost host) -> Microsoft.AspNetCore.TestHost.TestServer +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseSolutionRelativeContentRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, string solutionRelativePath, string applicationBasePath, string solutionName = "*.sln") -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseSolutionRelativeContentRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, string solutionRelativePath, string solutionName = "*.sln") -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseTestServer(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderFactory.CreateFromAssemblyEntryPoint(System.Reflection.Assembly assembly, string[] args) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder +~static Microsoft.AspNetCore.TestHost.WebHostBuilderFactory.CreateFromTypesAssemblyEntryPoint(string[] args) -> Microsoft.AspNetCore.Hosting.IWebHostBuilder diff --git a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs index ab7db21c5c..cd69b38de5 100644 --- a/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs +++ b/src/Hosting/TestHost/src/WebHostBuilderExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net.Http; @@ -93,6 +94,7 @@ namespace Microsoft.AspNetCore.TestHost return webHostBuilder; } + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IWebHostBuilder UseSolutionRelativeContentRoot( this IWebHostBuilder builder, string solutionRelativePath, @@ -101,6 +103,7 @@ namespace Microsoft.AspNetCore.TestHost return builder.UseSolutionRelativeContentRoot(solutionRelativePath, AppContext.BaseDirectory, solutionName); } + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] public static IWebHostBuilder UseSolutionRelativeContentRoot( this IWebHostBuilder builder, string solutionRelativePath, diff --git a/src/Hosting/WindowsServices/src/PublicAPI.Shipped.txt b/src/Hosting/WindowsServices/src/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Hosting/WindowsServices/src/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Hosting/WindowsServices/src/PublicAPI.Unshipped.txt b/src/Hosting/WindowsServices/src/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..23bfa41f51 --- /dev/null +++ b/src/Hosting/WindowsServices/src/PublicAPI.Unshipped.txt @@ -0,0 +1,11 @@ +#nullable enable +Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService +Microsoft.AspNetCore.Hosting.WindowsServices.WebHostWindowsServiceExtensions +override sealed Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStop() -> void +virtual Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStarted() -> void +virtual Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStopped() -> void +virtual Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStopping() -> void +~Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.WebHostService(Microsoft.AspNetCore.Hosting.IWebHost host) -> void +~override sealed Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStart(string[] args) -> void +~static Microsoft.AspNetCore.Hosting.WindowsServices.WebHostWindowsServiceExtensions.RunAsService(this Microsoft.AspNetCore.Hosting.IWebHost host) -> void +~virtual Microsoft.AspNetCore.Hosting.WindowsServices.WebHostService.OnStarting(string[] args) -> void diff --git a/src/Http/Authentication.Abstractions/src/AuthenticateResult.cs b/src/Http/Authentication.Abstractions/src/AuthenticateResult.cs index f10b5b9392..5bb29e8589 100644 --- a/src/Http/Authentication.Abstractions/src/AuthenticateResult.cs +++ b/src/Http/Authentication.Abstractions/src/AuthenticateResult.cs @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Authentication /// /// The failure exception. /// The result. - public static AuthenticateResult Fail(Exception? failure) + public static AuthenticateResult Fail(Exception failure) { return new AuthenticateResult() { Failure = failure }; } @@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Authentication /// The failure exception. /// Additional state values for the authentication session. /// The result. - public static AuthenticateResult Fail(Exception? failure, AuthenticationProperties? properties) + public static AuthenticateResult Fail(Exception failure, AuthenticationProperties? properties) { return new AuthenticateResult() { Failure = failure, Properties = properties }; } @@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Authentication /// /// The failure message. /// The result. - public static AuthenticateResult Fail(string? failureMessage) + public static AuthenticateResult Fail(string failureMessage) => Fail(new Exception(failureMessage)); /// @@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Authentication /// The failure message. /// Additional state values for the authentication session. /// The result. - public static AuthenticateResult Fail(string? failureMessage, AuthenticationProperties? properties) + public static AuthenticateResult Fail(string failureMessage, AuthenticationProperties? properties) => Fail(new Exception(failureMessage), properties); } } diff --git a/src/Http/Authentication.Abstractions/src/AuthenticationOptions.cs b/src/Http/Authentication.Abstractions/src/AuthenticationOptions.cs index ca512b0c5f..d6648f90aa 100644 --- a/src/Http/Authentication.Abstractions/src/AuthenticationOptions.cs +++ b/src/Http/Authentication.Abstractions/src/AuthenticationOptions.cs @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Authentication /// The responsible for the scheme. /// The name of the scheme being added. /// The display name for the scheme. - public void AddScheme<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]THandler>(string name, string displayName) where THandler : IAuthenticationHandler + public void AddScheme<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]THandler>(string name, string? displayName) where THandler : IAuthenticationHandler => AddScheme(name, b => { b.DisplayName = displayName; diff --git a/src/Http/Authentication.Abstractions/src/AuthenticationToken.cs b/src/Http/Authentication.Abstractions/src/AuthenticationToken.cs index 88c5d337ea..f03a1c965f 100644 --- a/src/Http/Authentication.Abstractions/src/AuthenticationToken.cs +++ b/src/Http/Authentication.Abstractions/src/AuthenticationToken.cs @@ -12,11 +12,11 @@ namespace Microsoft.AspNetCore.Authentication /// /// Name. /// - public string? Name { get; set; } + public string Name { get; set; } = default!; /// /// Value. /// - public string? Value { get; set; } + public string Value { get; set; } = default!; } } diff --git a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj index 573821ef75..d6e93d7b02 100644 --- a/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj +++ b/src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj @@ -2,7 +2,7 @@ ASP.NET Core HTTP feature interface definitions. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true $(NoWarn);CS1591 @@ -14,7 +14,15 @@ - + + + + + + + + + diff --git a/src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj b/src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj index 44552938d5..d3e0be0991 100644 --- a/src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj +++ b/src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);$(DefaultNetCoreTargetFramework) enable diff --git a/src/Http/Http/src/StreamResponseBodyFeature.cs b/src/Http/Http/src/StreamResponseBodyFeature.cs index 717b5c08d2..7e7ccae17c 100644 --- a/src/Http/Http/src/StreamResponseBodyFeature.cs +++ b/src/Http/Http/src/StreamResponseBodyFeature.cs @@ -71,10 +71,11 @@ namespace Microsoft.AspNetCore.Http } /// - /// Not supported. + /// Opts out of write buffering for the response. /// public virtual void DisableBuffering() { + PriorFeature?.DisableBuffering(); } /// diff --git a/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs b/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs index a7624e0969..0e6c2a4ea9 100644 --- a/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs +++ b/src/Http/Http/test/Features/StreamResponseBodyFeatureTests.cs @@ -41,6 +41,22 @@ namespace Microsoft.AspNetCore.Http.Features //Assert Assert.Equal(1, streamResponseBodyFeature.StartCalled); } + + [Fact] + public void DisableBufferingCallsInnerFeature() + { + // Arrange + var stream = new MemoryStream(); + + var innerFeature = new InnerDisableBufferingFeature(stream, null); + var streamResponseBodyFeature = new StreamResponseBodyFeature(stream, innerFeature); + + // Act + streamResponseBodyFeature.DisableBuffering(); + + //Assert + Assert.True(innerFeature.DisableBufferingCalled); + } } public class TestStreamResponseBodyFeature : StreamResponseBodyFeature @@ -59,4 +75,19 @@ namespace Microsoft.AspNetCore.Http.Features public int StartCalled { get; private set; } } + + public class InnerDisableBufferingFeature : StreamResponseBodyFeature + { + public InnerDisableBufferingFeature(Stream stream, IHttpResponseBodyFeature priorFeature) + : base(stream, priorFeature) + { + } + + public override void DisableBuffering() + { + DisableBufferingCalled = true; + } + + public bool DisableBufferingCalled { get; set; } + } } diff --git a/src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj b/src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj index 0a760c3f29..95e8ae3a5e 100644 --- a/src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj +++ b/src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj @@ -2,7 +2,7 @@ ASP.NET Core metadata. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) true $(NoWarn);CS1591 true diff --git a/src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj b/src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj index 5f6681e261..adf0a1a68e 100644 --- a/src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj +++ b/src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj @@ -2,7 +2,7 @@ ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. ASP.NET Core Identity allows you to add login features to your application and makes it easy to customize data about the logged in user. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true true @@ -13,8 +13,10 @@ + - + + diff --git a/src/Identity/Extensions.Core/src/PasswordHasher.cs b/src/Identity/Extensions.Core/src/PasswordHasher.cs index 31703ac59b..9b8951f20d 100644 --- a/src/Identity/Extensions.Core/src/PasswordHasher.cs +++ b/src/Identity/Extensions.Core/src/PasswordHasher.cs @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Identity _rng = options.Rng; } -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 // Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized. [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static bool ByteArraysEqual(byte[] a, byte[] b) @@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Identity // Hash the incoming password and verify it byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength); -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 return ByteArraysEqual(actualSubkey, expectedSubkey); #elif NETCOREAPP return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey); @@ -283,7 +283,7 @@ namespace Microsoft.AspNetCore.Identity // Hash the incoming password and verify it byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength); -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 return ByteArraysEqual(actualSubkey, expectedSubkey); #elif NETCOREAPP return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey); diff --git a/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs b/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs index 9b2b98a392..3d1ab86933 100644 --- a/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs +++ b/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Identity { private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3); private static readonly Encoding _encoding = new UTF8Encoding(false, true); -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 private static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); #endif @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Identity public static byte[] GenerateRandomKey() { byte[] bytes = new byte[20]; -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 _rng.GetBytes(bytes); #else RandomNumberGenerator.Fill(bytes); @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Identity // More info: https://tools.ietf.org/html/rfc6238#section-4 private static ulong GetCurrentTimeStepNumber() { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 var delta = DateTime.UtcNow - _unixEpoch; #else var delta = DateTimeOffset.UtcNow - DateTimeOffset.UnixEpoch; diff --git a/src/Identity/Extensions.Core/src/UserManager.cs b/src/Identity/Extensions.Core/src/UserManager.cs index afecd4d235..8bf0cdfb48 100644 --- a/src/Identity/Extensions.Core/src/UserManager.cs +++ b/src/Identity/Extensions.Core/src/UserManager.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Identity private TimeSpan _defaultLockout = TimeSpan.Zero; private bool _disposed; -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); #endif private IServiceProvider _services; @@ -2430,7 +2430,7 @@ namespace Microsoft.AspNetCore.Identity private static string NewSecurityStamp() { byte[] bytes = new byte[20]; -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NET461 _rng.GetBytes(bytes); #else RandomNumberGenerator.Fill(bytes); diff --git a/src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj b/src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj index fd80d41fcd..367a0069f1 100644 --- a/src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj +++ b/src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj @@ -2,7 +2,7 @@ ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. ASP.NET Core Identity allows you to add login features to your application and makes it easy to customize data about the logged in user. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true true @@ -13,7 +13,6 @@ - diff --git a/src/Identity/Specification.Tests/src/Microsoft.AspNetCore.Identity.Specification.Tests.csproj b/src/Identity/Specification.Tests/src/Microsoft.AspNetCore.Identity.Specification.Tests.csproj index ab593d04a1..ba7e177bfb 100644 --- a/src/Identity/Specification.Tests/src/Microsoft.AspNetCore.Identity.Specification.Tests.csproj +++ b/src/Identity/Specification.Tests/src/Microsoft.AspNetCore.Identity.Specification.Tests.csproj @@ -20,8 +20,4 @@ - - - - diff --git a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj index fb2f0d6eaa..685ffe67b5 100644 --- a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj +++ b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj @@ -42,6 +42,11 @@ + + + + + diff --git a/src/Installers/Windows/SharedFrameworkLib/SharedFrameworkLib.wixproj b/src/Installers/Windows/SharedFrameworkLib/SharedFrameworkLib.wixproj index 3b693fdf16..83abf6036b 100644 --- a/src/Installers/Windows/SharedFrameworkLib/SharedFrameworkLib.wixproj +++ b/src/Installers/Windows/SharedFrameworkLib/SharedFrameworkLib.wixproj @@ -40,4 +40,23 @@ $(InternalInstallerBaseName)-$(PackageVersion)-win-$(Platform)$(TargetExt) + + + + + + + + + + diff --git a/src/Installers/Windows/Wix.props b/src/Installers/Windows/Wix.props index c9b7565fe8..b3ad64d7ad 100644 --- a/src/Installers/Windows/Wix.props +++ b/src/Installers/Windows/Wix.props @@ -28,4 +28,12 @@ $(RepoRoot)\src\Installers\Windows\GenerateNugetPackageWithMsi.ps1 + + + + $(ArtifactsObjDir)/WixCommandPackages + + $(ArtifactsNonShippingPackagesDir) + + diff --git a/src/Installers/Windows/Wix.targets b/src/Installers/Windows/Wix.targets index 17b41491fa..ec321d4c41 100644 --- a/src/Installers/Windows/Wix.targets +++ b/src/Installers/Windows/Wix.targets @@ -24,6 +24,18 @@ $(Version);$(Platform);$(VersionSuffix);$(_BuildNumberLabels) + + + + + + $(NuGetPackageRoot)microsoft.dotnet.build.tasks.installers\$(MicrosoftDotNetBuildTasksInstallersPackageVersion)\tools\netcoreapp2.0\Microsoft.DotNet.Build.Tasks.Installers.dll + $(NuGetPackageRoot)microsoft.dotnet.build.tasks.installers\$(MicrosoftDotNetBuildTasksInstallersPackageVersion)\tools\net472\Microsoft.DotNet.Build.Tasks.Installers.dll + + + + + @@ -72,4 +84,27 @@ + + + + + + + + + diff --git a/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntimeExtensions.cs b/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntimeExtensions.cs index 5a040d9b78..fa55d37c1b 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntimeExtensions.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntimeExtensions.cs @@ -16,7 +16,7 @@ namespace Microsoft.JSInterop /// The . /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. /// JSON-serializable arguments. - public static void InvokeVoid(this IJSInProcessRuntime jsRuntime, string identifier, params object[] args) + public static void InvokeVoid(this IJSInProcessRuntime jsRuntime, string identifier, params object?[] args) { if (jsRuntime == null) { diff --git a/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs b/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs index 382e842df8..7e69eb3d21 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs +++ b/src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs @@ -110,7 +110,7 @@ namespace Microsoft.JSInterop object?[]? args) { var taskId = Interlocked.Increment(ref _nextPendingTaskId); - var tcs = new TaskCompletionSource(TaskContinuationOptions.RunContinuationsAsynchronously); + var tcs = new TaskCompletionSource(); if (cancellationToken != default) { _cancellationRegistrations[taskId] = cancellationToken.Register(() => diff --git a/src/Localization/Abstractions/src/Microsoft.Extensions.Localization.Abstractions.csproj b/src/Localization/Abstractions/src/Microsoft.Extensions.Localization.Abstractions.csproj index b97304edf8..d1d954caa3 100644 --- a/src/Localization/Abstractions/src/Microsoft.Extensions.Localization.Abstractions.csproj +++ b/src/Localization/Abstractions/src/Microsoft.Extensions.Localization.Abstractions.csproj @@ -6,7 +6,7 @@ Commonly used types: Microsoft.Extensions.Localization.IStringLocalizer Microsoft.Extensions.Localization.IStringLocalizer<T> - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true diff --git a/src/Localization/Localization/src/Microsoft.Extensions.Localization.csproj b/src/Localization/Localization/src/Microsoft.Extensions.Localization.csproj index d9275db659..1f42ed3827 100644 --- a/src/Localization/Localization/src/Microsoft.Extensions.Localization.csproj +++ b/src/Localization/Localization/src/Microsoft.Extensions.Localization.csproj @@ -3,7 +3,7 @@ Microsoft .NET Extensions Application localization services and default implementation based on ResourceManager to load localized assembly resources. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true diff --git a/src/Localization/Localization/test/Microsoft.Extensions.Localization.RootNamespace.Tests/Microsoft.Extensions.Localization.RootNamespace.Tests.csproj b/src/Localization/Localization/test/Microsoft.Extensions.Localization.RootNamespace.Tests/Microsoft.Extensions.Localization.RootNamespace.Tests.csproj index 29d2e8f504..793627e683 100644 --- a/src/Localization/Localization/test/Microsoft.Extensions.Localization.RootNamespace.Tests/Microsoft.Extensions.Localization.RootNamespace.Tests.csproj +++ b/src/Localization/Localization/test/Microsoft.Extensions.Localization.RootNamespace.Tests/Microsoft.Extensions.Localization.RootNamespace.Tests.csproj @@ -1,6 +1,6 @@ - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) LocalizationTest.Abc enable diff --git a/src/Localization/Localization/test/Microsoft.Extensions.Localization.Tests/Microsoft.Extensions.Localization.Tests.csproj b/src/Localization/Localization/test/Microsoft.Extensions.Localization.Tests/Microsoft.Extensions.Localization.Tests.csproj index 508310f142..f0b96ae1f3 100644 --- a/src/Localization/Localization/test/Microsoft.Extensions.Localization.Tests/Microsoft.Extensions.Localization.Tests.csproj +++ b/src/Localization/Localization/test/Microsoft.Extensions.Localization.Tests/Microsoft.Extensions.Localization.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) enable diff --git a/src/Logging.AzureAppServices/src/Microsoft.Extensions.Logging.AzureAppServices.csproj b/src/Logging.AzureAppServices/src/Microsoft.Extensions.Logging.AzureAppServices.csproj index 2a25b5b2c3..ab036f72f2 100644 --- a/src/Logging.AzureAppServices/src/Microsoft.Extensions.Logging.AzureAppServices.csproj +++ b/src/Logging.AzureAppServices/src/Microsoft.Extensions.Logging.AzureAppServices.csproj @@ -2,7 +2,7 @@ Logger implementation to support Azure App Services 'Diagnostics logs' and 'Log stream' features. - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 $(NoWarn);CS1591 true @@ -20,4 +20,8 @@ + + + + diff --git a/src/Logging.AzureAppServices/test/Microsoft.Extensions.Logging.AzureAppServices.Tests.csproj b/src/Logging.AzureAppServices/test/Microsoft.Extensions.Logging.AzureAppServices.Tests.csproj index 7365c79076..fde35d5fa2 100644 --- a/src/Logging.AzureAppServices/test/Microsoft.Extensions.Logging.AzureAppServices.Tests.csproj +++ b/src/Logging.AzureAppServices/test/Microsoft.Extensions.Logging.AzureAppServices.Tests.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) diff --git a/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseDeveloperPageExceptionFilter.cs b/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseDeveloperPageExceptionFilter.cs index 3ba74bc18f..447124077e 100644 --- a/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseDeveloperPageExceptionFilter.cs +++ b/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseDeveloperPageExceptionFilter.cs @@ -38,7 +38,8 @@ namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore { // Look for DbContext classes registered in the service provider var registeredContexts = errorContext.HttpContext.RequestServices.GetServices() - .Select(o => o.ContextType); + .Select(o => o.ContextType) + .Distinct(); // Workaround for https://github.com/dotnet/efcore/issues/22341 if (registeredContexts.Any()) { diff --git a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs index 52dec57e34..1b8df0af53 100644 --- a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs +++ b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs @@ -145,15 +145,14 @@ namespace Microsoft.AspNetCore.Diagnostics try { await next(); - - response.Body = originalResponseBody; - bufferingStream.Seek(0, SeekOrigin.Begin); - await bufferingStream.CopyToAsync(response.Body); } finally { response.Body = originalResponseBody; } + + bufferingStream.Seek(0, SeekOrigin.Begin); + await bufferingStream.CopyToAsync(response.Body); }); app.UseExceptionHandler("/handle-errors"); diff --git a/src/Middleware/NodeServices/README.md b/src/Middleware/NodeServices/README.md deleted file mode 100644 index 8f9b072899..0000000000 --- a/src/Middleware/NodeServices/README.md +++ /dev/null @@ -1,340 +0,0 @@ -# Microsoft.AspNetCore.NodeServices - -This NuGet package provides a fast and robust way to invoke Node.js code from a .NET application (typically ASP.NET Core web apps). You can use this whenever you want to use Node/NPM-supplied functionality at runtime in ASP.NET. For example, - - * Executing arbitrary JavaScript - * Runtime integration with JavaScript build or packaging tools, e.g., transpiling code via Babel - * Using of NPM modules for image resizing, audio compression, language recognition, etc. - * Calling third-party services that supply Node-based APIs but don't yet ship native .NET ones - -It is the underlying mechanism supporting the following packages: - - * [`Microsoft.AspNetCore.SpaServices`](/src/Middleware/SpaServices/) - builds on NodeServices, adding functionality commonly used in Single Page Applications, such as server-side prerendering, webpack middleware, and integration between server-side and client-side routing. - -### Requirements - -* [Node.js](https://nodejs.org/en/) - * To test this is installed and can be found, run `node -v` on a command line - * Note: If you're deploying to an Azure web site, you don't need to do anything here - Node is already installed and available in the server environments -* [.NET](https://dot.net) - * For .NET Core (e.g., ASP.NET Core apps), you need at least 1.0 RC2 - * For .NET Framework, you need at least version 4.5.1. - -### Installation - -For .NET Core apps: - - * Add `Microsoft.AspNetCore.NodeServices` to the dependencies list in your `project.json` file - * Run `dotnet restore` (or if you use Visual Studio, just wait a moment - it will restore dependencies automatically) - -For .NET Framework apps: - - * `nuget install Microsoft.AspNetCore.NodeServices` - -### Do you just want to build an ASP.NET Core app with Angular / React / Knockout / etc.? - -In that case, you don't need to use NodeServices directly (or install it manually). You can either: - -* **Recommended:** Use the `aspnetcore-spa` Yeoman generator to get a ready-to-go starting point using your choice of client-side framework. [Instructions here.](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/) -* Or set up your ASP.NET Core and client-side Angular/React/KO/etc. app manually, and then use the [`Microsoft.AspNetCore.SpaServices`](/src/Middleware/SpaServices/) package to add features like server-side prerendering or Webpack middleware. But really, at least try using the `aspnetcore-spa` generator first. - -# Simple usage example - -## For ASP.NET Core apps - -.NET Core has a built-in dependency injection (DI) system. NodeServices is designed to work with this, so you don't have to manage the creation or disposal of instances. - -Enable NodeServices in your application by first adding the following to your `ConfigureServices` method in `Startup.cs`: - -```csharp -public void ConfigureServices(IServiceCollection services) -{ - // ... all your existing configuration is here ... - - // Enable Node Services - services.AddNodeServices(); -} -``` - -Now you can receive an instance of `NodeServices` as an action method parameter to any MVC action, and then use it to make calls into Node.js code, e.g.: - -```csharp -public async Task MyAction([FromServices] INodeServices nodeServices) -{ - var result = await nodeServices.InvokeAsync("./addNumbers", 1, 2); - return Content("1 + 2 = " + result); -} -``` - -Of course, you also need to supply the Node.js code you want to invoke. Create a file called `addNumbers.js` at the root of your ASP.NET Core application, and add the following code: - -```javascript -module.exports = function (callback, first, second) { - var result = first + second; - callback(/* error */ null, result); -}; -``` - -As you can see, the exported JavaScript function will receive the arguments you pass from .NET (as long as they are JSON-serializable), along with a Node-style callback you can use to send back a result or error when you are ready. - -When the `InvokeAsync` method receives the result back from Node, the result will be JSON-deserialized to whatever generic type you specified when calling `InvokeAsync` (e.g., above, that type is `int`). If `InvokeAsync` receives an error from your Node code, it will throw an exception describing that error. - -If you want to put `addNumber.js` inside a subfolder rather than the root of your app, then also amend the path in the `_nodeServices.Invoke` call to match that path. - -## For non-ASP.NET apps - -In other types of .NET Core app, where you don't have ASP.NET supplying an `IServiceCollection` to you, you'll need to instantiate your own DI container. For example, add a reference to the .NET package `Microsoft.Extensions.DependencyInjection`, and then you can construct an `IServiceCollection`, then register NodeServices as usual: - -```csharp -var services = new ServiceCollection(); -services.AddNodeServices(options => { - // Set any properties that you want on 'options' here -}); -``` - -Now you can ask it to supply the shared `INodeServices` instance: - -```csharp -var serviceProvider = services.BuildServiceProvider(); -var nodeServices = serviceProvider.GetRequiredService(); -``` - -Or, if you want to obtain a separate (non-shared) `INodeServices` instance: - -```csharp -var options = new NodeServicesOptions(serviceProvider) { /* Assign/override any other options here */ }; -var nodeServices = NodeServicesFactory.CreateNodeServices(options); -``` - -Besides this, the usage is the same as described for ASP.NET above, so you can now call `nodeServices.InvokeAsync(...)` etc. - -You can dispose the `nodeServices` object whenever you are done with it (and it will shut down the associated Node.js instance), but because these instances are expensive to create, you should whenever possible retain and reuse instances. Don't dispose the shared instance returned from `serviceProvider.GetRequiredService` (except perhaps if you know your application is shutting down, although .NET's finalizers will dispose it anyway if the shutdown is graceful). - -NodeServices instances are thread-safe - you can call `InvokeAsync` simultaneously from multiple threads. Also, they are smart enough to detect if the associated Node instance has died and will automatically start a new Node instance if needed. - -# API Reference - -### AddNodeServices - -**Signatures:** - -```csharp -AddNodeServices() -AddNodeServices(Action setupAction) -``` - -This is an extension method on `IServiceCollection`. It registers NodeServices with ASP.NET Core's DI system. Typically you should call this from the `ConfigureServices` method in your `Startup.cs` file. - -To access this extension method, you'll need to add the following namespace import to the top of your file, if it isn't already there: - -```csharp -using Microsoft.Extensions.DependencyInjection; -``` - -**Examples** - -Using default options: - -```csharp -services.AddNodeServices(); -``` - -Or, specifying options: - -```csharp -services.AddNodeServices(options => -{ - options.WatchFileExtensions = new[] { ".coffee", ".sass" }; - // ... etc. - see other properties below -}); -``` - -**Parameters** - - * `setupAction` - type: `Action` - * Optional. If not specified, defaults will be used. - * Properties on `NodeServicesOptions`: - * `HostingModel` - an `NodeHostingModel` enum value. See: [hosting models](#hosting-models) - * `ProjectPath` - if specified, controls the working directory used when launching Node instances. This affects, for example, the location that `require` statements resolve relative paths against. If not specified, your application root directory is used. - * `WatchFileExtensions` - if specified, the launched Node instance will watch for changes to any files with these extensions, and auto-restarts when any are changed. The default array includes `.js`, `.jsx`, `.ts`, `.tsx`, `.json`, and `.html`. - -**Return type**: None. But once you've done this, you can get `NodeServices` instances out of ASP.NET's DI system. Typically it will be a singleton instance. - -### CreateNodeServices - -**Signature:** - -```csharp -CreateNodeServices(NodeServicesOptions options) -``` - -Supplies a new (non-shared) instance of `NodeServices`. - -**Example** - -```csharp -var options = new NodeServicesOptions(serviceProvider); // Obtains default options from DI config -var nodeServices = NodeServicesFactory.CreateNodeServices(options); -``` - -**Parameters** - * `options` - type: `NodeServicesOptions`. - * Configures the returned `NodeServices` instance. - * Properties: - * `HostingModel` - an `NodeHostingModel` enum value. See: [hosting models](#hosting-models) - * `ProjectPath` - if specified, controls the working directory used when launching Node instances. This affects, for example, the location that `require` statements resolve relative paths against. If not specified, your application root directory is used. - * `WatchFileExtensions` - if specified, the launched Node instance will watch for changes to any files with these extension, and auto-restarts when any are changed. - -**Return type:** `NodeServices` - -If you create a `NodeServices` instance this way, you can also dispose it (call `nodeServiceInstance.Dispose();`) and it will shut down the associated Node instance. But because these instances are expensive to create, you should whenever possible retain and reuse your `NodeServices` object. They are thread-safe - you can call `nodeServiceInstance.InvokeAsync(...)` simultaneously from multiple threads. - -### InvokeAsync<T> - -**Signature:** - -```csharp -InvokeAsync(string moduleName, params object[] args) -``` - -Asynchronously calls a JavaScript function and returns the result, or throws an exception if the result was an error. - -**Example 1: Getting a JSON-serializable object from Node (the most common use case)** - -```csharp -var result = await myNodeServicesInstance.InvokeAsync( - "./Node/transpile", - pathOfSomeFileToBeTranspiled); -``` - -... where `TranspilerResult` might be defined as follows: - -```csharp -public class TranspilerResult -{ - public string Code { get; set; } - public string[] Warnings { get; set; } -} -``` - -... and the corresponding JavaScript module (in `Node/transpile.js`) could be implemented as follows: - -```javascript -module.exports = function (callback, filePath) { - // Invoke some external transpiler (e.g., an NPM module) then: - callback(null, { - code: theTranspiledCodeAsAString, - warnings: someArrayOfStrings - }); -}; -``` - -**Example 2: Getting a stream of binary data from Node** - -```csharp -var imageStream = await myNodeServicesInstance.InvokeAsync( - "./Node/resizeImage", - fullImagePath, - width, - height); - -// In an MVC action method, you can pipe the result to the response as follows -return File(imageStream, someContentType); -``` - -... where the corresponding JavaScript module (in `Node/resizeImage.js`) could be implemented as follows: - -```javascript -var sharp = require('sharp'); // A popular image manipulation package on NPM - -module.exports = function(result, physicalPath, maxWidth, maxHeight) { - // Invoke the 'sharp' NPM module, and have it pipe the resulting image data back to .NET - sharp(physicalPath) - .resize(maxWidth || null, maxHeight || null) - .pipe(result.stream); -} -``` - -**Parameters** - -* `moduleName` - type: `string` - * The name of a JavaScript module that Node.js must be able to resolve by calling `require(moduleName)`. This can be a relative path such as `"./Some/Directory/mymodule"`. If you don't specify the `.js` filename extension, Node.js will infer it anyway. -* `params` - * Any set of JSON-serializable objects you want to pass to the exported JavaScript function - -**Return type:** `T`, which must be: - - * A JSON-serializable .NET type, if your JavaScript code uses the `callback(error, result)` pattern to return an object, as in example 1 above - * Or, the type `System.IO.Stream`, if your JavaScript code writes data to the `result.stream` object (which is a [Node `Duplex` stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex)), as in example 2 above - -### InvokeExportAsync<T> - -**Signature** - -```csharp -InvokeExportAsync(string moduleName, string exportName, params object[] args) -``` - -This is exactly the same as `InvokeAsync`, except that it also takes an `exportName` parameter. You can use this if you want your JavaScript module to export more than one function. - -**Example** - -```csharp -var someString = await myNodeServicesInstance.InvokeExportAsync( - "./Node/myNodeApis", - "getMeAString"); - -var someStringInFrench = await myNodeServicesInstance.InvokeExportAsync( - "./Node/myNodeApis", - "convertLanguage" - someString, - "fr-FR"); -``` - -... where the corresponding JavaScript module (in `Node/myNodeApis.js`) could be implemented as follows: - -```javascript -module.exports = { - - getMeAString: function (callback) { - callback(null, 'Here is a string'); - }, - - convertLanguage: function (callback, sourceString, targetLanguage) { - // Implementation detail left as an exercise for the reader - doMachineTranslation(sourceString, targetLanguage, function(error, result) { - callback(error, result); - }); - } - -}; -``` - -**Parameters, return type, etc.** For all other details, see the docs for [`InvokeAsync`](#invokeasynct) - -## Hosting models - -NodeServices has a pluggable hosting/transport mechanism, because it is an abstraction over various possible ways to invoke Node.js from .NET. This allows more high-level facilities (e.g., for Angular prerendering) to be agnostic to the details of launching Node and communicating with it - those high-level facilities can just trust that *somehow* we can invoke code in Node for them. - -Using this abstraction, we could run Node inside the .NET process, in a separate process on the same machine, or even on a different machine altogether. At the time of writing, all the built-in hosting mechanisms work by launching Node as a separate process on the same machine as your .NET code. - -**What about Edge.js?** - -[Edge.js](http://tjanczuk.github.io/edge/#/) hosts Node.js inside a .NET process, or vice-versa, and lets you interoperate between the two. - -NodeServices is not meant to compete with Edge.js. Instead, NodeServices is an abstraction over all possible ways to invoke Node from .NET. Eventually we may offer an in-process Node hosting mechanism via Edge.js, without you needing to change your higher-level code. This can be done when Edge.js supports hosting Node in cross-platform .NET Core processes ([discussion](https://github.com/tjanczuk/edge/issues/279)). - -**What about VroomJS?** - -People have asked about using [VroomJS](https://github.com/fogzot/vroomjs) as a hosting mechanism. We don't currently plan to implement that, because Vroom only supplies a V8 runtime environment, not a complete Node environment. The difference is that, with a true Node environment, *all* NPM modules and Node code will work exactly as expected, whereas in a Vroom environment, code will only work if it doesn't use any Node primitives, which rules out large portions of the NPM landscape. - -### Custom hosting models - -If you implement a custom hosting model (by implementing `INodeInstance`), then you can cause it to be used by populating `NodeInstanceFactory` on your options: - -```csharp -services.AddNodeServices(options => -{ - options.NodeInstanceFactory = () => new MyCustomNodeInstance(); -}); -``` diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Controllers/HomeController.cs b/src/Middleware/NodeServices/samples/NodeServicesExamples/Controllers/HomeController.cs deleted file mode 100644 index b6cf86a9bd..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Controllers/HomeController.cs +++ /dev/null @@ -1,47 +0,0 @@ -// 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.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.NodeServices; - -namespace NodeServicesExamples.Controllers -{ - public class HomeController : Controller - { - public IActionResult Index(int pageIndex) - { - return View(); - } - - public IActionResult ES2015Transpilation() - { - return View(); - } - -#pragma warning disable 0618 - public async Task Chart([FromServices] INodeServices nodeServices) -#pragma warning restore 0618 - { - var options = new { width = 400, height = 200, showArea = true, showPoint = true, fullWidth = true }; - var data = new - { - labels = new[] { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, - series = new[] { - new[] { 1, 5, 2, 5, 4, 3 }, - new[] { 2, 3, 4, 8, 1, 2 }, - new[] { 5, 4, 3, 2, 1, 0 } - } - }; - - ViewData["ChartMarkup"] = await nodeServices.InvokeAsync("./Node/renderChart", "line", options, data); - - return View(); - } - - public IActionResult Error() - { - return View("~/Views/Shared/Error.cshtml"); - } - } -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/prerenderPage.js b/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/prerenderPage.js deleted file mode 100644 index 7912a6f3cb..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/prerenderPage.js +++ /dev/null @@ -1,14 +0,0 @@ -var createServerRenderer = require('aspnet-prerendering').createServerRenderer; - -module.exports = createServerRenderer(function(params) { - return new Promise(function (resolve, reject) { - var message = 'The HTML was returned by the prerendering boot function. ' - + 'The boot function received the following params:' - + '
' + JSON.stringify(params, null, 4) + '
'; - - resolve({ - html: '

Hello, world!

' + message, - globals: { sampleData: { nodeVersion: process.version } } - }); - }); -}); diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/renderChart.js b/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/renderChart.js deleted file mode 100644 index 370df76654..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/renderChart.js +++ /dev/null @@ -1,8 +0,0 @@ -var generate = require('node-chartist'); - -module.exports = function (callback, type, options, data) { - generate(type, options, data).then( - result => callback(null, result), // Success case - error => callback(error) // Error case - ); -}; diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/transpilation.js b/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/transpilation.js deleted file mode 100644 index 86f605ac94..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Node/transpilation.js +++ /dev/null @@ -1,12 +0,0 @@ -var fs = require('fs'); -var babelCore = require('babel-core'); - -module.exports = function(cb, physicalPath, requestPath) { - var originalContents = fs.readFileSync(physicalPath); - var result = babelCore.transform(originalContents, { - presets: ['es2015'], - sourceMaps: 'inline', - sourceFileName: '/sourcemapped' + requestPath - }); - cb(null, result.code); -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/NodeServicesExamples.csproj b/src/Middleware/NodeServices/samples/NodeServicesExamples/NodeServicesExamples.csproj deleted file mode 100644 index 262b569d43..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/NodeServicesExamples.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - true - - - - - - - - - - - - - - - - - - - diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Properties/launchSettings.json b/src/Middleware/NodeServices/samples/NodeServicesExamples/Properties/launchSettings.json deleted file mode 100644 index f2904dc8ae..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Properties/launchSettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:51463/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "dotnet cli": { - "commandName": "Project", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Startup.cs b/src/Middleware/NodeServices/samples/NodeServicesExamples/Startup.cs deleted file mode 100644 index 44e7411132..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Startup.cs +++ /dev/null @@ -1,83 +0,0 @@ -// 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 System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.NodeServices; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace NodeServicesExamples -{ - public class Startup - { -#pragma warning disable 0618 - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc(); - - // Enable Node Services - services.AddNodeServices(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, INodeServices nodeServices) - { - app.UseDeveloperExceptionPage(); - - // Dynamically transpile any .js files under the '/js/' directory - app.Use(next => async context => - { - var requestPath = context.Request.Path.Value; - if (requestPath.StartsWith("/js/") && requestPath.EndsWith(".js")) - { - var fileInfo = env.WebRootFileProvider.GetFileInfo(requestPath); - if (fileInfo.Exists) - { - var transpiled = await nodeServices.InvokeAsync("./Node/transpilation.js", fileInfo.PhysicalPath, requestPath); - await context.Response.WriteAsync(transpiled); - return; - } - } - - // Not a JS file, or doesn't exist - let some other middleware handle it - await next.Invoke(context); - }); - - app.UseStaticFiles(); - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - endpoints.MapDefaultControllerRoute(); - }); - } -#pragma warning restore 0618 - - public static Task Main(string[] args) - { - var host = new HostBuilder() - .ConfigureWebHost(webHostBuilder => - { - webHostBuilder - .ConfigureLogging(factory => - { - factory.AddConsole(); - factory.AddDebug(); - }) - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup(); - }).Build(); - - return host.RunAsync(); - } - } -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Chart.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Chart.cshtml deleted file mode 100644 index 6aed4a5664..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Chart.cshtml +++ /dev/null @@ -1,12 +0,0 @@ -

Server-rendered chart

- -

- This sample demonstrates how arbitrary NPM modules can be invoked from .NET code. -

-

- In this case, we use node-chartist to render the following chart on the server. The output is - identical to what you'd get if you used chartist.js - on the client, except that in this example, we're not executing any client-side code at all. -

- -@Html.Raw(ViewData["ChartMarkup"]) diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/ES2015Transpilation.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/ES2015Transpilation.cshtml deleted file mode 100644 index 2e28cf67a0..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/ES2015Transpilation.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -

ES2015 Transpilation

- -

- This sample demonstrates a way of intercepting requests for .js files and dynamically transpiling them - from ES2015 code to browser-compatible ES5 code using the Babel library. -

- -

- To see that it's working, open your browser's 'Debug' console and look for the log message. This is - produced by the file /js/main.js, which is transpiled from ES2015 dynamically - when requested. -

- -@section scripts { - -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Index.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Index.cshtml deleted file mode 100644 index a89900803f..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Index.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -

NodeServices examples

- -

- These examples demonstrate the direct use of the NodeServices package, independently of the usual SPA scenarios. - In general, NodeServices offers an efficient way to use Node-provided functionality (e.g., NPM modules) from inside - a .NET application. -

- - diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Prerendering.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Prerendering.cshtml deleted file mode 100644 index 3f21ef722a..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Home/Prerendering.cshtml +++ /dev/null @@ -1,21 +0,0 @@ -

Server-side prerendering

- -

- This sample demonstrates how you can invoke a JavaScript module that contains - prerendering logic for a Single-Page Application framework. -

-

- Your prerendering boot function will receive parameters that describe the page - being rendered and any data supplied by the .NET code. The return value should be - a promise that resolves with data to be injected into the page, such as the - rendered HTML and any global data that should be made available to client-side code. -

- -@Html.Raw(ViewData["PrerenderedHtml"]) - - - - diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/Error.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/Error.cshtml deleted file mode 100644 index 4852442680..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/Error.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@{ - ViewData["Title"] = "Error"; -} - -

Error.

-

An error occurred while processing your request.

diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/_Layout.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/_Layout.cshtml deleted file mode 100644 index 93314312ad..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - NodeServices Examples - - - - @RenderBody() - @RenderSection("scripts", required: false) - - diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewImports.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewImports.cshtml deleted file mode 100644 index 3d98e6eaca..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewImports.cshtml +++ /dev/null @@ -1,2 +0,0 @@ -@using NodeServicesExamples -@addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewStart.cshtml b/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewStart.cshtml deleted file mode 100644 index a5f10045db..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/appsettings.json b/src/Middleware/NodeServices/samples/NodeServicesExamples/appsettings.json deleted file mode 100644 index 0967ef424b..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/appsettings.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/jsconfig.json b/src/Middleware/NodeServices/samples/NodeServicesExamples/jsconfig.json deleted file mode 100644 index 875bb90cd6..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/jsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "target": "ES6", - "module": "commonjs" - } -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/package.json b/src/Middleware/NodeServices/samples/NodeServicesExamples/package.json deleted file mode 100644 index 9787758bc4..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "nodeservicesexamples", - "version": "0.0.0", - "dependencies": { - "aspnet-prerendering": "^2.0.6", - "babel-core": "^6.7.4", - "babel-preset-es2015": "^6.6.0", - "node-chartist": "^1.0.2" - } -} diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/css/chartist.min.css b/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/css/chartist.min.css deleted file mode 100644 index 9f9b908e71..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/css/chartist.min.css +++ /dev/null @@ -1 +0,0 @@ -.ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-grid-background,.ct-line{fill:none}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0} \ No newline at end of file diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/favicon.ico b/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/favicon.ico deleted file mode 100644 index a3a799985c..0000000000 Binary files a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/favicon.ico and /dev/null differ diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/js/main.js b/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/js/main.js deleted file mode 100644 index 97780c1ce9..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/js/main.js +++ /dev/null @@ -1,7 +0,0 @@ -class Greeting { - getMessage() { - return 'Hello from the ES2015 class'; - } -} - -console.log(new Greeting().getMessage()); diff --git a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/web.config b/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/web.config deleted file mode 100644 index bb50c71648..0000000000 --- a/src/Middleware/NodeServices/samples/NodeServicesExamples/wwwroot/web.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/Middleware/NodeServices/src/Configuration/NodeServicesFactory.cs b/src/Middleware/NodeServices/src/Configuration/NodeServicesFactory.cs deleted file mode 100644 index 06968643bd..0000000000 --- a/src/Middleware/NodeServices/src/Configuration/NodeServicesFactory.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Supplies INodeServices instances. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class NodeServicesFactory - { - /// - /// Create an instance according to the supplied options. - /// - /// Options for creating the instance. - /// An instance. - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static INodeServices CreateNodeServices(NodeServicesOptions options) - { - if (options == null) - { - throw new ArgumentNullException(nameof (options)); - } - - return new NodeServicesImpl(options.NodeInstanceFactory); - } - } -} diff --git a/src/Middleware/NodeServices/src/Configuration/NodeServicesOptions.cs b/src/Middleware/NodeServices/src/Configuration/NodeServicesOptions.cs deleted file mode 100644 index a7aac6eba4..0000000000 --- a/src/Middleware/NodeServices/src/Configuration/NodeServicesOptions.cs +++ /dev/null @@ -1,118 +0,0 @@ -// 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.Collections.Generic; -using System.IO; -using System.Threading; -using Microsoft.AspNetCore.NodeServices.HostingModels; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Hosting; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Describes options used to configure an instance. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class NodeServicesOptions - { - internal const string TimeoutConfigPropertyName = nameof(InvocationTimeoutMilliseconds); - private const int DefaultInvocationTimeoutMilliseconds = 60 * 1000; - private const string LogCategoryName = "Microsoft.AspNetCore.NodeServices"; - private static readonly string[] DefaultWatchFileExtensions = { ".js", ".jsx", ".ts", ".tsx", ".json", ".html" }; - - /// - /// Creates a new instance of . - /// - /// The . - public NodeServicesOptions(IServiceProvider serviceProvider) - { - if (serviceProvider == null) - { - throw new ArgumentNullException(nameof (serviceProvider)); - } - - EnvironmentVariables = new Dictionary(); - InvocationTimeoutMilliseconds = DefaultInvocationTimeoutMilliseconds; - WatchFileExtensions = (string[])DefaultWatchFileExtensions.Clone(); - - var hostEnv = serviceProvider.GetService(); - if (hostEnv != null) - { - // In an ASP.NET environment, we can use the IHostingEnvironment data to auto-populate a few - // things that you'd otherwise have to specify manually - ProjectPath = hostEnv.ContentRootPath; - EnvironmentVariables["NODE_ENV"] = hostEnv.IsDevelopment() ? "development" : "production"; // De-facto standard values for Node - } - else - { - ProjectPath = Directory.GetCurrentDirectory(); - } - - var applicationLifetime = serviceProvider.GetService(); - if (applicationLifetime != null) - { - ApplicationStoppingToken = applicationLifetime.ApplicationStopping; - } - - // If the DI system gives us a logger, use it. Otherwise, set up a default one. - var loggerFactory = serviceProvider.GetService(); - NodeInstanceOutputLogger = loggerFactory != null - ? loggerFactory.CreateLogger(LogCategoryName) - : NullLogger.Instance; - // By default, we use this package's built-in out-of-process-via-HTTP hosting/transport - this.UseHttpHosting(); - } - - /// - /// Specifies how to construct Node.js instances. An encapsulates all details about - /// how Node.js instances are launched and communicated with. A new will be created - /// automatically if the previous instance has terminated (e.g., because a source file changed). - /// - public Func NodeInstanceFactory { get; set; } - - /// - /// If set, overrides the path to the root of your application. This path is used when locating Node.js modules relative to your project. - /// - public string ProjectPath { get; set; } - - /// - /// If set, the Node.js instance should restart when any matching file on disk within your project changes. - /// - public string[] WatchFileExtensions { get; set; } - - /// - /// The Node.js instance's stdout/stderr will be redirected to this . - /// - public ILogger NodeInstanceOutputLogger { get; set; } - - /// - /// If true, the Node.js instance will accept incoming V8 debugger connections (e.g., from node-inspector). - /// - public bool LaunchWithDebugging { get; set; } - - /// - /// If is true, the Node.js instance will listen for V8 debugger connections on this port. - /// - public int DebuggingPort { get; set; } - - /// - /// If set, starts the Node.js instance with the specified environment variables. - /// - public IDictionary EnvironmentVariables { get; set; } - - /// - /// Specifies the maximum duration, in milliseconds, that your .NET code should wait for Node.js RPC calls to return. - /// - public int InvocationTimeoutMilliseconds { get; set; } - - /// - /// A token that indicates when the host application is stopping. - /// - public CancellationToken ApplicationStoppingToken { get; set; } - } -} diff --git a/src/Middleware/NodeServices/src/Configuration/NodeServicesServiceCollectionExtensions.cs b/src/Middleware/NodeServices/src/Configuration/NodeServicesServiceCollectionExtensions.cs deleted file mode 100644 index 1d793671b8..0000000000 --- a/src/Middleware/NodeServices/src/Configuration/NodeServicesServiceCollectionExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 Microsoft.AspNetCore.NodeServices; - -namespace Microsoft.Extensions.DependencyInjection -{ - /// - /// Extension methods for setting up NodeServices in an . - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class NodeServicesServiceCollectionExtensions - { - /// - /// Adds NodeServices support to the . - /// - /// The . - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static void AddNodeServices(this IServiceCollection serviceCollection) - => AddNodeServices(serviceCollection, _ => {}); - - /// - /// Adds NodeServices support to the . - /// - /// The . - /// A callback that will be invoked to populate the . - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static void AddNodeServices(this IServiceCollection serviceCollection, Action setupAction) - { - if (setupAction == null) - { - throw new ArgumentNullException(nameof (setupAction)); - } - - serviceCollection.AddSingleton(typeof(INodeServices), serviceProvider => - { - // First we let NodeServicesOptions take its defaults from the IServiceProvider, - // then we let the developer override those options - var options = new NodeServicesOptions(serviceProvider); - setupAction(options); - - return NodeServicesFactory.CreateNodeServices(options); - }); - } - } -} diff --git a/src/Middleware/NodeServices/src/Content/Node/entrypoint-http.js b/src/Middleware/NodeServices/src/Content/Node/entrypoint-http.js deleted file mode 100644 index a992d0fe16..0000000000 --- a/src/Middleware/NodeServices/src/Content/Node/entrypoint-http.js +++ /dev/null @@ -1,416 +0,0 @@ -(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 1); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -module.exports = require("path"); - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(2); - - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -exports.__esModule = true; -// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive, -// but simplifies things for the consumer of this module. -__webpack_require__(3); -__webpack_require__(4); -var http = __webpack_require__(5); -var path = __webpack_require__(0); -var ArgsUtil_1 = __webpack_require__(6); -var ExitWhenParentExits_1 = __webpack_require__(7); -// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct -// reference to Node's runtime 'require' function. -var dynamicRequire = eval('require'); -var server = http.createServer(function (req, res) { - readRequestBodyAsJson(req, function (bodyJson) { - var hasSentResult = false; - var callback = function (errorValue, successValue) { - if (!hasSentResult) { - hasSentResult = true; - if (errorValue) { - respondWithError(res, errorValue); - } - else if (typeof successValue !== 'string') { - // Arbitrary object/number/etc - JSON-serialize it - var successValueJson = void 0; - try { - successValueJson = JSON.stringify(successValue); - } - catch (ex) { - // JSON serialization error - pass it back to .NET - respondWithError(res, ex); - return; - } - res.setHeader('Content-Type', 'application/json'); - res.end(successValueJson); - } - else { - // String - can bypass JSON-serialization altogether - res.setHeader('Content-Type', 'text/plain'); - res.end(successValue); - } - } - }; - // Support streamed responses - Object.defineProperty(callback, 'stream', { - enumerable: true, - get: function () { - if (!hasSentResult) { - hasSentResult = true; - res.setHeader('Content-Type', 'application/octet-stream'); - } - return res; - } - }); - try { - var resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName); - var invokedModule = dynamicRequire(resolvedPath); - var func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule; - if (!func) { - throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"'); - } - func.apply(null, [callback].concat(bodyJson.args)); - } - catch (synchronousException) { - callback(synchronousException, null); - } - }); -}); -var parsedArgs = ArgsUtil_1.parseArgs(process.argv); -var requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide' -server.listen(requestedPortOrZero, 'localhost', function () { - var addressInfo = server.address(); - // Signal to HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on - console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {' + addressInfo.address + '} port ' + addressInfo.port + '\]'); - // Signal to the NodeServices base class that we're ready to accept invocations - console.log('[Microsoft.AspNetCore.NodeServices:Listening]'); -}); -ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true); -function readRequestBodyAsJson(request, callback) { - var requestBodyAsString = ''; - request.on('data', function (chunk) { requestBodyAsString += chunk; }); - request.on('end', function () { callback(JSON.parse(requestBodyAsString)); }); -} -function respondWithError(res, errorValue) { - res.statusCode = 500; - res.end(JSON.stringify({ - errorMessage: errorValue.message || errorValue, - errorDetails: errorValue.stack || null - })); -} - - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -exports.__esModule = true; -var path = __webpack_require__(0); -var startsWith = function (str, prefix) { return str.substring(0, prefix.length) === prefix; }; -var appRootDir = process.cwd(); -function patchedLStat(pathToStatLong, fsReqWrap) { - try { - // If the lstat completes without errors, we don't modify its behavior at all - return origLStat.apply(this, arguments); - } - catch (ex) { - var shouldOverrideError = startsWith(ex.message, 'EPERM') // It's a permissions error - && typeof appRootDirLong === 'string' - && startsWith(appRootDirLong, pathToStatLong) // ... for an ancestor directory - && ex.stack.indexOf('Object.realpathSync ') >= 0; // ... during symlink resolution - if (shouldOverrideError) { - // Fake the result to give the same result as an 'lstat' on the app root dir. - // This stops Node failing to load modules just because it doesn't know whether - // ancestor directories are symlinks or not. If there's a genuine file - // permissions issue, it will still surface later when Node actually - // tries to read the file. - return origLStat.call(this, appRootDir, fsReqWrap); - } - else { - // In any other case, preserve the original error - throw ex; - } - } -} -; -// It's only necessary to apply this workaround on Windows -var appRootDirLong = null; -var origLStat = null; -if (/^win/.test(process.platform)) { - try { - // Get the app's root dir in Node's internal "long" format (e.g., \\?\C:\dir\subdir) - appRootDirLong = path._makeLong(appRootDir); - // Actually apply the patch, being as defensive as possible - var bindingFs = process.binding('fs'); - origLStat = bindingFs.lstat; - if (typeof origLStat === 'function') { - bindingFs.lstat = patchedLStat; - } - } - catch (ex) { - // If some future version of Node throws (e.g., to prevent use of process.binding()), - // don't apply the patch, but still let the application run. - } -} - - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - -// When Node writes to stdout/strerr, we capture that and convert the lines into calls on the -// active .NET ILogger. But by default, stdout/stderr don't have any way of distinguishing -// linebreaks inside log messages from the linebreaks that delimit separate log messages, -// so multiline strings will end up being written to the ILogger as multiple independent -// log messages. This makes them very hard to make sense of, especially when they represent -// something like stack traces. -// -// To fix this, we intercept stdout/stderr writes, and replace internal linebreaks with a -// marker token. When .NET receives the lines, it converts the marker tokens back to regular -// linebreaks within the logged messages. -// -// Note that it's better to do the interception at the stdout/stderr level, rather than at -// the console.log/console.error (etc.) level, because this takes place after any native -// message formatting has taken place (e.g., inserting values for % placeholders). -var findInternalNewlinesRegex = /\n(?!$)/g; -var encodedNewline = '__ns_newline__'; -encodeNewlinesWrittenToStream(process.stdout); -encodeNewlinesWrittenToStream(process.stderr); -function encodeNewlinesWrittenToStream(outputStream) { - var origWriteFunction = outputStream.write; - outputStream.write = function (value) { - // Only interfere with the write if it's definitely a string - if (typeof value === 'string') { - var argsClone = Array.prototype.slice.call(arguments, 0); - argsClone[0] = encodeNewlinesInString(value); - origWriteFunction.apply(this, argsClone); - } - else { - origWriteFunction.apply(this, arguments); - } - }; -} -function encodeNewlinesInString(str) { - return str.replace(findInternalNewlinesRegex, encodedNewline); -} - - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -module.exports = require("http"); - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -exports.__esModule = true; -function parseArgs(args) { - // Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external - // dependencies (such as an args-parsing library) to this file. - var result = {}; - var currentKey = null; - args.forEach(function (arg) { - if (arg.indexOf('--') === 0) { - var argName = arg.substring(2); - result[argName] = undefined; - currentKey = argName; - } - else if (currentKey) { - result[currentKey] = arg; - currentKey = null; - } - }); - return result; -} -exports.parseArgs = parseArgs; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/* -In general, we want the Node child processes to be terminated as soon as the parent .NET processes exit, -because we have no further use for them. If the .NET process shuts down gracefully, it will run its -finalizers, one of which (in OutOfProcessNodeInstance.cs) will kill its associated Node process immediately. - -But if the .NET process is terminated forcefully (e.g., on Linux/OSX with 'kill -9'), then it won't have -any opportunity to shut down its child processes, and by default they will keep running. In this case, it's -up to the child process to detect this has happened and terminate itself. - -There are many possible approaches to detecting when a parent process has exited, most of which behave -differently between Windows and Linux/OS X: - - - On Windows, the parent process can mark its child as being a 'job' that should auto-terminate when - the parent does (http://stackoverflow.com/a/4657392). Not cross-platform. - - The child Node process can get a callback when the parent disconnects (process.on('disconnect', ...)). - But despite http://stackoverflow.com/a/16487966, no callback fires in any case I've tested (Windows / OS X). - - The child Node process can get a callback when its stdin/stdout are disconnected, as described at - http://stackoverflow.com/a/15693934. This works well on OS X, but calling stdout.resume() on Windows - causes the process to terminate prematurely. - - I don't know why, but on Windows, it's enough to invoke process.stdin.resume(). For some reason this causes - the child Node process to exit as soon as the parent one does, but I don't see this documented anywhere. - - You can poll to see if the parent process, or your stdin/stdout connection to it, is gone - - You can directly pass a parent process PID to the child, and then have the child poll to see if it's - still running (e.g., using process.kill(pid, 0), which doesn't kill it but just tests whether it exists, - as per https://nodejs.org/api/process.html#process_process_kill_pid_signal) - - Or, on each poll, you can try writing to process.stdout. If the parent has died, then this will throw. - However I don't see this documented anywhere. It would be nice if you could just poll for whether or not - process.stdout is still connected (without actually writing to it) but I haven't found any property whose - value changes until you actually try to write to it. - -Of these, the only cross-platform approach that is actually documented as a valid strategy is simply polling -to check whether the parent PID is still running. So that's what we do here. -*/ -exports.__esModule = true; -var pollIntervalMs = 1000; -function exitWhenParentExits(parentPid, ignoreSigint) { - setInterval(function () { - if (!processExists(parentPid)) { - // Can't log anything at this point, because out stdout was connected to the parent, - // but the parent is gone. - process.exit(); - } - }, pollIntervalMs); - if (ignoreSigint) { - // Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree. - // By default, the Node process would then exit before the .NET process, because ASP.NET implements - // a delayed shutdown to allow ongoing requests to complete. - // - // This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware - // will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is - // already set up to shut itself down if it detects the .NET process is terminated, all we have to do is - // ignore the SIGINT. The Node process will then terminate automatically after the .NET process does. - // - // A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any - // ongoing EventSource connections before letting the Node process exit, independently of the .NET - // process exiting. However, doing this well in general is very nontrivial (see all the discussion at - // https://github.com/nodejs/node/issues/2642). - process.on('SIGINT', function () { - console.log('Received SIGINT. Waiting for .NET process to exit...'); - }); - } -} -exports.exitWhenParentExits = exitWhenParentExits; -function processExists(pid) { - try { - // Sending signal 0 - on all platforms - tests whether the process exists. As long as it doesn't - // throw, that means it does exist. - process.kill(pid, 0); - return true; - } - catch (ex) { - // If the reason for the error is that we don't have permission to ask about this process, - // report that as a separate problem. - if (ex.code === 'EPERM') { - throw new Error("Attempted to check whether process " + pid + " was running, but got a permissions error."); - } - return false; - } -} - - -/***/ }) -/******/ ]))); \ No newline at end of file diff --git a/src/Middleware/NodeServices/src/HostingModels/HttpNodeInstance.cs b/src/Middleware/NodeServices/src/HostingModels/HttpNodeInstance.cs deleted file mode 100644 index 9d7f5726b2..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/HttpNodeInstance.cs +++ /dev/null @@ -1,161 +0,0 @@ -// 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 System.Net.Http; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// A specialisation of the OutOfProcessNodeInstance base class that uses HTTP to perform RPC invocations. - /// - /// The Node child process starts an HTTP listener on an arbitrary available port (except where a nonzero - /// port number is specified as a constructor parameter), and signals which port was selected using the same - /// input/output-based mechanism that the base class uses to determine when the child process is ready to - /// accept RPC invocations. - /// - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class HttpNodeInstance : OutOfProcessNodeInstance - { - private static readonly Regex EndpointMessageRegex = - new Regex(@"^\[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {(.*?)} port (\d+)\]$"); - - private static readonly JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver(), - TypeNameHandling = TypeNameHandling.None - }; - - private readonly HttpClient _client; - private bool _disposed; - private string _endpoint; - - public HttpNodeInstance(NodeServicesOptions options, int port = 0) - : base( - EmbeddedResourceReader.Read( - typeof(HttpNodeInstance), - "/Content/Node/entrypoint-http.js"), - options.ProjectPath, - options.WatchFileExtensions, - MakeCommandLineOptions(port), - options.ApplicationStoppingToken, - options.NodeInstanceOutputLogger, - options.EnvironmentVariables, - options.InvocationTimeoutMilliseconds, - options.LaunchWithDebugging, - options.DebuggingPort) - { - _client = new HttpClient(); - _client.Timeout = TimeSpan.FromMilliseconds(options.InvocationTimeoutMilliseconds + 1000); - } - - private static string MakeCommandLineOptions(int port) - { - return $"--port {port}"; - } - - protected override async Task InvokeExportAsync( - NodeInvocationInfo invocationInfo, CancellationToken cancellationToken) - { - var payloadJson = JsonConvert.SerializeObject(invocationInfo, jsonSerializerSettings); - var payload = new StringContent(payloadJson, Encoding.UTF8, "application/json"); - var response = await _client.PostAsync(_endpoint, payload, cancellationToken); - - if (!response.IsSuccessStatusCode) - { - // Unfortunately there's no true way to cancel ReadAsStringAsync calls, hence AbandonIfCancelled - var responseJson = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); - var responseError = JsonConvert.DeserializeObject(responseJson, jsonSerializerSettings); - - throw new NodeInvocationException(responseError.ErrorMessage, responseError.ErrorDetails); - } - - var responseContentType = response.Content.Headers.ContentType; - switch (responseContentType.MediaType) - { - case "text/plain": - // String responses can skip JSON encoding/decoding - if (typeof(T) != typeof(string)) - { - throw new ArgumentException( - "Node module responded with non-JSON string. This cannot be converted to the requested generic type: " + - typeof(T).FullName); - } - - var responseString = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); - return (T)(object)responseString; - - case "application/json": - var responseJson = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); - return JsonConvert.DeserializeObject(responseJson, jsonSerializerSettings); - - case "application/octet-stream": - // Streamed responses have to be received as System.IO.Stream instances - if (typeof(T) != typeof(Stream) && typeof(T) != typeof(object)) - { - throw new ArgumentException( - "Node module responded with binary stream. This cannot be converted to the requested generic type: " + - typeof(T).FullName + ". Instead you must use the generic type System.IO.Stream."); - } - - return (T)(object)(await response.Content.ReadAsStreamAsync().OrThrowOnCancellation(cancellationToken)); - - default: - throw new InvalidOperationException("Unexpected response content type: " + responseContentType.MediaType); - } - } - - protected override void OnOutputDataReceived(string outputData) - { - // Watch for "port selected" messages, and when observed, - // store the IP (IPv4/IPv6) and port number - // so we can use it when making HTTP requests. The child process will always send - // one of these messages before it sends a "ready for connections" message. - var match = string.IsNullOrEmpty(_endpoint) ? EndpointMessageRegex.Match(outputData) : null; - if (match != null && match.Success) - { - var port = int.Parse(match.Groups[2].Captures[0].Value); - var resolvedIpAddress = match.Groups[1].Captures[0].Value; - - //IPv6 must be wrapped with [] brackets - resolvedIpAddress = resolvedIpAddress == "::1" ? $"[{resolvedIpAddress}]" : resolvedIpAddress; - _endpoint = $"http://{resolvedIpAddress}:{port}"; - } - else - { - base.OnOutputDataReceived(outputData); - } - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!_disposed) - { - if (disposing) - { - _client.Dispose(); - } - - _disposed = true; - } - } - -#pragma warning disable 649 // These properties are populated via JSON deserialization - private class RpcJsonResponse - { - public string ErrorMessage { get; set; } - public string ErrorDetails { get; set; } - } -#pragma warning restore 649 - } -} diff --git a/src/Middleware/NodeServices/src/HostingModels/INodeInstance.cs b/src/Middleware/NodeServices/src/HostingModels/INodeInstance.cs deleted file mode 100644 index 00bc1277ba..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/INodeInstance.cs +++ /dev/null @@ -1,27 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// Represents an instance of Node.js to which Remote Procedure Calls (RPC) may be sent. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public interface INodeInstance : IDisposable - { - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// A that can be used to cancel the invocation. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root that contains the code to be invoked. - /// If set, specifies the CommonJS export to be invoked. If not set, the module's default CommonJS export itself must be a function to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - Task InvokeExportAsync(CancellationToken cancellationToken, string moduleName, string exportNameOrNull, params object[] args); - } -} diff --git a/src/Middleware/NodeServices/src/HostingModels/NodeInvocationException.cs b/src/Middleware/NodeServices/src/HostingModels/NodeInvocationException.cs deleted file mode 100644 index 6e4b97b4be..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/NodeInvocationException.cs +++ /dev/null @@ -1,59 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// Represents an exception caused by invoking Node.js code. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class NodeInvocationException : Exception - { - /// - /// If true, indicates that the invocation failed because the Node.js instance could not be reached. For example, - /// it might have already shut down or previously crashed. - /// - public bool NodeInstanceUnavailable { get; private set; } - - /// - /// If true, indicates that even though the invocation failed because the Node.js instance could not be reached - /// or needs to be restarted, that Node.js instance may remain alive for a period in order to complete any - /// outstanding requests. - /// - public bool AllowConnectionDraining { get; private set;} - - /// - /// Creates a new instance of . - /// - /// A description of the exception. - /// Additional information, such as a Node.js stack trace, representing the exception. - public NodeInvocationException(string message, string details) - : base(message + Environment.NewLine + details) - { - } - - /// - /// Creates a new instance of . - /// - /// A description of the exception. - /// Additional information, such as a Node.js stack trace, representing the exception. - /// Specifies a value for the flag. - /// Specifies a value for the flag. - public NodeInvocationException(string message, string details, bool nodeInstanceUnavailable, bool allowConnectionDraining) - : this(message, details) - { - // Reject a meaningless combination of flags - if (allowConnectionDraining && !nodeInstanceUnavailable) - { - throw new ArgumentException( - $"The '${ nameof(allowConnectionDraining) }' parameter cannot be true " + - $"unless the '${ nameof(nodeInstanceUnavailable) }' parameter is also true."); - } - - NodeInstanceUnavailable = nodeInstanceUnavailable; - AllowConnectionDraining = allowConnectionDraining; - } - } -} diff --git a/src/Middleware/NodeServices/src/HostingModels/NodeInvocationInfo.cs b/src/Middleware/NodeServices/src/HostingModels/NodeInvocationInfo.cs deleted file mode 100644 index 7d32eacb26..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/NodeInvocationInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// Describes an RPC call sent from .NET code to Node.js code. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class NodeInvocationInfo - { - /// - /// Specifies the path to the Node.js module (i.e., .js file) relative to the project root. - /// - public string ModuleName { get; set; } - - /// - /// If set, specifies the name of CommonJS function export to be invoked. - /// If not set, the Node.js module's default export must itself be a function to be invoked. - /// - public string ExportedFunctionName { get; set; } - - /// - /// A sequence of JSON-serializable arguments to be passed to the Node.js function being invoked. - /// - public object[] Args { get; set; } - } -} diff --git a/src/Middleware/NodeServices/src/HostingModels/NodeServicesOptionsExtensions.cs b/src/Middleware/NodeServices/src/HostingModels/NodeServicesOptionsExtensions.cs deleted file mode 100644 index 674f0ee6dc..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/NodeServicesOptionsExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// Extension methods that help with populating a object. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class NodeServicesOptionsExtensions - { - /// - /// Configures the service so that it will use out-of-process - /// Node.js instances and perform RPC calls over HTTP. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static void UseHttpHosting(this NodeServicesOptions options) - { - options.NodeInstanceFactory = () => new HttpNodeInstance(options); - } - } -} diff --git a/src/Middleware/NodeServices/src/HostingModels/OutOfProcessNodeInstance.cs b/src/Middleware/NodeServices/src/HostingModels/OutOfProcessNodeInstance.cs deleted file mode 100644 index cf68baa338..0000000000 --- a/src/Middleware/NodeServices/src/HostingModels/OutOfProcessNodeInstance.cs +++ /dev/null @@ -1,479 +0,0 @@ -// 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.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.NodeServices.HostingModels -{ - /// - /// Class responsible for launching a Node child process on the local machine, determining when it is ready to - /// accept invocations, detecting if it dies on its own, and finally terminating it on disposal. - /// - /// This abstract base class uses the input/output streams of the child process to perform a simple handshake - /// to determine when the child process is ready to accept invocations. This is agnostic to the mechanism that - /// derived classes use to actually perform the invocations (e.g., they could use HTTP-RPC, or a binary TCP - /// protocol, or any other RPC-type mechanism). - /// - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public abstract class OutOfProcessNodeInstance : INodeInstance - { - /// - /// The to which the Node.js instance's stdout/stderr is being redirected. - /// - protected readonly ILogger OutputLogger; - - private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]"; - private readonly TaskCompletionSource _connectionIsReadySource = new TaskCompletionSource(); - private bool _disposed; - private readonly StringAsTempFile _entryPointScript; - private FileSystemWatcher _fileSystemWatcher; - private int _invocationTimeoutMilliseconds; - private bool _launchWithDebugging; - private readonly Process _nodeProcess; - private int? _nodeDebuggingPort; - private bool _nodeProcessNeedsRestart; - private readonly string[] _watchFileExtensions; - - /// - /// Creates a new instance of . - /// - /// The path to the entry point script that the Node instance should load and execute. - /// The root path of the current project. This is used when resolving Node.js module paths relative to the project root. - /// The filename extensions that should be watched within the project root. The Node instance will automatically shut itself down if any matching file changes. - /// Additional command-line arguments to be passed to the Node.js instance. - /// A token that indicates when the host application is stopping. - /// The to which the Node.js instance's stdout/stderr (and other log information) should be written. - /// Environment variables to be set on the Node.js process. - /// The maximum duration, in milliseconds, to wait for RPC calls to complete. - /// If true, passes a flag to the Node.js process telling it to accept V8 debugger connections. - /// If debugging is enabled, the Node.js process should listen for V8 debugger connections on this port. - public OutOfProcessNodeInstance( - string entryPointScript, - string projectPath, - string[] watchFileExtensions, - string commandLineArguments, - CancellationToken applicationStoppingToken, - ILogger nodeOutputLogger, - IDictionary environmentVars, - int invocationTimeoutMilliseconds, - bool launchWithDebugging, - int debuggingPort) - { - if (nodeOutputLogger == null) - { - throw new ArgumentNullException(nameof(nodeOutputLogger)); - } - - OutputLogger = nodeOutputLogger; - _entryPointScript = new StringAsTempFile(entryPointScript, applicationStoppingToken); - _invocationTimeoutMilliseconds = invocationTimeoutMilliseconds; - _launchWithDebugging = launchWithDebugging; - - var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments, - environmentVars, _launchWithDebugging, debuggingPort); - _nodeProcess = LaunchNodeProcess(startInfo); - _watchFileExtensions = watchFileExtensions; - _fileSystemWatcher = BeginFileWatcher(projectPath); - ConnectToInputOutputStreams(); - } - - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// A that can be used to cancel the invocation. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root that contains the code to be invoked. - /// If set, specifies the CommonJS export to be invoked. If not set, the module's default CommonJS export itself must be a function to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - public async Task InvokeExportAsync( - CancellationToken cancellationToken, string moduleName, string exportNameOrNull, params object[] args) - { - if (_nodeProcess.HasExited || _nodeProcessNeedsRestart) - { - // This special kind of exception triggers a transparent retry - NodeServicesImpl will launch - // a new Node instance and pass the invocation to that one instead. - // Note that if the Node process is listening for debugger connections, then we need it to shut - // down immediately and not stay open for connection draining (because if it did, the new Node - // instance wouldn't able to start, because the old one would still hold the debugging port). - var message = _nodeProcess.HasExited - ? "The Node process has exited" - : "The Node process needs to restart"; - throw new NodeInvocationException( - message, - details: null, - nodeInstanceUnavailable: true, - allowConnectionDraining: !_launchWithDebugging); - } - - // Construct a new cancellation token that combines the supplied token with the configured invocation - // timeout. Technically we could avoid wrapping the cancellationToken if no timeout is configured, - // but that's not really a major use case, since timeouts are enabled by default. - using (var timeoutSource = new CancellationTokenSource()) - using (var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutSource.Token)) - { - if (_invocationTimeoutMilliseconds > 0) - { - timeoutSource.CancelAfter(_invocationTimeoutMilliseconds); - } - - // By overwriting the supplied cancellation token, we ensure that it isn't accidentally used - // below. We only want to pass through the token that respects timeouts. - cancellationToken = combinedCancellationTokenSource.Token; - var connectionDidSucceed = false; - - try - { - // Wait until the connection is established. This will throw if the connection fails to initialize, - // or if cancellation is requested first. Note that we can't really cancel the "establishing connection" - // task because that's shared with all callers, but we can stop waiting for it if this call is cancelled. - await _connectionIsReadySource.Task.OrThrowOnCancellation(cancellationToken); - connectionDidSucceed = true; - - return await InvokeExportAsync(new NodeInvocationInfo - { - ModuleName = moduleName, - ExportedFunctionName = exportNameOrNull, - Args = args - }, cancellationToken); - } - catch (TaskCanceledException) - { - if (timeoutSource.IsCancellationRequested) - { - // It was very common for developers to report 'TaskCanceledException' when encountering almost any - // trouble when using NodeServices. Now we have a default invocation timeout, and attempt to give - // a more descriptive exception message if it happens. - if (!connectionDidSucceed) - { - // This is very unlikely, but for debugging, it's still useful to differentiate it from the - // case below. - throw new NodeInvocationException( - $"Attempt to connect to Node timed out after {_invocationTimeoutMilliseconds}ms.", - string.Empty); - } - else - { - // Developers encounter this fairly often (if their Node code fails without invoking the callback, - // all that the .NET side knows is that the invocation eventually times out). Previously, this surfaced - // as a TaskCanceledException, but this led to a lot of issue reports. Now we throw the following - // descriptive error. - throw new NodeInvocationException( - $"The Node invocation timed out after {_invocationTimeoutMilliseconds}ms.", - $"You can change the timeout duration by setting the {NodeServicesOptions.TimeoutConfigPropertyName} " - + $"property on {nameof(NodeServicesOptions)}.\n\n" - + "The first debugging step is to ensure that your Node.js function always invokes the supplied " - + "callback (or throws an exception synchronously), even if it encounters an error. Otherwise, " - + "the .NET code has no way to know that it is finished or has failed." - ); - } - } - else - { - throw; - } - } - } - } - - /// - /// Disposes this instance. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// Specifies the Node.js function to be invoked and arguments to be passed to it. - /// A that can be used to cancel the invocation. - /// A representing the completion of the RPC call. - protected abstract Task InvokeExportAsync( - NodeInvocationInfo invocationInfo, - CancellationToken cancellationToken); - - /// - /// Configures a instance describing how to launch the Node.js process. - /// - /// The entrypoint JavaScript file that the Node.js process should execute. - /// The root path of the project. This is used when locating Node.js modules relative to the project root. - /// Command-line arguments to be passed to the Node.js process. - /// Environment variables to be set on the Node.js process. - /// If true, passes a flag to the Node.js process telling it to accept V8 Inspector connections. - /// If debugging is enabled, the Node.js process should listen for V8 Inspector connections on this port. - /// - protected virtual ProcessStartInfo PrepareNodeProcessStartInfo( - string entryPointFilename, string projectPath, string commandLineArguments, - IDictionary environmentVars, bool launchWithDebugging, int debuggingPort) - { - // This method is virtual, as it provides a way to override the NODE_PATH or the path to node.exe - string debuggingArgs; - if (launchWithDebugging) - { - debuggingArgs = debuggingPort != default(int) ? $"--inspect={debuggingPort} " : "--inspect "; - _nodeDebuggingPort = debuggingPort; - } - else - { - debuggingArgs = string.Empty; - } - - var thisProcessPid = Process.GetCurrentProcess().Id; - var startInfo = new ProcessStartInfo("node") - { - Arguments = $"{debuggingArgs}\"{entryPointFilename}\" --parentPid {thisProcessPid} {commandLineArguments ?? string.Empty}", - UseShellExecute = false, - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - WorkingDirectory = projectPath - }; - - // Append environment vars - if (environmentVars != null) - { - foreach (var envVarKey in environmentVars.Keys) - { - var envVarValue = environmentVars[envVarKey]; - if (envVarValue != null) - { - SetEnvironmentVariable(startInfo, envVarKey, envVarValue); - } - } - } - - // Append projectPath to NODE_PATH so it can locate node_modules - var existingNodePath = Environment.GetEnvironmentVariable("NODE_PATH") ?? string.Empty; - if (existingNodePath != string.Empty) - { - existingNodePath += Path.PathSeparator; - } - - var nodePathValue = existingNodePath + Path.Combine(projectPath, "node_modules"); - SetEnvironmentVariable(startInfo, "NODE_PATH", nodePathValue); - - return startInfo; - } - - /// - /// Virtual method invoked whenever the Node.js process emits a line to its stdout. - /// - /// The line emitted to the Node.js process's stdout. - protected virtual void OnOutputDataReceived(string outputData) - { - OutputLogger.LogInformation(outputData); - } - - /// - /// Virtual method invoked whenever the Node.js process emits a line to its stderr. - /// - /// The line emitted to the Node.js process's stderr. - protected virtual void OnErrorDataReceived(string errorData) - { - OutputLogger.LogError(errorData); - } - - /// - /// Disposes the instance. - /// - /// True if the object is disposing or false if it is finalizing. - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - _entryPointScript.Dispose(); - EnsureFileSystemWatcherIsDisposed(); - } - - // Make sure the Node process is finished - // TODO: Is there a more graceful way to end it? Or does this still let it perform any cleanup? - if (_nodeProcess != null && !_nodeProcess.HasExited) - { - _nodeProcess.Kill(); - } - - _disposed = true; - } - } - - private void EnsureFileSystemWatcherIsDisposed() - { - if (_fileSystemWatcher != null) - { - _fileSystemWatcher.Dispose(); - _fileSystemWatcher = null; - } - } - - private static void SetEnvironmentVariable(ProcessStartInfo startInfo, string name, string value) - { - startInfo.Environment[name] = value; - } - - private static Process LaunchNodeProcess(ProcessStartInfo startInfo) - { - try { - var process = Process.Start(startInfo); - - // On Mac at least, a killed child process is left open as a zombie until the parent - // captures its exit code. We don't need the exit code for this process, and don't want - // to use process.WaitForExit() explicitly (we'd have to block the thread until it really - // has exited), but we don't want to leave zombies lying around either. It's sufficient - // to use process.EnableRaisingEvents so that .NET will grab the exit code and let the - // zombie be cleaned away without having to block our thread. - process.EnableRaisingEvents = true; - - return process; - } catch (Exception ex) { - var message = "Failed to start Node process. To resolve this:.\n\n" - + "[1] Ensure that Node.js is installed and can be found in one of the PATH directories.\n" - + $" Current PATH enviroment variable is: { Environment.GetEnvironmentVariable("PATH") }\n" - + " Make sure the Node executable is in one of those directories, or update your PATH.\n\n" - + "[2] See the InnerException for further details of the cause."; - throw new InvalidOperationException(message, ex); - } - } - - private static string UnencodeNewlines(string str) - { - if (str != null) - { - // The token here needs to match the const in OverrideStdOutputs.ts. - // See the comment there for why we're doing this. - str = str.Replace("__ns_newline__", Environment.NewLine); - } - - return str; - } - - private void ConnectToInputOutputStreams() - { - var initializationIsCompleted = false; - - _nodeProcess.OutputDataReceived += (sender, evt) => - { - if (evt.Data == ConnectionEstablishedMessage && !initializationIsCompleted) - { - _connectionIsReadySource.SetResult(null); - initializationIsCompleted = true; - } - else if (evt.Data != null) - { - OnOutputDataReceived(UnencodeNewlines(evt.Data)); - } - }; - - _nodeProcess.ErrorDataReceived += (sender, evt) => - { - if (evt.Data != null) - { - if (_launchWithDebugging && IsDebuggerMessage(evt.Data)) - { - OutputLogger.LogWarning(evt.Data); - } - else - { - OnErrorDataReceived(UnencodeNewlines(evt.Data)); - } - } - }; - - _nodeProcess.BeginOutputReadLine(); - _nodeProcess.BeginErrorReadLine(); - } - - private static bool IsDebuggerMessage(string message) - { - return message.StartsWith("Debugger attached", StringComparison.Ordinal) || - message.StartsWith("Debugger listening ", StringComparison.Ordinal) || - message.StartsWith("To start debugging", StringComparison.Ordinal) || - message.Equals("Warning: This is an experimental feature and could change at any time.", StringComparison.Ordinal) || - message.Equals("For help see https://nodejs.org/en/docs/inspector", StringComparison.Ordinal) || - message.Contains("chrome-devtools:"); - } - - private FileSystemWatcher BeginFileWatcher(string rootDir) - { - if (_watchFileExtensions == null || _watchFileExtensions.Length == 0) - { - // Nothing to watch - return null; - } - - var watcher = new FileSystemWatcher(rootDir) - { - IncludeSubdirectories = true, - NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName - }; - watcher.Changed += OnFileChanged; - watcher.Created += OnFileChanged; - watcher.Deleted += OnFileChanged; - watcher.Renamed += OnFileRenamed; - watcher.EnableRaisingEvents = true; - return watcher; - } - - private void OnFileChanged(object source, FileSystemEventArgs e) - { - if (IsFilenameBeingWatched(e.FullPath)) - { - RestartDueToFileChange(e.FullPath); - } - } - - private void OnFileRenamed(object source, RenamedEventArgs e) - { - if (IsFilenameBeingWatched(e.OldFullPath) || IsFilenameBeingWatched(e.FullPath)) - { - RestartDueToFileChange(e.OldFullPath); - } - } - - private bool IsFilenameBeingWatched(string fullPath) - { - if (string.IsNullOrEmpty(fullPath)) - { - return false; - } - else - { - var actualExtension = Path.GetExtension(fullPath) ?? string.Empty; - return _watchFileExtensions.Any(actualExtension.Equals); - } - } - - private void RestartDueToFileChange(string fullPath) - { - OutputLogger.LogInformation($"Node will restart because file changed: {fullPath}"); - - _nodeProcessNeedsRestart = true; - - // There's no need to watch for any more changes, since we're already restarting, and if the - // restart takes some time (e.g., due to connection draining), we could end up getting duplicate - // notifications. - EnsureFileSystemWatcherIsDisposed(); - } - - /// - /// Implements the finalization part of the IDisposable pattern by calling Dispose(false). - /// - ~OutOfProcessNodeInstance() - { - Dispose(false); - } - } -} diff --git a/src/Middleware/NodeServices/src/INodeServices.cs b/src/Middleware/NodeServices/src/INodeServices.cs deleted file mode 100644 index a88ece3c5c..0000000000 --- a/src/Middleware/NodeServices/src/INodeServices.cs +++ /dev/null @@ -1,58 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Represents the ability to invoke code in a Node.js environment. Although the underlying Node.js instance - /// might change over time (e.g., the process might be restarted), the instance - /// will remain constant. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public interface INodeServices : IDisposable - { - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root whose default CommonJS export is the function to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - Task InvokeAsync(string moduleName, params object[] args); - - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// A that can be used to cancel the invocation. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root whose default CommonJS export is the function to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - Task InvokeAsync(CancellationToken cancellationToken, string moduleName, params object[] args); - - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root that contains the code to be invoked. - /// Specifies the CommonJS export to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - Task InvokeExportAsync(string moduleName, string exportedFunctionName, params object[] args); - - /// - /// Asynchronously invokes code in the Node.js instance. - /// - /// The JSON-serializable data type that the Node.js code will asynchronously return. - /// A that can be used to cancel the invocation. - /// The path to the Node.js module (i.e., JavaScript file) relative to your project root that contains the code to be invoked. - /// Specifies the CommonJS export to be invoked. - /// Any sequence of JSON-serializable arguments to be passed to the Node.js function. - /// A representing the completion of the RPC call. - Task InvokeExportAsync(CancellationToken cancellationToken, string moduleName, string exportedFunctionName, params object[] args); - } -} diff --git a/src/Middleware/NodeServices/src/Microsoft.AspNetCore.NodeServices.csproj b/src/Middleware/NodeServices/src/Microsoft.AspNetCore.NodeServices.csproj deleted file mode 100644 index 33f90fc61f..0000000000 --- a/src/Middleware/NodeServices/src/Microsoft.AspNetCore.NodeServices.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - Invoke Node.js modules at runtime in ASP.NET Core applications. - $(DefaultNetCoreTargetFramework) - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Middleware/NodeServices/src/NodeServicesImpl.cs b/src/Middleware/NodeServices/src/NodeServicesImpl.cs deleted file mode 100644 index 621a9af7cc..0000000000 --- a/src/Middleware/NodeServices/src/NodeServicesImpl.cs +++ /dev/null @@ -1,169 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.NodeServices.HostingModels; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Default implementation of INodeServices. This is the primary API surface through which developers - /// make use of this package. It provides simple "InvokeAsync" methods that dispatch calls to the - /// correct Node instance, creating and destroying those instances as needed. - /// - /// If a Node instance dies (or none was yet created), this class takes care of creating a new one. - /// If a Node instance signals that it needs to be restarted (e.g., because a file changed), then this - /// class will create a new instance and dispatch future calls to it, while keeping the old instance - /// alive for a defined period so that any in-flight RPC calls can complete. This latter feature is - /// analogous to the "connection draining" feature implemented by HTTP load balancers. - /// - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class NodeServicesImpl : INodeServices - { - private static TimeSpan ConnectionDrainingTimespan = TimeSpan.FromSeconds(15); - private Func _nodeInstanceFactory; - private INodeInstance _currentNodeInstance; - private object _currentNodeInstanceAccessLock = new object(); - private Exception _instanceDelayedDisposalException; - - internal NodeServicesImpl(Func nodeInstanceFactory) - { - _nodeInstanceFactory = nodeInstanceFactory; - } - - public Task InvokeAsync(string moduleName, params object[] args) - { - return InvokeExportAsync(moduleName, null, args); - } - - public Task InvokeAsync(CancellationToken cancellationToken, string moduleName, params object[] args) - { - return InvokeExportAsync(cancellationToken, moduleName, null, args); - } - - public Task InvokeExportAsync(string moduleName, string exportedFunctionName, params object[] args) - { - return InvokeExportWithPossibleRetryAsync(moduleName, exportedFunctionName, args, /* allowRetry */ true, CancellationToken.None); - } - - public Task InvokeExportAsync(CancellationToken cancellationToken, string moduleName, string exportedFunctionName, params object[] args) - { - return InvokeExportWithPossibleRetryAsync(moduleName, exportedFunctionName, args, /* allowRetry */ true, cancellationToken); - } - - private async Task InvokeExportWithPossibleRetryAsync(string moduleName, string exportedFunctionName, object[] args, bool allowRetry, CancellationToken cancellationToken) - { - ThrowAnyOutstandingDelayedDisposalException(); - var nodeInstance = GetOrCreateCurrentNodeInstance(); - - try - { - return await nodeInstance.InvokeExportAsync(cancellationToken, moduleName, exportedFunctionName, args); - } - catch (NodeInvocationException ex) - { - // If the Node instance can't complete the invocation because it needs to restart (e.g., because the underlying - // Node process has exited, or a file it depends on has changed), then we make one attempt to restart transparently. - if (allowRetry && ex.NodeInstanceUnavailable) - { - // Perform the retry after clearing away the old instance - // Since we disposal is delayed even though the node instance is replaced immediately, this produces the - // "connection draining" feature whereby in-flight RPC calls are given a certain period to complete. - lock (_currentNodeInstanceAccessLock) - { - if (_currentNodeInstance == nodeInstance) - { - var disposalDelay = ex.AllowConnectionDraining ? ConnectionDrainingTimespan : TimeSpan.Zero; - DisposeNodeInstance(_currentNodeInstance, disposalDelay); - _currentNodeInstance = null; - } - } - - // One the next call, don't allow retries, because we could get into an infinite retry loop, or a long retry - // loop that masks an underlying problem. A newly-created Node instance should be able to accept invocations, - // or something more serious must be wrong. - return await InvokeExportWithPossibleRetryAsync(moduleName, exportedFunctionName, args, /* allowRetry */ false, cancellationToken); - } - else - { - throw; - } - } - } - - public void Dispose() - { - lock (_currentNodeInstanceAccessLock) - { - if (_currentNodeInstance != null) - { - DisposeNodeInstance(_currentNodeInstance, delay: TimeSpan.Zero); - _currentNodeInstance = null; - } - } - } - - private void DisposeNodeInstance(INodeInstance nodeInstance, TimeSpan delay) - { - if (delay == TimeSpan.Zero) - { - nodeInstance.Dispose(); - } - else - { - Task.Run(async () => { - try - { - await Task.Delay(delay); - nodeInstance.Dispose(); - } - catch(Exception ex) - { - // Nothing's waiting for the delayed disposal task, so any exceptions in it would - // by default just get ignored. To make these discoverable, capture them here so - // they can be rethrown to the next caller to InvokeExportAsync. - _instanceDelayedDisposalException = ex; - } - }); - } - } - - private void ThrowAnyOutstandingDelayedDisposalException() - { - if (_instanceDelayedDisposalException != null) - { - var ex = _instanceDelayedDisposalException; - _instanceDelayedDisposalException = null; - throw new AggregateException( - "A previous attempt to dispose a Node instance failed. See InnerException for details.", - ex); - } - } - - private INodeInstance GetOrCreateCurrentNodeInstance() - { - var instance = _currentNodeInstance; - if (instance == null) - { - lock (_currentNodeInstanceAccessLock) - { - instance = _currentNodeInstance; - if (instance == null) - { - instance = _currentNodeInstance = CreateNewNodeInstance(); - } - } - } - - return instance; - } - - private INodeInstance CreateNewNodeInstance() - { - return _nodeInstanceFactory(); - } - } -} diff --git a/src/Middleware/NodeServices/src/TypeScript/HttpNodeInstanceEntryPoint.ts b/src/Middleware/NodeServices/src/TypeScript/HttpNodeInstanceEntryPoint.ts deleted file mode 100644 index bd2af22a28..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/HttpNodeInstanceEntryPoint.ts +++ /dev/null @@ -1,97 +0,0 @@ -// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive, -// but simplifies things for the consumer of this module. -import './Util/PatchModuleResolutionLStat'; -import './Util/OverrideStdOutputs'; -import * as http from 'http'; -import * as path from 'path'; -import { parseArgs } from './Util/ArgsUtil'; -import { exitWhenParentExits } from './Util/ExitWhenParentExits'; -import { AddressInfo } from 'net'; - -// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct -// reference to Node's runtime 'require' function. -const dynamicRequire: (name: string) => any = eval('require'); - -const server = http.createServer((req, res) => { - readRequestBodyAsJson(req, bodyJson => { - let hasSentResult = false; - const callback = (errorValue, successValue) => { - if (!hasSentResult) { - hasSentResult = true; - if (errorValue) { - respondWithError(res, errorValue); - } else if (typeof successValue !== 'string') { - // Arbitrary object/number/etc - JSON-serialize it - let successValueJson: string; - try { - successValueJson = JSON.stringify(successValue); - } catch (ex) { - // JSON serialization error - pass it back to .NET - respondWithError(res, ex); - return; - } - res.setHeader('Content-Type', 'application/json'); - res.end(successValueJson); - } else { - // String - can bypass JSON-serialization altogether - res.setHeader('Content-Type', 'text/plain'); - res.end(successValue); - } - } - }; - - // Support streamed responses - Object.defineProperty(callback, 'stream', { - enumerable: true, - get: function() { - if (!hasSentResult) { - hasSentResult = true; - res.setHeader('Content-Type', 'application/octet-stream'); - } - - return res; - } - }); - - try { - const resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName); - const invokedModule = dynamicRequire(resolvedPath); - const func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule; - if (!func) { - throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"'); - } - - func.apply(null, [callback].concat(bodyJson.args)); - } catch (synchronousException) { - callback(synchronousException, null); - } - }); -}); - -const parsedArgs = parseArgs(process.argv); -const requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide' -server.listen(requestedPortOrZero, 'localhost', function () { - const addressInfo = server.address() as AddressInfo; - - // Signal to HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on - console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {' + addressInfo.address + '} port ' + addressInfo.port + '\]'); - - // Signal to the NodeServices base class that we're ready to accept invocations - console.log('[Microsoft.AspNetCore.NodeServices:Listening]'); -}); - -exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true); - -function readRequestBodyAsJson(request, callback) { - let requestBodyAsString = ''; - request.on('data', chunk => { requestBodyAsString += chunk; }); - request.on('end', () => { callback(JSON.parse(requestBodyAsString)); }); -} - -function respondWithError(res: http.ServerResponse, errorValue: any) { - res.statusCode = 500; - res.end(JSON.stringify({ - errorMessage: errorValue.message || errorValue, - errorDetails: errorValue.stack || null - })); -} diff --git a/src/Middleware/NodeServices/src/TypeScript/Util/ArgsUtil.ts b/src/Middleware/NodeServices/src/TypeScript/Util/ArgsUtil.ts deleted file mode 100644 index cfafb5d2c6..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/Util/ArgsUtil.ts +++ /dev/null @@ -1,18 +0,0 @@ -export function parseArgs(args: string[]): any { - // Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external - // dependencies (such as an args-parsing library) to this file. - const result = {}; - let currentKey = null; - args.forEach(arg => { - if (arg.indexOf('--') === 0) { - const argName = arg.substring(2); - result[argName] = undefined; - currentKey = argName; - } else if (currentKey) { - result[currentKey] = arg; - currentKey = null; - } - }); - - return result; -} diff --git a/src/Middleware/NodeServices/src/TypeScript/Util/ExitWhenParentExits.ts b/src/Middleware/NodeServices/src/TypeScript/Util/ExitWhenParentExits.ts deleted file mode 100644 index 43c865f352..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/Util/ExitWhenParentExits.ts +++ /dev/null @@ -1,81 +0,0 @@ -/* -In general, we want the Node child processes to be terminated as soon as the parent .NET processes exit, -because we have no further use for them. If the .NET process shuts down gracefully, it will run its -finalizers, one of which (in OutOfProcessNodeInstance.cs) will kill its associated Node process immediately. - -But if the .NET process is terminated forcefully (e.g., on Linux/OSX with 'kill -9'), then it won't have -any opportunity to shut down its child processes, and by default they will keep running. In this case, it's -up to the child process to detect this has happened and terminate itself. - -There are many possible approaches to detecting when a parent process has exited, most of which behave -differently between Windows and Linux/OS X: - - - On Windows, the parent process can mark its child as being a 'job' that should auto-terminate when - the parent does (http://stackoverflow.com/a/4657392). Not cross-platform. - - The child Node process can get a callback when the parent disconnects (process.on('disconnect', ...)). - But despite http://stackoverflow.com/a/16487966, no callback fires in any case I've tested (Windows / OS X). - - The child Node process can get a callback when its stdin/stdout are disconnected, as described at - http://stackoverflow.com/a/15693934. This works well on OS X, but calling stdout.resume() on Windows - causes the process to terminate prematurely. - - I don't know why, but on Windows, it's enough to invoke process.stdin.resume(). For some reason this causes - the child Node process to exit as soon as the parent one does, but I don't see this documented anywhere. - - You can poll to see if the parent process, or your stdin/stdout connection to it, is gone - - You can directly pass a parent process PID to the child, and then have the child poll to see if it's - still running (e.g., using process.kill(pid, 0), which doesn't kill it but just tests whether it exists, - as per https://nodejs.org/api/process.html#process_process_kill_pid_signal) - - Or, on each poll, you can try writing to process.stdout. If the parent has died, then this will throw. - However I don't see this documented anywhere. It would be nice if you could just poll for whether or not - process.stdout is still connected (without actually writing to it) but I haven't found any property whose - value changes until you actually try to write to it. - -Of these, the only cross-platform approach that is actually documented as a valid strategy is simply polling -to check whether the parent PID is still running. So that's what we do here. -*/ - -const pollIntervalMs = 1000; - -export function exitWhenParentExits(parentPid: number, ignoreSigint: boolean) { - setInterval(() => { - if (!processExists(parentPid)) { - // Can't log anything at this point, because out stdout was connected to the parent, - // but the parent is gone. - process.exit(); - } - }, pollIntervalMs); - - if (ignoreSigint) { - // Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree. - // By default, the Node process would then exit before the .NET process, because ASP.NET implements - // a delayed shutdown to allow ongoing requests to complete. - // - // This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware - // will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is - // already set up to shut itself down if it detects the .NET process is terminated, all we have to do is - // ignore the SIGINT. The Node process will then terminate automatically after the .NET process does. - // - // A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any - // ongoing EventSource connections before letting the Node process exit, independently of the .NET - // process exiting. However, doing this well in general is very nontrivial (see all the discussion at - // https://github.com/nodejs/node/issues/2642). - process.on('SIGINT', () => { - console.log('Received SIGINT. Waiting for .NET process to exit...'); - }); - } -} - -function processExists(pid: number) { - try { - // Sending signal 0 - on all platforms - tests whether the process exists. As long as it doesn't - // throw, that means it does exist. - process.kill(pid, 0); - return true; - } catch (ex) { - // If the reason for the error is that we don't have permission to ask about this process, - // report that as a separate problem. - if (ex.code === 'EPERM') { - throw new Error(`Attempted to check whether process ${pid} was running, but got a permissions error.`); - } - - return false; - } -} diff --git a/src/Middleware/NodeServices/src/TypeScript/Util/OverrideStdOutputs.ts b/src/Middleware/NodeServices/src/TypeScript/Util/OverrideStdOutputs.ts deleted file mode 100644 index 01e4bc6de3..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/Util/OverrideStdOutputs.ts +++ /dev/null @@ -1,37 +0,0 @@ -// When Node writes to stdout/strerr, we capture that and convert the lines into calls on the -// active .NET ILogger. But by default, stdout/stderr don't have any way of distinguishing -// linebreaks inside log messages from the linebreaks that delimit separate log messages, -// so multiline strings will end up being written to the ILogger as multiple independent -// log messages. This makes them very hard to make sense of, especially when they represent -// something like stack traces. -// -// To fix this, we intercept stdout/stderr writes, and replace internal linebreaks with a -// marker token. When .NET receives the lines, it converts the marker tokens back to regular -// linebreaks within the logged messages. -// -// Note that it's better to do the interception at the stdout/stderr level, rather than at -// the console.log/console.error (etc.) level, because this takes place after any native -// message formatting has taken place (e.g., inserting values for % placeholders). -const findInternalNewlinesRegex = /\n(?!$)/g; -const encodedNewline = '__ns_newline__'; - -encodeNewlinesWrittenToStream(process.stdout); -encodeNewlinesWrittenToStream(process.stderr); - -function encodeNewlinesWrittenToStream(outputStream: NodeJS.WritableStream) { - const origWriteFunction = outputStream.write; - outputStream.write = function (value: any) { - // Only interfere with the write if it's definitely a string - if (typeof value === 'string') { - const argsClone = Array.prototype.slice.call(arguments, 0); - argsClone[0] = encodeNewlinesInString(value); - origWriteFunction.apply(this, argsClone); - } else { - origWriteFunction.apply(this, arguments); - } - }; -} - -function encodeNewlinesInString(str: string): string { - return str.replace(findInternalNewlinesRegex, encodedNewline); -} diff --git a/src/Middleware/NodeServices/src/TypeScript/Util/PatchModuleResolutionLStat.ts b/src/Middleware/NodeServices/src/TypeScript/Util/PatchModuleResolutionLStat.ts deleted file mode 100644 index de5185ff8b..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/Util/PatchModuleResolutionLStat.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as path from 'path'; -const startsWith = (str: string, prefix: string) => str.substring(0, prefix.length) === prefix; -const appRootDir = process.cwd(); - -function patchedLStat(pathToStatLong: string, fsReqWrap?: any) { - try { - // If the lstat completes without errors, we don't modify its behavior at all - return origLStat.apply(this, arguments); - } catch(ex) { - const shouldOverrideError = - startsWith(ex.message, 'EPERM') // It's a permissions error - && typeof appRootDirLong === 'string' - && startsWith(appRootDirLong, pathToStatLong) // ... for an ancestor directory - && ex.stack.indexOf('Object.realpathSync ') >= 0; // ... during symlink resolution - - if (shouldOverrideError) { - // Fake the result to give the same result as an 'lstat' on the app root dir. - // This stops Node failing to load modules just because it doesn't know whether - // ancestor directories are symlinks or not. If there's a genuine file - // permissions issue, it will still surface later when Node actually - // tries to read the file. - return origLStat.call(this, appRootDir, fsReqWrap); - } else { - // In any other case, preserve the original error - throw ex; - } - } -}; - -// It's only necessary to apply this workaround on Windows -let appRootDirLong: string = null; -let origLStat: Function = null; -if (/^win/.test(process.platform)) { - try { - // Get the app's root dir in Node's internal "long" format (e.g., \\?\C:\dir\subdir) - appRootDirLong = (path as any)._makeLong(appRootDir); - - // Actually apply the patch, being as defensive as possible - const bindingFs = (process as any).binding('fs'); - origLStat = bindingFs.lstat; - if (typeof origLStat === 'function') { - bindingFs.lstat = patchedLStat; - } - } catch(ex) { - // If some future version of Node throws (e.g., to prevent use of process.binding()), - // don't apply the patch, but still let the application run. - } -} diff --git a/src/Middleware/NodeServices/src/TypeScript/tsconfig.json b/src/Middleware/NodeServices/src/TypeScript/tsconfig.json deleted file mode 100644 index 896fc88253..0000000000 --- a/src/Middleware/NodeServices/src/TypeScript/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "es3", - "module": "commonjs", - "moduleResolution": "node", - "types": ["node"] - }, - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/NodeServices/src/Util/EmbeddedResourceReader.cs b/src/Middleware/NodeServices/src/Util/EmbeddedResourceReader.cs deleted file mode 100644 index 0c4c777e74..0000000000 --- a/src/Middleware/NodeServices/src/Util/EmbeddedResourceReader.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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 System.Reflection; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Contains methods for reading embedded resources. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class EmbeddedResourceReader - { - /// - /// Reads the specified embedded resource from a given assembly. - /// - /// Any in the assembly whose resource is to be read. - /// The path of the resource to be read. - /// The contents of the resource. - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static string Read(Type assemblyContainingType, string path) - { - var asm = assemblyContainingType.GetTypeInfo().Assembly; - var embeddedResourceName = asm.GetName().Name + path.Replace("/", "."); - - using (var stream = asm.GetManifestResourceStream(embeddedResourceName)) - using (var sr = new StreamReader(stream)) - { - return sr.ReadToEnd(); - } - } - } -} diff --git a/src/Middleware/NodeServices/src/Util/StringAsTempFile.cs b/src/Middleware/NodeServices/src/Util/StringAsTempFile.cs deleted file mode 100644 index ed9ee76172..0000000000 --- a/src/Middleware/NodeServices/src/Util/StringAsTempFile.cs +++ /dev/null @@ -1,86 +0,0 @@ -// 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 System.Threading; - -namespace Microsoft.AspNetCore.NodeServices -{ - /// - /// Makes it easier to pass script files to Node in a way that's sure to clean up after the process exits. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public sealed class StringAsTempFile : IDisposable - { - private bool _disposedValue; - private bool _hasDeletedTempFile; - private object _fileDeletionLock = new object(); - private IDisposable _applicationLifetimeRegistration; - - /// - /// Create a new instance of . - /// - /// The contents of the temporary file to be created. - /// A token that indicates when the host application is stopping. - public StringAsTempFile(string content, CancellationToken applicationStoppingToken) - { - FileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - File.WriteAllText(FileName, content); - - // Because .NET finalizers don't reliably run when the process is terminating, also - // add event handlers for other shutdown scenarios. - _applicationLifetimeRegistration = applicationStoppingToken.Register(EnsureTempFileDeleted); - } - - /// - /// Specifies the filename of the temporary file. - /// - public string FileName { get; } - - /// - /// Disposes the instance and deletes the associated temporary file. - /// - public void Dispose() - { - DisposeImpl(true); - GC.SuppressFinalize(this); - } - - private void DisposeImpl(bool disposing) - { - if (!_disposedValue) - { - if (disposing) - { - // Dispose managed state - _applicationLifetimeRegistration.Dispose(); - } - - EnsureTempFileDeleted(); - - _disposedValue = true; - } - } - - private void EnsureTempFileDeleted() - { - lock (_fileDeletionLock) - { - if (!_hasDeletedTempFile) - { - File.Delete(FileName); - _hasDeletedTempFile = true; - } - } - } - - /// - /// Implements the finalization part of the IDisposable pattern by calling Dispose(false). - /// - ~StringAsTempFile() - { - DisposeImpl(false); - } - } -} diff --git a/src/Middleware/NodeServices/src/Util/TaskExtensions.cs b/src/Middleware/NodeServices/src/Util/TaskExtensions.cs deleted file mode 100644 index 8743b9e4b5..0000000000 --- a/src/Middleware/NodeServices/src/Util/TaskExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.NodeServices -{ - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal static class TaskExtensions - { - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static Task OrThrowOnCancellation(this Task task, CancellationToken cancellationToken) - { - return task.IsCompleted - ? task // If the task is already completed, no need to wrap it in a further layer of task - : task.ContinueWith( - _ => {}, // If the task completes, allow execution to continue - cancellationToken, - TaskContinuationOptions.ExecuteSynchronously, - TaskScheduler.Default); - } - - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static Task OrThrowOnCancellation(this Task task, CancellationToken cancellationToken) - { - return task.IsCompleted - ? task // If the task is already completed, no need to wrap it in a further layer of task - : task.ContinueWith( - t => t.Result, // If the task completes, pass through its result - cancellationToken, - TaskContinuationOptions.ExecuteSynchronously, - TaskScheduler.Default); - } - } -} diff --git a/src/Middleware/NodeServices/src/package.json b/src/Middleware/NodeServices/src/package.json deleted file mode 100644 index 4cf7243410..0000000000 --- a/src/Middleware/NodeServices/src/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "nodeservices", - "version": "1.0.0", - "description": "This is not really an NPM package and will not be published. This file exists only to reference compilation tools.", - "private": true, - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "webpack --mode production" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "devDependencies": { - "@types/node": "^10.9.2", - "ts-loader": "^4.5.0", - "typescript": "^3.0.1", - "webpack": "^4.17.1", - "webpack-cli": "^3.1.0" - } -} diff --git a/src/Middleware/NodeServices/src/webpack.config.js b/src/Middleware/NodeServices/src/webpack.config.js deleted file mode 100644 index af32593fb3..0000000000 --- a/src/Middleware/NodeServices/src/webpack.config.js +++ /dev/null @@ -1,24 +0,0 @@ -const path = require('path'); - -module.exports = { - target: 'node', - resolve: { - extensions: [ '.ts' ] - }, - module: { - rules: [ - { test: /\.ts$/, use: 'ts-loader' }, - ] - }, - entry: { - 'entrypoint-http': ['./TypeScript/HttpNodeInstanceEntryPoint'] - }, - output: { - libraryTarget: 'commonjs', - path: path.join(__dirname, 'Content', 'Node'), - filename: '[name].js' - }, - optimization: { - minimize: false - } -}; diff --git a/src/Middleware/NodeServices/src/yarn.lock b/src/Middleware/NodeServices/src/yarn.lock deleted file mode 100644 index 09857158cf..0000000000 --- a/src/Middleware/NodeServices/src/yarn.lock +++ /dev/null @@ -1,2962 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/node@^10.9.2": - version "10.9.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.9.2.tgz#f0ab8dced5cd6c56b26765e1c0d9e4fdcc9f2a00" - integrity sha512-pwZnkVyCGJ3LsQ0/3flQK5lCFao4esIzwUVzzk5NvL9vnkEyDhNf4fhHzUMHvyr56gNZywWTS2MR0euabMSz4A== - -"@webassemblyjs/ast@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" - integrity sha512-49nwvW/Hx9i+OYHg+mRhKZfAlqThr11Dqz8TsrvqGKMhdI2ijy3KBJOun2Z4770TPjrIJhR6KxChQIDaz8clDA== - dependencies: - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - debug "^3.1.0" - mamacro "^0.0.3" - -"@webassemblyjs/floating-point-hex-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" - integrity sha512-vrvvB18Kh4uyghSKb0NTv+2WZx871WL2NzwMj61jcq2bXkyhRC+8Q0oD7JGVf0+5i/fKQYQSBCNMMsDMRVAMqA== - -"@webassemblyjs/helper-api-error@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" - integrity sha512-dBh2CWYqjaDlvMmRP/kudxpdh30uXjIbpkLj9HQe+qtYlwvYjPRjdQXrq1cTAAOUSMTtzqbXIxEdEZmyKfcwsg== - -"@webassemblyjs/helper-buffer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" - integrity sha512-v7igWf1mHcpJNbn4m7e77XOAWXCDT76Xe7Is1VQFXc4K5jRcFrl9D0NrqM4XifQ0bXiuTSkTKMYqDxu5MhNljA== - dependencies: - debug "^3.1.0" - -"@webassemblyjs/helper-code-frame@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" - integrity sha512-yN6ScQQDFCiAXnVctdVO/J5NQRbwyTbQzsGzEgXsAnrxhjp0xihh+nNHQTMrq5UhOqTb5LykpJAvEv9AT0jnAQ== - dependencies: - "@webassemblyjs/wast-printer" "1.5.13" - -"@webassemblyjs/helper-fsm@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" - integrity sha512-hSIKzbXjVMRvy3Jzhgu+vDd/aswJ+UMEnLRCkZDdknZO3Z9e6rp1DAs0tdLItjCFqkz9+0BeOPK/mk3eYvVzZg== - -"@webassemblyjs/helper-module-context@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" - integrity sha512-zxJXULGPLB7r+k+wIlvGlXpT4CYppRz8fLUM/xobGHc9Z3T6qlmJD9ySJ2jknuktuuiR9AjnNpKYDECyaiX+QQ== - dependencies: - debug "^3.1.0" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" - integrity sha512-0n3SoNGLvbJIZPhtMFq0XmmnA/YmQBXaZKQZcW8maGKwLpVcgjNrxpFZHEOLKjXJYVN5Il8vSfG7nRX50Zn+aw== - -"@webassemblyjs/helper-wasm-section@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" - integrity sha512-IJ/goicOZ5TT1axZFSnlAtz4m8KEjYr12BNOANAwGFPKXM4byEDaMNXYowHMG0yKV9a397eU/NlibFaLwr1fbw== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/ieee754@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" - integrity sha512-TseswvXEPpG5TCBKoLx9tT7+/GMACjC1ruo09j46ULRZWYm8XHpDWaosOjTnI7kr4SRJFzA6MWoUkAB+YCGKKg== - dependencies: - ieee754 "^1.1.11" - -"@webassemblyjs/leb128@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" - integrity sha512-0NRMxrL+GG3eISGZBmLBLAVjphbN8Si15s7jzThaw1UE9e5BY1oH49/+MA1xBzxpf1OW5sf9OrPDOclk9wj2yg== - dependencies: - long "4.0.0" - -"@webassemblyjs/utf8@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" - integrity sha512-Ve1ilU2N48Ew0lVGB8FqY7V7hXjaC4+PeZM+vDYxEd+R2iQ0q+Wb3Rw8v0Ri0+rxhoz6gVGsnQNb4FjRiEH/Ng== - -"@webassemblyjs/wasm-edit@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" - integrity sha512-X7ZNW4+Hga4f2NmqENnHke2V/mGYK/xnybJSIXImt1ulxbCOEs/A+ZK/Km2jgihjyVxp/0z0hwIcxC6PrkWtgw== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/helper-wasm-section" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - "@webassemblyjs/wast-printer" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/wasm-gen@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" - integrity sha512-yfv94Se8R73zmr8GAYzezFHc3lDwE/lBXQddSiIZEKZFuqy7yWtm3KMwA1uGbv5G1WphimJxboXHR80IgX1hQA== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" - -"@webassemblyjs/wasm-opt@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" - integrity sha512-IkXSkgzVhQ0QYAdIayuCWMmXSYx0dHGU8Ah/AxJf1gBvstMWVnzJnBwLsXLyD87VSBIcsqkmZ28dVb0mOC3oBg== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-buffer" "1.5.13" - "@webassemblyjs/wasm-gen" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - debug "^3.1.0" - -"@webassemblyjs/wasm-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" - integrity sha512-XnYoIcu2iqq8/LrtmdnN3T+bRjqYFjRHqWbqK3osD/0r/Fcv4d9ecRzjVtC29ENEuNTK4mQ9yyxCBCbK8S/cpg== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-wasm-bytecode" "1.5.13" - "@webassemblyjs/ieee754" "1.5.13" - "@webassemblyjs/leb128" "1.5.13" - "@webassemblyjs/utf8" "1.5.13" - -"@webassemblyjs/wast-parser@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" - integrity sha512-Lbz65T0LQ1LgzKiUytl34CwuhMNhaCLgrh0JW4rJBN6INnBB8NMwUfQM+FxTnLY9qJ+lHJL/gCM5xYhB9oWi4A== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/floating-point-hex-parser" "1.5.13" - "@webassemblyjs/helper-api-error" "1.5.13" - "@webassemblyjs/helper-code-frame" "1.5.13" - "@webassemblyjs/helper-fsm" "1.5.13" - long "^3.2.0" - mamacro "^0.0.3" - -"@webassemblyjs/wast-printer@1.5.13": - version "1.5.13" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" - integrity sha512-QcwogrdqcBh8Z+eUF8SG+ag5iwQSXxQJELBEHmLkk790wgQgnIMmntT2sMAMw53GiFNckArf5X0bsCA44j3lWQ== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/wast-parser" "1.5.13" - long "^3.2.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-dynamic-import@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== - dependencies: - acorn "^5.0.0" - -acorn@^5.0.0, acorn@^5.6.2: - version "5.7.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5" - integrity sha512-cJrKCNcr2kv8dlDnbw+JPUGjHZzo4myaxOLmpOX8a+rgX94YeTcTMv/LFJUSByRpc+i4GgVnnhLxvMu/2Y+rqw== - -ajv-keywords@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" - integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= - -ajv@^6.1.0: - version "6.5.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" - integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - integrity sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0= - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= - dependencies: - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== - -binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - integrity sha1-RqoXUftqL5PuXmibsQh9SxTGwgU= - -bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.0, braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -cacache@^10.0.4: - version "10.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" - integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== - dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.1" - mississippi "^2.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.2" - ssri "^5.2.4" - unique-filename "^1.1.0" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chardet@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" - integrity sha512-9ZTaoBaePSCFvNlNGrsyI8ZVACP2svUtq0DkM7t4K2ClAa96sqOIRjAzDTc8zXzFt1cZR46rRzLTiHFSJ+Qw0g== - -chokidar@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" - integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" - glob-parent "^3.1.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" - optionalDependencies: - fsevents "^1.2.2" - -chownr@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= - -chrome-trace-event@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" - integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== - dependencies: - tslib "^1.9.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= - -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= - -debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -decamelize@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" - integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== - dependencies: - xregexp "4.0.0" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-extend@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f" - integrity sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w== - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" - integrity sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -elliptic@^6.0.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" - integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= - -events@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -external-editor@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.1.tgz#fc9638c4d7cde4f0bb82b12307a1a23912c492e3" - integrity sha512-e1neqvSt5pSwQcFnYc6yfGuJD2Q4336cdbHs5VeUO0zTkqPbrHMyw2q1r47fpfLWbvIG8H8A6YO3sck7upTV6Q== - dependencies: - chardet "^0.5.0" - iconv-lite "^0.4.22" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= - dependencies: - commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flush-write-stream@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" - integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" - integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob@^7.0.5, glob@^7.1.2: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules-path@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" - integrity sha512-HchvMJNYh9dGSCy8pOQ2O8u/hoXaL+0XhnrwH0RyLiSXMMTl9W3N6KUU73+JFOg5PGjtzl6VZzUQsnrpm7Szag== - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" - integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -iconv-lite@^0.4.22: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.4.4: - version "0.4.21" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" - integrity sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw== - dependencies: - safer-buffer "^2.1.0" - -ieee754@^1.1.11, ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -import-local@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" - integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== - dependencies: - pkg-dir "^2.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" - integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.17.10" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -interpret@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -loader-runner@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" - integrity sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI= - -loader-utils@^1.0.2, loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash@^4.17.10: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== - -long@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= - -lru-cache@^4.0.1, lru-cache@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" - integrity sha1-6b296UogpawYsENA/Fdk1bCdkB0= - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - -memory-fs@^0.4.0, memory-fs@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -micromatch@^3.1.4, micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.4.tgz#03c824d84551ec38a8d1bb5bc350a5a30a354a40" - integrity sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g== - dependencies: - safe-buffer "^5.1.1" - yallist "^3.0.0" - -minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" - integrity sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA== - dependencies: - minipass "^2.2.1" - -mississippi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" - integrity sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^2.0.1" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nan@^2.9.2: - version "2.11.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" - integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -needle@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.0.tgz#f14efc69cee1024b72c8b21c7bdf94a731dc12fa" - integrity sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w== - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.5.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.2.tgz#489105ce7bc54e709d736b195f82135048c50fcc" - integrity sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-libs-browser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" - integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^1.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.0" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.10.3" - vm-browserify "0.0.4" - -node-pre-gyp@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz#6e4ef5bb5c5203c6552448828c852c40111aac46" - integrity sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.0" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.1.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -npm-bundled@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" - integrity sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow== - -npm-packlist@^1.1.6: - version "1.1.10" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" - integrity sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" - integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" - integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== - -pako@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" - integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== - -parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= - dependencies: - cyclist "~0.2.2" - inherits "^2.0.3" - readable-stream "^2.1.5" - -parse-asn1@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" - integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -pbkdf2@^3.0.3: - version "3.0.16" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" - integrity sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -public-encrypt@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" - integrity sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - -pump@^2.0.0, pump@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -rc@^1.1.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.7.tgz#8a10ca30d588d00464360372b890d06dacd02297" - integrity sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA== - dependencies: - deep-extend "^0.5.1" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - integrity sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg= - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== - dependencies: - glob "^7.0.5" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -rxjs@^6.1.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9" - integrity sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -schema-utils@^0.4.4, schema-utils@^0.4.5: - version "0.4.7" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" - integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== - dependencies: - ajv "^6.1.0" - ajv-keywords "^3.1.0" - -semver@^5.0.1, semver@^5.5.0: - version "5.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" - integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== - -semver@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== - -serialize-javascript@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" - integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" - integrity sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A== - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -ssri@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" - integrity sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ== - dependencies: - safe-buffer "^5.1.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.0.0, string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -supports-color@^5.3.0, supports-color@^5.4.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -tapable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" - integrity sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg== - -tar@^4: - version "4.4.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.1.tgz#b25d5a8470c976fd7a9a8a350f42c59e9fa81749" - integrity sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg== - dependencies: - chownr "^1.0.1" - fs-minipass "^1.2.5" - minipass "^2.2.4" - minizlib "^1.1.0" - mkdirp "^0.5.0" - safe-buffer "^5.1.1" - yallist "^3.0.2" - -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== - dependencies: - setimmediate "^1.0.4" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -ts-loader@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-4.5.0.tgz#a1ce70b2dc799941fb2197605f0d67874097859b" - integrity sha512-ihgVaSmgrX4crGV4n7yuoHPoCHbDzj9aepCZR9TgIx4SgJ9gdnB6xLHgUBb7bsFM/f0K6x9iXa65KY/Fu1Klkw== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^3.1.4" - semver "^5.0.1" - -tslib@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.1.tgz#43738f29585d3a87575520a4b93ab6026ef11fdb" - integrity sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg== - -uglify-es@^3.3.4: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -uglifyjs-webpack-plugin@^1.2.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" - integrity sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw== - dependencies: - cacache "^10.0.4" - find-cache-dir "^1.0.0" - schema-utils "^0.4.5" - serialize-javascript "^1.4.0" - source-map "^0.6.1" - uglify-es "^3.3.4" - webpack-sources "^1.1.0" - worker-farm "^1.5.2" - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unique-filename@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" - integrity sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM= - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" - integrity sha1-22Z258fMBimHj/GWCXx4hVrp9Ks= - dependencies: - imurmurhash "^0.1.4" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.10.3: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== - dependencies: - inherits "2.0.3" - -v8-compile-cache@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" - integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== - -vm-browserify@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" - integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= - dependencies: - indexof "0.0.1" - -watchpack@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -webpack-cli@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.0.tgz#d71a83687dcfeb758fdceeb0fe042f96bcf62994" - integrity sha512-p5NeKDtYwjZozUWq6kGNs9w+Gtw/CPvyuXjXn2HMdz8Tie+krjEg8oAtonvIyITZdvpF7XG9xDHwscLr2c+ugQ== - dependencies: - chalk "^2.4.1" - cross-spawn "^6.0.5" - enhanced-resolve "^4.0.0" - global-modules-path "^2.1.0" - import-local "^1.0.0" - inquirer "^6.0.0" - interpret "^1.1.0" - loader-utils "^1.1.0" - supports-color "^5.4.0" - v8-compile-cache "^2.0.0" - yargs "^12.0.1" - -webpack-sources@^1.0.1, webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" - integrity sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.17.1.tgz#0f026e3d823f3fc604f811ed3ea8f0d9b267fb1e" - integrity sha512-vdPYogljzWPhFKDj3Gcp01Vqgu7K3IQlybc3XIdKSQHelK1C3eIQuysEUR7MxKJmdandZlQB/9BG2Jb1leJHaw== - dependencies: - "@webassemblyjs/ast" "1.5.13" - "@webassemblyjs/helper-module-context" "1.5.13" - "@webassemblyjs/wasm-edit" "1.5.13" - "@webassemblyjs/wasm-opt" "1.5.13" - "@webassemblyjs/wasm-parser" "1.5.13" - acorn "^5.6.2" - acorn-dynamic-import "^3.0.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - chrome-trace-event "^1.0.0" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.0" - json-parse-better-errors "^1.0.2" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - micromatch "^3.1.8" - mkdirp "~0.5.0" - neo-async "^2.5.0" - node-libs-browser "^2.0.0" - schema-utils "^0.4.4" - tapable "^1.0.0" - uglifyjs-webpack-plugin "^1.2.4" - watchpack "^1.5.0" - webpack-sources "^1.0.1" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - integrity sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w== - dependencies: - string-width "^1.0.2" - -worker-farm@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" - integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xregexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" - integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= - -yargs-parser@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" - integrity sha512-B0vRAp1hRX4jgIOWFtjfNjd9OA9RWYZ6tqGA9/I/IrTMsxmKvtWy+ersM+jzpQqbC3YfLzeABPdeTgcJ9eu1qQ== - dependencies: - cliui "^4.0.0" - decamelize "^2.0.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^10.1.0" diff --git a/src/Middleware/NodeServices/test/Microsoft.AspNetCore.NodeServices.Tests.csproj b/src/Middleware/NodeServices/test/Microsoft.AspNetCore.NodeServices.Tests.csproj deleted file mode 100644 index 2d1a5aab26..0000000000 --- a/src/Middleware/NodeServices/test/Microsoft.AspNetCore.NodeServices.Tests.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - true - - - - - - - - - diff --git a/src/Middleware/NodeServices/test/NodeServicesTest.cs b/src/Middleware/NodeServices/test/NodeServicesTest.cs deleted file mode 100644 index 0ad53c117b..0000000000 --- a/src/Middleware/NodeServices/test/NodeServicesTest.cs +++ /dev/null @@ -1,138 +0,0 @@ -// 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 System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; -using Microsoft.AspNetCore.NodeServices.HostingModels; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace Microsoft.AspNetCore.NodeServices -{ - [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/22084", Queues = "Windows.10.Arm64;Windows.10.Arm64.Open")] - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class NodeServicesTest : IDisposable - { - private readonly INodeServices _nodeServices; - - public NodeServicesTest() - { - // In typical ASP.NET Core applications, INodeServices is made available - // through DI using services.AddNodeServices(). But for these tests we - // create our own INodeServices instance manually, since the tests are - // not about DI (and we might want different config for each test). - var serviceProvider = new ServiceCollection().BuildServiceProvider(); - var options = new NodeServicesOptions(serviceProvider); - _nodeServices = NodeServicesFactory.CreateNodeServices(options); - } - - [ConditionalFact] - public async Task CanGetSuccessResult() - { - // Act - var result = await _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "getFixedString"); - - // Assert - Assert.Equal("test result", result); - } - - [ConditionalFact] - public async Task CanGetErrorResult() - { - // Act/Assert - var ex = await Assert.ThrowsAsync(() => - _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "raiseError")); - Assert.StartsWith("This is an error from Node", ex.Message); - } - - [ConditionalFact] - public async Task CanGetResultAsynchronously() - { - // Act - // All the invocations are async, but this test shows we're not reliant - // on the response coming back immediately - var result = await _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "getFixedStringWithDelay"); - - // Assert - Assert.Equal("delayed test result", result); - } - - [ConditionalFact] - public async Task CanPassParameters() - { - // Act - var result = await _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "echoSimpleParameters", - "Hey", - 123); - - // Assert - Assert.Equal("Param0: Hey; Param1: 123", result); - } - - [ConditionalFact] - public async Task CanPassParametersWithCamelCaseNameConversion() - { - // Act - var result = await _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "echoComplexParameters", - new ComplexModel { StringProp = "Abc", IntProp = 123, BoolProp = true }); - - // Assert - Assert.Equal("Received: [{\"stringProp\":\"Abc\",\"intProp\":123,\"boolProp\":true}]", result); - } - - [ConditionalFact] - public async Task CanReceiveComplexResultWithPascalCaseNameConversion() - { - // Act - var result = await _nodeServices.InvokeExportAsync( - ModulePath("testCases"), - "getComplexObject"); - - // Assert - Assert.Equal("Hi from Node", result.StringProp); - Assert.Equal(456, result.IntProp); - Assert.True(result.BoolProp); - } - - [ConditionalFact] - public async Task CanInvokeDefaultModuleExport() - { - // Act - var result = await _nodeServices.InvokeAsync( - ModulePath("moduleWithDefaultExport"), - "This is from .NET"); - - // Assert - Assert.Equal("Hello from the default export. You passed: This is from .NET", result); - } - - private static string ModulePath(string testModuleName) - => Path.Combine(AppContext.BaseDirectory, "js", testModuleName); - - public void Dispose() - { - _nodeServices.Dispose(); - } - - class ComplexModel - { - public string StringProp { get; set; } - - public int IntProp { get; set; } - - public bool BoolProp { get; set; } - } - } -} diff --git a/src/Middleware/NodeServices/test/js/moduleWithDefaultExport.js b/src/Middleware/NodeServices/test/js/moduleWithDefaultExport.js deleted file mode 100644 index eae7f7ccf4..0000000000 --- a/src/Middleware/NodeServices/test/js/moduleWithDefaultExport.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (callback, message) { - callback(null, `Hello from the default export. You passed: ${message}`); -}; diff --git a/src/Middleware/NodeServices/test/js/testCases.js b/src/Middleware/NodeServices/test/js/testCases.js deleted file mode 100644 index 74b3a49ccf..0000000000 --- a/src/Middleware/NodeServices/test/js/testCases.js +++ /dev/null @@ -1,28 +0,0 @@ -// Function signatures follow Node conventions. -// i.e., parameters: (callback, arg0, arg1, ... etc ...) -// When done, functions must invoke 'callback', passing (errorInfo, result) -// where errorInfo should be null/undefined if there was no error. - -exports.getFixedString = function (callback) { - callback(null, 'test result'); -}; - -exports.getFixedStringWithDelay = function (callback) { - setTimeout(callback(null, 'delayed test result'), 100); -}; - -exports.raiseError = function (callback) { - callback('This is an error from Node'); -}; - -exports.echoSimpleParameters = function (callback, param0, param1) { - callback(null, `Param0: ${param0}; Param1: ${param1}`); -}; - -exports.echoComplexParameters = function (callback, ...otherArgs) { - callback(null, `Received: ${JSON.stringify(otherArgs)}`); -}; - -exports.getComplexObject = function (callback) { - callback(null, { stringProp: 'Hi from Node', intProp: 456, boolProp: true }); -}; diff --git a/src/Middleware/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj b/src/Middleware/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj index 6e6befbe9b..f05b05d9ea 100644 --- a/src/Middleware/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj +++ b/src/Middleware/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj @@ -6,7 +6,6 @@ - @@ -16,4 +15,10 @@ + + + + diff --git a/src/Middleware/SpaServices.Extensions/src/Prerendering/SpaPrerenderingExtensions.cs b/src/Middleware/SpaServices.Extensions/src/Prerendering/SpaPrerenderingExtensions.cs deleted file mode 100644 index a9438b3f4c..0000000000 --- a/src/Middleware/SpaServices.Extensions/src/Prerendering/SpaPrerenderingExtensions.cs +++ /dev/null @@ -1,272 +0,0 @@ -// 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 Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.NodeServices; -using Microsoft.AspNetCore.SpaServices; -using Microsoft.AspNetCore.SpaServices.Extensions.Util; -using Microsoft.AspNetCore.SpaServices.Prerendering; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Net.Http.Headers; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Builder -{ - /// - /// Extension methods for configuring prerendering of a Single Page Application. - /// - [Obsolete("Prerendering is no longer supported out of box")] - public static class SpaPrerenderingExtensions - { - /// - /// Enables server-side prerendering middleware for a Single Page Application. - /// - /// The . - /// Supplies configuration for the prerendering middleware. - [Obsolete("Prerendering is no longer supported out of box")] - public static void UseSpaPrerendering( - this ISpaBuilder spaBuilder, - Action configuration) - { - if (spaBuilder == null) - { - throw new ArgumentNullException(nameof(spaBuilder)); - } - - if (configuration == null) - { - throw new ArgumentNullException(nameof(configuration)); - } - - var options = new SpaPrerenderingOptions(); - configuration.Invoke(options); - - var capturedBootModulePath = options.BootModulePath; - if (string.IsNullOrEmpty(capturedBootModulePath)) - { - throw new InvalidOperationException($"To use {nameof(UseSpaPrerendering)}, you " + - $"must set a nonempty value on the ${nameof(SpaPrerenderingOptions.BootModulePath)} " + - $"property on the ${nameof(SpaPrerenderingOptions)}."); - } - - // If we're building on demand, start that process in the background now - var buildOnDemandTask = options.BootModuleBuilder?.Build(spaBuilder); - - // Get all the necessary context info that will be used for each prerendering call - var applicationBuilder = spaBuilder.ApplicationBuilder; - var serviceProvider = applicationBuilder.ApplicationServices; - var nodeServices = GetNodeServices(serviceProvider); - var applicationStoppingToken = serviceProvider.GetRequiredService() - .ApplicationStopping; - var applicationBasePath = serviceProvider.GetRequiredService() - .ContentRootPath; - var moduleExport = new JavaScriptModuleExport(capturedBootModulePath); - var excludePathStrings = (options.ExcludeUrls ?? Array.Empty()) - .Select(url => new PathString(url)) - .ToArray(); - var buildTimeout = spaBuilder.Options.StartupTimeout; - - applicationBuilder.Use(async (context, next) => - { - // If this URL is excluded, skip prerendering. - // This is typically used to ensure that static client-side resources - // (e.g., /dist/*.css) are served normally or through SPA development - // middleware, and don't return the prerendered index.html page. - foreach (var excludePathString in excludePathStrings) - { - if (context.Request.Path.StartsWithSegments(excludePathString)) - { - await next(); - return; - } - } - - // If we're building on demand, wait for that to finish, or raise any build errors - if (buildOnDemandTask != null && !buildOnDemandTask.IsCompleted) - { - // For better debuggability, create a per-request timeout that makes it clear if the - // prerendering builder took too long for this request, but without aborting the - // underlying build task so that subsequent requests could still work. - await buildOnDemandTask.WithTimeout(buildTimeout, - $"The prerendering build process did not complete within the " + - $"timeout period of {buildTimeout.Seconds} seconds. " + - $"Check the log output for error information."); - } - - // It's no good if we try to return a 304. We need to capture the actual - // HTML content so it can be passed as a template to the prerenderer. - RemoveConditionalRequestHeaders(context.Request); - - // Make sure we're not capturing compressed content, because then we'd have - // to decompress it. Since this sub-request isn't leaving the machine, there's - // little to no benefit in having compression on it. - var originalAcceptEncodingValue = GetAndRemoveAcceptEncodingHeader(context.Request); - - // Capture the non-prerendered responses, which in production will typically only - // be returning the default SPA index.html page (because other resources will be - // served statically from disk). We will use this as a template in which to inject - // the prerendered output. - using (var outputBuffer = new MemoryStream()) - { - var originalResponseStream = context.Response.Body; - context.Response.Body = outputBuffer; - - try - { - await next(); - outputBuffer.Seek(0, SeekOrigin.Begin); - } - finally - { - context.Response.Body = originalResponseStream; - - if (!string.IsNullOrEmpty(originalAcceptEncodingValue)) - { - context.Request.Headers[HeaderNames.AcceptEncoding] = originalAcceptEncodingValue; - } - } - - // If it isn't an HTML page that we can use as the template for prerendering, - // - ... because it's not text/html - // - ... or because it's an error - // then prerendering doesn't apply to this request, so just pass through the - // response as-is. Note that the non-text/html case is not an error: this is - // typically how the SPA dev server responses for static content are returned - // in development mode. - var canPrerender = IsSuccessStatusCode(context.Response.StatusCode) - && IsHtmlContentType(context.Response.ContentType); - if (!canPrerender) - { - await outputBuffer.CopyToAsync(context.Response.Body); - return; - } - - // Most prerendering logic will want to know about the original, unprerendered - // HTML that the client would be getting otherwise. Typically this is used as - // a template from which the fully prerendered page can be generated. - var customData = new Dictionary - { - { "originalHtml", Encoding.UTF8.GetString(outputBuffer.GetBuffer()) } - }; - - // If the developer wants to use custom logic to pass arbitrary data to the - // prerendering JS code (e.g., to pass through cookie data), now's their chance - options.SupplyData?.Invoke(context, customData); - - var (unencodedAbsoluteUrl, unencodedPathAndQuery) - = GetUnencodedUrlAndPathQuery(context); - var renderResult = await Prerenderer.RenderToString( - applicationBasePath, - nodeServices, - applicationStoppingToken, - moduleExport, - unencodedAbsoluteUrl, - unencodedPathAndQuery, - customDataParameter: customData, - timeoutMilliseconds: 0, - requestPathBase: context.Request.PathBase.ToString()); - - await ServePrerenderResult(context, renderResult); - } - }); - } - - private static bool IsHtmlContentType(string contentType) - { - if (string.Equals(contentType, "text/html", StringComparison.Ordinal)) - { - return true; - } - - return contentType != null - && contentType.StartsWith("text/html;", StringComparison.Ordinal); - } - - private static bool IsSuccessStatusCode(int statusCode) - => statusCode >= 200 && statusCode < 300; - - private static void RemoveConditionalRequestHeaders(HttpRequest request) - { - request.Headers.Remove(HeaderNames.IfMatch); - request.Headers.Remove(HeaderNames.IfModifiedSince); - request.Headers.Remove(HeaderNames.IfNoneMatch); - request.Headers.Remove(HeaderNames.IfUnmodifiedSince); - request.Headers.Remove(HeaderNames.IfRange); - } - - private static string GetAndRemoveAcceptEncodingHeader(HttpRequest request) - { - var headers = request.Headers; - var value = (string)null; - - if (headers.ContainsKey(HeaderNames.AcceptEncoding)) - { - value = headers[HeaderNames.AcceptEncoding]; - headers.Remove(HeaderNames.AcceptEncoding); - } - - return value; - } - - private static (string, string) GetUnencodedUrlAndPathQuery(HttpContext httpContext) - { - // This is a duplicate of code from Prerenderer.cs in the SpaServices package. - // Once the SpaServices.Extension package implementation gets merged back into - // SpaServices, this duplicate can be removed. To remove this, change the code - // above that calls Prerenderer.RenderToString to use the internal overload - // that takes an HttpContext instead of a url/path+query pair. - var requestFeature = httpContext.Features.Get(); - var unencodedPathAndQuery = requestFeature.RawTarget; - var request = httpContext.Request; - var unencodedAbsoluteUrl = $"{request.Scheme}://{request.Host}{unencodedPathAndQuery}"; - return (unencodedAbsoluteUrl, unencodedPathAndQuery); - } - - private static async Task ServePrerenderResult(HttpContext context, RenderToStringResult renderResult) - { - context.Response.Clear(); - - if (!string.IsNullOrEmpty(renderResult.RedirectUrl)) - { - var permanentRedirect = renderResult.StatusCode.GetValueOrDefault() == 301; - context.Response.Redirect(renderResult.RedirectUrl, permanentRedirect); - } - else - { - // The Globals property exists for back-compatibility but is meaningless - // for prerendering that returns complete HTML pages - if (renderResult.Globals != null) - { - throw new InvalidOperationException($"{nameof(renderResult.Globals)} is not " + - $"supported when prerendering via {nameof(UseSpaPrerendering)}(). Instead, " + - $"your prerendering logic should return a complete HTML page, in which you " + - $"embed any information you wish to return to the client."); - } - - if (renderResult.StatusCode.HasValue) - { - context.Response.StatusCode = renderResult.StatusCode.Value; - } - - context.Response.ContentType = "text/html"; - await context.Response.WriteAsync(renderResult.Html); - } - } - - private static INodeServices GetNodeServices(IServiceProvider serviceProvider) - { - // Use the registered instance, or create a new private instance if none is registered - var instance = (INodeServices)serviceProvider.GetService(typeof(INodeServices)); - return instance ?? NodeServicesFactory.CreateNodeServices( - new NodeServicesOptions(serviceProvider)); - } - } -} diff --git a/src/Middleware/SpaServices/README.md b/src/Middleware/SpaServices/README.md deleted file mode 100644 index c5a524a656..0000000000 --- a/src/Middleware/SpaServices/README.md +++ /dev/null @@ -1,821 +0,0 @@ -# Microsoft.AspNetCore.SpaServices - -If you're building an ASP.NET Core application, and want to use Angular, React, Knockout, or another single-page app (SPA) framework, this NuGet package contains useful infrastructure for you. - -This package enables: - - * [**Server-side prerendering**](#server-side-prerendering) for *universal* (a.k.a. *isomorphic*) applications, where your Angular / React / etc. components are first rendered on the server, and then transferred to the client where execution continues - * [**Webpack middleware**](#webpack-dev-middleware) so that, during development, any webpack-built resources will be generated on demand, without you having to run webpack manually or compile files to disk - * [**Hot module replacement**](#webpack-hot-module-replacement) so that, during development, your code and markup changes will be pushed to your browser and updated in the running application automatically, without even needing to reload the page - * [**Routing helpers**](#routing-helper-mapspafallbackroute) for integrating server-side routing with client-side routing - -Behind the scenes, it uses the [`Microsoft.AspNetCore.NodeServices`](src/Middleware/NodeServices) package as a fast and robust way to invoke Node.js-hosted code from ASP.NET Core at runtime. - -### Requirements - -* [Node.js](https://nodejs.org/en/) - * To test this is installed and can be found, run `node -v` on a command line - * Note: If you're deploying to an Azure web site, you don't need to do anything here - Node is already installed and available in the server environments -* [.NET Core](https://dot.net), version 1.0 RC2 or later - -### Installation into existing projects - - * Install the `Microsoft.AspNetCore.SpaServices` NuGet package - * Run `dotnet restore` (or if you use Visual Studio, just wait a moment - it will restore dependencies automatically) - * Install supporting NPM packages for the features you'll be using: - * For **server-side prerendering**, install `aspnet-prerendering` - * For **server-side prerendering with Webpack build support**, also install `aspnet-webpack` - * For **webpack dev middleware**, install `aspnet-webpack` - * For **webpack dev middleware with hot module replacement**, also install `webpack-hot-middleware` - * For **webpack dev middleware with React hot module replacement**, also install `aspnet-webpack-react` - - For example, run `npm install --save aspnet-prerendering aspnet-webpack` to install `aspnet-prerendering` and `aspnet-webpack`. - - -### Creating entirely new projects - -If you're starting from scratch, you might prefer to use the `aspnetcore-spa` Yeoman generator to get a ready-to-go starting point using your choice of client-side framework. This includes `Microsoft.AspNetCore.SpaServices` along with everything configured for webpack middleware, server-side prerendering, etc. - -See: [Getting started with the aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/) - -Also, if you want to debug projects created with the aspnetcore-spa generator, see [Debugging your projects](#debugging-your-projects) - -## Server-side prerendering - -The `SpaServices` package isn't tied to any particular client-side framework, and it doesn't force you to set up your client-side application in any one particular style. So, `SpaServices` doesn't contain hard-coded logic for rendering Angular / React / etc. components. - -Instead, what `SpaServices` offers is ASP.NET Core APIs that know how to invoke a JavaScript function that you supply, passing through context information that you'll need for server-side prerendering, and then injects the resulting HTML string into your rendered page. In this document, you'll find examples of setting this up to render Angular and React components. - -### 1. Enable the asp-prerender-* tag helpers - -Make sure you've installed into your project: - - * The `Microsoft.AspNetCore.SpaServices` NuGet package, version 1.1.0-* or later - * The `aspnet-prerendering` NPM package, version 2.0.1 or later - -Together these contain the server-side and client-side library code you'll need. Now go to your `Views/_ViewImports.cshtml` file, and add the following line: - - @addTagHelper "*, Microsoft.AspNetCore.SpaServices" - -### 2. Use asp-prerender-* in a view - -Choose a place in one of your MVC views where you want to prerender a SPA component. For example, open `Views/Home/Index.cshtml`, and add markup like the following: - -
- -If you run your application now, and browse to whatever page renders the view you just edited, you should get an error similar to the following (assuming you're running in *Development* mode so you can see the error information): *Error: Cannot find module 'some/directory/ClientApp/boot-server'*. You've told the prerendering tag helper to execute code from a JavaScript module called `boot-server`, but haven't yet supplied any such module! - -### 3. Supplying JavaScript code to perform prerendering - -Create a JavaScript file at the path matching the `asp-prerender-module` value you specified above. In this example, that means creating a folder called `ClientApp` at the root of your project, and creating a file inside it called `boot-server.js`. Try putting the following into it: - -```javascript -var prerendering = require('aspnet-prerendering'); - -module.exports = prerendering.createServerRenderer(function(params) { - return new Promise(function (resolve, reject) { - var result = '

Hello world!

' - + '

Current time in Node is: ' + new Date() + '

' - + '

Request path is: ' + params.location.path + '

' - + '

Absolute URL is: ' + params.absoluteUrl + '

'; - - resolve({ html: result }); - }); -}); -``` - -If you try running your app now, you should see the HTML snippet generated by your JavaScript getting injected into your page. - -As you can see, your JavaScript code receives context information (such as the URL being requested), and returns a `Promise` so that it can asynchronously supply the markup to be injected into the page. You can put whatever logic you like here, but typically you'll want to execute a component from your Angular / React / etc. application. - -**Passing data from .NET code into JavaScript code** - -If you want to supply additional data to the JavaScript function that performs your prerendering, you can use the `asp-prerender-data` attribute. You can give any value as long as it's JSON-serializable. Bear in mind that it will be serialized and sent as part of the remote procedure call (RPC) to Node.js, so avoid trying to pass massive amounts of data. - -For example, in your `cshtml`, - -
- -Now in your JavaScript prerendering function, you can access this data by reading `params.data`, e.g.: - -```javascript -var prerendering = require('aspnet-prerendering'); - -module.exports = prerendering.createServerRenderer(function(params) { - return new Promise(function (resolve, reject) { - var result = '

Hello world!

' - + '

Is gold user: ' + params.data.isGoldUser + '

' - + '

Number of cookies: ' + params.data.cookies.length + '

'; - - resolve({ html: result }); - }); -}); -``` - -Notice that the property names are received in JavaScript-style casing (e.g., `isGoldUser`) even though they were sent in C#-style casing (e.g., `IsGoldUser`). This is because of how the JSON serialization is configured by default. - -**Passing data from server-side to client-side code** - -If, as well as returning HTML, you also want to pass some contextual data from your server-side code to your client-side code, you can supply a `globals` object alongside the initial `html`, e.g.: - -```javascript -resolve({ - html: result, - globals: { - albumsList: someDataHere, - userData: someMoreDataHere - } -}); -``` - -When the `aspnet-prerender-*` tag helper emits this result into the document, as well as injecting the `html` string, it will also emit code that populates `window.albumsList` and `window.userData` with JSON-serialized copies of the objects you passed. - -This can be useful if, for example, you want to avoid loading the same data twice (once on the server and once on the client). - -### 4. Enabling webpack build tooling - -Of course, rather than writing your `boot-server` module and your entire SPA in plain ES5 JavaScript, it's quite likely that you'll want to write your client-side code in TypeScript or at least ES2015 code. To enable this, you need to set up a build system. - -#### Example: Configuring Webpack to build TypeScript - -Let's say you want to write your boot module and SPA code in TypeScript, and build it using Webpack. First ensure that `webpack` is installed, along with the libraries needed for TypeScript compilation: - - npm install -g webpack - npm install --save ts-loader typescript - -Next, create a file `webpack.config.js` at the root of your project, containing: - -```javascript -var path = require('path'); - -module.exports = { - entry: { 'main-server': './ClientApp/boot-server.ts' }, - resolve: { extensions: [ '', '.js', '.ts' ] }, - output: { - path: path.join(__dirname, './ClientApp/dist'), - filename: '[name].js', - libraryTarget: 'commonjs' - }, - module: { - loaders: [ - { test: /\.ts$/, loader: 'ts-loader' } - ] - }, - target: 'node', - devtool: 'inline-source-map' -}; -``` - -This tells webpack that it should compile `.ts` files using TypeScript, and that when looking for modules by name (e.g., `boot-server`), it should also find files with `.js` and `.ts` extensions. - -If you don't already have a `tsconfig.json` file at the root of your project, add one now. Make sure your `tsconfig.json` includes `"es6"` in its `"lib"` array so that TypeScript knows about intrinsics such as `Promise`. Here's an example `tsconfig.json`: - -```json -{ - "compilerOptions": { - "moduleResolution": "node", - "target": "es5", - "sourceMap": true, - "lib": [ "es6", "dom" ] - }, - "exclude": [ "bin", "node_modules" ] -} -``` - -Now you can delete `ClientApp/boot-server.js`, and in its place, create `ClientApp/boot-server.ts`, containing the TypeScript equivalent of what you had before: - -```javascript -import { createServerRenderer } from 'aspnet-prerendering'; - -export default createServerRenderer(params => { - return new Promise((resolve, reject) => { - const html = ` -

Hello world!

-

Current time in Node is: ${ new Date() }

-

Request path is: ${ params.location.path }

-

Absolute URL is: ${ params.absoluteUrl }

`; - - resolve({ html }); - }); -}); -``` - -Finally, run `webpack` on the command line to build `ClientApp/dist/main-server.js`. Then you can tell `SpaServices` to use that file for server-side prerendering. In your MVC view where you use `aspnet-prerender-module`, update the attribute value: - -
- -Webpack is a broad and powerful tool and can do far more than just invoke the TypeScript compiler. To learn more, see the [webpack website](https://webpack.github.io/). - - -### 5(a). Prerendering Angular components - -If you're building an Angular application, you can run your components on the server inside your `boot-server.ts` file so they will be injected into the resulting web page. - -First install the NPM package `angular2-universal` - this contains infrastructure for executing Angular components inside Node.js: - -``` -npm install --save angular2-universal -``` - -Now you can use the [`angular2-universal` APIs](https://github.com/angular/universal) from your `boot-server.ts` TypeScript module to execute your Angular component on the server. The code needed for this is fairly complex, but that's unavoidable because Angular supports so many different ways of being configured, and you need to provide wiring for whatever combination of DI modules you're using. - -The easiest way to get started with Angular server-side rendering on ASP.NET Core is to use the [aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/), which creates a ready-made working starting point. - -### 5(b). Prerendering React components - -React components can be executed synchronously on the server quite easily, although asynchronous execution is tricker as described below. - -#### Setting up client-side React code - -Let's say you want to write a React component in ES2015 code. You might install the NPM modules `react react-dom babel-loader babel-preset-react babel-preset-es2015`, and then prepare Webpack to build `.jsx` files by creating `webpack.config.js` in your project root, containing: - -```javascript -var path = require('path'); - -module.exports = { - resolve: { extensions: [ '', '.js', '.jsx' ] }, - module: { - loaders: [ - { test: /\.jsx?$/, loader: 'babel-loader' } - ] - }, - entry: { - main: ['./ClientApp/react-app.jsx'], - }, - output: { - path: path.join(__dirname, 'wwwroot', 'dist'), - filename: '[name].js' - }, -}; -``` - -You will also need a `.babelrc` file in your project root, containing: - -```javascript -{ - "presets": ["es2015", "react"] -} -``` - -This is enough to be able to build ES2015 `.jsx` files via Webpack. Now you could implement a simple React component, for example the following at `ClientApp/react-app.jsx`: - -```javascript -import * as React from 'react'; - -export class HelloMessage extends React.Component -{ - render() { - return

Hello {this.props.message}!

; - } -} -``` - -... and the following code to run it in a browser at `ClientApp/boot-client.jsx`: - -```javascript -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { HelloMessage } from './react-app'; - -ReactDOM.render(, document.getElementById('my-spa')); -``` - -At this stage, run `webpack` on the command line to build `wwwroot/dist/main.js`. Or, to avoid having to do this manually, you could use the `SpaServices` package to [enable Webpack dev middleware](#webpack-dev-middleware). - -You can now run your React code on the client by adding the following to one of your MVC views: - -
- - -If you want to enable server-side prerendering too, follow the same process as described under [server-side prerendering](#server-side-prerendering). - -#### Realistic React apps and Redux - -The above example is extremely simple - it doesn't use `react-router`, and it doesn't load any data asynchronously. Real applications are likely to do both of these. - -Supporting asynchronous data loading involves more considerations. Unlike Angular applications that run asynchronously on the server and freely overwrite server-generated markup with client-generated markup, React strictly wants to run synchronously on the server and always produce the same markup on the server as it does on the client. - -To make this work, you most likely need some way to know in advance what data your React components will need to use, load it separately from those components, and have some way of transferring information about the loaded data from server to client. If you try to implement this in a generalized way, you'll end up reinventing something like the Flux/Redux pattern. - -To avoid inventing your own incomplete version of Flux/Redux, you probably should just use [Redux](https://github.com/reactjs/redux). This is at first a very unfamiliar and tricky-looking abstraction, but does solve all the problems around server-side execution of React apps. To get a working starting point for an ASP.NET Core site with React+Redux on the client (and server-side prerendering), see the [aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). - -## Webpack dev middleware - -If you're using webpack, the webpack dev middleware feature included in `Microsoft.AspNetCore.SpaServices` will streamline your development process. It intercepts requests that would match files built by webpack, and dynamically builds those files on demand. They don't need to be written to disk - they are just held in memory and served directly to the browser. - -Benefits: - - * You don't have to run `webpack` manually or set up any file watchers - * The browser is always guaranteed to receive up-to-date built output - * The built artifacts are normally served instantly or at least extremely quickly, because internally, an instance of `webpack` stays active and has partial compilation states pre-cached in memory - -It lets you work as if the browser natively understands whatever file types you are working with (e.g., TypeScript, SASS), because it's as if there's no build process to wait for. - -### Example: A simple Webpack setup that builds TypeScript - -**Note:** If you already have Webpack in your project, then you can skip this section. - -As a simple example, here's how you can set up Webpack to build TypeScript files. First install the relevant NPM packages by executing this from the root directory of your project: - -``` -npm install --save typescript ts-loader -``` - -And if you don't already have it, you'll find it useful to install the `webpack` command-line tool: - -``` -npm install -g webpack -``` - -Now add a Webpack configuration file. Create `webpack.config.js` in the root of your project, containing the following: - -```javascript -module.exports = { - resolve: { - // For modules referenced with no filename extension, Webpack will consider these extensions - extensions: [ '', '.js', '.ts' ] - }, - module: { - loaders: [ - // This example only configures Webpack to load .ts files. You can also drop in loaders - // for other file types, e.g., .coffee, .sass, .jsx, ... - { test: /\.ts$/, loader: 'ts-loader' } - ] - }, - entry: { - // The loader will follow all chains of reference from this entry point... - main: ['./ClientApp/MyApp.ts'] - }, - output: { - // ... and emit the built result in this location - path: __dirname + '/wwwroot/dist', - filename: '[name].js' - }, -}; -``` - -Now you can put some TypeScript code (minimally, just `console.log('Hello');`) at `ClientApp/MyApp.ts` and then run `webpack` from the command line to build it (and everything it references). The output will be placed in `wwwroot/dist`, so you can load and run it in a browser by adding the following to one of your views (e.g., `Views\Home\Index.cshtml`): - - - -The Webpack loader, `ts-loader`, follows all chains of reference from `MyApp.ts` and will compile all referenced TypeScript code into your output. If you want, you can create a [`tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) to control things like whether source maps will be included in the output. If you add other Webpack loaders to your `webpack.config.js`, you can even reference things like SASS from your TypeScript, and then it will get built to CSS and loaded automatically. - -So that's enough to build TypeScript. Here's where webpack dev middleware comes in to auto-build your code whenever needed (so you don't need any file watchers or to run `webpack` manually), and optionally hot module replacement (HMR) to push your changes automatically from code editor to browser without even reloading the page. - -### Example: A simple Webpack setup that builds LESS - -Following on from the preceding example that builds TypeScript, you could extend your Webpack configuration further to support building LESS. There are three major approaches to doing this: - -1. **If using Angular, use its native style loader to attach the styles to components**. This is extremely simple and is usually the right choice if you are using Angular. However it only applies to Angular components, not to any other part of the host page, so sometimes you might want to combine this technique with options 2 or 3 below. - -2. **Or, use Webpack's style loader to attach the styles at runtime**. The CSS markup will be included in your JavaScript bundles and will be attached to the document dynamically. This has certain benefits during development but isn't recommended in production. - -3. **Or, have each build write a standalone `.css` file to disk**. At runtime, load it using a regular `` tag. This is likely to be the approach you'll want for production use (at least for non-Angular applications, such as React applications) as it's the most robust and best-performing option. - -If instead of LESS you prefer SASS or another CSS preprocessor, the exact same techniques should work, but of course you'll need to replace the `less-loader` with an equivalent Webpack loader for SASS or your chosen preprocessor. - -#### Approach 1: Scoping styles to Angular components - -If you are using Angular, this is the easiest way to perform styling. It works with both server and client rendering, supports Hot Module Replacement, and robustly scopes styles to particular components (and optionally, their descendant elements). - -This repository's Angular template uses this technique to scope styles to components out of the box. It defines those styles as `.css` files. For example, its components reference `.css` files like this: - -```javascript -@Component({ - ... - styles: [require('./somecomponent.css')] -}) -export class SomeComponent { ... } -``` - -To make this work, the template has Webpack configured to inject the contents of the `.css` file as a string literal in the built file. Here's the configuration that enables this: - -```javascript -// This goes into webpack.config.js, in the module loaders array: -{ test: /\.css/, include: /ClientApp/, loader: 'raw-loader' } -``` - -Now if you want to use LESS instead of plain CSS, you just need to include a LESS loader. Run the following in a command prompt at your project root: - -``` -npm install --save less-loader less -``` - -Next, add the following loader configuration to the `loaders` array in `webpack.config.js`: - -```javascript -{ test: /\.less/, include: /ClientApp/, loader: 'raw-loader!less-loader' } -``` - -Notice how this chains together with `less-loader` (which transforms `.less` syntax to plain CSS syntax), then the `raw` loader (which turn the result into a string literal). With this in place, you can reference `.less` files from your Angular components in the obvious way: - -```javascript -@Component({ - ... - styles: [require('./somecomponent.less')] -}) -export class SomeComponent { ... } -``` - -... and your styles will be applied in both server-side and client-side rendering. - -#### Approach 2: Loading the styles using Webpack and JavaScript - -This technique works with any client-side framework (not just Angular), and can also apply styles to the entire document rather than just individual components. It's a little simpler to set up than technique 3, plus it works flawlessly with Hot Module Replacement (HMR). The downside is that it's really only good for development time, because in production you probably don't want users to wait until JavaScript is loaded before styles are applied to the page (this would mean they'd see a 'flash of unstyled content' while the page is being loaded). - -First create a `.less` file in your project. For example, create a file at `ClientApp/styles/mystyles.less` containing: - -```less -@base: #f938ab; - -h1 { - color: @base; -} -``` - -Reference this file from an `import` or `require` statement in one of your JavaScript or TypeScript files. For example, if you've got a `boot-client.ts` file, add the following near the top: - -```javascript -import './styles/mystyles.less'; -``` - -If you try to run the Webpack compiler now (e.g., via `webpack` on the command line), you'll get an error saying it doesn't know how to build `.less` files. So, it's time to install a Webpack loader for LESS (plus related NPM modules). In a command prompt at your project's root directory, run: - -``` -npm install --save less-loader less -``` - -Finally, tell Webpack to use this whenever it encounters a `.less` file. In `webpack.config.js`, add to the `loaders` array: - -``` -{ test: /\.less/, loader: 'style-loader!css-loader!less-loader' } -``` - -This means that when you `import` or `require` a `.less` file, it should pass it first to the LESS compiler to produce CSS, then the output goes to the CSS and Style loaders that know how to attach it dynamically to the page at runtime. - -That's all you need to do! Restart your site and you should see the LESS styles being applied. This technique is compatible with both source maps and Hot Module Replacement (HMR), so you can edit your `.less` files at will and see the changes appearing live in the browser. - -#### Approach 3: Building LESS to CSS files on disk - -This technique takes a little more work to set up than technique 2, and lacks compatibility with HMR. But it's much better for production use if your styles are applied to the whole page (not just elements constructed via JavaScript), because it loads the CSS independently of JavaScript. - -First add a `.less` file into your project. For example, create a file at `ClientApp/styles/mystyles.less` containing: - -```less -@base: #f938ab; - -h1 { - color: @base; -} -``` - -Reference this file from an `import` or `require` statement in one of your JavaScript or TypeScript files. For example, if you've got a `boot-client.ts` file, add the following near the top: - -```javascript -import './styles/mystyles.less'; -``` - -If you try to run the Webpack compiler now (e.g., via `webpack` on the command line), you'll get an error saying it doesn't know how to build `.less` files. So, it's time to install a Webpack loader for LESS (plus related NPM modules). In a command prompt at your project's root directory, run: - -``` -npm install --save less less-loader extract-text-webpack-plugin -``` - -Next, you can extend your Webpack configuration to handle `.less` files. In `webpack.config.js`, at the top, add: - -```javascript -var extractStyles = new (require('extract-text-webpack-plugin'))('mystyles.css'); -``` - -This creates a plugin instance that will output text to a file called `mystyles.css`. You can now compile `.less` files and emit the resulting CSS text into that file. To do so, add the following to the `loaders` array in your Webpack configuration: - -```javascript -{ test: /\.less$/, loader: extractStyles.extract('css-loader!less-loader') } -``` - -This tells Webpack that, whenever it finds a `.less` file, it should use the LESS loader to produce CSS, and then feed that CSS into the `extractStyles` object which you've already configured to write a file on disk called `mystyles.css`. Finally, for this to actually work, you need to include `extractStyles` in the list of active plugins. Just add that object to the `plugins` array in your Webpack config, e.g.: - -```javascript -plugins: [ - extractStyles, - ... leave any other plugins here ... -] -``` - -If you run `webpack` on the command line now, you should now find that it emits a new file at `dist/mystyles.css`. You can make browsers load this file simply by adding a regular `` tag. For example, in `Views/Shared/_Layout.cshtml`, add: - -```html - -``` - -**Note:** This technique (writing the built `.css` file to disk) is ideal for production use. But note that, at development time, *it does not support Hot Module Replacement (HMR)*. You will need to reload the page each time you edit your `.less` file. This is a known limitation of `extract-text-webpack-plugin`. If you have constructive opinions on how this can be improved, see the [discussion here](https://github.com/webpack/extract-text-webpack-plugin/issues/30). - -### Enabling webpack dev middleware - -First install the `Microsoft.AspNetCore.SpaServices` NuGet package and the `aspnet-webpack` NPM package, then go to your `Startup.cs` file, and **before your call to `UseStaticFiles`**, add the following: - -```csharp -if (env.IsDevelopment()) { - app.UseWebpackDevMiddleware(); -} - -// Your call to app.UseStaticFiles(); should be here -``` - -Also check your webpack configuration at `webpack.config.js`. Since `UseWebpackDevMiddleware` needs to know which incoming requests to intercept, make sure you've specified a `publicPath` value on your `output`, for example: - -```javascript -module.exports = { - // ... rest of your webpack config is here ... - - output: { - path: path.join(__dirname, 'wwwroot', 'dist'), - publicPath: '/dist/', - filename: '[name].js' - }, -}; -``` - -Now, assuming you're running in [development mode](https://docs.asp.net/en/latest/fundamentals/environments.html), any requests for files under `/dist` will be intercepted and served using Webpack dev middleware. - -**This is for development time only, not for production use (hence the `env.IsDevelopment()` check in the code above).** While you could technically remove that check and serve your content in production through the webpack middleware, it's hard to think of a good reason for doing so. For best performance, it makes sense to prebuild your client-side resources so they can be served directly from disk with no build middleware. If you use the [aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/), you'll get a site that produces optimised static builds for production, while also supporting webpack dev middleware at development time. - -## Webpack Hot Module Replacement - -For an even more streamlined development experience, you can enhance webpack dev middleware by enabling Hot Module Replacement (HMR) support. This watches for any changes you make to source files on disk (e.g., `.ts`/`.html`/`.sass`/etc. files), and automatically rebuilds them and pushes the result into your browser window, without even needing to reload the page. - -This is *not* the same as a simple live-reload mechanism. It does not reload the page; it replaces code or markup directly in place. This is better, because it does not interfere with any state your SPA might have in memory, or any debugging session you have in progress. - -Typically, when you change a source file, the effects appear in your local browser window in under 2 seconds, even when your overall application is large. This is superbly productive, especially in multi-monitor setups. If you cause a build error (e.g., a syntax error), details of the error will appear in your browser window. When you fix it, your application will reappear, without having lost its in-memory state. - -### Enabling Hot Module Replacement - -First ensure you already have a working Webpack dev middleware setup. Then, install the `webpack-hot-middleware` NPM module: - -``` -npm install --save-dev webpack-hot-middleware -``` - -At the top of your `Startup.cs` file, add the following namespace reference: - -```csharp -using Microsoft.AspNetCore.SpaServices.Webpack; -``` - -Now amend your call to `UseWebpackDevMiddleware` as follows: - -```csharp -app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { - HotModuleReplacement = true -}); -``` - -Also, to work around a temporary issue in `SpaServices`, you must ensure that your Webpack config includes a `plugins` array, even if it's empty. For example, in `webpack.config.js`: - -```javascript -module.exports = { - // ... rest of your webpack config is here ... - - plugins: [ - // Put webpack plugins here if needed, or leave it as an empty array if not - ] -}; -``` - -Now when you load your application in a browser, you should see a message like the following in your browser console: - -``` -[HMR] connected -``` - -If you edit any of your source files that get built by webpack, the result will automatically be pushed into the browser. As for what the browser does with these updates - that's a matter of how you configure it - see below. - -**Note for TypeScript + Visual Studio users** - -If you want HMR to work correctly with TypeScript, and you use Visual Studio on Windows as an IDE (but not VS Code), then you will need to make a further configuration change. In your `.csproj` file, in one of the `` elements, add this: - - true - -This is necessary because otherwise, Visual Studio will try to auto-compile TypeScript files as you save changes to them. That default auto-compilation behavior is unhelpful in projects where you have a proper build system (e.g., Webpack), because VS doesn't know about your build system and would emit `.js` files in the wrong locations, which would in turn cause problems with your real build or deployment mechanisms. - -#### Enabling hot replacement for React components - -Webpack has built-in support for updating React components in place. To enable this, amend your `UseWebpackDevMiddleware` call further as follows: - -```csharp -app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { - HotModuleReplacement = true, - ReactHotModuleReplacement = true -}); -``` - -Also, install the NPM module `aspnet-webpack-react`, e.g.: - -``` -npm install --save-dev aspnet-webpack-react -``` - -Now if you edit any React component (e.g., in `.jsx` or `.tsx` files), the updated component will be injected into the running application, and will even preserve its in-memory state. - -**Note**: In you webpack config, be sure that your React components are loaded using `babel-loader` (and *not* just directly using `babel` or `ts-loader`), because `babel-loader` is where the HMR instrumentation is injected. For an example of HMR for React components built with TypeScript, see the [aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). - -#### Enabling hot replacement for other module types - -Webpack has built-in HMR support for various types of module, such as styles and React components as described above. But to support HMR for other code modules, you need to add a small block of code that calls `module.hot.accept` to receive the updated module and update the running application. - -This is [documented in detail on the Webpack site](https://webpack.github.io/docs/hot-module-replacement.html). Or to get a working HMR-enabled ASP.NET Core site with Angular, React, React+Redux, or Knockout, you can use the [aspnetcore-spa generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). - -#### Passing options to the Webpack Hot Middleware client - -You can configure the [Webpack Hot Middleware client](https://github.com/glenjamin/webpack-hot-middleware#client) -by using the `HotModuleReplacementClientOptions` property on `WebpackDevMiddlewareOptions`: - -```csharp -app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { - HotModuleReplacement = true, - HotModuleReplacementClientOptions = new Dictionary { - { "reload", "true" }, - }, -}); -``` - -For the list of available options, please see [Webpack Hot Middleware docs](https://github.com/glenjamin/webpack-hot-middleware#client). - -**Note**: The `path` option cannot be overridden this way - it is controlled by the `HotModuleReplacementEndpoint` setting. - -## Routing helper: MapSpaFallbackRoute - -*Note: this functionality has been superseded by `endpoints.MapFallbackToFile(...)` provided by endpoint routing. -`MapFallbackToFile` behaves similarly to `MapSpaFallbackRoute`.* - -In most single-page applications, you'll want client-side routing as well as your server-side routing. Most of the time, the two routing systems work independently without interfering. However, there is one case where things get challenging: identifying 404s. - -If a request arrives for `/some/page`, and it doesn't match any server-side route, it's likely that you want to return HTML that starts up your client-side application, which probably understands the route `/some/page`. But if a request arrives for `/images/user-512.png`, and it doesn't match any server-side route or static file, it's **not** likely that your client-side application would handle it - you probably want to return a 404. - -To help distinguish between these cases, the `Microsoft.AspNetCore.SpaServices` NuGet package includes a routing helper, `MapSpaFallbackRoute`. For example, in your `Startup.cs` file's `Configure` method, you might add: - -```csharp - app.UseStaticFiles(); - - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - - routes.MapSpaFallbackRoute( - name: "spa-fallback", - defaults: new { controller = "Home", action = "Index" }); - }); -``` - -Since `UseStaticFiles` goes first, any requests that actually match physical files under `wwwroot` will be handled by serving that static file. - -Since the default server-side MVC route goes next, any requests that match existing controller/action pairs will be handled by invoking that action. - -Then, since `MapSpaFallbackRoute` is last, any other requests **that don't appear to be for static files** will be served by invoking the `Index` action on `HomeController`. This action's view should serve your client-side application code, allowing the client-side routing system to handle whatever URL has been requested. - -Any requests that do appear to be for static files (i.e., those that end with filename extensions), will *not* be handled by `MapSpaFallbackRoute`, and so will end up as 404s. - -This is not a perfect solution to the problem of identifying 404s, because for example `MapSpaFallbackRoute` will not match requests for `/users/albert.einstein`, because it appears to contain a filename extension (`.einstein`). If you need your SPA to handle routes like that, then don't use `MapSpaFallbackRoute` - just use a regular MVC catch-all route. But then beware that requests for unknown static files will result in your client-side app being rendered. - -## Debugging your projects - -How to attach and use a debugger depends on what code you want to debug. For details, see: - - * [How to debug your C# code that runs on the server](#debugging-your-c-code-that-runs-on-the-server) - * How to debug your JavaScript/TypeScript code: - * ... [when it's running in a browser](#debugging-your-javascripttypescript-code-when-its-running-in-a-browser) - * ... [when it's running on the server](#debugging-your-javascripttypescript-code-when-it-runs-on-the-server) (i.e., via `asp-prerender` or NodeSevices) - -### Debugging your C# code that runs on the server - -You can use any .NET debugger, for example Visual Studio's C# debugger or [Visual Studio Code's C# debugger](https://code.visualstudio.com/Docs/editor/debugging). - -### Debugging your JavaScript/TypeScript code when it's running in a browser - -**The absolute most reliable way of debugging your client-side code is to use your browser's built-in debugger.** This is much easier to make work than debugging via an IDE, plus it offers much richer insight into what's going on than your IDE will do (for example, you'll be able to inspect the DOM and capture performance profiles as well as just set breakpoints and step through code). - -If you're unfamiliar with your browser's debugging tools, then take the time to get familiar with them. You will become more productive. - -#### Using your browser's built-in debugging tools - -##### Using Chrome's developer tools for debugging - -In Chrome, with your application running in the browser, [open the developer tools](https://developer.chrome.com/devtools#access). You can now find your code: - - * In the developer tools *Sources* tab, expand folders in the hierarchy pane on the left to find the file you want - * Or, press `ctrl`+`o` (on Windows) or `cmd`+`o` on Mac, then start to type name name of the file you want to open (e.g., `counter.component.ts`) - -With source maps enabled (which is the case in the project templates in this repo), you'll be able to see your original TypeScript source code, set breakpoints on it, etc. - -##### Using Internet Explorer/Edge's developer tools (F12) for debugging - -In Internet Explorer or Edge, with your application running in the browser, open the F12 developer tools by pressing `F12`. You can now find your code: - - * In the F12 tools *Debugger* tab, expand folders in the hierarchy pane on the left to find the file you want - * Or, press `ctrl`+`o`, then start to type name name of the file you want to open (e.g., `counter.component.ts`) - -With source maps enabled (which is the case in the project templates in this repo), you'll be able to see your original TypeScript source code, set breakpoints on it, etc. - -##### Using Firefox's developer tools for debugging - -In Firefox, with your application running in the browser, open the developer tools by pressing `F12`. You can now find your code: - - * In the developer tools *Debugger* tab, expand folders in the hierarchy pane titled *Sources* towards the bottom to find the file you want - * Or, press `ctrl`+`o` (on Windows) or `cmd`+`o` on Mac, then start to type name name of the file you want to open (e.g., `counter.component.ts`) - -With source maps enabled (which is the case in the project templates in this repo), you'll be able to see your original TypeScript source code, set breakpoints on it, etc. - -##### How browser-based debugging interacts with Hot Module Replacement (HMR) - -If you're using HMR, then each time you modify a file, the Webpack dev middleware restarts your client-side application, adding a new version of each affected module, without reloading the page. This can be confusing during debugging, because any breakpoints set on the old version of the code will still be there, but they will no longer get hit, because the old version of the module is no longer in use. - -You have two options to get breakpoints that will be hit as expected: - - * **Reload the page** (e.g., by pressing `F5`). Then your existing breakpoints will be applied to the new version of the module. This is obviously the easiest solution. - * Or, if you don't want to reload the page, you can **set new breakpoints on the new version of the module**. To do this, look in your browser's debug tools' list of source files, and identify the newly-injected copy of the module you want to debug. It will typically have a suffix on its URL such as `?4a2c`, and may appear in a new top-level hierarchy entry called `webpack://`. Set a breakpoint in the newly-injected module, and it will be hit as expected as your application runs. - -#### Using Visual Studio Code's "Debugger for Chrome" extension - -If you're using Visual Studio Code and Chrome, you can set breakpoints directly on your TypeScript source code in the IDE. To do this: - -1. Install VS Code's [*Debugger for Chrome* extension](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) -2. Ensure your application server has started and can be reached with a browser (for example, run `dotnet watch run`) -3. In VS Code, open its *Debug* view (on Windows/Linux, press `ctrl`+`shift`+`d`; on Mac, press `cmd`+`shift`+`d`). -4. Press the cog icon and when prompted to *Select environment*, choose `Chrome`. VS Code will create a `launch.json` file for you. This describes how the debugger and browser should be launched. -5. Edit your new `.vscode/launch.json` file to specify the correct `url` and `webRoot` for your application. If you're using the project templates in this repo, then the values you probably want are: - * For `url`, put `"http://localhost:5000"` (but of course, change this if you're using a different port) - * For `port`, put `5000` (or your custom port number if applicable) - * For `workspace` in **both** configurations, put `"${workspaceRoot}/wwwroot"` - * This tells the debugger how URLs within your application correspond to files in your VS Code workspace. By default, ASP.NET Core projects treat `wwwroot` as the root directory for publicly-served files, so `http://localhost:5000/dist/myfile.js` corresponds to `/wwwroot/dist/myfile.js`. VS Code doesn't know about `wwwroot` unless you tell it. - * **Important:** If your VS Code window's workspace root is not the same as your ASP.NET Core project root (for example, if VS Code is opened at a higher-level directory to show both your ASP.NET Core project plus other peer-level directories), then you will need to amend `workspace` correspondingly (e.g., to `"${workspaceRoot}/SomeDir/MyAspNetProject/wwwroot"`). -6. Start the debugger: - * While still on the *Debug* view, from the dropdown near the top-left, choose "*Launch Chrome against localhost, with sourcemaps*". - * Press the *Play* icon. Your application will launch in Chrome. - * If it does nothing for a while, then eventually gives the error *Cannot connect to runtime process*, that's because you already have an instance of Chrome running. Close it first, then try again. -7. Finally, you can now set and hit breakpoints in your TypeScript code in VS Code. - -For more information about VS Code's built-in debugging facilities, [see its documentation](https://code.visualstudio.com/Docs/editor/debugging). - -Caveats: - - * The debugging interface between VS Code and Chrome occasionally has issues. If you're unable to set or hit breakpoints, or if you try to set a breakpoint but it appears in the wrong place, you may need to stop and restart the debugger (and often, the whole Chrome process). - * If you're using Hot Module Replacement (HMR), then whenever you edit a file, the breakpoints in it will no longer hit. This is because HMR loads a new version of the module into the browser, so the old code no longer runs. To fix this, you must: - * Reload the page in Chrome (e.g., by pressing `F5`) - * **Then** (and only then), remove and re-add the breakpoint in VS Code. It will now be attached to the current version of your module. Alternatively, stop and restart debugging altogether. - * If you prefer, you can use "*Attach to Chrome, with sourcemaps*" instead of launching a new Chrome instance, but this is a bit trickier: you must first start Chrome using the command-line option `--remote-debugging-port=9222`, and you must ensure there are no other tabs opened (otherwise, it might try to connect to the wrong one). - - -#### Using Visual Studio's built-in debugger for Internet Explorer - -If you're using Visual Studio on Windows, and are running your app in Internet Explorer 11 (not Edge!), then you can use VS's built-in debugger rather than Interner Explorer's F12 tools if you prefer. To do this: - - 1. In Internet Explorer, [enable script debugging](https://msdn.microsoft.com/en-us/library/ms241741\(v=vs.100\).aspx) - 2. In Visual Studio, [set the default "*Browse with*" option](http://stackoverflow.com/a/31959053) to Internet Explorer - 3. In Visual Studio, press F5 to launch your application with the debugger in Internet Explorer. - * When the page has loaded in the browser, you'll be able to set and hit breakpoints in your TypeScript source files in Visual Studio. - -Caveats: - - * If you're using Hot Module Replacement, you'll need to stop and restart the debugger any time you change a source file. VS's IE debugger does not recognise that source files might change while the debugging session is in progress. - * Realistically, you are not going to be as productive using this approach to debugging as you would be if you used your browser's built-in debugging tools. The browser's built-in debugging tools are far more effective: they are always available (you don't have to have launched your application in a special way), they better handle HMR, and they don't make your application very slow to launch. - -## Debugging your JavaScript/TypeScript code when it runs on the server - -When you're using NodeServices or the server-side prerendering feature included in the project templates in this repo, your JavaScript/TypeScript code will execute on the server in a background instance of Node.js. You can enable debugging via [V8 Inspector Integration](https://nodejs.org/api/debugger.html#debugger_v8_inspector_integration_for_node_js) on that Node.js instance. Here's how to do it. - -First, in your `Startup.cs` file, in the `ConfigureServices` method, add the following: - -``` -services.AddNodeServices(options => { - options.LaunchWithDebugging = true; - options.DebuggingPort = 9229; -}); -``` - -Now, run your application from that command line (e.g., `dotnet run`). Then in a browser visit one of your pages that causes server-side JS to execute. - -In the console, you should see all the normal trace messages appear, plus among them will be: - -``` -warn: Microsoft.AspNetCore.NodeServices[0] - Debugger listening on port 9229. -warn: Microsoft.AspNetCore.NodeServices[0] - Warning: This is an experimental feature and could change at any time. -warn: Microsoft.AspNetCore.NodeServices[0] - To start debugging, open the following URL in Chrome: -warn: Microsoft.AspNetCore.NodeServices[0] - chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -``` - -As per instructions open the URL in Chrome. Alternatively you can go to the `Sources` tab of the Dev Tools (at http://localhost:5000) and connect to the Node instance under `Threads` in the right sidebar. - -By expanding the `webpack://` entry in the sidebar, you'll be able to find your original source code (it's using source maps), and then set breakpoints in it. When you re-run your app in another browser window, your breakpoints will be hit, then you can debug the server-side execution just like you'd debug client-side execution. It looks like this: - -![screenshot from 2017-03-25 13-33-26](https://cloud.githubusercontent.com/assets/1596280/24324604/ab888a7e-115f-11e7-89d1-1586acf5e35c.png) - diff --git a/src/Middleware/SpaServices/src/Content/Node/prerenderer.js b/src/Middleware/SpaServices/src/Content/Node/prerenderer.js deleted file mode 100644 index ffee00bd24..0000000000 --- a/src/Middleware/SpaServices/src/Content/Node/prerenderer.js +++ /dev/null @@ -1,224 +0,0 @@ -(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(1); - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -exports.__esModule = true; -var path = __webpack_require__(2); -// Separate declaration and export just to add type checking on function signature -exports.renderToString = renderToStringImpl; -// This function is invoked by .NET code (via NodeServices). Its job is to hand off execution to the application's -// prerendering boot function. It can operate in two modes: -// [1] Legacy mode -// This is for backward compatibility with projects created with templates older than the generator version 0.6.0. -// In this mode, we don't really do anything here - we just load the 'aspnet-prerendering' NPM module (which must -// exist in node_modules, and must be v1.x (not v2+)), and pass through all the parameters to it. Code in -// 'aspnet-prerendering' v1.x will locate the boot function and invoke it. -// The drawback to this mode is that, for it to work, you have to deploy node_modules to production. -// [2] Current mode -// This is for projects created with the Yeoman generator 0.6.0+ (or projects manually updated). In this mode, -// we don't invoke 'require' at runtime at all. All our dependencies are bundled into the NuGet package, so you -// don't have to deploy node_modules to production. -// To determine whether we're in mode [1] or [2], the code locates your prerendering boot function, and checks whether -// a certain flag is attached to the function instance. -function renderToStringImpl(callback, applicationBasePath, bootModule, absoluteRequestUrl, requestPathAndQuery, customDataParameter, overrideTimeoutMilliseconds) { - try { - var forceLegacy = isLegacyAspNetPrerendering(); - var renderToStringFunc = !forceLegacy && findRenderToStringFunc(applicationBasePath, bootModule); - var isNotLegacyMode = renderToStringFunc && renderToStringFunc['isServerRenderer']; - if (isNotLegacyMode) { - // Current (non-legacy) mode - we invoke the exported function directly (instead of going through aspnet-prerendering) - // It's type-safe to just apply the incoming args to this function, because we already type-checked that it's a RenderToStringFunc, - // just like renderToStringImpl itself is. - renderToStringFunc.apply(null, arguments); - } - else { - // Legacy mode - just hand off execution to 'aspnet-prerendering' v1.x, which must exist in node_modules at runtime - var aspNetPrerenderingV1RenderToString = __webpack_require__(3).renderToString; - if (aspNetPrerenderingV1RenderToString) { - aspNetPrerenderingV1RenderToString(callback, applicationBasePath, bootModule, absoluteRequestUrl, requestPathAndQuery, customDataParameter, overrideTimeoutMilliseconds); - } - else { - callback('If you use aspnet-prerendering >= 2.0.0, you must update your server-side boot module to call createServerRenderer. ' - + 'Either update your boot module code, or revert to aspnet-prerendering version 1.x'); - } - } - } - catch (ex) { - // Make sure loading errors are reported back to the .NET part of the app - callback('Prerendering failed because of error: ' - + ex.stack - + '\nCurrent directory is: ' - + process.cwd()); - } -} -; -function findBootModule(applicationBasePath, bootModule) { - var bootModuleNameFullPath = path.resolve(applicationBasePath, bootModule.moduleName); - if (bootModule.webpackConfig) { - // If you're using asp-prerender-webpack-config, you're definitely in legacy mode - return null; - } - else { - return require(bootModuleNameFullPath); - } -} -function findRenderToStringFunc(applicationBasePath, bootModule) { - // First try to load the module - var foundBootModule = findBootModule(applicationBasePath, bootModule); - if (foundBootModule === null) { - return null; // Must be legacy mode - } - // Now try to pick out the function they want us to invoke - var renderToStringFunc; - if (bootModule.exportName) { - // Explicitly-named export - renderToStringFunc = foundBootModule[bootModule.exportName]; - } - else if (typeof foundBootModule !== 'function') { - // TypeScript-style default export - renderToStringFunc = foundBootModule["default"]; - } - else { - // Native default export - renderToStringFunc = foundBootModule; - } - // Validate the result - if (typeof renderToStringFunc !== 'function') { - if (bootModule.exportName) { - throw new Error("The module at " + bootModule.moduleName + " has no function export named " + bootModule.exportName + "."); - } - else { - throw new Error("The module at " + bootModule.moduleName + " does not export a default function, and you have not specified which export to invoke."); - } - } - return renderToStringFunc; -} -function isLegacyAspNetPrerendering() { - var version = getAspNetPrerenderingPackageVersion(); - return version && /^1\./.test(version); -} -function getAspNetPrerenderingPackageVersion() { - try { - var packageEntryPoint = require.resolve('aspnet-prerendering'); - var packageDir = path.dirname(packageEntryPoint); - var packageJsonPath = path.join(packageDir, 'package.json'); - var packageJson = require(packageJsonPath); - return packageJson.version.toString(); - } - catch (ex) { - // Implies aspnet-prerendering isn't in node_modules at all (or node_modules itself doesn't exist, - // which will be the case in production based on latest templates). - return null; - } -} - - -/***/ }), -/* 2 */ -/***/ (function(module, exports) { - -module.exports = require("path"); - -/***/ }), -/* 3 */ -/***/ (function(module, exports) { - -module.exports = require("aspnet-prerendering"); - -/***/ }) -/******/ ]))); \ No newline at end of file diff --git a/src/Middleware/SpaServices/src/Content/Node/webpack-dev-middleware.js b/src/Middleware/SpaServices/src/Content/Node/webpack-dev-middleware.js deleted file mode 100644 index 78d03802c2..0000000000 --- a/src/Middleware/SpaServices/src/Content/Node/webpack-dev-middleware.js +++ /dev/null @@ -1,133 +0,0 @@ -(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 4); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(5); - - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -exports.__esModule = true; -// Pass through the invocation to the 'aspnet-webpack' package, verifying that it can be loaded -function createWebpackDevServer(callback) { - var aspNetWebpack; - try { - aspNetWebpack = __webpack_require__(6); - } - catch (ex) { - // Developers sometimes have trouble with badly-configured Node installations, where it's unable - // to find node_modules. Or they accidentally fail to deploy node_modules, or even to run 'npm install'. - // Make sure such errors are reported back to the .NET part of the app. - callback('Webpack dev middleware failed because of an error while loading \'aspnet-webpack\'. Error was: ' - + ex.stack - + '\nCurrent directory is: ' - + process.cwd()); - return; - } - return aspNetWebpack.createWebpackDevServer.apply(this, arguments); -} -exports.createWebpackDevServer = createWebpackDevServer; - - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -module.exports = require("aspnet-webpack"); - -/***/ }) -/******/ ]))); \ No newline at end of file diff --git a/src/Middleware/SpaServices/src/Microsoft.AspNetCore.SpaServices.csproj b/src/Middleware/SpaServices/src/Microsoft.AspNetCore.SpaServices.csproj deleted file mode 100644 index 20ad3236ae..0000000000 --- a/src/Middleware/SpaServices/src/Microsoft.AspNetCore.SpaServices.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - Helpers for building single-page applications on ASP.NET MVC Core. - $(DefaultNetCoreTargetFramework) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Middleware/SpaServices/src/Prerendering/DefaultSpaPrerenderer.cs b/src/Middleware/SpaServices/src/Prerendering/DefaultSpaPrerenderer.cs deleted file mode 100644 index be38e0c0f5..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/DefaultSpaPrerenderer.cs +++ /dev/null @@ -1,55 +0,0 @@ -// 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.Threading; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.NodeServices; -using System.Threading.Tasks; -using Microsoft.Extensions.Hosting; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// Default implementation of a DI service that provides convenient access to - /// server-side prerendering APIs. This is an alternative to prerendering via - /// the asp-prerender-module tag helper. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class DefaultSpaPrerenderer : ISpaPrerenderer - { - private readonly string _applicationBasePath; - private readonly CancellationToken _applicationStoppingToken; - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly INodeServices _nodeServices; - - public DefaultSpaPrerenderer( - INodeServices nodeServices, - IHostApplicationLifetime applicationLifetime, - IWebHostEnvironment hostingEnvironment, - IHttpContextAccessor httpContextAccessor) - { - _applicationBasePath = hostingEnvironment.ContentRootPath; - _applicationStoppingToken = applicationLifetime.ApplicationStopping; - _httpContextAccessor = httpContextAccessor; - _nodeServices = nodeServices; - } - - public Task RenderToString( - string moduleName, - string exportName = null, - object customDataParameter = null, - int timeoutMilliseconds = default(int)) - { - return Prerenderer.RenderToString( - _applicationBasePath, - _nodeServices, - _applicationStoppingToken, - new JavaScriptModuleExport(moduleName) { ExportName = exportName }, - _httpContextAccessor.HttpContext, - customDataParameter, - timeoutMilliseconds); - } - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/ISpaPrerenderer.cs b/src/Middleware/SpaServices/src/Prerendering/ISpaPrerenderer.cs deleted file mode 100644 index dcf986673e..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/ISpaPrerenderer.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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.Threading.Tasks; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// Represents a service that can perform server-side prerendering for - /// JavaScript-based Single Page Applications. This is an alternative - /// to using the 'asp-prerender-module' tag helper. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public interface ISpaPrerenderer - { - /// - /// Invokes JavaScript code to perform server-side prerendering for a - /// Single-Page Application. This is an alternative to using the - /// 'asp-prerender-module' tag helper. - /// - /// The JavaScript module that exports a prerendering function. - /// The name of the export from the JavaScript module, if it is not the default export. - /// An optional JSON-serializable object to pass to the JavaScript prerendering function. - /// If specified, the prerendering task will time out after this duration if not already completed. - /// - Task RenderToString( - string moduleName, - string exportName = null, - object customDataParameter = null, - int timeoutMilliseconds = default(int)); - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/JavaScriptModuleExport.cs b/src/Middleware/SpaServices/src/Prerendering/JavaScriptModuleExport.cs deleted file mode 100644 index 13fd2177dd..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/JavaScriptModuleExport.cs +++ /dev/null @@ -1,34 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// Describes how to find the JavaScript code that performs prerendering. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class JavaScriptModuleExport - { - /// - /// Creates a new instance of . - /// - /// The path to the JavaScript module containing prerendering code. - public JavaScriptModuleExport(string moduleName) - { - ModuleName = moduleName; - } - - /// - /// Specifies the path to the JavaScript module containing prerendering code. - /// - public string ModuleName { get; private set; } - - /// - /// If set, specifies the name of the CommonJS export that is the prerendering function to execute. - /// If not set, the JavaScript module's default CommonJS export must itself be the prerendering function. - /// - public string ExportName { get; set; } - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/PrerenderTagHelper.cs b/src/Middleware/SpaServices/src/Prerendering/PrerenderTagHelper.cs deleted file mode 100644 index 3aaed1445a..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/PrerenderTagHelper.cs +++ /dev/null @@ -1,132 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc.ViewFeatures; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.AspNetCore.NodeServices; -using Microsoft.AspNetCore.Razor.TagHelpers; -using Microsoft.Extensions.Hosting; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// A tag helper for prerendering JavaScript applications on the server. - /// - [HtmlTargetElement(Attributes = PrerenderModuleAttributeName)] - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class PrerenderTagHelper : TagHelper - { - private const string PrerenderModuleAttributeName = "asp-prerender-module"; - private const string PrerenderExportAttributeName = "asp-prerender-export"; - private const string PrerenderDataAttributeName = "asp-prerender-data"; - private const string PrerenderTimeoutAttributeName = "asp-prerender-timeout"; - private static INodeServices _fallbackNodeServices; // Used only if no INodeServices was registered with DI - - private readonly string _applicationBasePath; - private readonly CancellationToken _applicationStoppingToken; - private readonly INodeServices _nodeServices; - - /// - /// Creates a new instance of . - /// - /// The . - public PrerenderTagHelper(IServiceProvider serviceProvider) - { - var hostEnv = (IWebHostEnvironment)serviceProvider.GetService(typeof(IWebHostEnvironment)); - _nodeServices = (INodeServices)serviceProvider.GetService(typeof(INodeServices)) ?? _fallbackNodeServices; - _applicationBasePath = hostEnv.ContentRootPath; - - var applicationLifetime = (IHostApplicationLifetime)serviceProvider.GetService(typeof(IHostApplicationLifetime)); - _applicationStoppingToken = applicationLifetime.ApplicationStopping; - - // Consider removing the following. Having it means you can get away with not putting app.AddNodeServices() - // in your startup file, but then again it might be confusing that you don't need to. - if (_nodeServices == null) - { - _nodeServices = _fallbackNodeServices = NodeServicesFactory.CreateNodeServices( - new NodeServicesOptions(serviceProvider)); - } - } - - /// - /// Specifies the path to the JavaScript module containing prerendering code. - /// - [HtmlAttributeName(PrerenderModuleAttributeName)] - public string ModuleName { get; set; } - - /// - /// If set, specifies the name of the CommonJS export that is the prerendering function to execute. - /// If not set, the JavaScript module's default CommonJS export must itself be the prerendering function. - /// - [HtmlAttributeName(PrerenderExportAttributeName)] - public string ExportName { get; set; } - - /// - /// An optional JSON-serializable parameter to be supplied to the prerendering code. - /// - [HtmlAttributeName(PrerenderDataAttributeName)] - public object CustomDataParameter { get; set; } - - /// - /// The maximum duration to wait for prerendering to complete. - /// - [HtmlAttributeName(PrerenderTimeoutAttributeName)] - public int TimeoutMillisecondsParameter { get; set; } - - /// - /// The . - /// - [HtmlAttributeNotBound] - [ViewContext] - public ViewContext ViewContext { get; set; } - - /// - /// Executes the tag helper to perform server-side prerendering. - /// - /// The . - /// The . - /// A representing the operation. - public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) - { - var result = await Prerenderer.RenderToString( - _applicationBasePath, - _nodeServices, - _applicationStoppingToken, - new JavaScriptModuleExport(ModuleName) - { - ExportName = ExportName - }, - ViewContext.HttpContext, - CustomDataParameter, - TimeoutMillisecondsParameter); - - if (!string.IsNullOrEmpty(result.RedirectUrl)) - { - // It's a redirection - var permanentRedirect = result.StatusCode.GetValueOrDefault() == 301; - ViewContext.HttpContext.Response.Redirect(result.RedirectUrl, permanentRedirect); - return; - } - - if (result.StatusCode.HasValue) - { - ViewContext.HttpContext.Response.StatusCode = result.StatusCode.Value; - } - - // It's some HTML to inject - output.Content.SetHtmlContent(result.Html); - - // Also attach any specified globals to the 'window' object. This is useful for transferring - // general state between server and client. - var globalsScript = result.CreateGlobalsAssignmentScript(); - if (!string.IsNullOrEmpty(globalsScript)) - { - output.PostElement.SetHtmlContent($""); - } - } - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/Prerenderer.cs b/src/Middleware/SpaServices/src/Prerendering/Prerenderer.cs deleted file mode 100644 index 26316320c6..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/Prerenderer.cs +++ /dev/null @@ -1,109 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.NodeServices; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// Performs server-side prerendering by invoking code in Node.js. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class Prerenderer - { - private static readonly object CreateNodeScriptLock = new object(); - - private static StringAsTempFile NodeScript; - - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal static Task RenderToString( - string applicationBasePath, - INodeServices nodeServices, - CancellationToken applicationStoppingToken, - JavaScriptModuleExport bootModule, - HttpContext httpContext, - object customDataParameter, - int timeoutMilliseconds) - { - // We want to pass the original, unencoded incoming URL data through to Node, so that - // server-side code has the same view of the URL as client-side code (on the client, - // location.pathname returns an unencoded string). - // The following logic handles special characters in URL paths in the same way that - // Node and client-side JS does. For example, the path "/a=b%20c" gets passed through - // unchanged (whereas other .NET APIs do change it - Path.Value will return it as - // "/a=b c" and Path.ToString() will return it as "/a%3db%20c") - var requestFeature = httpContext.Features.Get(); - var unencodedPathAndQuery = requestFeature.RawTarget; - - var request = httpContext.Request; - var unencodedAbsoluteUrl = $"{request.Scheme}://{request.Host}{unencodedPathAndQuery}"; - - return RenderToString( - applicationBasePath, - nodeServices, - applicationStoppingToken, - bootModule, - unencodedAbsoluteUrl, - unencodedPathAndQuery, - customDataParameter, - timeoutMilliseconds, - request.PathBase.ToString()); - } - - /// - /// Performs server-side prerendering by invoking code in Node.js. - /// - /// The root path to your application. This is used when resolving project-relative paths. - /// The instance of that will be used to invoke JavaScript code. - /// A token that indicates when the host application is stopping. - /// The path to the JavaScript file containing the prerendering logic. - /// The URL of the currently-executing HTTP request. This is supplied to the prerendering code. - /// The path and query part of the URL of the currently-executing HTTP request. This is supplied to the prerendering code. - /// An optional JSON-serializable parameter to be supplied to the prerendering code. - /// The maximum duration to wait for prerendering to complete. - /// The PathBase for the currently-executing HTTP request. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static Task RenderToString( - string applicationBasePath, - INodeServices nodeServices, - CancellationToken applicationStoppingToken, - JavaScriptModuleExport bootModule, - string requestAbsoluteUrl, - string requestPathAndQuery, - object customDataParameter, - int timeoutMilliseconds, - string requestPathBase) - { - return nodeServices.InvokeExportAsync( - GetNodeScriptFilename(applicationStoppingToken), - "renderToString", - applicationBasePath, - bootModule, - requestAbsoluteUrl, - requestPathAndQuery, - customDataParameter, - timeoutMilliseconds, - requestPathBase); - } - - private static string GetNodeScriptFilename(CancellationToken applicationStoppingToken) - { - lock (CreateNodeScriptLock) - { - if (NodeScript == null) - { - var script = EmbeddedResourceReader.Read(typeof(Prerenderer), "/Content/Node/prerenderer.js"); - NodeScript = new StringAsTempFile(script, applicationStoppingToken); // Will be cleaned up on process exit - } - } - - return NodeScript.FileName; - } - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/PrerenderingServiceCollectionExtensions.cs b/src/Middleware/SpaServices/src/Prerendering/PrerenderingServiceCollectionExtensions.cs deleted file mode 100644 index cabc57adcf..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/PrerenderingServiceCollectionExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 Microsoft.AspNetCore.SpaServices.Prerendering; - -namespace Microsoft.Extensions.DependencyInjection -{ - /// - /// Extension methods for setting up prerendering features in an . - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class PrerenderingServiceCollectionExtensions - { - /// - /// Configures the dependency injection system to supply an implementation - /// of . - /// - /// The . - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static void AddSpaPrerenderer(this IServiceCollection serviceCollection) - { - serviceCollection.AddHttpContextAccessor(); - serviceCollection.AddSingleton(); - } - } -} diff --git a/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs b/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs deleted file mode 100644 index ce37c54fed..0000000000 --- a/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs +++ /dev/null @@ -1,70 +0,0 @@ -// 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 Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Text; -using System.Text.Encodings.Web; - -namespace Microsoft.AspNetCore.SpaServices.Prerendering -{ - /// - /// Describes the prerendering result returned by JavaScript code. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class RenderToStringResult - { - /// - /// If set, specifies JSON-serializable data that should be added as a set of global JavaScript variables in the document. - /// This can be used to transfer arbitrary data from server-side prerendering code to client-side code (for example, to - /// transfer the state of a Redux store). - /// - public JObject Globals { get; set; } - - /// - /// The HTML generated by the prerendering logic. - /// - public string Html { get; set; } - - /// - /// If set, specifies that instead of rendering HTML, the response should be an HTTP redirection to this URL. - /// This can be used if the prerendering code determines that the requested URL would lead to a redirection according - /// to the SPA's routing configuration. - /// - public string RedirectUrl { get; set; } - - /// - /// If set, specifies the HTTP status code that should be sent back with the server response. - /// - public int? StatusCode { get; set; } - - /// - /// Constructs a block of JavaScript code that assigns data from the - /// property to the global namespace. - /// - /// A block of JavaScript code. - public string CreateGlobalsAssignmentScript() - { - if (Globals == null) - { - return string.Empty; - } - - var stringBuilder = new StringBuilder(); - - foreach (var property in Globals.Properties()) - { - var propertyNameJavaScriptString = JavaScriptEncoder.Default.Encode(property.Name); - var valueJson = property.Value.ToString(Formatting.None); - var valueJsonJavaScriptString = JavaScriptEncoder.Default.Encode(valueJson); - - stringBuilder.AppendFormat("window[\"{0}\"] = JSON.parse(\"{1}\");", - propertyNameJavaScriptString, - valueJsonJavaScriptString); - } - - return stringBuilder.ToString(); - } - } -} diff --git a/src/Middleware/SpaServices/src/Routing/SpaRouteConstraint.cs b/src/Middleware/SpaServices/src/Routing/SpaRouteConstraint.cs deleted file mode 100644 index 6f25a25379..0000000000 --- a/src/Middleware/SpaServices/src/Routing/SpaRouteConstraint.cs +++ /dev/null @@ -1,41 +0,0 @@ -// 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 Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; - -namespace Microsoft.AspNetCore.SpaServices -{ - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class SpaRouteConstraint : IRouteConstraint - { - private readonly string _clientRouteTokenName; - - public SpaRouteConstraint(string clientRouteTokenName) - { - if (string.IsNullOrEmpty(clientRouteTokenName)) - { - throw new ArgumentException("Value cannot be null or empty", nameof(clientRouteTokenName)); - } - - _clientRouteTokenName = clientRouteTokenName; - } - - public bool Match( - HttpContext httpContext, - IRouter route, - string routeKey, - RouteValueDictionary values, - RouteDirection routeDirection) - { - return !HasDotInLastSegment(values[_clientRouteTokenName] as string ?? string.Empty); - } - - private bool HasDotInLastSegment(string uri) - { - var lastSegmentStartPos = uri.LastIndexOf('/'); - return uri.IndexOf('.', lastSegmentStartPos + 1) >= 0; - } - } -} diff --git a/src/Middleware/SpaServices/src/Routing/SpaRouteExtensions.cs b/src/Middleware/SpaServices/src/Routing/SpaRouteExtensions.cs deleted file mode 100644 index 547cf7c8ad..0000000000 --- a/src/Middleware/SpaServices/src/Routing/SpaRouteExtensions.cs +++ /dev/null @@ -1,98 +0,0 @@ -// 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.Collections.Generic; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.SpaServices; - -// Putting in this namespace so it's always available whenever MapRoute is - -namespace Microsoft.AspNetCore.Builder -{ - /// - /// Extension methods useful for configuring routing in a single-page application (SPA). - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class SpaRouteExtensions - { - private const string ClientRouteTokenName = "clientRoute"; - - /// - /// Configures a route that is automatically bypassed if the requested URL appears to be for a static file - /// (e.g., if it has a filename extension). - /// - /// The . - /// The route name. - /// Default route parameters. - /// Route constraints. - /// Route data tokens. - public static void MapSpaFallbackRoute( - this IRouteBuilder routeBuilder, - string name, - object defaults, - object constraints = null, - object dataTokens = null) - { - MapSpaFallbackRoute( - routeBuilder, - name, - /* templatePrefix */ null, - defaults, - constraints, - dataTokens); - } - - /// - /// Configures a route that is automatically bypassed if the requested URL appears to be for a static file - /// (e.g., if it has a filename extension). - /// - /// The . - /// The route name. - /// The template prefix. - /// Default route parameters. - /// Route constraints. - /// Route data tokens. - public static void MapSpaFallbackRoute( - this IRouteBuilder routeBuilder, - string name, - string templatePrefix, - object defaults, - object constraints = null, - object dataTokens = null) - { - var template = CreateRouteTemplate(templatePrefix); - var constraintsDict = ObjectToDictionary(constraints); - constraintsDict.Add(ClientRouteTokenName, new SpaRouteConstraint(ClientRouteTokenName)); - - routeBuilder.MapRoute(name, template, defaults, constraintsDict, dataTokens); - } - - private static string CreateRouteTemplate(string templatePrefix) - { - templatePrefix = templatePrefix ?? string.Empty; - - if (templatePrefix.Contains("?")) - { - // TODO: Consider supporting this. The {*clientRoute} part should be added immediately before the '?' - throw new ArgumentException("SPA fallback route templates don't support querystrings"); - } - - if (templatePrefix.Contains("#")) - { - throw new ArgumentException( - "SPA fallback route templates should not include # characters. The hash part of a URI does not get sent to the server."); - } - - if (templatePrefix != string.Empty && !templatePrefix.EndsWith("/")) - { - templatePrefix += "/"; - } - - return templatePrefix + $"{{*{ClientRouteTokenName}}}"; - } - - private static IDictionary ObjectToDictionary(object value) - => value as IDictionary ?? new RouteValueDictionary(value); - } -} diff --git a/src/Middleware/SpaServices/src/TypeScript/Prerenderer.ts b/src/Middleware/SpaServices/src/TypeScript/Prerenderer.ts deleted file mode 100644 index bc49154719..0000000000 --- a/src/Middleware/SpaServices/src/TypeScript/Prerenderer.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { BootModuleInfo, RenderToStringFunc, RenderToStringCallback } from '../npm/aspnet-prerendering/src/PrerenderingInterfaces'; -import * as path from 'path'; -declare var __non_webpack_require__; - -// Separate declaration and export just to add type checking on function signature -export const renderToString: RenderToStringFunc = renderToStringImpl; - -// This function is invoked by .NET code (via NodeServices). Its job is to hand off execution to the application's -// prerendering boot function. It can operate in two modes: -// [1] Legacy mode -// This is for backward compatibility with projects created with templates older than the generator version 0.6.0. -// In this mode, we don't really do anything here - we just load the 'aspnet-prerendering' NPM module (which must -// exist in node_modules, and must be v1.x (not v2+)), and pass through all the parameters to it. Code in -// 'aspnet-prerendering' v1.x will locate the boot function and invoke it. -// The drawback to this mode is that, for it to work, you have to deploy node_modules to production. -// [2] Current mode -// This is for projects created with the Yeoman generator 0.6.0+ (or projects manually updated). In this mode, -// we don't invoke 'require' at runtime at all. All our dependencies are bundled into the NuGet package, so you -// don't have to deploy node_modules to production. -// To determine whether we're in mode [1] or [2], the code locates your prerendering boot function, and checks whether -// a certain flag is attached to the function instance. -function renderToStringImpl(callback: RenderToStringCallback, applicationBasePath: string, bootModule: BootModuleInfo, absoluteRequestUrl: string, requestPathAndQuery: string, customDataParameter: any, overrideTimeoutMilliseconds: number) { - try { - const forceLegacy = isLegacyAspNetPrerendering(); - const renderToStringFunc = !forceLegacy && findRenderToStringFunc(applicationBasePath, bootModule); - const isNotLegacyMode = renderToStringFunc && renderToStringFunc['isServerRenderer']; - - if (isNotLegacyMode) { - // Current (non-legacy) mode - we invoke the exported function directly (instead of going through aspnet-prerendering) - // It's type-safe to just apply the incoming args to this function, because we already type-checked that it's a RenderToStringFunc, - // just like renderToStringImpl itself is. - renderToStringFunc.apply(null, arguments); - } else { - // Legacy mode - just hand off execution to 'aspnet-prerendering' v1.x, which must exist in node_modules at runtime - const aspNetPrerenderingV1RenderToString = require('aspnet-prerendering').renderToString; - if (aspNetPrerenderingV1RenderToString) { - aspNetPrerenderingV1RenderToString(callback, applicationBasePath, bootModule, absoluteRequestUrl, requestPathAndQuery, customDataParameter, overrideTimeoutMilliseconds); - } else { - callback('If you use aspnet-prerendering >= 2.0.0, you must update your server-side boot module to call createServerRenderer. ' - + 'Either update your boot module code, or revert to aspnet-prerendering version 1.x'); - } - } - } catch (ex) { - // Make sure loading errors are reported back to the .NET part of the app - callback( - 'Prerendering failed because of error: ' - + ex.stack - + '\nCurrent directory is: ' - + process.cwd() - ); - } -}; - -function findBootModule(applicationBasePath: string, bootModule: BootModuleInfo): any { - const bootModuleNameFullPath = path.resolve(applicationBasePath, bootModule.moduleName); - if (bootModule.webpackConfig) { - // If you're using asp-prerender-webpack-config, you're definitely in legacy mode - return null; - } else { - return __non_webpack_require__(bootModuleNameFullPath); - } -} - -function findRenderToStringFunc(applicationBasePath: string, bootModule: BootModuleInfo): RenderToStringFunc { - // First try to load the module - const foundBootModule = findBootModule(applicationBasePath, bootModule); - if (foundBootModule === null) { - return null; // Must be legacy mode - } - - // Now try to pick out the function they want us to invoke - let renderToStringFunc: RenderToStringFunc; - if (bootModule.exportName) { - // Explicitly-named export - renderToStringFunc = foundBootModule[bootModule.exportName]; - } else if (typeof foundBootModule !== 'function') { - // TypeScript-style default export - renderToStringFunc = foundBootModule.default; - } else { - // Native default export - renderToStringFunc = foundBootModule; - } - - // Validate the result - if (typeof renderToStringFunc !== 'function') { - if (bootModule.exportName) { - throw new Error(`The module at ${ bootModule.moduleName } has no function export named ${ bootModule.exportName }.`); - } else { - throw new Error(`The module at ${ bootModule.moduleName } does not export a default function, and you have not specified which export to invoke.`); - } - } - - return renderToStringFunc; -} - -function isLegacyAspNetPrerendering() { - const version = getAspNetPrerenderingPackageVersion(); - return version && /^1\./.test(version); -} - -function getAspNetPrerenderingPackageVersion() { - try { - const packageEntryPoint = __non_webpack_require__.resolve('aspnet-prerendering'); - const packageDir = path.dirname(packageEntryPoint); - const packageJsonPath = path.join(packageDir, 'package.json'); - const packageJson = __non_webpack_require__(packageJsonPath); - return packageJson.version.toString(); - } catch(ex) { - // Implies aspnet-prerendering isn't in node_modules at all (or node_modules itself doesn't exist, - // which will be the case in production based on latest templates). - return null; - } -} diff --git a/src/Middleware/SpaServices/src/TypeScript/WebpackDevMiddleware.ts b/src/Middleware/SpaServices/src/TypeScript/WebpackDevMiddleware.ts deleted file mode 100644 index 142ca000ab..0000000000 --- a/src/Middleware/SpaServices/src/TypeScript/WebpackDevMiddleware.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Pass through the invocation to the 'aspnet-webpack' package, verifying that it can be loaded -export function createWebpackDevServer(callback) { - let aspNetWebpack; - try { - aspNetWebpack = require('aspnet-webpack'); - } catch (ex) { - // Developers sometimes have trouble with badly-configured Node installations, where it's unable - // to find node_modules. Or they accidentally fail to deploy node_modules, or even to run 'npm install'. - // Make sure such errors are reported back to the .NET part of the app. - callback( - 'Webpack dev middleware failed because of an error while loading \'aspnet-webpack\'. Error was: ' - + ex.stack - + '\nCurrent directory is: ' - + process.cwd() - ); - return; - } - - return aspNetWebpack.createWebpackDevServer.apply(this, arguments); -} diff --git a/src/Middleware/SpaServices/src/TypeScript/tsconfig.json b/src/Middleware/SpaServices/src/TypeScript/tsconfig.json deleted file mode 100644 index 433cde0493..0000000000 --- a/src/Middleware/SpaServices/src/TypeScript/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "target": "es3", - "module": "commonjs", - "moduleResolution": "node", - "types": ["node"], - "lib": ["es2015"] - }, - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddleware.cs b/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddleware.cs deleted file mode 100644 index 59623ad879..0000000000 --- a/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddleware.cs +++ /dev/null @@ -1,126 +0,0 @@ -// 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.Linq; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; - -namespace Microsoft.AspNetCore.SpaServices.Webpack -{ - /// - /// Based on ProxyMiddleware from https://github.com/aspnet/Proxy/. - /// Differs in that, if the proxied request returns a 404, we pass through to the next middleware in the chain - /// This is useful for Webpack middleware, because it lets you fall back on prebuilt files on disk for - /// chunks not exposed by the current Webpack config (e.g., DLL/vendor chunks). - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class ConditionalProxyMiddleware - { - private const int DefaultHttpBufferSize = 4096; - - private readonly HttpClient _httpClient; - private readonly RequestDelegate _next; - private readonly ConditionalProxyMiddlewareOptions _options; - private readonly string _pathPrefix; - private readonly bool _pathPrefixIsRoot; - - public ConditionalProxyMiddleware( - RequestDelegate next, - string pathPrefix, - ConditionalProxyMiddlewareOptions options) - { - if (!pathPrefix.StartsWith("/")) - { - pathPrefix = "/" + pathPrefix; - } - - _next = next; - _pathPrefix = pathPrefix; - _pathPrefixIsRoot = string.Equals(_pathPrefix, "/", StringComparison.Ordinal); - _options = options; - _httpClient = new HttpClient(new HttpClientHandler()); - _httpClient.Timeout = _options.RequestTimeout; - } - - public async Task Invoke(HttpContext context) - { - if (context.Request.Path.StartsWithSegments(_pathPrefix) || _pathPrefixIsRoot) - { - var didProxyRequest = await PerformProxyRequest(context); - if (didProxyRequest) - { - return; - } - } - - // Not a request we can proxy - await _next.Invoke(context); - } - - private async Task PerformProxyRequest(HttpContext context) - { - var requestMessage = new HttpRequestMessage(); - - // Copy the request headers - foreach (var header in context.Request.Headers) - { - if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray())) - { - requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); - } - } - - requestMessage.Headers.Host = _options.Host + ":" + _options.Port; - var uriString = - $"{_options.Scheme}://{_options.Host}:{_options.Port}{context.Request.Path}{context.Request.QueryString}"; - requestMessage.RequestUri = new Uri(uriString); - requestMessage.Method = new HttpMethod(context.Request.Method); - - using ( - var responseMessage = await _httpClient.SendAsync( - requestMessage, - HttpCompletionOption.ResponseHeadersRead, - context.RequestAborted)) - { - if (responseMessage.StatusCode == HttpStatusCode.NotFound) - { - // Let some other middleware handle this - return false; - } - - // We can handle this - context.Response.StatusCode = (int)responseMessage.StatusCode; - foreach (var header in responseMessage.Headers) - { - context.Response.Headers[header.Key] = header.Value.ToArray(); - } - - foreach (var header in responseMessage.Content.Headers) - { - context.Response.Headers[header.Key] = header.Value.ToArray(); - } - - // SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response. - context.Response.Headers.Remove("transfer-encoding"); - - using (var responseStream = await responseMessage.Content.ReadAsStreamAsync()) - { - try - { - await responseStream.CopyToAsync(context.Response.Body, DefaultHttpBufferSize, context.RequestAborted); - } - catch (OperationCanceledException) - { - // The CopyToAsync task will be canceled if the client disconnects (e.g., user - // closes or refreshes the browser tab). Don't treat this as an error. - } - } - - return true; - } - } - } -} diff --git a/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddlewareOptions.cs b/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddlewareOptions.cs deleted file mode 100644 index 7f6f80fd77..0000000000 --- a/src/Middleware/SpaServices/src/Webpack/ConditionalProxyMiddlewareOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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; - -namespace Microsoft.AspNetCore.SpaServices.Webpack -{ - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - internal class ConditionalProxyMiddlewareOptions - { - public ConditionalProxyMiddlewareOptions(string scheme, string host, string port, TimeSpan requestTimeout) - { - Scheme = scheme; - Host = host; - Port = port; - RequestTimeout = requestTimeout; - } - - public string Scheme { get; } - public string Host { get; } - public string Port { get; } - public TimeSpan RequestTimeout { get; } - } -} diff --git a/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddleware.cs b/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddleware.cs deleted file mode 100644 index 1a39d2de20..0000000000 --- a/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddleware.cs +++ /dev/null @@ -1,153 +0,0 @@ -// 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 System.Threading; -using Microsoft.AspNetCore.NodeServices; -using Microsoft.AspNetCore.SpaServices.Webpack; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.AspNetCore.Builder -{ - /// - /// Extension methods that can be used to enable Webpack dev middleware support. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static class WebpackDevMiddleware - { - private const string DefaultConfigFile = "webpack.config.js"; - - private static readonly JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings - { - // Note that the aspnet-webpack JS code specifically expects options to be serialized with - // PascalCase property names, so it's important to be explicit about this contract resolver - ContractResolver = new DefaultContractResolver(), - - TypeNameHandling = TypeNameHandling.None - }; - - /// - /// Enables Webpack dev middleware support. This hosts an instance of the Webpack compiler in memory - /// in your application so that you can always serve up-to-date Webpack-built resources without having - /// to run the compiler manually. Since the Webpack compiler instance is retained in memory, incremental - /// compilation is vastly faster that re-running the compiler from scratch. - /// - /// Incoming requests that match Webpack-built files will be handled by returning the Webpack compiler - /// output directly, regardless of files on disk. If compilation is in progress when the request arrives, - /// the response will pause until updated compiler output is ready. - /// - /// The . - /// Options for configuring the Webpack compiler instance. - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public static void UseWebpackDevMiddleware( - this IApplicationBuilder appBuilder, - WebpackDevMiddlewareOptions options = null) - { - // Prepare options - if (options == null) - { - options = new WebpackDevMiddlewareOptions(); - } - - // Validate options - if (options.ReactHotModuleReplacement && !options.HotModuleReplacement) - { - throw new ArgumentException( - "To enable ReactHotModuleReplacement, you must also enable HotModuleReplacement."); - } - - // Unlike other consumers of NodeServices, WebpackDevMiddleware dosen't share Node instances, nor does it - // use your DI configuration. It's important for WebpackDevMiddleware to have its own private Node instance - // because it must *not* restart when files change (if it did, you'd lose all the benefits of Webpack - // middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't - // as fast as some theoretical future alternative. - var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices); - nodeServicesOptions.WatchFileExtensions = new string[] { }; // Don't watch anything - if (!string.IsNullOrEmpty(options.ProjectPath)) - { - nodeServicesOptions.ProjectPath = options.ProjectPath; - } - - if (options.EnvironmentVariables != null) - { - foreach (var kvp in options.EnvironmentVariables) - { - nodeServicesOptions.EnvironmentVariables[kvp.Key] = kvp.Value; - } - } - - var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServicesOptions); - - // Get a filename matching the middleware Node script - var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware), - "/Content/Node/webpack-dev-middleware.js"); - var nodeScript = new StringAsTempFile(script, nodeServicesOptions.ApplicationStoppingToken); // Will be cleaned up on process exit - - // Ideally, this would be relative to the application's PathBase (so it could work in virtual directories) - // but it's not clear that such information exists during application startup, as opposed to within the context - // of a request. - var hmrEndpoint = !string.IsNullOrEmpty(options.HotModuleReplacementEndpoint) - ? options.HotModuleReplacementEndpoint - : "/__webpack_hmr"; // Matches webpack's built-in default - - // Tell Node to start the server hosting webpack-dev-middleware - var devServerOptions = new - { - webpackConfigPath = Path.Combine(nodeServicesOptions.ProjectPath, options.ConfigFile ?? DefaultConfigFile), - suppliedOptions = options, - understandsMultiplePublicPaths = true, - hotModuleReplacementEndpointUrl = hmrEndpoint - }; - var devServerInfo = - nodeServices.InvokeExportAsync(nodeScript.FileName, "createWebpackDevServer", - JsonConvert.SerializeObject(devServerOptions, jsonSerializerSettings)).Result; - - // If we're talking to an older version of aspnet-webpack, it will return only a single PublicPath, - // not an array of PublicPaths. Handle that scenario. - if (devServerInfo.PublicPaths == null) - { - devServerInfo.PublicPaths = new[] { devServerInfo.PublicPath }; - } - - // Proxy the corresponding requests through ASP.NET and into the Node listener - // Anything under / (e.g., /dist) is proxied as a normal HTTP request with a typical timeout (100s is the default from HttpClient), - // plus /__webpack_hmr is proxied with infinite timeout, because it's an EventSource (long-lived request). - foreach (var publicPath in devServerInfo.PublicPaths) - { - appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath + hmrEndpoint, devServerInfo.Port, Timeout.InfiniteTimeSpan); - appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath, devServerInfo.Port, TimeSpan.FromSeconds(100)); - } - } - - private static void UseProxyToLocalWebpackDevMiddleware(this IApplicationBuilder appBuilder, string publicPath, int proxyToPort, TimeSpan requestTimeout) - { - // Note that this is hardcoded to make requests to "localhost" regardless of the hostname of the - // server as far as the client is concerned. This is because ConditionalProxyMiddlewareOptions is - // the one making the internal HTTP requests, and it's going to be to some port on this machine - // because aspnet-webpack hosts the dev server there. We can't use the hostname that the client - // sees, because that could be anything (e.g., some upstream load balancer) and we might not be - // able to make outbound requests to it from here. - // Also note that the webpack HMR service always uses HTTP, even if your app server uses HTTPS, - // because the HMR service has no need for HTTPS (the client doesn't see it directly - all traffic - // to it is proxied), and the HMR service couldn't use HTTPS anyway (in general it wouldn't have - // the necessary certificate). - var proxyOptions = new ConditionalProxyMiddlewareOptions( - "http", "localhost", proxyToPort.ToString(), requestTimeout); - appBuilder.UseMiddleware(publicPath, proxyOptions); - } - -#pragma warning disable CS0649 - class WebpackDevServerInfo - { - public int Port { get; set; } - public string[] PublicPaths { get; set; } - - // For back-compatibility with older versions of aspnet-webpack, in the case where your webpack - // configuration contains exactly one config entry. This will be removed soon. - public string PublicPath { get; set; } - } - } -#pragma warning restore CS0649 -} diff --git a/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddlewareOptions.cs b/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddlewareOptions.cs deleted file mode 100644 index 28685e0d90..0000000000 --- a/src/Middleware/SpaServices/src/Webpack/WebpackDevMiddlewareOptions.cs +++ /dev/null @@ -1,66 +0,0 @@ -// 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.Collections.Generic; - -namespace Microsoft.AspNetCore.SpaServices.Webpack -{ - /// - /// Options for configuring a Webpack dev middleware compiler. - /// - [Obsolete("Use Microsoft.AspNetCore.SpaServices.Extensions")] - public class WebpackDevMiddlewareOptions - { - /// - /// If true, hot module replacement (HMR) will be enabled. This automatically updates Webpack-built - /// resources (such as JavaScript, CSS, or images) in your web browser whenever source files are changed. - /// - public bool HotModuleReplacement { get; set; } - - /// - /// If set, overrides the URL that Webpack's client-side code will connect to when listening for updates. - /// This must be a root-relative URL similar to "/__webpack_hmr" (which is the default endpoint). - /// - public string HotModuleReplacementEndpoint { get; set; } - - /// - /// Overrides the internal port number that client-side HMR code will connect to. - /// - public int HotModuleReplacementServerPort { get; set; } - - /// - /// If true, enables React-specific extensions to Webpack's hot module replacement (HMR) feature. - /// This enables React components to be updated without losing their in-memory state. - /// - public bool ReactHotModuleReplacement { get; set; } - - /// - /// Specifies additional options to be passed to the Webpack Hot Middleware client, if used. - /// - public IDictionary HotModuleReplacementClientOptions { get; set; } - - /// - /// Specifies the Webpack configuration file to be used. If not set, defaults to 'webpack.config.js'. - /// - public string ConfigFile { get; set; } - - /// - /// The root path of your project. Webpack runs in this context. - /// - public string ProjectPath { get; set; } - - /// - /// Specifies additional environment variables to be passed to the Node instance hosting - /// the webpack compiler. - /// - public IDictionary EnvironmentVariables { get; set; } - - /// - /// Specifies a value for the "env" parameter to be passed into the Webpack configuration - /// function. The value must be JSON-serializable, and will only be used if the Webpack - /// configuration is exported as a function. - /// - public object EnvParam { get; set; } - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/.gitignore b/src/Middleware/SpaServices/src/npm/aspnet-angular/.gitignore deleted file mode 100644 index 93666fdf9a..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/node_modules/ -**/*.js -**/*.d.ts -**/*.metadata.json -/compiled diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/.npmignore b/src/Middleware/SpaServices/src/npm/aspnet-angular/.npmignore deleted file mode 100644 index 2df2c09c07..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -!/*.js -!/*.d.ts -/compiled diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/LICENSE.txt b/src/Middleware/SpaServices/src/npm/aspnet-angular/LICENSE.txt deleted file mode 100644 index 0bdc1962b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/LICENSE.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) .NET Foundation. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/package.json b/src/Middleware/SpaServices/src/npm/aspnet-angular/package.json deleted file mode 100644 index 5153adeaad..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "aspnet-angular", - "version": "0.1.1", - "description": "Helpers for using Angular in ASP.NET Core projects", - "main": "index.js", - "scripts": { - "prepublish": "rimraf *.d.ts && ngc && echo 'Finished building NPM package \"aspnet-angular\"'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "https://github.com/aspnet/JavaScriptServices.git" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/aspnet/JavaScriptServices/issues" - }, - "devDependencies": { - "@angular/common": "^4.3.2", - "@angular/compiler": "^4.3.2", - "@angular/compiler-cli": "^4.3.2", - "@angular/core": "^4.3.2", - "@angular/http": "^4.3.2", - "@angular/platform-browser": "^4.3.2", - "rimraf": "^2.6.1", - "rxjs": "^5.4.2", - "zone.js": "^0.8.16" - }, - "peerDependencies": { - "@angular/core": "^4.2.5 || ^5.0.0-beta" - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/src/HttpWithStateTransfer.ts b/src/Middleware/SpaServices/src/npm/aspnet-angular/src/HttpWithStateTransfer.ts deleted file mode 100644 index 517dd7e784..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/src/HttpWithStateTransfer.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Provider, NgModule, Inject } from '@angular/core'; -import { Headers, Http, ResponseOptions, RequestOptionsArgs, Response } from '@angular/http'; -import { Observable } from 'rxjs/Observable'; -import 'rxjs/add/observable/of'; -import 'rxjs/add/operator/map'; -const globalSerializedStateKey = 'HTTP_STATE_TRANSFER'; -const backingStoreDIToken = 'HTTP_STATE_BACKING_STORE'; - -export interface CacheOptions { - permanent: boolean; -} - -export interface CachedHttpResponse { - headers: { [name: string]: any } | null; - status: number; - statusText: string | null; - text: string; - url: string; -} - -export type BackingStore = { [key: string]: CachedHttpResponse }; - -export class HttpWithStateTransfer { - private backingStore: BackingStore; - private http: Http; - - constructor(@Inject(Http) http: Http, @Inject(backingStoreDIToken) backingStore: BackingStore) { - this.http = http; - this.backingStore = backingStore; - } - - public stateForTransfer(): any { - return { [globalSerializedStateKey]: this.backingStore }; - } - - public get(url: string, options?: CacheOptions, requestOptions?: RequestOptionsArgs): Observable { - return this.getCachedResponse(/* cacheKey */ url, () => this.http.get(url, requestOptions), options); - } - - private getCachedResponse(cacheKey: string, provider: () => Observable, options?: CacheOptions): Observable { - // By default, the cache is only used for the *first* client-side read. So, we're only performing - // a one-time transfer of server-side response to the client. If you want to keep and reuse cached - // responses continually during server-side and client-side execution, set 'permanent' to 'true. - const isClient = typeof window !== 'undefined'; - const isPermanent = options && options.permanent; - - const allowReadFromCache = isClient || isPermanent; - if (allowReadFromCache && this.backingStore.hasOwnProperty(cacheKey)) { - const cachedValue = this.backingStore[cacheKey]; - if (!isPermanent) { - delete this.backingStore[cacheKey]; - } - return Observable.of(new Response(new ResponseOptions({ - body: cachedValue.text, - headers: new Headers(cachedValue.headers), - status: cachedValue.status, - url: cachedValue.url - }))); - } - - return provider() - .map(response => { - const allowWriteToCache = !isClient || isPermanent; - if (allowWriteToCache) { - this.backingStore[cacheKey] = { - headers: response.headers ? response.headers.toJSON() : null, - status: response.status, - statusText: response.statusText, - text: response.text(), - url: response.url - }; - } - - return response; - }); - } -} - -export function defaultBackingStoreFactory() { - const transferredData = typeof window !== 'undefined' ? (window as any)[globalSerializedStateKey] : null; - return transferredData || {}; -} - -@NgModule({ - providers: [ - // The backing store is a separate DI service so you could override exactly how it gets - // transferred from server to client - { provide: backingStoreDIToken, useFactory: defaultBackingStoreFactory }, - - { provide: HttpWithStateTransfer, useClass: HttpWithStateTransfer }, - ] -}) -export class HttpWithStateTransferModule { -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/src/index.ts b/src/Middleware/SpaServices/src/npm/aspnet-angular/src/index.ts deleted file mode 100644 index 93d21853b3..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './HttpWithStateTransfer'; diff --git a/src/Middleware/SpaServices/src/npm/aspnet-angular/tsconfig.json b/src/Middleware/SpaServices/src/npm/aspnet-angular/tsconfig.json deleted file mode 100644 index 3c6a30b769..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-angular/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "experimentalDecorators": true, - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "declaration": true, - "outDir": ".", - "lib": ["es2015", "dom"] - }, - "files": [ - "src/index.ts" - ], - "exclude": [ - "node_modules" - ], - "angularCompilerOptions": { - "genDir": "compiled" - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.gitignore b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.gitignore deleted file mode 100644 index e1ef4d0a83..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/typings/ -/node_modules/ -/**/*.js - -/**/.d.ts -!/src/**/*.d.ts - -yarn.lock diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.npmignore b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.npmignore deleted file mode 100644 index 542947e4a9..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -!/*.js -!/*.d.ts -/typings/ -yarn.lock diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/LICENSE.txt b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/LICENSE.txt deleted file mode 100644 index 0bdc1962b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/LICENSE.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) .NET Foundation. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/README.md b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/README.md deleted file mode 100644 index 30cdc0c29f..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Not for general use - -This NPM package is an internal implementation detail of the `Microsoft.AspNetCore.SpaServices` NuGet package. - -You should not use this package directly in your own applications, because it is not supported, and there are no -guarantees about how its APIs will change in the future. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/package.json b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/package.json deleted file mode 100644 index e239460fe8..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "aspnet-prerendering", - "version": "3.0.1", - "description": "Helpers for server-side rendering of JavaScript applications in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", - "main": "index.js", - "scripts": { - "prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-prerendering\"'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/aspnet/JavaScriptServices/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/aspnet/JavaScriptServices.git" - }, - "dependencies": { - "domain-task": "^3.0.0" - }, - "devDependencies": { - "@types/node": "^6.0.42", - "rimraf": "^2.5.4", - "typescript": "^2.2.1" - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/Prerendering.ts b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/Prerendering.ts deleted file mode 100644 index a313cbade0..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/Prerendering.ts +++ /dev/null @@ -1,112 +0,0 @@ -import * as url from 'url'; -import * as path from 'path'; -import * as domain from 'domain'; -import { run as domainTaskRun, baseUrl as domainTaskBaseUrl } from 'domain-task/main'; -import { BootFunc, BootFuncParams, BootModuleInfo, RenderToStringCallback, RenderToStringFunc } from './PrerenderingInterfaces'; - -const defaultTimeoutMilliseconds = 30 * 1000; - -export function createServerRenderer(bootFunc: BootFunc): RenderToStringFunc { - const resultFunc = (callback: RenderToStringCallback, applicationBasePath: string, bootModule: BootModuleInfo, absoluteRequestUrl: string, requestPathAndQuery: string, customDataParameter: any, overrideTimeoutMilliseconds: number, requestPathBase: string) => { - // Prepare a promise that will represent the completion of all domain tasks in this execution context. - // The boot code will wait for this before performing its final render. - let domainTaskCompletionPromiseResolve; - const domainTaskCompletionPromise = new Promise((resolve, reject) => { - domainTaskCompletionPromiseResolve = resolve; - }); - const parsedAbsoluteRequestUrl = url.parse(absoluteRequestUrl); - const params: BootFuncParams = { - // It's helpful for boot funcs to receive the query as a key-value object, so parse it here - // e.g., react-redux-router requires location.query to be a key-value object for consistency with client-side behaviour - location: url.parse(requestPathAndQuery, /* parseQueryString */ true), - origin: parsedAbsoluteRequestUrl.protocol + '//' + parsedAbsoluteRequestUrl.host, - url: requestPathAndQuery, - baseUrl: (requestPathBase || '') + '/', - absoluteUrl: absoluteRequestUrl, - domainTasks: domainTaskCompletionPromise, - data: customDataParameter - }; - const absoluteBaseUrl = params.origin + params.baseUrl; // Should be same value as page's - - // Open a new domain that can track all the async tasks involved in the app's execution - domainTaskRun(/* code to run */ () => { - // Workaround for Node bug where native Promise continuations lose their domain context - // (https://github.com/nodejs/node-v0.x-archive/issues/8648) - // The domain.active property is set by the domain-context module - bindPromiseContinuationsToDomain(domainTaskCompletionPromise, domain['active']); - - // Make the base URL available to the 'domain-tasks/fetch' helper within this execution context - domainTaskBaseUrl(absoluteBaseUrl); - - // Begin rendering, and apply a timeout - const bootFuncPromise = bootFunc(params); - if (!bootFuncPromise || typeof bootFuncPromise.then !== 'function') { - callback(`Prerendering failed because the boot function in ${bootModule.moduleName} did not return a promise.`, null); - return; - } - const timeoutMilliseconds = overrideTimeoutMilliseconds || defaultTimeoutMilliseconds; // e.g., pass -1 to override as 'never time out' - const bootFuncPromiseWithTimeout = timeoutMilliseconds > 0 - ? wrapWithTimeout(bootFuncPromise, timeoutMilliseconds, - `Prerendering timed out after ${timeoutMilliseconds}ms because the boot function in '${bootModule.moduleName}' ` - + 'returned a promise that did not resolve or reject. Make sure that your boot function always resolves or ' - + 'rejects its promise. You can change the timeout value using the \'asp-prerender-timeout\' tag helper.') - : bootFuncPromise; - - // Actually perform the rendering - bootFuncPromiseWithTimeout.then(successResult => { - callback(null, successResult); - }, error => { - callback(error, null); - }); - }, /* completion callback */ errorOrNothing => { - if (errorOrNothing) { - callback(errorOrNothing, null); - } else { - // There are no more ongoing domain tasks (typically data access operations), so we can resolve - // the domain tasks promise which notifies the boot code that it can do its final render. - domainTaskCompletionPromiseResolve(); - } - }); - }; - - // Indicate to the prerendering code bundled into Microsoft.AspNetCore.SpaServices that this is a serverside rendering - // function, so it can be invoked directly. This flag exists only so that, in its absence, we can run some different - // backward-compatibility logic. - resultFunc['isServerRenderer'] = true; - - return resultFunc; -} - -function wrapWithTimeout(promise: Promise, timeoutMilliseconds: number, timeoutRejectionValue: any): Promise { - return new Promise((resolve, reject) => { - const timeoutTimer = setTimeout(() => { - reject(timeoutRejectionValue); - }, timeoutMilliseconds); - - promise.then( - resolvedValue => { - clearTimeout(timeoutTimer); - resolve(resolvedValue); - }, - rejectedValue => { - clearTimeout(timeoutTimer); - reject(rejectedValue); - } - ) - }); -} - -function bindPromiseContinuationsToDomain(promise: Promise, domainInstance: domain.Domain) { - const originalThen = promise.then; - promise.then = (function then(resolve, reject) { - if (typeof resolve === 'function') { - resolve = domainInstance.bind(resolve); - } - - if (typeof reject === 'function') { - reject = domainInstance.bind(reject); - } - - return originalThen.call(this, resolve, reject); - }) as any; -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/PrerenderingInterfaces.ts b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/PrerenderingInterfaces.ts deleted file mode 100644 index ae101bdff3..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/PrerenderingInterfaces.ts +++ /dev/null @@ -1,39 +0,0 @@ -export interface RenderToStringFunc { - (callback: RenderToStringCallback, applicationBasePath: string, bootModule: BootModuleInfo, absoluteRequestUrl: string, requestPathAndQuery: string, customDataParameter: any, overrideTimeoutMilliseconds: number, requestPathBase: string): void; -} - -export interface RenderToStringCallback { - (error: any, result?: RenderResult): void; -} - -export interface RenderToStringResult { - html: string; - statusCode?: number; - globals?: { [key: string]: any }; -} - -export interface RedirectResult { - redirectUrl: string; -} - -export type RenderResult = RenderToStringResult | RedirectResult; - -export interface BootFunc { - (params: BootFuncParams): Promise; -} - -export interface BootFuncParams { - location: any; // e.g., Location object containing information '/some/path' - origin: string; // e.g., 'https://example.com:1234' - url: string; // e.g., '/some/path' - baseUrl: string; // e.g., '' or '/myVirtualDir' - absoluteUrl: string; // e.g., 'https://example.com:1234/some/path' - domainTasks: Promise; - data: any; // any custom object passed through from .NET -} - -export interface BootModuleInfo { - moduleName: string; - exportName?: string; - webpackConfig?: string; -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/index.ts b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/index.ts deleted file mode 100644 index 082f07c785..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './Prerendering'; -export * from './PrerenderingInterfaces'; diff --git a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/tsconfig.json b/src/Middleware/SpaServices/src/npm/aspnet-prerendering/tsconfig.json deleted file mode 100644 index 19facdd357..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-prerendering/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "declaration": true, - "outDir": ".", - "lib": ["es2015", "dom"] - }, - "files": [ - "src/index.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.gitignore b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.gitignore deleted file mode 100644 index 025755a469..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules/ -/*.js -/*.d.ts diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.npmignore b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.npmignore deleted file mode 100644 index 858cdc4c3b..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -!/*.js -!/*.d.ts -/typings/ diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/LICENSE.txt b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/LICENSE.txt deleted file mode 100644 index 0bdc1962b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/LICENSE.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) .NET Foundation. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/README.md b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/README.md deleted file mode 100644 index 65f78bc1b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Not for general use - -This NPM package is an internal implementation detail of the `Microsoft.AspNetCore.SpaServices` NuGet package. - -You should not use this package directly in your own applications, because it is not supported, and there are no -guarantees about how its APIs will change in the future. - -## History - -* Version 1.x amends the Webpack config to insert `react-transform` and `react-transform-hmr` entries on `babel-loader`. -* Version 2.x drops support for the Babel plugin, and instead amends the Webpack config to insert `react-hot-loader/webpack` and `react-hot-loader/patch` entries. This means it works with React Hot Loader v3. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/package.json b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/package.json deleted file mode 100644 index 0e469c7802..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "aspnet-webpack-react", - "version": "4.0.0", - "description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", - "main": "index.js", - "scripts": { - "prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-webpack-react\"'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/aspnet/JavaScriptServices/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/aspnet/JavaScriptServices.git" - }, - "devDependencies": { - "@types/webpack": "^4.4.0", - "rimraf": "^2.5.4", - "typescript": "^2.0.0", - "webpack": "^4.16.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/HotModuleReplacement.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/HotModuleReplacement.ts deleted file mode 100644 index 4f63516c21..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/HotModuleReplacement.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as webpack from 'webpack'; - -const supportedTypeScriptLoaders = ['ts-loader', 'awesome-typescript-loader']; - -export function addReactHotModuleReplacementConfig(webpackConfig: webpack.Configuration) { - const moduleConfig = webpackConfig.module as webpack.Module; - const moduleRules = moduleConfig.rules; - if (!moduleRules) { - return; // Unknown rules list format. Might be Webpack 1.x, which is not supported. - } - - // Find the rule that loads TypeScript files, and prepend 'react-hot-loader/webpack' - // to its array of loaders - for (let ruleIndex = 0; ruleIndex < moduleRules.length; ruleIndex++) { - // We only support NewUseRule (i.e., { use: ... }) because OldUseRule doesn't accept array values - const rule = moduleRules[ruleIndex] as webpack.RuleSetRule; - if (!rule.use) { - continue; - } - - // We're looking for the first 'use' value that's a TypeScript loader - const loadersArray: webpack.RuleSetUseItem[] = rule.use instanceof Array ? rule.use : [rule.use as webpack.RuleSetUseItem]; - const isTypescriptLoader = supportedTypeScriptLoaders.some(typeScriptLoaderName => containsLoader(loadersArray, typeScriptLoaderName)); - if (!isTypescriptLoader) { - continue; - } - - break; - } - - // Ensure the entrypoint is prefixed with 'react-hot-loader/patch' (unless it's already in there). - // We only support entrypoints of the form { name: value } (not just 'name' or ['name']) - // because that gives us a place to prepend the new value - if (!webpackConfig.entry || typeof webpackConfig.entry === 'string' || webpackConfig.entry instanceof Array) { - throw new Error('Cannot enable React HMR because \'entry\' in Webpack config is not of the form { name: value }'); - } - const entryConfig = webpackConfig.entry as webpack.Entry; - Object.getOwnPropertyNames(entryConfig).forEach(entrypointName => { - if (typeof(entryConfig[entrypointName]) === 'string') { - // Normalise to array - entryConfig[entrypointName] = [entryConfig[entrypointName] as string]; - } - }); -} - -function containsLoader(loadersArray: webpack.RuleSetUseItem[], loaderName: string) { - return loadersArray.some(loader => { - // Allow 'use' values to be either { loader: 'name' } or 'name' - // No need to support legacy webpack.OldLoader - const actualLoaderName = (loader as webpack.RuleSetLoader).loader || (loader as string); - return actualLoaderName && new RegExp(`\\b${ loaderName }\\b`).test(actualLoaderName); - }); -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/index.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/index.ts deleted file mode 100644 index c4284f2ff6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { addReactHotModuleReplacementConfig } from './HotModuleReplacement'; - -// Temporarily alias addReactHotModuleReplacementConfig as addReactHotModuleReplacementBabelTransform for backward -// compatibility with aspnet-webpack 1.x. In aspnet-webpack 2.0, we can drop the old name (and also deprecate -// some other no-longer-supported functionality, such as LoadViaWebpack). -export { addReactHotModuleReplacementConfig as addReactHotModuleReplacementBabelTransform } from './HotModuleReplacement'; diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/tsconfig.json b/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/tsconfig.json deleted file mode 100644 index 2ebeb45d5f..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack-react/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "declaration": true, - "outDir": ".", - "lib": ["es2015"] - }, - "files": [ - "src/index.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/.gitignore b/src/Middleware/SpaServices/src/npm/aspnet-webpack/.gitignore deleted file mode 100644 index 025755a469..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules/ -/*.js -/*.d.ts diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/.npmignore b/src/Middleware/SpaServices/src/npm/aspnet-webpack/.npmignore deleted file mode 100644 index 858cdc4c3b..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -!/*.js -!/*.d.ts -/typings/ diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/LICENSE.txt b/src/Middleware/SpaServices/src/npm/aspnet-webpack/LICENSE.txt deleted file mode 100644 index 0bdc1962b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/LICENSE.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) .NET Foundation. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/README.md b/src/Middleware/SpaServices/src/npm/aspnet-webpack/README.md deleted file mode 100644 index 30cdc0c29f..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Not for general use - -This NPM package is an internal implementation detail of the `Microsoft.AspNetCore.SpaServices` NuGet package. - -You should not use this package directly in your own applications, because it is not supported, and there are no -guarantees about how its APIs will change in the future. diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/package.json b/src/Middleware/SpaServices/src/npm/aspnet-webpack/package.json deleted file mode 100644 index b9b956c287..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "aspnet-webpack", - "version": "3.0.0", - "description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", - "main": "index.js", - "scripts": { - "prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-webpack\"'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/aspnet/JavaScriptServices/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/aspnet/JavaScriptServices.git" - }, - "dependencies": { - "connect": "^3.4.1", - "es6-promise": "^3.1.2", - "memory-fs": "^0.3.0", - "require-from-string": "^1.1.0", - "webpack-node-externals": "^1.4.3" - }, - "devDependencies": { - "@types/connect": "^3.4.30", - "@types/node": "^6.0.42", - "@types/webpack": "^4.1.3", - "rimraf": "^2.5.4", - "typescript": "^2.0.0", - "webpack": "^4.5.0" - }, - "peerDependencies": { - "webpack": "^1.13.2 || ^2.1.0-beta || ^3.0.0 || ^4.0.0", - "webpack-dev-middleware": "^1.8.4 || ^3.0.0" - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/LoadViaWebpack.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/LoadViaWebpack.ts deleted file mode 100644 index 0c75afc8bf..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/LoadViaWebpack.ts +++ /dev/null @@ -1,146 +0,0 @@ -// When you're using Webpack, it's often convenient to be able to require modules from regular JavaScript -// and have them transformed by Webpack. This is especially useful when doing ASP.NET server-side prerendering, -// because it means your boot module can use whatever source language you like (e.g., TypeScript), and means -// that your loader plugins (e.g., require('./mystyles.less')) work in exactly the same way on the server as -// on the client. -import 'es6-promise'; -import * as path from 'path'; -import * as webpack from 'webpack'; -import { requireNewCopy } from './RequireNewCopy'; - -// Strange import syntax to work around https://github.com/Microsoft/TypeScript/issues/2719 -import { requirefromstring } from './typings/require-from-string'; -import { memoryfs } from './typings/memory-fs'; -const nodeExternals = require('webpack-node-externals'); -const requireFromString = require('require-from-string') as typeof requirefromstring.requireFromString; -const MemoryFS = require('memory-fs') as typeof memoryfs.MemoryFS; - -// Ensure we only go through the compile process once per [config, module] pair -const loadViaWebpackPromisesCache: { [key: string]: any } = {}; - -export interface LoadViaWebpackCallback { - (error: any, result: T): void; -} - -export function loadViaWebpack(webpackConfigPath: string, modulePath: string, callback: LoadViaWebpackCallback) { - const cacheKey = JSON.stringify(webpackConfigPath) + JSON.stringify(modulePath); - if (!(cacheKey in loadViaWebpackPromisesCache)) { - loadViaWebpackPromisesCache[cacheKey] = loadViaWebpackNoCache(webpackConfigPath, modulePath); - } - loadViaWebpackPromisesCache[cacheKey].then(result => { - callback(null, result); - }, error => { - callback(error, null); - }) -} - -function setExtension(filePath: string, newExtension: string) { - const oldExtensionIfAny = path.extname(filePath); - const basenameWithoutExtension = path.basename(filePath, oldExtensionIfAny); - return path.join(path.dirname(filePath), basenameWithoutExtension) + newExtension; -} - -function loadViaWebpackNoCache(webpackConfigPath: string, modulePath: string) { - return new Promise((resolve, reject) => { - // Load the Webpack config and make alterations needed for loading the output into Node - const webpackConfig: webpack.Configuration = requireNewCopy(webpackConfigPath); - webpackConfig.entry = modulePath; - webpackConfig.target = 'node'; - - // Make sure we preserve the 'path' and 'publicPath' config values if specified, as these - // can affect the build output (e.g., when using 'file' loader, the publicPath value gets - // set as a prefix on output paths). - webpackConfig.output = webpackConfig.output || {}; - webpackConfig.output.path = webpackConfig.output.path || '/'; - webpackConfig.output.filename = 'webpack-output.js'; - webpackConfig.output.libraryTarget = 'commonjs'; - const outputVirtualPath = path.join(webpackConfig.output.path, webpackConfig.output.filename); - - // In Node, we want any JavaScript modules under /node_modules/ to be loaded natively and not bundled into the - // output (partly because it's faster, but also because otherwise there'd be different instances of modules - // depending on how they were loaded, which could lead to errors). - // --- - // NOTE: We have to use webpack-node-externals rather than webpack-externals-plugin because - // webpack-externals-plugin doesn't correctly resolve relative paths, which means you can't - // use css-loader, since tries to require('./../../node_modules/css-loader/lib/css-base.js') (see #132) - // --- - // So, ensure that webpackConfig.externals is an array, and push WebpackNodeExternals into it: - let externalsArray: any[] = (webpackConfig.externals as any[]) || []; - if (!(externalsArray instanceof Array)) { - externalsArray = [externalsArray]; - } - webpackConfig.externals = externalsArray; - externalsArray.push(nodeExternals({ - // However, we do *not* want to treat non-JS files under /node_modules/ as externals (i.e., things - // that should be loaded via regular CommonJS 'require' statements). For example, if you reference - // a .css file inside an NPM module (e.g., require('somepackage/somefile.css')), then we do need to - // load that via Webpack rather than as a regular CommonJS module. - // - // So, configure webpack-externals-plugin to 'whitelist' (i.e., not treat as external) any file - // that has an extension other than .js. Also, since some libraries such as font-awesome refer to - // their own files with cache-busting querystrings (e.g., (url('./something.css?v=4.1.2'))), we - // need to treat '?' as an alternative 'end of filename' marker. - // - // The complex, awkward regex can be eliminated once webpack-externals-plugin merges - // https://github.com/liady/webpack-node-externals/pull/12 - // - // This regex looks for at least one dot character that is *not* followed by "js", but - // is followed by some series of non-dot characters followed by : - whitelist: [/\.(?!js(\?|$))([^.]+(\?|$))/] - })); - - // The CommonsChunkPlugin is not compatible with a CommonJS environment like Node, nor is it needed in that case - const ChunkPlugin = webpack.optimize['CommonsChunkPlugin']; - if (ChunkPlugin !== undefined) { - webpackConfig.plugins = webpackConfig.plugins.filter(plugin => { - return !(plugin instanceof ChunkPlugin); - }); - } - - // The typical use case for DllReferencePlugin is for referencing vendor modules. In a Node - // environment, it doesn't make sense to load them from a DLL bundle, nor would that even - // work, because then you'd get different module instances depending on whether a module - // was referenced via a normal CommonJS 'require' or via Webpack. So just remove any - // DllReferencePlugin from the config. - // If someone wanted to load their own DLL modules (not an NPM module) via DllReferencePlugin, - // that scenario is not supported today. We would have to add some extra option to the - // asp-prerender tag helper to let you specify a list of DLL bundles that should be evaluated - // in this context. But even then you'd need special DLL builds for the Node environment so that - // external dependencies were fetched via CommonJS requires, so it's unclear how that could work. - // The ultimate escape hatch here is just prebuilding your code as part of the application build - // and *not* using asp-prerender-webpack-config at all, then you can do anything you want. - webpackConfig.plugins = webpackConfig.plugins.filter(plugin => { - // DllReferencePlugin is missing from webpack.d.ts for some reason, hence referencing it - // as a key-value object property - return !(plugin instanceof webpack['DllReferencePlugin']); - }); - - // Create a compiler instance that stores its output in memory, then load its output - const compiler = webpack(webpackConfig); - compiler.outputFileSystem = new MemoryFS(); - compiler.run((err, stats) => { - if (err) { - reject(err); - } else { - // We're in a callback, so need an explicit try/catch to propagate any errors up the promise chain - try { - if (stats.hasErrors()) { - throw new Error('Webpack compilation reported errors. Compiler output follows: ' - + stats.toString({ chunks: false })); - } - - // The dynamically-built module will only appear in node-inspector if it has some nonempty - // file path. The following value is arbitrary (since there's no real compiled file on disk) - // but is sufficient to enable debugging. - const fakeModulePath = setExtension(modulePath, '.js'); - - const fileContent = compiler.outputFileSystem.readFileSync(outputVirtualPath, 'utf8'); - const moduleInstance = requireFromString(fileContent, fakeModulePath); - resolve(moduleInstance); - } catch(ex) { - reject(ex); - } - } - }); - }); -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/RequireNewCopy.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/RequireNewCopy.ts deleted file mode 100644 index 940c83ef92..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/RequireNewCopy.ts +++ /dev/null @@ -1,22 +0,0 @@ -export function requireNewCopy(moduleNameOrPath: string): any { - // Store a reference to whatever's in the 'require' cache, - // so we don't permanently destroy it, and then ensure there's - // no cache entry for this module - const resolvedModule = require.resolve(moduleNameOrPath); - const wasCached = resolvedModule in require.cache; - let cachedInstance; - if (wasCached) { - cachedInstance = require.cache[resolvedModule]; - delete require.cache[resolvedModule]; - } - - try { - // Return a new copy - return require(resolvedModule); - } finally { - // Restore the cached entry, if any - if (wasCached) { - require.cache[resolvedModule] = cachedInstance; - } - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackDevMiddleware.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackDevMiddleware.ts deleted file mode 100644 index 324f5db878..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackDevMiddleware.ts +++ /dev/null @@ -1,396 +0,0 @@ -import * as connect from 'connect'; -import * as webpack from 'webpack'; -import * as url from 'url'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as querystring from 'querystring'; -import { requireNewCopy } from './RequireNewCopy'; -import { hasSufficientPermissions } from './WebpackTestPermissions'; - -export type CreateDevServerResult = { - Port: number, - PublicPaths: string[] -}; - -export interface CreateDevServerCallback { - (error: any, result: CreateDevServerResult): void; -} - -// These are the options passed by WebpackDevMiddleware.cs -interface CreateDevServerOptions { - webpackConfigPath: string; - suppliedOptions: DevServerOptions; - hotModuleReplacementEndpointUrl: string; -} - -type EsModuleExports = { __esModule: true, default: T }; -type StringMap = [(key: string) => T]; - -// These are the options configured in C# and then JSON-serialized, hence the C#-style naming -interface DevServerOptions { - HotModuleReplacement: boolean; - HotModuleReplacementServerPort: number; - HotModuleReplacementClientOptions: StringMap; - ReactHotModuleReplacement: boolean; - EnvParam: any; -} - -// Interface as defined in es6-promise -interface Thenable { - then(onFulfilled?: (value: T) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; - then(onFulfilled?: (value: T) => U | Thenable, onRejected?: (error: any) => void): Thenable; -} - -// We support these four kinds of webpack.config.js export -type WebpackConfigOrArray = webpack.Configuration | webpack.Configuration[]; -type WebpackConfigOrArrayOrThenable = WebpackConfigOrArray | Thenable; -interface WebpackConfigFunc { - (env?: any): WebpackConfigOrArrayOrThenable; -} -type WebpackConfigExport = WebpackConfigOrArrayOrThenable | WebpackConfigFunc; -type WebpackConfigModuleExports = WebpackConfigExport | EsModuleExports; - -function isThenable(obj: any): obj is Thenable { - return obj && typeof (>obj).then === 'function'; -} - -function attachWebpackDevMiddleware(app: any, webpackConfig: webpack.Configuration, enableHotModuleReplacement: boolean, enableReactHotModuleReplacement: boolean, hmrClientOptions: StringMap, hmrServerEndpoint: string) { - // Build the final Webpack config based on supplied options - if (enableHotModuleReplacement) { - // For this, we only support the key/value config format, not string or string[], since - // those ones don't clearly indicate what the resulting bundle name will be - const entryPoints = webpackConfig.entry; - const isObjectStyleConfig = entryPoints - && typeof entryPoints === 'object' - && !(entryPoints instanceof Array); - if (!isObjectStyleConfig) { - throw new Error('To use HotModuleReplacement, your webpack config must specify an \'entry\' value as a key-value object (e.g., "entry: { main: \'ClientApp/boot-client.ts\' }")'); - } - - // Augment all entry points so they support HMR (unless they already do) - Object.getOwnPropertyNames(entryPoints).forEach(entryPointName => { - const webpackHotMiddlewareEntryPoint = 'webpack-hot-middleware/client'; - const webpackHotMiddlewareOptions = '?' + querystring.stringify(hmrClientOptions); - if (typeof entryPoints[entryPointName] === 'string') { - entryPoints[entryPointName] = [webpackHotMiddlewareEntryPoint + webpackHotMiddlewareOptions, entryPoints[entryPointName]]; - } else if (firstIndexOfStringStartingWith(entryPoints[entryPointName], webpackHotMiddlewareEntryPoint) < 0) { - entryPoints[entryPointName].unshift(webpackHotMiddlewareEntryPoint + webpackHotMiddlewareOptions); - } - - // Now also inject eventsource polyfill so this can work on IE/Edge (unless it's already there) - // To avoid this being a breaking change for everyone who uses aspnet-webpack, we only do this if you've - // referenced event-source-polyfill in your package.json. Note that having event-source-polyfill available - // on the server in node_modules doesn't imply that you've also included it in your client-side bundle, - // but the converse is true (if it's not in node_modules, then you obviously aren't trying to use it at - // all, so it would definitely not work to take a dependency on it). - const eventSourcePolyfillEntryPoint = 'event-source-polyfill'; - if (npmModuleIsPresent(eventSourcePolyfillEntryPoint)) { - const entryPointsArray: string[] = entryPoints[entryPointName]; // We know by now that it's an array, because if it wasn't, we already wrapped it in one - if (entryPointsArray.indexOf(eventSourcePolyfillEntryPoint) < 0) { - const webpackHmrIndex = firstIndexOfStringStartingWith(entryPointsArray, webpackHotMiddlewareEntryPoint); - if (webpackHmrIndex < 0) { - // This should not be possible, since we just added it if it was missing - throw new Error('Cannot find ' + webpackHotMiddlewareEntryPoint + ' in entry points array: ' + entryPointsArray); - } - - // Insert the polyfill just before the HMR entrypoint - entryPointsArray.splice(webpackHmrIndex, 0, eventSourcePolyfillEntryPoint); - } - } - }); - - webpackConfig.plugins = [].concat(webpackConfig.plugins || []); // Be sure not to mutate the original array, as it might be shared - webpackConfig.plugins.push( - new webpack.HotModuleReplacementPlugin() - ); - - // Set up React HMR support if requested. This requires the 'aspnet-webpack-react' package. - if (enableReactHotModuleReplacement) { - let aspNetWebpackReactModule: any; - try { - aspNetWebpackReactModule = require('aspnet-webpack-react'); - } catch(ex) { - throw new Error('ReactHotModuleReplacement failed because of an error while loading \'aspnet-webpack-react\'. Error was: ' + ex.stack); - } - - aspNetWebpackReactModule.addReactHotModuleReplacementBabelTransform(webpackConfig); - } - } - - // Attach Webpack dev middleware and optional 'hot' middleware - const compiler = webpack(webpackConfig); - app.use(require('webpack-dev-middleware')(compiler, { - noInfo: true, - stats: webpackConfig.stats, - publicPath: ensureLeadingSlash(webpackConfig.output.publicPath), - watchOptions: webpackConfig.watchOptions - })); - - // After each compilation completes, copy the in-memory filesystem to disk. - // This is needed because the debuggers in both VS and VS Code assume that they'll be able to find - // the compiled files on the local disk (though it would be better if they got the source file from - // the browser they are debugging, which would be more correct and make this workaround unnecessary). - // Without this, Webpack plugins like HMR that dynamically modify the compiled output in the dev - // middleware's in-memory filesystem only (and not on disk) would confuse the debugger, because the - // file on disk wouldn't match the file served to the browser, and the source map line numbers wouldn't - // match up. Breakpoints would either not be hit, or would hit the wrong lines. - const copy = stats => copyRecursiveToRealFsSync(compiler.outputFileSystem, '/', [/\.hot-update\.(js|json|js\.map)$/]); - if (compiler.hooks) { - compiler.hooks.done.tap('aspnet-webpack', copy); - } else { - compiler.plugin('done', copy); - } - - if (enableHotModuleReplacement) { - let webpackHotMiddlewareModule; - try { - webpackHotMiddlewareModule = require('webpack-hot-middleware'); - } catch (ex) { - throw new Error('HotModuleReplacement failed because of an error while loading \'webpack-hot-middleware\'. Error was: ' + ex.stack); - } - app.use(workaroundIISExpressEventStreamFlushingIssue(hmrServerEndpoint)); - app.use(webpackHotMiddlewareModule(compiler, { - path: hmrServerEndpoint - })); - } -} - -function workaroundIISExpressEventStreamFlushingIssue(path: string): connect.NextHandleFunction { - // IIS Express makes HMR seem very slow, because when it's reverse-proxying an EventStream response - // from Kestrel, it doesn't pass through the lines to the browser immediately, even if you're calling - // response.Flush (or equivalent) in your ASP.NET Core code. For some reason, it waits until the following - // line is sent. By default, that wouldn't be until the next HMR heartbeat, which can be up to 5 seconds later. - // In effect, it looks as if your code is taking 5 seconds longer to compile than it really does. - // - // As a workaround, this connect middleware intercepts requests to the HMR endpoint, and modifies the response - // stream so that all EventStream 'data' lines are immediately followed with a further blank line. This is - // harmless in non-IIS-Express cases, because it's OK to have extra blank lines in an EventStream response. - // The implementation is simplistic - rather than using a true stream reader, we just patch the 'write' - // method. This relies on webpack's HMR code always writing complete EventStream messages with a single - // 'write' call. That works fine today, but if webpack's HMR code was changed, this workaround might have - // to be updated. - const eventStreamLineStart = /^data\:/; - return (req, res, next) => { - // We only want to interfere with requests to the HMR endpoint, so check this request matches - const urlMatchesPath = (req.url === path) || (req.url.split('?', 1)[0] === path); - if (urlMatchesPath) { - const origWrite = res.write; - res.write = function (chunk) { - const result = origWrite.apply(this, arguments); - - // We only want to interfere with actual EventStream data lines, so check it is one - if (typeof (chunk) === 'string') { - if (eventStreamLineStart.test(chunk) && chunk.charAt(chunk.length - 1) === '\n') { - origWrite.call(this, '\n\n'); - } - } - - return result; - } - } - - return next(); - }; -} - -function copyRecursiveToRealFsSync(from: typeof fs, rootDir: string, exclude: RegExp[]) { - from.readdirSync(rootDir).forEach(filename => { - const fullPath = pathJoinSafe(rootDir, filename); - const shouldExclude = exclude.filter(re => re.test(fullPath)).length > 0; - if (!shouldExclude) { - const fileStat = from.statSync(fullPath); - if (fileStat.isFile()) { - const fileBuf = from.readFileSync(fullPath); - fs.writeFileSync(fullPath, fileBuf); - } else if (fileStat.isDirectory()) { - if (!fs.existsSync(fullPath)) { - fs.mkdirSync(fullPath); - } - copyRecursiveToRealFsSync(from, fullPath, exclude); - } - } - }); -} - -function ensureLeadingSlash(value: string) { - if (value !== null && value.substring(0, 1) !== '/') { - value = '/' + value; - } - - return value; -} - -function pathJoinSafe(rootPath: string, filePath: string) { - // On Windows, MemoryFileSystem's readdirSync output produces directory entries like 'C:' - // which then trigger errors if you call statSync for them. Avoid this by detecting drive - // names at the root, and adding a backslash (so 'C:' becomes 'C:\', which works). - if (rootPath === '/' && path.sep === '\\' && filePath.match(/^[a-z0-9]+\:$/i)) { - return filePath + '\\'; - } else { - return path.join(rootPath, filePath); - } -} - -function beginWebpackWatcher(webpackConfig: webpack.Configuration) { - const compiler = webpack(webpackConfig); - compiler.watch(webpackConfig.watchOptions || {}, (err, stats) => { - // The default error reporter is fine for now, but could be customized here in the future if desired - }); -} - -export function createWebpackDevServer(callback: CreateDevServerCallback, optionsJson: string) { - const options: CreateDevServerOptions = JSON.parse(optionsJson); - - // Enable TypeScript loading if the webpack config is authored in TypeScript - if (path.extname(options.webpackConfigPath) === '.ts') { - try { - require('ts-node/register'); - } catch (ex) { - throw new Error('Error while attempting to enable support for Webpack config file written in TypeScript. Make sure your project depends on the "ts-node" NPM package. The underlying error was: ' + ex.stack); - } - } - - // See the large comment in WebpackTestPermissions.ts for details about this - if (!hasSufficientPermissions()) { - console.log('WARNING: Webpack dev middleware is not enabled because the server process does not have sufficient permissions. You should either remove the UseWebpackDevMiddleware call from your code, or to make it work, give your server process user account permission to write to your application directory and to read all ancestor-level directories.'); - callback(null, { - Port: 0, - PublicPaths: [] - }); - return; - } - - // Read the webpack config's export, and normalize it into the more general 'array of configs' format - const webpackConfigModuleExports: WebpackConfigModuleExports = requireNewCopy(options.webpackConfigPath); - let webpackConfigExport = (webpackConfigModuleExports as EsModuleExports<{}>).__esModule === true - ? (webpackConfigModuleExports as EsModuleExports).default - : (webpackConfigModuleExports as WebpackConfigExport); - - if (webpackConfigExport instanceof Function) { - // If you export a function, then Webpack convention is that it takes zero or one param, - // and that param is called `env` and reflects the `--env.*` args you can specify on - // the command line (e.g., `--env.prod`). - // When invoking it via WebpackDevMiddleware, we let you configure the `env` param in - // your Startup.cs. - webpackConfigExport = webpackConfigExport(options.suppliedOptions.EnvParam); - } - - const webpackConfigThenable = isThenable(webpackConfigExport) - ? webpackConfigExport - : { then: callback => callback(webpackConfigExport) } as Thenable; - - webpackConfigThenable.then(webpackConfigResolved => { - const webpackConfigArray = webpackConfigResolved instanceof Array ? webpackConfigResolved : [webpackConfigResolved]; - - const enableHotModuleReplacement = options.suppliedOptions.HotModuleReplacement; - const enableReactHotModuleReplacement = options.suppliedOptions.ReactHotModuleReplacement; - if (enableReactHotModuleReplacement && !enableHotModuleReplacement) { - callback('To use ReactHotModuleReplacement, you must also enable the HotModuleReplacement option.', null); - return; - } - - // The default value, 0, means 'choose randomly' - const suggestedHMRPortOrZero = options.suppliedOptions.HotModuleReplacementServerPort || 0; - - const app = connect(); - const listener = app.listen(suggestedHMRPortOrZero, () => { - try { - // For each webpack config that specifies a public path, add webpack dev middleware for it - const normalizedPublicPaths: string[] = []; - webpackConfigArray.forEach(webpackConfig => { - if (webpackConfig.target === 'node') { - // For configs that target Node, it's meaningless to set up an HTTP listener, since - // Node isn't going to load those modules over HTTP anyway. It just loads them directly - // from disk. So the most relevant thing we can do with such configs is just write - // updated builds to disk, just like "webpack --watch". - beginWebpackWatcher(webpackConfig); - } else { - // For configs that target browsers, we can set up an HTTP listener, and dynamically - // modify the config to enable HMR etc. This just requires that we have a publicPath. - const publicPath = (webpackConfig.output.publicPath || '').trim(); - if (!publicPath) { - throw new Error('To use the Webpack dev server, you must specify a value for \'publicPath\' on the \'output\' section of your webpack config (for any configuration that targets browsers)'); - } - const publicPathNoTrailingSlash = removeTrailingSlash(publicPath); - normalizedPublicPaths.push(publicPathNoTrailingSlash); - - // This is the URL the client will connect to, except that since it's a relative URL - // (no leading slash), Webpack will resolve it against the runtime URL - // plus it also adds the publicPath - const hmrClientEndpoint = removeLeadingSlash(options.hotModuleReplacementEndpointUrl); - - // This is the URL inside the Webpack middleware Node server that we'll proxy to. - // We have to prefix with the public path because Webpack will add the publicPath - // when it resolves hmrClientEndpoint as a relative URL. - const hmrServerEndpoint = ensureLeadingSlash(publicPathNoTrailingSlash + options.hotModuleReplacementEndpointUrl); - - // We always overwrite the 'path' option as it needs to match what the .NET side is expecting - const hmrClientOptions = options.suppliedOptions.HotModuleReplacementClientOptions || >{}; - hmrClientOptions['path'] = hmrClientEndpoint; - - const dynamicPublicPathKey = 'dynamicPublicPath'; - if (!(dynamicPublicPathKey in hmrClientOptions)) { - // dynamicPublicPath default to true, so we can work with nonempty pathbases (virtual directories) - hmrClientOptions[dynamicPublicPathKey] = true; - } else { - // ... but you can set it to any other value explicitly if you want (e.g., false) - hmrClientOptions[dynamicPublicPathKey] = JSON.parse(hmrClientOptions[dynamicPublicPathKey]); - } - - attachWebpackDevMiddleware(app, webpackConfig, enableHotModuleReplacement, enableReactHotModuleReplacement, hmrClientOptions, hmrServerEndpoint); - } - }); - - // Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here - callback(null, { - Port: listener.address().port, - PublicPaths: normalizedPublicPaths - }); - } catch (ex) { - callback(ex.stack, null); - } - }); - }, - err => callback(err.stack, null) - ); -} - -function removeLeadingSlash(str: string) { - if (str.indexOf('/') === 0) { - str = str.substring(1); - } - - return str; -} - -function removeTrailingSlash(str: string) { - if (str.lastIndexOf('/') === str.length - 1) { - str = str.substring(0, str.length - 1); - } - - return str; -} - -function getPath(publicPath: string) { - return url.parse(publicPath).path; -} - -function firstIndexOfStringStartingWith(array: string[], prefixToFind: string) { - for (let index = 0; index < array.length; index++) { - const candidate = array[index]; - if ((typeof candidate === 'string') && (candidate.substring(0, prefixToFind.length) === prefixToFind)) { - return index; - } - } - - return -1; // Not found -} - -function npmModuleIsPresent(moduleName: string) { - try { - require.resolve(moduleName); - return true; - } catch (ex) { - return false; - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackTestPermissions.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackTestPermissions.ts deleted file mode 100644 index 5747614715..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/WebpackTestPermissions.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -const isWindows = /^win/.test(process.platform); - -// On Windows, Node (still as of v8.1.3) has an issue whereby, when locating JavaScript modules -// on disk, it walks up the directory hierarchy to the disk root, testing whether each directory -// is a symlink or not. This fails with an exception if the process doesn't have permission to -// read those directories. This is a problem when hosting in full IIS, because in typical cases -// the process does not have read permission for higher-level directories. -// -// NodeServices itself works around this by injecting a patched version of Node's 'lstat' API that -// suppresses these irrelevant errors during module loads. This covers most scenarios, but isn't -// enough to make Webpack dev middleware work, because typical Webpack configs use loaders such as -// 'awesome-typescript-loader', which works by forking a child process to do some of its work. The -// child process does not get the patched 'lstat', and hence fails. It's an especially bad failure, -// because the Webpack compiler doesn't even surface the exception - it just never completes the -// compilation process, causing the application to hang indefinitely. -// -// Additionally, Webpack dev middleware will want to write its output to disk, which is also going -// to fail in a typical IIS process, because you won't have 'write' permission to the app dir by -// default. We have to actually write the build output to disk (and not purely keep it in the in- -// memory file system) because the server-side prerendering Node instance is a separate process -// that only knows about code changes when it sees the compiled files on disk change. -// -// In the future, we'll hopefully get Node to fix its underlying issue, and figure out whether VS -// could give 'write' access to the app dir when launching sites in IIS. But until then, disable -// Webpack dev middleware if we detect the server process doesn't have the necessary permissions. - -export function hasSufficientPermissions() { - if (isWindows) { - return canReadDirectoryAndAllAncestors(process.cwd()); - } else { - return true; - } -} - -function canReadDirectoryAndAllAncestors(dir: string): boolean { - if (!canReadDirectory(dir)) { - return false; - } - - const parentDir = path.resolve(dir, '..'); - if (parentDir === dir) { - // There are no more parent directories - we've reached the disk root - return true; - } else { - return canReadDirectoryAndAllAncestors(parentDir); - } -} - -function canReadDirectory(dir: string): boolean { - try { - fs.statSync(dir); - return true; - } catch(ex) { - return false; - } -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/index.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/index.ts deleted file mode 100644 index 2d5ff4b856..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { createWebpackDevServer } from './WebpackDevMiddleware'; -export { loadViaWebpack } from './LoadViaWebpack'; diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/memory-fs.d.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/memory-fs.d.ts deleted file mode 100644 index 6a2d353ed6..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/memory-fs.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export namespace memoryfs { - export class MemoryFS {} -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/require-from-string.d.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/require-from-string.d.ts deleted file mode 100644 index ba41884c7d..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/require-from-string.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export namespace requirefromstring { - export function requireFromString(fileContent: string, filename?: string): T; -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/webpack-node-externals.d.ts b/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/webpack-node-externals.d.ts deleted file mode 100644 index 0bc9e4506d..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/src/typings/webpack-node-externals.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare module 'webpack-node-externals' { -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/tsconfig.json b/src/Middleware/SpaServices/src/npm/aspnet-webpack/tsconfig.json deleted file mode 100644 index edd184de47..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "declaration": true, - "outDir": ".", - "lib": ["es2015"], - "types": ["node"] - }, - "files": [ - "src/index.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock b/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock deleted file mode 100644 index 3727098d92..0000000000 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock +++ /dev/null @@ -1,2646 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== - -"@types/connect@^3.4.30": - version "3.4.32" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" - integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== - dependencies: - "@types/node" "*" - -"@types/node@*": - version "12.12.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.14.tgz#1c1d6e3c75dba466e0326948d56e8bd72a1903d2" - integrity sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA== - -"@types/node@^6.0.42": - version "6.14.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.9.tgz#733583e21ef0eab85a9737dfafbaa66345a92ef0" - integrity sha512-leP/gxHunuazPdZaCvsCefPQxinqUDsCxCR5xaDUrY2MkYxQRFZZwU5e7GojyYsGB7QVtCi7iVEl/hoFXQYc+w== - -"@types/source-list-map@*": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" - integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== - -"@types/tapable@*": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" - integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== - -"@types/uglify-js@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" - integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== - dependencies: - source-map "^0.6.1" - -"@types/webpack-sources@*": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.5.tgz#be47c10f783d3d6efe1471ff7f042611bd464a92" - integrity sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w== - dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.6.1" - -"@types/webpack@^4.1.3": - version "4.41.0" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.0.tgz#b813a044d8b0dec7dfcd7622fdbe327bde06eb9a" - integrity sha512-tWkdf9nO0zFgAY/EumUKwrDUhraHKDqCPhwfFR/R8l0qnPdgb9le0Gzhvb7uzVpouuDGBgiE//ZdY+5jcZy2TA== - dependencies: - "@types/anymatch" "*" - "@types/node" "*" - "@types/tapable" "*" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - source-map "^0.6.0" - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== - -ajv@^6.1.0, ajv@^6.10.2: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -chokidar@^2.0.2: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== - -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect@^3.4.1: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -es6-promise@^3.1.2: - version "3.3.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" - integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.12.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -infer-owner@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -memory-fs@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20" - integrity sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" - integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -semver@^5.3.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -serialize-javascript@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" - integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tar@^4: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - -terser-webpack-plugin@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz#e23c0d554587d1f473bd0cf68627720e733890a4" - integrity sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.1" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser@^4.1.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.2.tgz#448fffad0245f4c8a277ce89788b458bfd7706e8" - integrity sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== - dependencies: - setimmediate "^1.0.4" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^2.0.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" - integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -webpack-node-externals@^1.4.3: - version "1.7.2" - resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" - integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== - -webpack-sources@^1.4.0, webpack-sources@^1.4.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.5.0: - version "4.41.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" - integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.1" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== diff --git a/src/Middleware/SpaServices/src/npm/domain-task/.gitignore b/src/Middleware/SpaServices/src/npm/domain-task/.gitignore deleted file mode 100644 index 025755a469..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules/ -/*.js -/*.d.ts diff --git a/src/Middleware/SpaServices/src/npm/domain-task/.npmignore b/src/Middleware/SpaServices/src/npm/domain-task/.npmignore deleted file mode 100644 index 858cdc4c3b..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -!/*.js -!/*.d.ts -/typings/ diff --git a/src/Middleware/SpaServices/src/npm/domain-task/LICENSE.txt b/src/Middleware/SpaServices/src/npm/domain-task/LICENSE.txt deleted file mode 100644 index 0bdc1962b6..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/LICENSE.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) .NET Foundation. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -these files except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. diff --git a/src/Middleware/SpaServices/src/npm/domain-task/README.md b/src/Middleware/SpaServices/src/npm/domain-task/README.md deleted file mode 100644 index 1333ed77b7..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/README.md +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/src/Middleware/SpaServices/src/npm/domain-task/package.json b/src/Middleware/SpaServices/src/npm/domain-task/package.json deleted file mode 100644 index b22be854a2..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "domain-task", - "version": "3.0.3", - "description": "Tracks outstanding operations for a logical thread of execution", - "main": "index.js", - "scripts": { - "prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"domain-task\"'", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/aspnet/JavaScriptServices/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/aspnet/JavaScriptServices.git" - }, - "dependencies": { - "domain-context": "^0.5.1", - "is-absolute-url": "^2.1.0", - "isomorphic-fetch": "^2.2.1" - }, - "devDependencies": { - "@types/node": "^6.0.42", - "rimraf": "^2.5.4", - "typescript": "^2.2.1" - } -} diff --git a/src/Middleware/SpaServices/src/npm/domain-task/src/domain-context.d.ts b/src/Middleware/SpaServices/src/npm/domain-task/src/domain-context.d.ts deleted file mode 100644 index 1114f929fd..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/src/domain-context.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module 'domain' { - var active: Domain; -} - -declare module 'domain-context' { - function get(key: string): any; - function set(key: string, value: any): void; - function runInNewDomain(code: () => void): void; -} diff --git a/src/Middleware/SpaServices/src/npm/domain-task/src/fetch.ts b/src/Middleware/SpaServices/src/npm/domain-task/src/fetch.ts deleted file mode 100644 index fa576cf679..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/src/fetch.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as url from 'url'; -import * as domain from 'domain'; -import * as domainContext from 'domain-context'; -import * as isAbsoluteUrl from 'is-absolute-url'; -import { baseUrl } from './main'; -const isomorphicFetch = require('isomorphic-fetch'); -const isNode = typeof process === 'object' && process.versions && !!process.versions.node; -const nodeHttps = isNode && require('https'); -const isHttpsRegex = /^https\:/; - -function issueRequest(baseUrl: string, req: string | Request, init?: RequestInit): Promise { - const reqUrl = (req instanceof Request) ? req.url : req; - const isRelativeUrl = reqUrl && !isAbsoluteUrl(reqUrl); - - // Resolve relative URLs - if (baseUrl) { - if (req instanceof Request) { - const reqAsRequest = req as Request; - (reqAsRequest as any).url = url.resolve(baseUrl, reqAsRequest.url); - } else { - req = url.resolve(baseUrl, req as string); - } - } else if (isNode) { - // TODO: Consider only throwing if it's a relative URL, since absolute ones would work fine - throw new Error(` - When running outside the browser (e.g., in Node.js), you must specify a base URL - before invoking domain-task's 'fetch' wrapper. - Example: - import { baseUrl } from 'domain-task/fetch'; - baseUrl('http://example.com'); // Relative URLs will be resolved against this - `); - } - - init = applyHttpsAgentPolicy(init, isRelativeUrl, baseUrl); - return isomorphicFetch(req, init); -} - -function applyHttpsAgentPolicy(init: RequestInit, isRelativeUrl: boolean, baseUrl: string): RequestInit { - // HTTPS is awkward in Node because it uses a built-in list of CAs, rather than recognizing - // the OS's system-level CA list. There are dozens of issues filed against Node about this, - // but still (as of v8.0.0) no resolution besides manually duplicating your CA config. - // - // The biggest problem for typical isomorphic-SPA development this causes is that if you're - // using a self-signed localhost cert in development, Node won't be able to make API calls - // to it (e.g., https://github.com/aspnet/JavaScriptServices/issues/1089). Developers could - // fix this by either manually configuring the cert in Node (which is extremely inconvenient, - // especially if multiple devs on a team have different self-signed localhost certs), or by - // disabling cert verification on their API requests. - // - // Fortunately, 'domain-task/fetch' knows when you're making a relative-URL request to your - // own web server (as opposed to an arbitrary request to anywhere else). In this specific case, - // there's no real point in cert verification, since the request never even leaves the machine - // so a MitM attack isn't meaningful. So by default, when your code is running in Node and - // is making a relative-URL request, *and* if you haven't explicitly configured any option - // for 'agent' (which would let you set up other HTTPS-handling policies), then we automatically - // disable cert verification for that request. - if (isNode && isRelativeUrl) { - const isHttps = baseUrl && isHttpsRegex.test(baseUrl); - if (isHttps) { - const hasAgentConfig = init && ('agent' in init); - if (!hasAgentConfig) { - const agentForRequest = new (nodeHttps.Agent)({ rejectUnauthorized: false }); - - init = init || {}; - (init as any).agent = agentForRequest; - } - } - } - - return init; -} - -export function fetch(url: string | Request, init?: RequestInit): Promise { - // As of domain-task 2.0.0, we no longer auto-add the 'fetch' promise to the current domain task list. - // This is because it's misleading to do so, and can result in race-condition bugs, e.g., - // https://github.com/aspnet/JavaScriptServices/issues/166 - // - // Consider this usage: - // - // import { fetch } from 'domain-task/fetch'; - // fetch(something).then(callback1).then(callback2) ...etc... .then(data => updateCriticalAppState); - // - // If we auto-add the very first 'fetch' promise to the domain task list, then the domain task completion - // callback might fire at any point among all the chained callbacks. If there are enough chained callbacks, - // it's likely to occur before the final 'updateCriticalAppState' one. Previously we thought it was enough - // for domain-task to use setTimeout(..., 0) so that its action occurred after all synchronously-scheduled - // chained promise callbacks, but this turns out not to be the case. Current versions of Node will run - // setTimeout-scheduled callbacks *before* setImmediate ones, if their timeout has elapsed. So even if you - // use setTimeout(..., 10), then this callback will run before setImmediate(...) if there were 10ms or more - // of CPU-blocking activity. In other words, a race condition. - // - // The correct design is for the final chained promise to be the thing added to the domain task list, but - // this can only be done by the developer and not baked into the 'fetch' API. The developer needs to write - // something like: - // - // var myTask = fetch(something).then(callback1).then(callback2) ...etc... .then(data => updateCriticalAppState); - // addDomainTask(myTask); - // - // ... so that the domain-tasks-completed callback never fires until after 'updateCriticalAppState'. - return issueRequest(baseUrl(), url, init); -} - -// Re-exporting baseUrl from this module for back-compatibility only -// Newer code that wants to access baseUrl should use the version exported from the root of this package -export { baseUrl } from './main'; diff --git a/src/Middleware/SpaServices/src/npm/domain-task/src/index.ts b/src/Middleware/SpaServices/src/npm/domain-task/src/index.ts deleted file mode 100644 index b6cb2ab2da..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file determines the top-level package exports -export { addTask, run, baseUrl } from './main'; -export { fetch } from './fetch'; diff --git a/src/Middleware/SpaServices/src/npm/domain-task/src/main.ts b/src/Middleware/SpaServices/src/npm/domain-task/src/main.ts deleted file mode 100644 index 0a944d0cc4..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/src/main.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as domain from 'domain'; -import * as domainContext from 'domain-context'; - -// Not using symbols, because this may need to run in a version of Node.js that doesn't support them -const domainTasksStateKey = '__DOMAIN_TASKS'; -const domainTaskBaseUrlStateKey = '__DOMAIN_TASK_INTERNAL_FETCH_BASEURL__DO_NOT_REFERENCE_THIS__'; - -let noDomainBaseUrl: string; - -export function addTask(task: PromiseLike): PromiseLike { - if (task && domain.active) { - const state = domainContext.get(domainTasksStateKey) as DomainTasksState; - if (state) { - state.numRemainingTasks++; - task.then(() => { - // The application may have other listeners chained to this promise *after* - // this listener, which may in turn register further tasks. Since we don't - // want the combined task to complete until all the handlers for child tasks - // have finished, delay the response to give time for more tasks to be added - // synchronously. - setTimeout(() => { - state.numRemainingTasks--; - if (state.numRemainingTasks === 0 && !state.hasIssuedSuccessCallback) { - state.hasIssuedSuccessCallback = true; - setTimeout(() => { - state.completionCallback(/* error */ null); - }, 0); - } - }, 0); - }, (error) => { - state.completionCallback(error); - }); - } - } - - return task; -} - -export function run(codeToRun: () => T, completionCallback: (error: any) => void): T { - let synchronousResult: T; - domainContext.runInNewDomain(() => { - const state: DomainTasksState = { - numRemainingTasks: 0, - hasIssuedSuccessCallback: false, - completionCallback: domain.active.bind(completionCallback) - }; - - try { - domainContext.set(domainTasksStateKey, state); - synchronousResult = codeToRun(); - - // If no tasks were registered synchronously, then we're done already - if (state.numRemainingTasks === 0 && !state.hasIssuedSuccessCallback) { - state.hasIssuedSuccessCallback = true; - setTimeout(() => { - state.completionCallback(/* error */ null); - }, 0); - } - } catch(ex) { - state.completionCallback(ex); - } - }); - - return synchronousResult; -} - -export function baseUrl(url?: string): string { - if (url) { - if (domain.active) { - // There's an active domain (e.g., in Node.js), so associate the base URL with it - domainContext.set(domainTaskBaseUrlStateKey, url); - } else { - // There's no active domain (e.g., in browser), so there's just one shared base URL - noDomainBaseUrl = url; - } - } - - return domain.active ? domainContext.get(domainTaskBaseUrlStateKey) : noDomainBaseUrl; -} - -interface DomainTasksState { - numRemainingTasks: number; - hasIssuedSuccessCallback: boolean; - completionCallback: (error: any) => void; -} diff --git a/src/Middleware/SpaServices/src/npm/domain-task/tsconfig.json b/src/Middleware/SpaServices/src/npm/domain-task/tsconfig.json deleted file mode 100644 index 518dc798e9..0000000000 --- a/src/Middleware/SpaServices/src/npm/domain-task/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "declaration": true, - "outDir": ".", - "lib": ["es2015", "dom"] - }, - "files": [ - "src/index.ts", - "src/domain-context.d.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/src/Middleware/SpaServices/src/package.json b/src/Middleware/SpaServices/src/package.json deleted file mode 100644 index 9e9cd841ac..0000000000 --- a/src/Middleware/SpaServices/src/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "spaservices", - "version": "1.0.0", - "description": "This is not really an NPM package and will not be published. This file exists only to reference compilation tools.", - "private": true, - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "webpack --mode production" - }, - "author": "Microsoft", - "license": "Apache-2.0", - "devDependencies": { - "@types/node": "^10.9.2", - "ts-loader": "^4.5.0", - "typescript": "^3.0.1", - "webpack": "^4.17.1", - "webpack-cli": "^3.1.0" - } -} diff --git a/src/Middleware/SpaServices/src/webpack.config.js b/src/Middleware/SpaServices/src/webpack.config.js deleted file mode 100644 index e2d4c5d60a..0000000000 --- a/src/Middleware/SpaServices/src/webpack.config.js +++ /dev/null @@ -1,31 +0,0 @@ -const path = require('path'); - -module.exports = { - target: 'node', - externals: [ - // These NPM modules are loaded dynamically at runtime, rather than being bundled into the Content/Node/*.js files - // So, at runtime, they have to either be in node_modules or be built-in Node modules (e.g., 'fs') - 'aspnet-prerendering', - 'aspnet-webpack' - ], - resolve: { - extensions: [ '.ts' ] - }, - module: { - rules: [ - { test: /\.ts$/, use: 'ts-loader' }, - ] - }, - entry: { - 'prerenderer': ['./TypeScript/Prerenderer'], - 'webpack-dev-middleware': ['./TypeScript/WebpackDevMiddleware'], - }, - output: { - libraryTarget: 'commonjs', - path: path.join(__dirname, 'Content', 'Node'), - filename: '[name].js' - }, - optimization: { - minimize: false - } -}; diff --git a/src/Middleware/SpaServices/src/yarn.lock b/src/Middleware/SpaServices/src/yarn.lock deleted file mode 100644 index 78a57b8922..0000000000 --- a/src/Middleware/SpaServices/src/yarn.lock +++ /dev/null @@ -1,2938 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/node@^10.9.2": - version "10.17.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.6.tgz#1aaabd6f6470a6ac3824ab1e94d731ca1326d93d" - integrity sha512-0a2X6cgN3RdPBL2MIlR6Lt0KlM7fOFsutuXcdglcOq6WvLnYXgPQSh0Mx6tO1KCAE8MxbHSOSTWDoUxRq+l3DA== - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== - -ajv@^6.1.0, ajv@^6.10.2: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -chalk@2.4.2, chalk@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chokidar@^2.0.2: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== - -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@6.0.5, cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -findup-sync@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.12.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - -import-local@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -infer-owner@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -interpret@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.0, memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" - integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -semver@^5.0.1, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -serialize-javascript@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" - integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string_decoder@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -supports-color@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tar@^4: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - -terser-webpack-plugin@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz#e23c0d554587d1f473bd0cf68627720e733890a4" - integrity sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.1" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser@^4.1.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.2.tgz#448fffad0245f4c8a277ce89788b458bfd7706e8" - integrity sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== - dependencies: - setimmediate "^1.0.4" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -ts-loader@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-4.5.0.tgz#a1ce70b2dc799941fb2197605f0d67874097859b" - integrity sha512-ihgVaSmgrX4crGV4n7yuoHPoCHbDzj9aepCZR9TgIx4SgJ9gdnB6xLHgUBb7bsFM/f0K6x9iXa65KY/Fu1Klkw== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^3.1.4" - semver "^5.0.1" - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typescript@^3.0.1: - version "3.7.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3.tgz#b36840668a16458a7025b9eabfad11b66ab85c69" - integrity sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -v8-compile-cache@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -webpack-cli@^3.1.0: - version "3.3.10" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.10.tgz#17b279267e9b4fb549023fae170da8e6e766da13" - integrity sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg== - dependencies: - chalk "2.4.2" - cross-spawn "6.0.5" - enhanced-resolve "4.1.0" - findup-sync "3.0.0" - global-modules "2.0.0" - import-local "2.0.0" - interpret "1.2.0" - loader-utils "1.2.3" - supports-color "6.1.0" - v8-compile-cache "2.0.3" - yargs "13.2.4" - -webpack-sources@^1.4.0, webpack-sources@^1.4.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.17.1: - version "4.41.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" - integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.1" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.14, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yargs-parser@^13.1.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" diff --git a/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests.csproj b/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests.csproj deleted file mode 100644 index bf7f3dbbb2..0000000000 --- a/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - - - - - - - diff --git a/src/Middleware/SpaServices/test/RenderToStringResultTests.cs b/src/Middleware/SpaServices/test/RenderToStringResultTests.cs deleted file mode 100644 index 2a828c6596..0000000000 --- a/src/Middleware/SpaServices/test/RenderToStringResultTests.cs +++ /dev/null @@ -1,77 +0,0 @@ -// 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.Collections.Generic; -using Microsoft.AspNetCore.SpaServices.Prerendering; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Xunit; - -namespace Microsoft.AspNetCore.SpaServices.Tests -{ - public class RenderToStringResultTest - { - [Fact] - public void HandlesNullGlobals() - { - // Arrange -#pragma warning disable CS0618 // Type or member is obsolete - var renderToStringResult = new RenderToStringResult(); -#pragma warning restore CS0618 // Type or member is obsolete - renderToStringResult.Globals = null; - - // Act - var actualScript = renderToStringResult.CreateGlobalsAssignmentScript(); - - // Assert - Assert.Equal(string.Empty, actualScript); - } - - [Fact] - public void HandlesGlobalsWithMultipleProperties() - { - // Arrange -#pragma warning disable CS0618 // Type or member is obsolete - var renderToStringResult = new RenderToStringResult(); -#pragma warning restore CS0618 // Type or member is obsolete - renderToStringResult.Globals = ToJObject(new - { - FirstProperty = "first value", - SecondProperty = new[] { "Array entry 0", "Array entry 1" } - }); - - // Act - var actualScript = renderToStringResult.CreateGlobalsAssignmentScript(); - - // Assert - var expectedScript = @"window[""FirstProperty""] = JSON.parse(""\u0022first value\u0022"");" + - @"window[""SecondProperty""] = JSON.parse(""[\u0022Array entry 0\u0022,\u0022Array entry 1\u0022]"");"; - Assert.Equal(expectedScript, actualScript); - } - - [Fact] - public void HandlesGlobalsWithCorrectStringEncoding() - { - // Arrange -#pragma warning disable CS0618 // Type or member is obsolete - var renderToStringResult = new RenderToStringResult(); -#pragma warning restore CS0618 // Type or member is obsolete - renderToStringResult.Globals = ToJObject(new Dictionary - { - { "Va\"'}\u260E" } - }); - - // Act - var actualScript = renderToStringResult.CreateGlobalsAssignmentScript(); - - // Assert - var expectedScript = @"window[""Va\u003Cl\u0027u\u0022e""] = JSON.parse(""\u0022\u003C/tag\u003E\\\u0022\u0027}\u260E\u0022"");"; - Assert.Equal(expectedScript, actualScript); - } - - private static JObject ToJObject(object value) - { - return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value)); - } - } -} diff --git a/src/Mvc/Mvc.Abstractions/src/IUrlHelper.cs b/src/Mvc/Mvc.Abstractions/src/IUrlHelper.cs index 8a0a75db9e..c18009e626 100644 --- a/src/Mvc/Mvc.Abstractions/src/IUrlHelper.cs +++ b/src/Mvc/Mvc.Abstractions/src/IUrlHelper.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Mvc /// your deployment environment. /// /// - string Action(UrlActionContext actionContext); + string? Action(UrlActionContext actionContext); /// /// Converts a virtual (relative, starting with ~/) path to an application absolute path. @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// The virtual path of the content. /// The application absolute path. - string Content(string contentPath); + string? Content(string? contentPath); /// /// Returns a value that indicates whether the URL is local. A URL is considered local if it does not have a @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// /// - bool IsLocalUrl(string url); + bool IsLocalUrl(string? url); /// /// Generates a URL with an absolute path, which contains the route name, route values, protocol to use, host @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc /// your deployment environment. /// /// - string RouteUrl(UrlRouteContext routeContext); + string? RouteUrl(UrlRouteContext routeContext); /// /// Generates an absolute URL for the specified and route @@ -99,11 +99,11 @@ namespace Microsoft.AspNetCore.Mvc /// /// /// This method uses the value of to populate the host section of the generated URI. - /// Relying on the value of the current request can allow untrusted input to influence the resulting URI unless - /// the Host header has been validated. See the deployment documentation for instructions on how to properly + /// Relying on the value of the current request can allow untrusted input to influence the resulting URI unless + /// the Host header has been validated. See the deployment documentation for instructions on how to properly /// validate the Host header in your deployment environment. /// /// - string Link(string routeName, object values); + string? Link(string? routeName, object? values); } } diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/IModelBinderProvider.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/IModelBinderProvider.cs index 397fa7e637..a2807b3598 100644 --- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/IModelBinderProvider.cs +++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/IModelBinderProvider.cs @@ -14,6 +14,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// /// The . /// An . - IModelBinder GetBinder(ModelBinderProviderContext context); + IModelBinder? GetBinder(ModelBinderProviderContext context); } } \ No newline at end of file diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelBindingResult.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelBindingResult.cs index 3ab9c0ba4f..b29736cd57 100644 --- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelBindingResult.cs +++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelBindingResult.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// /// The model value. May be null. /// A representing a successful model bind. - public static ModelBindingResult Success(object model) + public static ModelBindingResult Success(object? model) { return new ModelBindingResult(model, isModelSet: true); } diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelMetadata.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelMetadata.cs index 4ce3e2afbb..d27f38d104 100644 --- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelMetadata.cs +++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelMetadata.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.Extensions.Internal; @@ -26,11 +28,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// public static readonly int DefaultOrder = 10000; - private static readonly IReadOnlyDictionary EmptyParameterMapping = new Dictionary(0); - private int? _hashCode; private IReadOnlyList? _boundProperties; private IReadOnlyDictionary? _parameterMapping; + private Exception? _recordTypeValidatorsOnPropertiesError; + private bool _recordTypeConstructorDetailsCalculated; /// /// Creates a new . @@ -137,37 +139,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } } + /// + /// A mapping from parameters to their corresponding properties on a record type. + /// internal IReadOnlyDictionary BoundConstructorParameterMapping { get { - if (_parameterMapping != null) - { - return _parameterMapping; - } + Debug.Assert(BoundConstructor != null, "This API can be only called for types with bound constructors."); + CalculateRecordTypeConstructorDetails(); - if (BoundConstructor is null) - { - _parameterMapping = EmptyParameterMapping; - return _parameterMapping; - } - - var boundParameters = BoundConstructor.BoundConstructorParameters!; - var parameterMapping = new Dictionary(); - - foreach (var parameter in boundParameters) - { - var property = Properties.FirstOrDefault(p => - string.Equals(p.Name, parameter.ParameterName, StringComparison.Ordinal) && - p.ModelType == parameter.ModelType); - - if (property != null) - { - parameterMapping[parameter] = property; - } - } - - _parameterMapping = parameterMapping; return _parameterMapping; } } @@ -494,6 +475,62 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// public virtual Func? BoundConstructorInvoker => null; + /// + /// Gets a value that determines if validators can be constructed using metadata exclusively defined on the property. + /// + internal virtual bool PropertyHasValidators => false; + + /// + /// Throws if the ModelMetadata is for a record type with validation on properties. + /// + internal void ThrowIfRecordTypeHasValidationOnProperties() + { + CalculateRecordTypeConstructorDetails(); + if (_recordTypeValidatorsOnPropertiesError != null) + { + throw _recordTypeValidatorsOnPropertiesError; + } + } + + [MemberNotNull(nameof(_parameterMapping))] + private void CalculateRecordTypeConstructorDetails() + { + if (_recordTypeConstructorDetailsCalculated) + { + Debug.Assert(_parameterMapping != null); + return; + } + + + var boundParameters = BoundConstructor!.BoundConstructorParameters!; + var parameterMapping = new Dictionary(); + + foreach (var parameter in boundParameters) + { + var property = Properties.FirstOrDefault(p => + string.Equals(p.Name, parameter.ParameterName, StringComparison.Ordinal) && + p.ModelType == parameter.ModelType); + + if (property != null) + { + parameterMapping[parameter] = property; + + if (property.PropertyHasValidators) + { + // When constructing the mapping of paramets -> properties, also determine + // if the property has any validators (without looking at metadata on the type). + // This will help us throw during validation if a user defines validation attributes + // on the property of a record type. + _recordTypeValidatorsOnPropertiesError = new InvalidOperationException( + Resources.FormatRecordTypeHasValidationOnProperties(ModelType, property.Name)); + } + } + } + + _recordTypeConstructorDetailsCalculated = true; + _parameterMapping = parameterMapping; + } + /// /// Gets a display name for the model. /// diff --git a/src/Mvc/Mvc.Abstractions/src/PublicAPI.Unshipped.txt b/src/Mvc/Mvc.Abstractions/src/PublicAPI.Unshipped.txt index af32a8728d..8d5fe4b5b5 100644 --- a/src/Mvc/Mvc.Abstractions/src/PublicAPI.Unshipped.txt +++ b/src/Mvc/Mvc.Abstractions/src/PublicAPI.Unshipped.txt @@ -290,12 +290,12 @@ Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext.OutputFormatterW Microsoft.AspNetCore.Mvc.IActionResult Microsoft.AspNetCore.Mvc.IActionResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext! context) -> System.Threading.Tasks.Task! Microsoft.AspNetCore.Mvc.IUrlHelper -Microsoft.AspNetCore.Mvc.IUrlHelper.Action(Microsoft.AspNetCore.Mvc.Routing.UrlActionContext! actionContext) -> string! +Microsoft.AspNetCore.Mvc.IUrlHelper.Action(Microsoft.AspNetCore.Mvc.Routing.UrlActionContext! actionContext) -> string? Microsoft.AspNetCore.Mvc.IUrlHelper.ActionContext.get -> Microsoft.AspNetCore.Mvc.ActionContext! -Microsoft.AspNetCore.Mvc.IUrlHelper.Content(string! contentPath) -> string! -Microsoft.AspNetCore.Mvc.IUrlHelper.IsLocalUrl(string! url) -> bool -Microsoft.AspNetCore.Mvc.IUrlHelper.Link(string! routeName, object! values) -> string! -Microsoft.AspNetCore.Mvc.IUrlHelper.RouteUrl(Microsoft.AspNetCore.Mvc.Routing.UrlRouteContext! routeContext) -> string! +Microsoft.AspNetCore.Mvc.IUrlHelper.Content(string? contentPath) -> string? +Microsoft.AspNetCore.Mvc.IUrlHelper.IsLocalUrl(string? url) -> bool +Microsoft.AspNetCore.Mvc.IUrlHelper.Link(string? routeName, object? values) -> string? +Microsoft.AspNetCore.Mvc.IUrlHelper.RouteUrl(Microsoft.AspNetCore.Mvc.Routing.UrlRouteContext! routeContext) -> string? Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo.BinderModelName.get -> string? Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo.BinderModelName.set -> void @@ -337,7 +337,7 @@ Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata.BindingSource.get - Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder.BindModelAsync(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext! bindingContext) -> System.Threading.Tasks.Task! Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderProvider -Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderProvider.GetBinder(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderProviderContext! context) -> Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder! +Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderProvider.GetBinder(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderProviderContext! context) -> Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder? Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider.GetMetadataForProperties(System.Type! modelType) -> System.Collections.Generic.IEnumerable! Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider.GetMetadataForType(System.Type! modelType) -> Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata! @@ -742,7 +742,7 @@ static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity.ForP static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity.ForProperty(System.Type! modelType, string! name, System.Type! containerType) -> Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity.ForType(System.Type! modelType) -> Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Failed() -> Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult -static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Success(object! model) -> Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult +static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Success(object? model) -> Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.operator !=(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult x, Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult y) -> bool static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.operator ==(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult x, Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult y) -> bool static Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary.StartsWithPrefix(string! prefix, string! key) -> bool diff --git a/src/Mvc/Mvc.Abstractions/src/Resources.resx b/src/Mvc/Mvc.Abstractions/src/Resources.resx index 99f5998ae6..c4159218e7 100644 --- a/src/Mvc/Mvc.Abstractions/src/Resources.resx +++ b/src/Mvc/Mvc.Abstractions/src/Resources.resx @@ -177,4 +177,7 @@ The type '{0}' must implement '{1}' to be used as a model binder. - \ No newline at end of file + + Record type '{0}' has validation metadata defined on property '{1}' that will be ignored. '{1}' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter. + + diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ComplexObjectModelBinder.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ComplexObjectModelBinder.cs index 2bd38a4bae..392af54ea6 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ComplexObjectModelBinder.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Binders/ComplexObjectModelBinder.cs @@ -75,32 +75,33 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders var bindingSucceeded = false; var modelMetadata = bindingContext.ModelMetadata; + var boundConstructor = modelMetadata.BoundConstructor; - if (bindingContext.Model == null) + if (boundConstructor != null) { - var boundConstructor = modelMetadata.BoundConstructor; - if (boundConstructor != null) - { - var values = new object[boundConstructor.BoundConstructorParameters.Count]; - var (attemptedParameterBinding, parameterBindingSucceeded) = await BindParametersAsync( - bindingContext, - propertyData, - boundConstructor.BoundConstructorParameters, - values); + // Only record types are allowed to have a BoundConstructor. Binding a record type requires + // instantiating the type. This means we'll ignore a previously assigned bindingContext.Model value. + // This behaior is identical to input formatting with S.T.Json and Json.NET. + + var values = new object[boundConstructor.BoundConstructorParameters.Count]; + var (attemptedParameterBinding, parameterBindingSucceeded) = await BindParametersAsync( + bindingContext, + propertyData, + boundConstructor.BoundConstructorParameters, + values); - attemptedBinding |= attemptedParameterBinding; - bindingSucceeded |= parameterBindingSucceeded; + attemptedBinding |= attemptedParameterBinding; + bindingSucceeded |= parameterBindingSucceeded; - if (!CreateModel(bindingContext, boundConstructor, values)) - { - return; - } - } - else + if (!CreateModel(bindingContext, boundConstructor, values)) { - CreateModel(bindingContext); + return; } } + else if (bindingContext.Model == null) + { + CreateModel(bindingContext); + } var (attemptedPropertyBinding, propertyBindingSucceeded) = await BindPropertiesAsync( bindingContext, diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultBindingMetadataProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultBindingMetadataProvider.cs index e5b7c54df0..dcb76f2afa 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultBindingMetadataProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultBindingMetadataProvider.cs @@ -143,8 +143,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata static bool IsRecordType(Type type) { // Based on the state of the art as described in https://github.com/dotnet/roslyn/issues/45777 - var cloneMethod = type.GetMethod("$", BindingFlags.Public | BindingFlags.Instance) ?? - type.GetMethod("<>Clone", BindingFlags.Public | BindingFlags.Instance); + var cloneMethod = type.GetMethod("$", BindingFlags.Public | BindingFlags.Instance); return cloneMethod != null && cloneMethod.ReturnType == type; } } diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadata.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadata.cs index 7d57a10f39..ef55b0e711 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadata.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadata.cs @@ -468,6 +468,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata } } + internal override bool PropertyHasValidators => ValidationMetadata.PropertyHasValidators; + internal static bool CalculateHasValidators(HashSet visited, ModelMetadata metadata) { RuntimeHelpers.EnsureSufficientExecutionStack(); diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/HasValidatorsValidationMetadataProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/HasValidatorsValidationMetadataProvider.cs index 6378ba518f..a3ca241908 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/HasValidatorsValidationMetadataProvider.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/HasValidatorsValidationMetadataProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -40,7 +40,23 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation if (provider.HasValidators(context.Key.ModelType, context.ValidationMetadata.ValidatorMetadata)) { context.ValidationMetadata.HasValidators = true; - return; + + if (context.Key.MetadataKind == ModelMetadataKind.Property) + { + // For properties, additionally determine that if there's validators defined exclusively + // from property attributes. This is later used to produce a error for record types + // where a record type property that is bound as a parameter defines validation attributes. + + if (!(context.PropertyAttributes is IList propertyAttributes)) + { + propertyAttributes = context.PropertyAttributes.ToList(); + } + + if (provider.HasValidators(typeof(object), propertyAttributes)) + { + context.ValidationMetadata.PropertyHasValidators = true; + } + } } } diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/ValidationMetadata.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/ValidationMetadata.cs index d205fdf172..0785f720f9 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/ValidationMetadata.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/ValidationMetadata.cs @@ -46,5 +46,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata /// Gets a value that indicates if the model has validators . /// public bool? HasValidators { get; set; } + + /// + /// Gets or sets a value that determines if validators can be constructed using metadata on properties. + /// + internal bool PropertyHasValidators { get; set; } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/ModelBindingHelper.cs b/src/Mvc/Mvc.Core/src/ModelBinding/ModelBindingHelper.cs index bc2f84b235..8e7e6bbcf4 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/ModelBindingHelper.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/ModelBindingHelper.cs @@ -268,6 +268,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } var modelMetadata = metadataProvider.GetMetadataForType(modelType); + + if (modelMetadata.BoundConstructor != null) + { + throw new NotSupportedException(Resources.FormatTryUpdateModel_RecordTypeNotSupported(nameof(TryUpdateModelAsync), modelType)); + } + var modelState = actionContext.ModelState; var modelBindingContext = DefaultModelBindingContext.CreateBindingContext( diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs index e9a17b5a4b..ec1f794c37 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs @@ -58,6 +58,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation } else { + _modelMetadata.ThrowIfRecordTypeHasValidationOnProperties(); _parameters = _modelMetadata.BoundConstructor.BoundConstructorParameters; } diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs index ba2bbcf214..79108314f3 100644 --- a/src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs +++ b/src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs @@ -304,6 +304,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation else if (metadata.HasValidators == false && ModelState.GetFieldValidationState(key) != ModelValidationState.Invalid) { + if (metadata.BoundConstructor != null) + { + metadata.ThrowIfRecordTypeHasValidationOnProperties(); + } + // No validators will be created for this graph of objects. Mark it as valid if it wasn't previously validated. var entries = ModelState.FindKeysWithPrefix(key); foreach (var item in entries) diff --git a/src/Mvc/Mvc.Core/src/Resources.resx b/src/Mvc/Mvc.Core/src/Resources.resx index 2ae1743410..acdcf3cb99 100644 --- a/src/Mvc/Mvc.Core/src/Resources.resx +++ b/src/Mvc/Mvc.Core/src/Resources.resx @@ -534,4 +534,7 @@ No property found that maps to constructor parameter '{0}' for type '{1}'. Validation requires that each bound parameter of a record type's primary constructor must have a property to read the value. + + {0} cannot update a record type model. If a '{1}' must be updated, include it in an object type. + diff --git a/src/Mvc/Mvc.RazorPages/src/Infrastructure/PageLoaderMatcherPolicy.cs b/src/Mvc/Mvc.RazorPages/src/Infrastructure/PageLoaderMatcherPolicy.cs index 18c14db7c6..0744a11755 100644 --- a/src/Mvc/Mvc.RazorPages/src/Infrastructure/PageLoaderMatcherPolicy.cs +++ b/src/Mvc/Mvc.RazorPages/src/Infrastructure/PageLoaderMatcherPolicy.cs @@ -111,6 +111,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure for (var i = index + 1; i < candidates.Count; i++) { + if (!candidates.IsValidCandidate(i)) + { + continue; + } + var candidate = candidates[i]; var endpoint = candidate.Endpoint; diff --git a/src/Mvc/test/Mvc.FunctionalTests/SystemTextJsonInputFormatterTest.cs b/src/Mvc/test/Mvc.FunctionalTests/SystemTextJsonInputFormatterTest.cs index a81adfeb80..c59c7369b7 100644 --- a/src/Mvc/test/Mvc.FunctionalTests/SystemTextJsonInputFormatterTest.cs +++ b/src/Mvc/test/Mvc.FunctionalTests/SystemTextJsonInputFormatterTest.cs @@ -17,11 +17,11 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests public override Task JsonInputFormatter_RoundtripsRecordType() => base.JsonInputFormatter_RoundtripsRecordType(); - [Fact(Skip = "https://github.com/dotnet/runtime/issues/38539")] + [Fact] public override Task JsonInputFormatter_ValidationWithRecordTypes_NoValidationErrors() => base.JsonInputFormatter_ValidationWithRecordTypes_NoValidationErrors(); - [Fact(Skip = "https://github.com/dotnet/runtime/issues/38539")] + [Fact] public override Task JsonInputFormatter_ValidationWithRecordTypes_ValidationErrors() => base.JsonInputFormatter_ValidationWithRecordTypes_ValidationErrors(); } diff --git a/src/Mvc/test/Mvc.IntegrationTests/TryUpdateModelIntegrationTest.cs b/src/Mvc/test/Mvc.IntegrationTests/TryUpdateModelIntegrationTest.cs index 1487aa7cff..1e5ebffeaf 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/TryUpdateModelIntegrationTest.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/TryUpdateModelIntegrationTest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -1145,7 +1146,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests } [Fact] - public async Task TryUpdateModel_RecordTypeModel_DoesNotOverwriteConstructorParameters() + public async Task TryUpdateModel_RecordTypeModel_Throws() { // Arrange var testContext = ModelBindingTestHelper.GetTestContext(request => @@ -1160,61 +1161,10 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests }; var oldModel = model; - // Act - var result = await TryUpdateModelAsync(model, string.Empty, testContext); + // Act & Assert + var ex = await Assert.ThrowsAsync(() => TryUpdateModelAsync(model, string.Empty, testContext)); + Assert.Equal($"TryUpdateModelAsync cannot update a record type model. If a '{model.GetType()}' must be updated, include it in an object type." , ex.Message); - // Assert - Assert.True(result); - - // Model - Assert.Same(oldModel, model); - Assert.Equal("DefaultStreet", model.Street); - Assert.Equal("Toronto", model.City); - Assert.Equal("98001", model.ZipCode); - - // ModelState - Assert.True(modelState.IsValid); - Assert.Empty(modelState); - } - - [Fact] - public async Task TryUpdateModel_RecordTypeModel_UpdatesProperties() - { - // Arrange - var testContext = ModelBindingTestHelper.GetTestContext(request => - { - request.QueryString = QueryString.Create("ZipCode", "98007").Add("Street", "SomeStreet"); - }); - - var modelState = testContext.ModelState; - var model = new AddressRecord("DefaultStreet", "Toronto") - { - ZipCode = "98001", - }; - var oldModel = model; - - // Act - var result = await TryUpdateModelAsync(model, string.Empty, testContext); - - // Assert - Assert.True(result); - - // Model - Assert.Same(oldModel, model); - Assert.Equal("DefaultStreet", model.Street); - Assert.Equal("Toronto", model.City); - Assert.Equal("98007", model.ZipCode); - - // ModelState - Assert.True(modelState.IsValid); - - var entry = Assert.Single(modelState); - Assert.Equal("ZipCode", entry.Key); - var state = entry.Value; - Assert.Equal("98007", state.AttemptedValue); - Assert.Equal("98007", state.RawValue); - Assert.Empty(state.Errors); - Assert.Equal(ModelValidationState.Valid, state.ValidationState); } private class ModelWithRecordTypeProperty @@ -1269,7 +1219,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests } [Fact] - public async Task TryUpdateModel_RecordTypeProperty_InitializedDoesNotOverwriteConstructorParameters() + public async Task TryUpdateModel_RecordTypePropertyIsOverwritten() { // Arrange var testContext = ModelBindingTestHelper.GetTestContext(request => @@ -1297,19 +1247,33 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Same(oldModel, model); Assert.NotNull(model.Address); var address = model.Address; - Assert.Equal("DefaultStreet", address.Street); - Assert.Equal("DefaultCity", address.City); + Assert.Equal("SomeStreet", address.Street); + Assert.Null(address.City); Assert.Equal("98007", address.ZipCode); // ModelState Assert.True(modelState.IsValid); - var entry = Assert.Single(modelState); - var state = entry.Value; - Assert.Equal("98007", state.AttemptedValue); - Assert.Equal("98007", state.RawValue); - Assert.Empty(state.Errors); - Assert.Equal(ModelValidationState.Valid, state.ValidationState); + Assert.Collection( + modelState.OrderBy(kvp => kvp.Key), + kvp => + { + Assert.Equal("Address.Street", kvp.Key); + var state = kvp.Value; + Assert.Equal("SomeStreet", state.AttemptedValue); + Assert.Equal("SomeStreet", state.RawValue); + Assert.Empty(state.Errors); + Assert.Equal(ModelValidationState.Valid, state.ValidationState); + }, + kvp => + { + Assert.Equal("Address.ZipCode", kvp.Key); + var state = kvp.Value; + Assert.Equal("98007", state.AttemptedValue); + Assert.Equal("98007", state.RawValue); + Assert.Empty(state.Errors); + Assert.Equal(ModelValidationState.Valid, state.ValidationState); + }); } private void UpdateRequest(HttpRequest request, string data, string name) diff --git a/src/Mvc/test/Mvc.IntegrationTests/ValidationWithRecordIntegrationTests.cs b/src/Mvc/test/Mvc.IntegrationTests/ValidationWithRecordIntegrationTests.cs index 92865e46bf..1b4fb23dac 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/ValidationWithRecordIntegrationTests.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/ValidationWithRecordIntegrationTests.cs @@ -1151,7 +1151,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Equal("The value '-123' is not valid.", error.ErrorMessage); } - private record NeverValid(string NeverValidProperty) : IValidatableObject + private record NeverValid(string NeverValidProperty) : IValidatableObject { public IEnumerable Validate(ValidationContext validationContext) { @@ -2298,6 +2298,163 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests private static void Validation_InifnitelyRecursiveModel_ValidationOnTopLevelParameterMethod([Required] RecursiveModel model) { } + private record RecordTypeWithValidatorsOnProperties(string Property1) + { + [Required] + public string Property1 { get; init; } + } + + [Fact] + public async Task Validation_ValidatorsDefinedOnRecordTypeProperties() + { + // Arrange + var modelType = typeof(RecordTypeWithValidatorsOnProperties); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType); + var parameterBinder = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider); + var expected = $"Record type '{modelType}' has validation metadata defined on property 'Property1' that will be ignored. " + + "'Property1' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter."; + + var parameter = new ParameterDescriptor() + { + Name = "parameter", + ParameterType = modelType, + }; + + var testContext = ModelBindingTestHelper.GetTestContext(request => + { + request.QueryString = new QueryString("?Property1=8"); + }); + + var modelState = testContext.ModelState; + + // Act & Assert + var ex = await Assert.ThrowsAsync(() => + parameterBinder.BindModelAsync(parameter, testContext, modelMetadataProvider, modelMetadata)); + + Assert.Equal(expected, ex.Message); + } + + private record RecordTypeWithValidatorsOnPropertiesAndParameters([Required] string Property1) + { + [Required] + public string Property1 { get; init; } + } + + [Fact] + public async Task Validation_ValidatorsDefinedOnRecordTypePropertiesAndParameters() + { + // Arrange + var modelType = typeof(RecordTypeWithValidatorsOnPropertiesAndParameters); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType); + var parameterBinder = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider); + var expected = $"Record type '{modelType}' has validation metadata defined on property 'Property1' that will be ignored. " + + "'Property1' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter."; + + var parameter = new ParameterDescriptor() + { + Name = "parameter", + ParameterType = modelType, + }; + + var testContext = ModelBindingTestHelper.GetTestContext(request => + { + request.QueryString = new QueryString("?Property1=8"); + }); + + var modelState = testContext.ModelState; + + // Act & Assert + var ex = await Assert.ThrowsAsync(() => + parameterBinder.BindModelAsync(parameter, testContext, modelMetadataProvider, modelMetadata)); + + Assert.Equal(expected, ex.Message); + } + + private record RecordTypeWithValidatorsOnMixOfPropertiesAndParameters([Required] string Property1, string Property2) + { + [Required] + public string Property2 { get; init; } + } + + [Fact] + public async Task Validation_ValidatorsDefinedOnMixOfRecordTypePropertiesAndParameters() + { + // Variation of Validation_ValidatorsDefinedOnRecordTypePropertiesAndParameters, but validators + // appear on a mix of properties and parameters. + // Arrange + var modelType = typeof(RecordTypeWithValidatorsOnMixOfPropertiesAndParameters); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType); + var parameterBinder = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider); + var expected = $"Record type '{modelType}' has validation metadata defined on property 'Property2' that will be ignored. " + + "'Property2' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter."; + + var parameter = new ParameterDescriptor() + { + Name = "parameter", + ParameterType = modelType, + }; + + var testContext = ModelBindingTestHelper.GetTestContext(request => + { + request.QueryString = new QueryString("?Property1=8"); + }); + + var modelState = testContext.ModelState; + + // Act & Assert + var ex = await Assert.ThrowsAsync(() => + parameterBinder.BindModelAsync(parameter, testContext, modelMetadataProvider, modelMetadata)); + + Assert.Equal(expected, ex.Message); + } + + private record RecordTypeWithPropertiesAndParameters([Required] string Property1) + { + [Required] + public string Property2 { get; init; } + } + + [Fact] + public async Task Validation_ValidatorsOnParametersAndProperties() + { + // Arrange + var modelType = typeof(RecordTypeWithPropertiesAndParameters); + var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var modelMetadata = modelMetadataProvider.GetMetadataForType(modelType); + var parameterBinder = ModelBindingTestHelper.GetParameterBinder(modelMetadataProvider); + + var parameter = new ParameterDescriptor() + { + Name = "parameter", + ParameterType = modelType, + }; + + var testContext = ModelBindingTestHelper.GetTestContext(request => + { + request.QueryString = new QueryString("?Property1=SomeValue"); + }); + + var modelState = testContext.ModelState; + + // Act + var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext); + + Assert.Equal(2, modelState.Count); + Assert.Equal(1, modelState.ErrorCount); + Assert.False(modelState.IsValid); + + var entry = Assert.Single(modelState, e => e.Key == "Property1").Value; + Assert.Equal("SomeValue", entry.AttemptedValue); + Assert.Equal("SomeValue", entry.RawValue); + Assert.Equal(ModelValidationState.Valid, entry.ValidationState); + + entry = Assert.Single(modelState, e => e.Key == "Property2").Value; + Assert.Equal(ModelValidationState.Invalid, entry.ValidationState); + } + private static void AssertRequiredError(string key, ModelError error) { Assert.Equal(ValidationAttributeUtil.GetRequiredErrorMessage(key), error.ErrorMessage); diff --git a/src/ObjectPool/src/Microsoft.Extensions.ObjectPool.csproj b/src/ObjectPool/src/Microsoft.Extensions.ObjectPool.csproj index ff51de0442..b2f3e690e3 100644 --- a/src/ObjectPool/src/Microsoft.Extensions.ObjectPool.csproj +++ b/src/ObjectPool/src/Microsoft.Extensions.ObjectPool.csproj @@ -2,7 +2,7 @@ A simple object pool implementation. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true pooling diff --git a/src/ObjectPool/test/Microsoft.Extensions.ObjectPool.Tests.csproj b/src/ObjectPool/test/Microsoft.Extensions.ObjectPool.Tests.csproj index bef91a57eb..e292498a03 100644 --- a/src/ObjectPool/test/Microsoft.Extensions.ObjectPool.Tests.csproj +++ b/src/ObjectPool/test/Microsoft.Extensions.ObjectPool.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) enable diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj index 2da0e11666..6a024814c2 100644 --- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj +++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplates.Tests.csproj @@ -10,6 +10,10 @@ true true + + + true + false true diff --git a/src/ProjectTemplates/Web.ProjectTemplates/BlazorServerWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/BlazorServerWeb-CSharp.csproj.in index 6eeaeb4d72..bfebf3e0f2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/BlazorServerWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/BlazorServerWeb-CSharp.csproj.in @@ -23,11 +23,8 @@ - - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Server.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Server.csproj.in index dfa8d096e1..c424c7f614 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Server.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Server.csproj.in @@ -1,4 +1,4 @@ - + ${DefaultNetCoreTargetFramework} @@ -38,11 +38,8 @@ - - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Shared.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Shared.csproj.in index 797f21c216..fdffee5bc5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Shared.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Shared.csproj.in @@ -4,4 +4,7 @@ ${DefaultNetCoreTargetFramework} + + + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj index e2021461e6..b61cd6f6d3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj +++ b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj @@ -38,8 +38,6 @@ - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in index 193e19b5a9..d7d8786b54 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/RazorPagesWeb-CSharp.csproj.in @@ -23,11 +23,8 @@ - - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in index dce287512d..2f77d16ec4 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/StarterWeb-CSharp.csproj.in @@ -23,11 +23,8 @@ - - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in index 44619a1663..064078a06d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/WebApi-CSharp.csproj.in @@ -9,10 +9,7 @@ - - - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json index 463e0eb7ba..3d3cb33674 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json @@ -26,6 +26,31 @@ "sources": [ { "modifiers": [ + { + "condition": "(!OrganizationalAuth && !IndividualAuth)", + "exclude": [ + "Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml", + "Areas/Identity/Pages/Shared/_LoginPartial.OrgAuth.cshtml" + ] + }, + { + "condition": "(OrganizationalAuth || IndividualB2CAuth)", + "rename": { + "Areas/Identity/Pages/Shared/_LoginPartial.OrgAuth.cshtml": "Areas/Identity/Pages/Shared/_LoginPartial.cshtml" + }, + "exclude": [ + "Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml" + ] + }, + { + "condition": "(IndividualLocalAuth)", + "rename": { + "Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml": "Areas/Identity/Pages/Shared/_LoginPartial.cshtml" + }, + "exclude": [ + "Areas/Identity/Pages/Shared/_LoginPartial.OrgAuth.cshtml" + ] + }, { "condition": "(!IndividualLocalAuth || UseLocalDB)", "exclude": [ @@ -131,15 +156,12 @@ { "condition": "(!GenerateApi)", "exclude": [ - "Services/DownstreamWebApi.cs", "Pages/CallWebApi.razor" ] }, { "condition": "(!GenerateGraph)", "exclude": [ - "Services/MicrosoftGraphServiceExtensions.cs", - "Services/TokenAcquisitionCredentialProvider.cs", "Shared/NavMenu.CallsMicrosoftGraph.razor", "Pages/ShowProfile.razor" ] diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml new file mode 100644 index 0000000000..a4f854aac3 --- /dev/null +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.Identity.cshtml @@ -0,0 +1,27 @@ +@using Microsoft.AspNetCore.Identity +@inject SignInManager SignInManager +@inject UserManager UserManager +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.OrgAuth.cshtml similarity index 100% rename from src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.cshtml rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.OrgAuth.cshtml diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/CallWebApi.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/CallWebApi.razor index 858bf6f09f..d3bad28a25 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/CallWebApi.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/CallWebApi.razor @@ -21,13 +21,25 @@ else } @code { + private HttpResponseMessage response; private string apiResult; protected override async Task OnInitializedAsync() { try { - apiResult = await downstreamAPI.CallWebApiAsync("me"); + response = await downstreamAPI.CallWebApiForUserAsync( + "DownstreamApi", + options => options.RelativePath = ""); + + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + apiResult = await response.Content.ReadAsStringAsync(); + } + else + { + apiResult = "Failed to call the web API"; + } } catch (Exception ex) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/DownstreamWebApi.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/DownstreamWebApi.cs deleted file mode 100644 index fbb0de85f6..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/DownstreamWebApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Identity.Web; - -namespace BlazorServerWeb_CSharp -{ - public interface IDownstreamWebApi - { - Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null); - } - - public static class DownstreamWebApiExtensions - { - public static void AddDownstreamWebApiService(this IServiceCollection services, IConfiguration configuration) - { - // https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests - services.AddHttpClient(); - } - } - - public class DownstreamWebApi : IDownstreamWebApi - { - private readonly ITokenAcquisition _tokenAcquisition; - - private readonly IConfiguration _configuration; - - private readonly HttpClient _httpClient; - - public DownstreamWebApi( - ITokenAcquisition tokenAcquisition, - IConfiguration configuration, - HttpClient httpClient) - { - _tokenAcquisition = tokenAcquisition; - _configuration = configuration; - _httpClient = httpClient; - } - - /// - /// Calls the Web API with the required scopes - /// - /// [Optional] Scopes required to call the Web API. If - /// not specified, uses scopes from the configuration - /// Endpoint relative to the CalledApiUrl configuration - /// A JSON string representing the result of calling the Web API - public async Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null) - { - string[] scopes = requiredScopes ?? _configuration["CalledApi:CalledApiScopes"]?.Split(' '); - string apiUrl = (_configuration["CalledApi:CalledApiUrl"] as string)?.TrimEnd('/') + $"/{relativeEndpoint}"; - - string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl); - httpRequestMessage.Headers.Add("Authorization", $"bearer {accessToken}"); - - string apiResult; - var response = await _httpClient.SendAsync(httpRequestMessage); - if (response.StatusCode == HttpStatusCode.OK) - { - apiResult = await response.Content.ReadAsStringAsync(); - } - else - { - apiResult = $"Error calling the API '{apiUrl}'"; - } - - return apiResult; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs deleted file mode 100644 index f917fbed58..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Graph; -using Microsoft.Identity.Web; - -namespace BlazorServerWeb_CSharp -{ - public static class MicrosoftGraphServiceExtensions - { - /// - /// Adds the Microsoft Graph client as a singleton. - /// - /// Service collection. - /// Initial scopes. - /// Base URL for Microsoft graph. This can be - /// changed for instance for applications running in national clouds - public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, - IEnumerable initialScopes, - string graphBaseUrl = "https://graph.microsoft.com/v1.0") - { - services.AddTokenAcquisition(true); - services.AddSingleton(serviceProvider => - { - var tokenAquisitionService = serviceProvider.GetService(); - GraphServiceClient client = string.IsNullOrWhiteSpace(graphBaseUrl) ? - new GraphServiceClient(new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)) : - new GraphServiceClient(graphBaseUrl, new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)); - return client; - }); - return services; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs deleted file mode 100644 index 5d6c643ca4..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Graph; -using Microsoft.Identity.Web; -using System.Collections; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -namespace BlazorServerWeb_CSharp -{ - internal class TokenAcquisitionCredentialProvider : IAuthenticationProvider - { - public TokenAcquisitionCredentialProvider(ITokenAcquisition tokenAcquisition, IEnumerable initialScopes) - { - _tokenAcquisition = tokenAcquisition; - _initialScopes = initialScopes; - } - - ITokenAcquisition _tokenAcquisition; - IEnumerable _initialScopes; - - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - request.Headers.Add("Authorization", - $"Bearer {await _tokenAcquisition.GetAccessTokenForUserAsync(_initialScopes)}"); - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs index 72c0379b57..652c82a570 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Threading.Tasks; #if (OrganizationalAuth || IndividualB2CAuth) using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; #endif #if (OrganizationalAuth) #if (MultiOrgAuth) @@ -73,33 +73,36 @@ namespace BlazorServerWeb_CSharp .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) - string[] scopes = Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + #endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) #if (GenerateApiOrGraph) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd") - .AddMicrosoftWebAppCallsWebApi(Configuration, scopes, "AzureAd") - .AddInMemoryTokenCaches(); -#else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd"); -#endif + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) #if (GenerateApi) - services.AddDownstreamWebApiService(Configuration); + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) #endif #if (GenerateGraph) - services.AddMicrosoftGraph(scopes, Configuration.GetValue("CalledApi:CalledApiUrl")); + .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); #endif #elif (IndividualB2CAuth) #if (GenerateApi) - string[] scopes = Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '); -#endif -#if (GenerateApi) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C") - .AddMicrosoftWebAppCallsWebApi(Configuration, scopes, "AzureAdB2C") - .AddInMemoryTokenCaches(); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - services.AddDownstreamWebApiService(Configuration); +#endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); #else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C"); + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); #endif #endif #if (OrganizationalAuth || IndividualB2CAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/_Imports.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/_Imports.razor index 48dcfafe89..4fe5a889de 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/_Imports.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/_Imports.razor @@ -4,7 +4,6 @@ @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web -@using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using BlazorServerWeb_CSharp @using BlazorServerWeb_CSharp.Shared diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/appsettings.json index b2b1a5fa42..1c0516223b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/appsettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/appsettings.json @@ -17,10 +17,10 @@ // }, ////#elseif (OrganizationalAuth) // "AzureAd": { -//#if (MultiOrgAuth) -// "Instance": "https:////login.microsoftonline.com/common", -//#elseif (SingleOrgAuth) // "Instance": "https:////login.microsoftonline.com/", +//#if (MultiOrgAuth) +// "TenantId": "common", +//#elseif (SingleOrgAuth) // "Domain": "qualified.domain.name", // "TenantId": "22222222-2222-2222-2222-222222222222", //#endif @@ -34,16 +34,16 @@ // }, ////#endif ////#if (GenerateApiOrGraph) -// "CalledApi": { +// "DownstreamApi": { // /* -// 'CalledApiScopes' contains space separated scopes of the Web API you want to call. This can be: +// 'Scopes' contains space separated scopes of the Web API you want to call. This can be: // - a scope for a V2 application (for instance api://b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user) // - a scope corresponding to a V1 application (for instance /.default, where is the // App ID URI of a legacy v1 Web application // Applications are registered in the https://portal.azure.com portal. // */ -// "CalledApiScopes": "user.read", -// "CalledApiUrl": "[WebApiUrl]" +// "BaseUrl": "[WebApiUrl]", +// "Scopes": "user.read" // }, ////#endif ////#if (IndividualLocalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json index 74be1e1bff..0e8fd2766f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/.template.config/template.json @@ -211,19 +211,6 @@ "Server/Controllers/OidcConfigurationController.cs", "Server/Models/ApplicationUser.cs" ] - }, - { - "condition": "(Hosted && !GenerateApi)", - "exclude": [ - "Server/Services/DownstreamWebApi.cs" - ] - }, - { - "condition": "(Hosted &&!GenerateGraph)", - "exclude": [ - "Server/Services/MicrosoftGraphServiceExtensions.cs", - "Server/Services/TokenAcquisitionCredentialProvider.cs" - ] } ] } @@ -301,7 +288,7 @@ "SignUpSignInPolicyId": { "type": "parameter", "datatype": "string", - "defaultValue": "", + "defaultValue": "b2c_1_susi", "replaces": "MySignUpSignInPolicyId", "description": "The sign-in and sign-up policy ID for this project (use with IndividualB2C auth)." }, @@ -340,7 +327,7 @@ "type": "parameter", "datatype": "string", "replaces": "api-scope", - "defaultValue": "user_impersonation", + "defaultValue": "access_as_user", "description": "The API scope the client needs to request to provision an access token. (use with IndividualB2C, SingleOrg)." }, "TenantId": { @@ -470,7 +457,7 @@ "type": "parameter", "datatype": "string", "replaces": "[WebApiUrl]", - "defaultValue" : "https://graph.microsoft.com/v1.0/me", + "defaultValue": "https://graph.microsoft.com/v1.0", "description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C without and ASP.NET Core host is specified." }, "CallsMicrosoftGraph": { @@ -487,7 +474,7 @@ }, "GenerateApi": { "type": "computed", - "value": "(( (IndividualB2CAuth && !Hosted) || OrganizationalAuth) && (CalledApiUrl != \"https://graph.microsoft.com/v1.0/me\" || CalledApiScopes != \"user.read\"))" + "value": "(( (IndividualB2CAuth && !Hosted) || OrganizationalAuth) && (CalledApiUrl != \"https://graph.microsoft.com/v1.0\" || CalledApiScopes != \"user.read\"))" }, "GenerateGraph": { "type": "computed", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Controllers/WeatherForecastController.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Controllers/WeatherForecastController.cs index 99971dfae8..b2e4339447 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Controllers/WeatherForecastController.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Controllers/WeatherForecastController.cs @@ -15,10 +15,10 @@ using System.Net.Http; using Microsoft.Graph; #endif using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; #if (OrganizationalAuth || IndividualB2CAuth) using Microsoft.Identity.Web.Resource; #endif -using Microsoft.Extensions.Logging; using ComponentsWebAssembly_CSharp.Shared; namespace ComponentsWebAssembly_CSharp.Server.Controllers @@ -37,7 +37,7 @@ namespace ComponentsWebAssembly_CSharp.Server.Controllers private readonly ILogger _logger; - // The Web API will only accept tokens 1) for users, and 2) having the api-scope scope for this API + // The Web API will only accept tokens 1) for users, and 2) having the "api-scope" scope for this API static readonly string[] scopeRequiredByApi = new string[] { "api-scope" }; #if (GenerateApi) @@ -55,7 +55,17 @@ namespace ComponentsWebAssembly_CSharp.Server.Controllers { HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi); - string downstreamApiResult = await _downstreamWebApi.CallWebApiAsync(); + using var response = await _downstreamWebApi.CallWebApiForUserAsync("DownstreamApi").ConfigureAwait(false); + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + var apiResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + // Do something + } + else + { + var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}: {error}"); + } var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast @@ -75,7 +85,7 @@ namespace ComponentsWebAssembly_CSharp.Server.Controllers { _logger = logger; _graphServiceClient = graphServiceClient; - } + } [HttpGet] public async Task> Get() diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/DownstreamWebApi.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/DownstreamWebApi.cs deleted file mode 100644 index 0c7d0fcb96..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/DownstreamWebApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Identity.Web; - -namespace ComponentsWebAssembly_CSharp.Server -{ - public interface IDownstreamWebApi - { - Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null); - } - - public static class DownstreamWebApiExtensions - { - public static void AddDownstreamWebApiService(this IServiceCollection services, IConfiguration configuration) - { - // https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests - services.AddHttpClient(); - } - } - - public class DownstreamWebApi : IDownstreamWebApi - { - private readonly ITokenAcquisition _tokenAcquisition; - - private readonly IConfiguration _configuration; - - private readonly HttpClient _httpClient; - - public DownstreamWebApi( - ITokenAcquisition tokenAcquisition, - IConfiguration configuration, - HttpClient httpClient) - { - _tokenAcquisition = tokenAcquisition; - _configuration = configuration; - _httpClient = httpClient; - } - - /// - /// Calls the Web API with the required scopes - /// - /// [Optional] Scopes required to call the Web API. If - /// not specified, uses scopes from the configuration - /// Endpoint relative to the CalledApiUrl configuration - /// A JSON string representing the result of calling the Web API - public async Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null) - { - string[] scopes = requiredScopes ?? _configuration["CalledApi:CalledApiScopes"]?.Split(' '); - string apiUrl = (_configuration["CalledApi:CalledApiUrl"] as string)?.TrimEnd('/') + $"/{relativeEndpoint}"; - - string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl); - httpRequestMessage.Headers.Add("Authorization", $"bearer {accessToken}"); - - string apiResult; - var response = await _httpClient.SendAsync(httpRequestMessage); - if (response.StatusCode == HttpStatusCode.OK) - { - apiResult = await response.Content.ReadAsStringAsync(); - } - else - { - apiResult = $"Error calling the API '{apiUrl}'"; - } - - return apiResult; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/MicrosoftGraphServiceExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/MicrosoftGraphServiceExtensions.cs deleted file mode 100644 index 6702cc3371..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/MicrosoftGraphServiceExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Graph; -using Microsoft.Identity.Web; - -namespace ComponentsWebAssembly_CSharp.Server -{ - public static class MicrosoftGraphServiceExtensions - { - /// - /// Adds the Microsoft Graph client as a singleton. - /// - /// Service collection. - /// Initial scopes. - /// Base URL for Microsoft graph. This can be - /// changed for instance for applications running in national clouds - public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, - IEnumerable initialScopes, - string graphBaseUrl = "https://graph.microsoft.com/v1.0") - { - services.AddTokenAcquisition(true); - services.AddSingleton(serviceProvider => - { - var tokenAquisitionService = serviceProvider.GetService(); - GraphServiceClient client = string.IsNullOrWhiteSpace(graphBaseUrl) ? - new GraphServiceClient(new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)) : - new GraphServiceClient(graphBaseUrl, new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)); - return client; - }); - return services; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/TokenAcquisitionCredentialProvider.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/TokenAcquisitionCredentialProvider.cs deleted file mode 100644 index a6cc2b080e..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Services/TokenAcquisitionCredentialProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Graph; -using Microsoft.Identity.Web; -using System.Collections; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -namespace ComponentsWebAssembly_CSharp.Server -{ - internal class TokenAcquisitionCredentialProvider : IAuthenticationProvider - { - public TokenAcquisitionCredentialProvider(ITokenAcquisition tokenAcquisition, IEnumerable initialScopes) - { - _tokenAcquisition = tokenAcquisition; - _initialScopes = initialScopes; - } - - ITokenAcquisition _tokenAcquisition; - IEnumerable _initialScopes; - - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - request.Headers.Add("Authorization", - $"Bearer {await _tokenAcquisition.GetAccessTokenForUserAsync(_initialScopes)}"); - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs index 80c2560a8e..52df8d06aa 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs @@ -3,8 +3,8 @@ using Microsoft.AspNetCore.Authentication; #endif using Microsoft.AspNetCore.Builder; #if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Identity.Web; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; #endif #if (RequiresHttps) using Microsoft.AspNetCore.HttpsPolicy; @@ -49,9 +49,9 @@ namespace ComponentsWebAssembly_CSharp.Server #else options.UseSqlite( Configuration.GetConnectionString("DefaultConnection"))); +#endif services.AddDatabaseDeveloperPageExceptionFilter(); -#endif services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); @@ -63,31 +63,29 @@ namespace ComponentsWebAssembly_CSharp.Server .AddIdentityServerJwt(); #endif #if (OrganizationalAuth) + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) #if (GenerateApiOrGraph) - // Adds Microsoft Identity platform (AAD v2.0) support to protect this Api - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAd") - .AddMicrosoftWebApiCallsWebApi(Configuration, "AzureAd") - .AddInMemoryTokenCaches(); -#else - // Adds Microsoft Identity platform (AAD v2.0) support to protect this Api - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAd"); -#endif + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi() #if (GenerateApi) - services.AddDownstreamWebApiService(Configuration); + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) #endif #if (GenerateGraph) - services.AddMicrosoftGraph(Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '), - Configuration.GetValue("CalledApi:CalledApiUrl")); + .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); #endif #elif (IndividualB2CAuth) + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) #if (GenerateApi) - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAdB2C") - .AddMicrosoftWebApiCallsWebApi(Configuration, "AzureAdB2C") - .AddInMemoryTokenCaches(); - - services.AddDownstreamWebApiService(Configuration); + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi() + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); #else - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAdB2C"); + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")); #endif #endif diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/appsettings.json index da1c94c1b9..b5f991734b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/appsettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/appsettings.json @@ -21,10 +21,10 @@ // }, ////#elseif (OrganizationalAuth) // "AzureAd": { -//#if (!SingleOrgAuth) -// "Instance": "https:////login.microsoftonline.com/common", -//#else // "Instance": "https:////login.microsoftonline.com/", +//#if (!SingleOrgAuth) +// "TenantId": "common", +//#else // "Domain": "qualified.domain.name", // "TenantId": "22222222-2222-2222-2222-222222222222", //#endif @@ -38,16 +38,16 @@ // }, ////#endif ////#if (GenerateApiOrGraph) -// "CalledApi": { +// "DownstreamAPI": { // /* -// 'CalledApiScopes' contains space separated scopes of the Web API you want to call. This can be: +// 'Scopes' contains space separated scopes of the Web API you want to call. This can be: // - a scope for a V2 application (for instance api://b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user) // - a scope corresponding to a V1 application (for instance /.default, where is the // App ID URI of a legacy v1 Web application // Applications are registered in the https://portal.azure.com portal. // */ -// "CalledApiScopes": "user.read", -// "CalledApiUrl": "[WebApiUrl]" +// "BaseUrl": "[WebApiUrl]", +// "Scopes": "user.read" // }, ////#endif "Logging": { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json index f939274638..a13d60b66a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json @@ -94,19 +94,6 @@ "exclude": [ "Data/SqlServer/**" ] - }, - { - "condition": "(!GenerateApi)", - "exclude": [ - "Services/DownstreamWebApi.cs" - ] - }, - { - "condition": "(!GenerateGraph)", - "exclude": [ - "Services/MicrosoftGraphServiceExtensions.cs", - "Services/TokenAcquisitionCredentialProvider.cs" - ] } ] } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Index.cshtml.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Index.cshtml.cs index bac6493345..35b806d386 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Index.cshtml.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Index.cshtml.cs @@ -18,7 +18,7 @@ using Microsoft.Extensions.Logging; namespace Company.WebApplication1.Pages { #if (GenerateApiOrGraph) - [AuthorizeForScopes(ScopeKeySection = "CalledApi:CalledApiScopes")] + [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")] #endif public class IndexModel : PageModel { @@ -36,7 +36,17 @@ namespace Company.WebApplication1.Pages public async Task OnGet() { - ViewData["ApiResult"] = await _downstreamWebApi.CallWebApiAsync(); + using var response = await _downstreamWebApi.CallWebApiForUserAsync("DownstreamApi").ConfigureAwait(false); + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + var apiResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + ViewData["ApiResult"] = apiResult; + } + else + { + var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}: {error}"); + } } #elseif (GenerateGraph) private readonly GraphServiceClient _graphServiceClient; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/DownstreamWebApi.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/DownstreamWebApi.cs deleted file mode 100644 index 4806ca192d..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/DownstreamWebApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public interface IDownstreamWebApi - { - Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null); - } - - public static class DownstreamWebApiExtensions - { - public static void AddDownstreamWebApiService(this IServiceCollection services, IConfiguration configuration) - { - // https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests - services.AddHttpClient(); - } - } - - public class DownstreamWebApi : IDownstreamWebApi - { - private readonly ITokenAcquisition _tokenAcquisition; - - private readonly IConfiguration _configuration; - - private readonly HttpClient _httpClient; - - public DownstreamWebApi( - ITokenAcquisition tokenAcquisition, - IConfiguration configuration, - HttpClient httpClient) - { - _tokenAcquisition = tokenAcquisition; - _configuration = configuration; - _httpClient = httpClient; - } - - /// - /// Calls the Web API with the required scopes - /// - /// [Optional] Scopes required to call the Web API. If - /// not specified, uses scopes from the configuration - /// Endpoint relative to the CalledApiUrl configuration - /// A JSON string representing the result of calling the Web API - public async Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null) - { - string[] scopes = requiredScopes ?? _configuration["CalledApi:CalledApiScopes"]?.Split(' '); - string apiUrl = (_configuration["CalledApi:CalledApiUrl"] as string)?.TrimEnd('/') + $"/{relativeEndpoint}"; - - string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl); - httpRequestMessage.Headers.Add("Authorization", $"bearer {accessToken}"); - - string apiResult; - var response = await _httpClient.SendAsync(httpRequestMessage); - if (response.StatusCode == HttpStatusCode.OK) - { - apiResult = await response.Content.ReadAsStringAsync(); - } - else - { - apiResult = $"Error calling the API '{apiUrl}'"; - } - - return apiResult; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs deleted file mode 100644 index 2e805a9688..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Graph; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public static class MicrosoftGraphServiceExtensions - { - /// - /// Adds the Microsoft Graph client as a singleton. - /// - /// Service collection. - /// Initial scopes. - /// Base URL for Microsoft graph. This can be - /// changed for instance for applications running in national clouds - public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, - IEnumerable initialScopes, - string graphBaseUrl = "https://graph.microsoft.com/v1.0") - { - services.AddTokenAcquisition(true); - services.AddSingleton(serviceProvider => - { - var tokenAquisitionService = serviceProvider.GetService(); - GraphServiceClient client = string.IsNullOrWhiteSpace(graphBaseUrl) ? - new GraphServiceClient(new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)) : - new GraphServiceClient(graphBaseUrl, new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)); - return client; - }); - - return services; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs deleted file mode 100644 index 8042149d82..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Graph; -using Microsoft.Identity.Web; -using System.Collections; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Company.WebApplication1 -{ - internal class TokenAcquisitionCredentialProvider : IAuthenticationProvider - { - public TokenAcquisitionCredentialProvider(ITokenAcquisition tokenAcquisition, IEnumerable initialScopes) - { - _tokenAcquisition = tokenAcquisition; - _initialScopes = initialScopes; - } - - ITokenAcquisition _tokenAcquisition; - IEnumerable _initialScopes; - - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - request.Headers.Add("Authorization", - $"Bearer {await _tokenAcquisition.GetAccessTokenForUserAsync(_initialScopes)}"); - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs index c181d5a49c..0114d62081 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs @@ -4,21 +4,11 @@ using System.Linq; using System.Threading.Tasks; #if (OrganizationalAuth || IndividualB2CAuth) using Microsoft.AspNetCore.Authentication; -#endif -#if (OrganizationalAuth) using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; -#if (MultiOrgAuth) using Microsoft.AspNetCore.Authentication.OpenIdConnect; -#endif using Microsoft.AspNetCore.Authorization; #endif -#if (IndividualB2CAuth) -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.UI; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; -#endif using Microsoft.AspNetCore.Builder; #if (IndividualLocalAuth) using Microsoft.AspNetCore.Identity; @@ -73,28 +63,36 @@ namespace Company.WebApplication1 .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd") - .AddMicrosoftWebAppCallsWebApi(Configuration, "AzureAd") - .AddInMemoryTokenCaches(); -#else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd"); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + #endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) #if (GenerateApi) - services.AddDownstreamWebApiService(Configuration); + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) #endif #if (GenerateGraph) - services.AddMicrosoftGraph(Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '), - Configuration.GetValue("CalledApi:CalledApiUrl")); + .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); #endif #elif (IndividualB2CAuth) #if (GenerateApi) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C") - .AddMicrosoftWebAppCallsWebApi(Configuration, "AzureAdB2C") - .AddInMemoryTokenCaches(); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - services.AddDownstreamWebApiService(Configuration); +#endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); #else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C"); + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); #endif #endif #if (OrganizationalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/appsettings.json index c0dd4d1ab9..634fb6db8a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/appsettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/appsettings.json @@ -17,10 +17,10 @@ // }, ////#elseif (OrganizationalAuth) // "AzureAd": { -//#if (MultiOrgAuth) -// "Instance": "https:////login.microsoftonline.com/common", -//#elseif (SingleOrgAuth) // "Instance": "https:////login.microsoftonline.com/", +//#if (MultiOrgAuth) +// "TenantId": "common", +//#elseif (SingleOrgAuth) // "Domain": "qualified.domain.name", // "TenantId": "22222222-2222-2222-2222-222222222222", //#endif @@ -34,16 +34,16 @@ // }, ////#endif ////#if (GenerateApiOrGraph) -// "CalledApi": { +// "DownstreamApi": { // /* -// 'CalledApiScopes' contains space separated scopes of the Web API you want to call. This can be: +// 'Scopes' contains space separated scopes of the Web API you want to call. This can be: // - a scope for a V2 application (for instance api://b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user) // - a scope corresponding to a V1 application (for instance /.default, where is the // App ID URI of a legacy v1 Web application // Applications are registered in the https://portal.azure.com portal. // */ -// "CalledApiScopes": "user.read", -// "CalledApiUrl": "[WebApiUrl]" +// "BaseUrl": "[WebApiUrl]", +// "Scopes": "user.read" // }, ////#endif ////#if (IndividualLocalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json index f0e86147b2..ac54ee3f91 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json @@ -90,19 +90,6 @@ "exclude": [ "Data/SqlServer/**" ] - }, - { - "condition": "(!GenerateApi)", - "exclude": [ - "Services/DownstreamWebApi.cs" - ] - }, - { - "condition": "(!GenerateGraph)", - "exclude": [ - "Services/MicrosoftGraphServiceExtensions.cs", - "Services/TokenAcquisitionCredentialProvider.cs" - ] } ] } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Controllers/HomeController.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Controllers/HomeController.cs index cd05892b06..4aea265a2e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Controllers/HomeController.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Controllers/HomeController.cs @@ -38,11 +38,20 @@ namespace Company.WebApplication1.Controllers _downstreamWebApi = downstreamWebApi; } - [AuthorizeForScopes(ScopeKeySection = "CalledApi:CalledApiScopes")] + [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")] public async Task Index() { - ViewData["ApiResult"] = await _downstreamWebApi.CallWebApiAsync(); - + using var response = await _downstreamWebApi.CallWebApiForUserAsync("DownstreamApi").ConfigureAwait(false); + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + var apiResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + ViewData["ApiResult"] = apiResult; + } + else + { + var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}: {error}"); + } return View(); } #elseif (GenerateGraph) @@ -55,7 +64,7 @@ namespace Company.WebApplication1.Controllers _graphServiceClient = graphServiceClient; } - [AuthorizeForScopes(ScopeKeySection = "CalledApi:CalledApiScopes")] + [AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")] public async Task Index() { var user = await _graphServiceClient.Me.Request().GetAsync(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/DownstreamWebApi.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/DownstreamWebApi.cs deleted file mode 100644 index 4806ca192d..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/DownstreamWebApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public interface IDownstreamWebApi - { - Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null); - } - - public static class DownstreamWebApiExtensions - { - public static void AddDownstreamWebApiService(this IServiceCollection services, IConfiguration configuration) - { - // https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests - services.AddHttpClient(); - } - } - - public class DownstreamWebApi : IDownstreamWebApi - { - private readonly ITokenAcquisition _tokenAcquisition; - - private readonly IConfiguration _configuration; - - private readonly HttpClient _httpClient; - - public DownstreamWebApi( - ITokenAcquisition tokenAcquisition, - IConfiguration configuration, - HttpClient httpClient) - { - _tokenAcquisition = tokenAcquisition; - _configuration = configuration; - _httpClient = httpClient; - } - - /// - /// Calls the Web API with the required scopes - /// - /// [Optional] Scopes required to call the Web API. If - /// not specified, uses scopes from the configuration - /// Endpoint relative to the CalledApiUrl configuration - /// A JSON string representing the result of calling the Web API - public async Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null) - { - string[] scopes = requiredScopes ?? _configuration["CalledApi:CalledApiScopes"]?.Split(' '); - string apiUrl = (_configuration["CalledApi:CalledApiUrl"] as string)?.TrimEnd('/') + $"/{relativeEndpoint}"; - - string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl); - httpRequestMessage.Headers.Add("Authorization", $"bearer {accessToken}"); - - string apiResult; - var response = await _httpClient.SendAsync(httpRequestMessage); - if (response.StatusCode == HttpStatusCode.OK) - { - apiResult = await response.Content.ReadAsStringAsync(); - } - else - { - apiResult = $"Error calling the API '{apiUrl}'"; - } - - return apiResult; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs deleted file mode 100644 index 2e805a9688..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/MicrosoftGraphServiceExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Graph; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public static class MicrosoftGraphServiceExtensions - { - /// - /// Adds the Microsoft Graph client as a singleton. - /// - /// Service collection. - /// Initial scopes. - /// Base URL for Microsoft graph. This can be - /// changed for instance for applications running in national clouds - public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, - IEnumerable initialScopes, - string graphBaseUrl = "https://graph.microsoft.com/v1.0") - { - services.AddTokenAcquisition(true); - services.AddSingleton(serviceProvider => - { - var tokenAquisitionService = serviceProvider.GetService(); - GraphServiceClient client = string.IsNullOrWhiteSpace(graphBaseUrl) ? - new GraphServiceClient(new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)) : - new GraphServiceClient(graphBaseUrl, new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)); - return client; - }); - - return services; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs deleted file mode 100644 index 8042149d82..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Services/TokenAcquisitionCredentialProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Graph; -using Microsoft.Identity.Web; -using System.Collections; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Company.WebApplication1 -{ - internal class TokenAcquisitionCredentialProvider : IAuthenticationProvider - { - public TokenAcquisitionCredentialProvider(ITokenAcquisition tokenAcquisition, IEnumerable initialScopes) - { - _tokenAcquisition = tokenAcquisition; - _initialScopes = initialScopes; - } - - ITokenAcquisition _tokenAcquisition; - IEnumerable _initialScopes; - - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - request.Headers.Add("Authorization", - $"Bearer {await _tokenAcquisition.GetAccessTokenForUserAsync(_initialScopes)}"); - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs index f0d19f0712..1308fe4cab 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs @@ -4,20 +4,10 @@ using System.Linq; using System.Threading.Tasks; #if (OrganizationalAuth || IndividualB2CAuth) using Microsoft.AspNetCore.Authentication; -#endif -#if (OrganizationalAuth) -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.UI; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; -#if (MultiOrgAuth) using Microsoft.AspNetCore.Authentication.OpenIdConnect; -#endif using Microsoft.AspNetCore.Authorization; -#endif -#if (IndividualB2CAuth) using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; #endif using Microsoft.AspNetCore.Builder; #if (IndividualLocalAuth) @@ -74,28 +64,36 @@ namespace Company.WebApplication1 .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd") - .AddMicrosoftWebAppCallsWebApi(Configuration, "AzureAd") - .AddInMemoryTokenCaches(); -#else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAd"); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + #endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) #if (GenerateApi) - services.AddDownstreamWebApiService(Configuration); + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) #endif #if (GenerateGraph) - services.AddMicrosoftGraph(Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '), - Configuration.GetValue("CalledApi:CalledApiUrl")); + .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); #endif #elif (IndividualB2CAuth) #if (GenerateApi) - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C") - .AddMicrosoftWebAppCallsWebApi(Configuration, "AzureAdB2C") - .AddInMemoryTokenCaches(); + var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - services.AddDownstreamWebApiService(Configuration); +#endif + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); #else - services.AddMicrosoftWebAppAuthentication(Configuration, "AzureAdB2C"); + .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); #endif #endif #if (OrganizationalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/appsettings.json index f72b1ef631..f6582afb07 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/appsettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/appsettings.json @@ -17,10 +17,10 @@ // }, ////#elseif (OrganizationalAuth) // "AzureAd": { -//#if (MultiOrgAuth) -// "Instance": "https:////login.microsoftonline.com/common", -//#elseif (SingleOrgAuth) // "Instance": "https:////login.microsoftonline.com/", +//#if (MultiOrgAuth) +// "TenantId": "common", +//#elseif (SingleOrgAuth) // "Domain": "qualified.domain.name", // "TenantId": "22222222-2222-2222-2222-222222222222", //#endif @@ -34,16 +34,16 @@ // }, ////#endif ////#if (GenerateApiOrGraph) -// "CalledApi": { +// "DownstreamApi": { // /* -// 'CalledApiScopes' contains space separated scopes of the Web API you want to call. This can be: +// 'Scopes' contains space separated scopes of the Web API you want to call. This can be: // - a scope for a V2 application (for instance api://b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user) // - a scope corresponding to a V1 application (for instance /.default, where is the // App ID URI of a legacy v1 Web application // Applications are registered in the https://portal.azure.com portal. // */ -// "CalledApiScopes": "user.read", -// "CalledApiUrl": "[WebApiUrl]" +// "BaseUrl": "[WebApiUrl]", +// "Scopes": "user.read" // }, ////#endif ////#if (IndividualLocalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json index af0458974c..b16a1f9a27 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/dotnetcli.host.json @@ -32,6 +32,10 @@ "longName": "tenant-id", "shortName": "" }, + "DefaultScope": { + "longName": "default-scope", + "shortName": "" + }, "Framework": { "longName": "framework" }, diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json index f11b772861..78260944d2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json @@ -36,19 +36,6 @@ "exclude": [ "Properties/launchSettings.json" ] - }, - { - "condition": "(!GenerateApi)", - "exclude": [ - "Services/DownstreamWebApi.cs" - ] - }, - { - "condition": "(!GenerateGraph)", - "exclude": [ - "Services/MicrosoftGraphServiceExtensions.cs", - "Services/TokenAcquisitionCredentialProvider.cs" - ] } ] } @@ -111,6 +98,13 @@ "replaces": "qualified.domain.name", "description": "The domain for the directory tenant (use with SingleOrg or IndividualB2C auth)." }, + "DefaultScope": { + "type": "parameter", + "datatype": "string", + "replaces": "api-scope", + "defaultValue": "access_as_user", + "description": "The API scope the client needs to request to provision an access token. (use with IndividualB2C, SingleOrg)." + }, "TenantId": { "type": "parameter", "datatype": "string", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Controllers/WeatherForecastController.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Controllers/WeatherForecastController.cs index 584c64869c..0cf62870ff 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Controllers/WeatherForecastController.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Controllers/WeatherForecastController.cs @@ -36,8 +36,8 @@ namespace Company.WebApplication1.Controllers private readonly ILogger _logger; - // The Web API will only accept tokens 1) for users, and 2) having the access_as_user scope for this API - static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" }; + // The Web API will only accept tokens 1) for users, and 2) having the "api-scope" scope for this API + static readonly string[] scopeRequiredByApi = new string[] { "api-scope" }; #if (GenerateApi) private readonly IDownstreamWebApi _downstreamWebApi; @@ -54,7 +54,17 @@ namespace Company.WebApplication1.Controllers { HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi); - string downstreamApiResult = await _downstreamWebApi.CallWebApiAsync(); + using var response = await _downstreamWebApi.CallWebApiForUserAsync("DownstreamApi").ConfigureAwait(false); + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + var apiResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + // Do something + } + else + { + var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}: {error}"); + } var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/DownstreamWebApi.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/DownstreamWebApi.cs deleted file mode 100644 index 4806ca192d..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/DownstreamWebApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public interface IDownstreamWebApi - { - Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null); - } - - public static class DownstreamWebApiExtensions - { - public static void AddDownstreamWebApiService(this IServiceCollection services, IConfiguration configuration) - { - // https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests - services.AddHttpClient(); - } - } - - public class DownstreamWebApi : IDownstreamWebApi - { - private readonly ITokenAcquisition _tokenAcquisition; - - private readonly IConfiguration _configuration; - - private readonly HttpClient _httpClient; - - public DownstreamWebApi( - ITokenAcquisition tokenAcquisition, - IConfiguration configuration, - HttpClient httpClient) - { - _tokenAcquisition = tokenAcquisition; - _configuration = configuration; - _httpClient = httpClient; - } - - /// - /// Calls the Web API with the required scopes - /// - /// [Optional] Scopes required to call the Web API. If - /// not specified, uses scopes from the configuration - /// Endpoint relative to the CalledApiUrl configuration - /// A JSON string representing the result of calling the Web API - public async Task CallWebApiAsync(string relativeEndpoint = "", string[] requiredScopes = null) - { - string[] scopes = requiredScopes ?? _configuration["CalledApi:CalledApiScopes"]?.Split(' '); - string apiUrl = (_configuration["CalledApi:CalledApiUrl"] as string)?.TrimEnd('/') + $"/{relativeEndpoint}"; - - string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl); - httpRequestMessage.Headers.Add("Authorization", $"bearer {accessToken}"); - - string apiResult; - var response = await _httpClient.SendAsync(httpRequestMessage); - if (response.StatusCode == HttpStatusCode.OK) - { - apiResult = await response.Content.ReadAsStringAsync(); - } - else - { - apiResult = $"Error calling the API '{apiUrl}'"; - } - - return apiResult; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/MicrosoftGraphServiceExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/MicrosoftGraphServiceExtensions.cs deleted file mode 100644 index 2e805a9688..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/MicrosoftGraphServiceExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Graph; -using Microsoft.Identity.Web; - -namespace Company.WebApplication1 -{ - public static class MicrosoftGraphServiceExtensions - { - /// - /// Adds the Microsoft Graph client as a singleton. - /// - /// Service collection. - /// Initial scopes. - /// Base URL for Microsoft graph. This can be - /// changed for instance for applications running in national clouds - public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, - IEnumerable initialScopes, - string graphBaseUrl = "https://graph.microsoft.com/v1.0") - { - services.AddTokenAcquisition(true); - services.AddSingleton(serviceProvider => - { - var tokenAquisitionService = serviceProvider.GetService(); - GraphServiceClient client = string.IsNullOrWhiteSpace(graphBaseUrl) ? - new GraphServiceClient(new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)) : - new GraphServiceClient(graphBaseUrl, new TokenAcquisitionCredentialProvider(tokenAquisitionService, initialScopes)); - return client; - }); - - return services; - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/TokenAcquisitionCredentialProvider.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/TokenAcquisitionCredentialProvider.cs deleted file mode 100644 index 8042149d82..0000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Services/TokenAcquisitionCredentialProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Graph; -using Microsoft.Identity.Web; -using System.Collections; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Company.WebApplication1 -{ - internal class TokenAcquisitionCredentialProvider : IAuthenticationProvider - { - public TokenAcquisitionCredentialProvider(ITokenAcquisition tokenAcquisition, IEnumerable initialScopes) - { - _tokenAcquisition = tokenAcquisition; - _initialScopes = initialScopes; - } - - ITokenAcquisition _tokenAcquisition; - IEnumerable _initialScopes; - - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - request.Headers.Add("Authorization", - $"Bearer {await _tokenAcquisition.GetAccessTokenForUserAsync(_initialScopes)}"); - } - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs index 0e935d107a..e1fedd249a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs @@ -10,14 +10,8 @@ using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; #if (OrganizationalAuth || IndividualB2CAuth) using Microsoft.AspNetCore.Authentication; -#endif -#if (OrganizationalAuth) +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Identity.Web; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; -#endif -#if (IndividualB2CAuth) -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.TokenCacheProviders.InMemory; #endif using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -45,32 +39,29 @@ namespace Company.WebApplication1 public void ConfigureServices(IServiceCollection services) { #if (OrganizationalAuth) + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) #if (GenerateApiOrGraph) - // Adds Microsoft Identity platform (AAD v2.0) support to protect this Api - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAd") - .AddMicrosoftWebApiCallsWebApi(Configuration, "AzureAd") - .AddInMemoryTokenCaches(); - -#else - // Adds Microsoft Identity platform (AAD v2.0) support to protect this Api - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAd"); -#endif + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi() #if (GenerateApi) - services.AddDownstreamWebApiService(Configuration); + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) #endif #if (GenerateGraph) - services.AddMicrosoftGraph(Configuration.GetValue("CalledApi:CalledApiScopes")?.Split(' '), - Configuration.GetValue("CalledApi:CalledApiUrl")); + .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); #endif #elif (IndividualB2CAuth) + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) #if (GenerateApi) - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAdB2C") - .AddMicrosoftWebApiCallsWebApi(Configuration, "AzureAdB2C") - .AddInMemoryTokenCaches(); - - services.AddDownstreamWebApiService(Configuration); + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi() + .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); #else - services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAdB2C"); + .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")); #endif #endif @@ -98,6 +89,7 @@ namespace Company.WebApplication1 app.UseHttpsRedirection(); #endif + app.UseRouting(); #if (OrganizationalAuth || IndividualAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/appsettings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/appsettings.json index cd6a5721b6..2b965fcc65 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/appsettings.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/appsettings.json @@ -13,10 +13,10 @@ // }, ////#elseif (OrganizationalAuth) // "AzureAd": { -//#if (!SingleOrgAuth) -// "Instance": "https:////login.microsoftonline.com/common", -//#else // "Instance": "https:////login.microsoftonline.com/", +//#if (!SingleOrgAuth) +// "TenantId": "common", +//#else // "Domain": "qualified.domain.name", // "TenantId": "22222222-2222-2222-2222-222222222222", //#endif @@ -31,16 +31,16 @@ // }, ////#endif ////#if (GenerateApiOrGraph) -// "CalledApi": { +// "DownstreamAPI": { // /* -// 'CalledApiScopes' contains space separated scopes of the Web API you want to call. This can be: +// 'Scopes' contains space separated scopes of the Web API you want to call. This can be: // - a scope for a V2 application (for instance api://b3682cc7-8b30-4bd2-aaba-080c6bf0fd31/access_as_user) // - a scope corresponding to a V1 application (for instance /.default, where is the // App ID URI of a legacy v1 Web application // Applications are registered in the https://portal.azure.com portal. // */ -// "CalledApiScopes": "user.read", -// "CalledApiUrl": "[WebApiUrl]" +// "BaseUrl": "[WebApiUrl]", +// "Scopes": "user.read" // }, ////#endif "Logging": { diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs index ba27271667..73e8a87af1 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs @@ -42,9 +42,9 @@ namespace Company.WebApplication1 #else options.UseSqlite( Configuration.GetConnectionString("DefaultConnection"))); +#endif services.AddDatabaseDeveloperPageExceptionFilter(); -#endif services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs index 1c58bdd186..378ce7bcee 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs @@ -42,9 +42,9 @@ namespace Company.WebApplication1 #else options.UseSqlite( Configuration.GetConnectionString("DefaultConnection"))); +#endif services.AddDatabaseDeveloperPageExceptionFilter(); -#endif services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj index 083ef01134..cccdb7fa3e 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - $(TargetFrameworks);net461 + $(TargetFrameworks);$(DefaultNetFxTargetFramework) true $(DefaultItemExcludes);TestFiles\** diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj index 2e2fc83450..da741703dc 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.Test.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - $(TargetFrameworks);net461 + $(TargetFrameworks);$(DefaultNetFxTargetFramework) true $(DefaultItemExcludes);TestFiles\** diff --git a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj index 4b460daa58..c72d1cef6a 100644 --- a/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - $(TargetFrameworks);net461 + $(TargetFrameworks);$(DefaultNetFxTargetFramework) true $(DefaultItemExcludes);TestFiles\** diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs index 93df99a41e..005941d915 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs @@ -852,11 +852,20 @@ namespace Microsoft.AspNetCore.Razor.Language.Components private void WriteAttribute(CodeRenderingContext context, string key, IList value) { BeginWriteAttribute(context, key); + if (value.Count > 0) { context.CodeWriter.WriteParameterSeparator(); WriteAttributeValue(context, value); } + else if (!context.Options.OmitMinimizedComponentAttributeValues) + { + // In version 5+, there's no need to supply a value for a minimized attribute. + // But for older language versions, minimized attributes were represented as "true". + context.CodeWriter.WriteParameterSeparator(); + context.CodeWriter.WriteBooleanLiteral(true); + } + context.CodeWriter.WriteEndMethodInvocation(); } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs index 5addb92cf2..0b1441b945 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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. namespace Microsoft.AspNetCore.Razor.Language @@ -13,7 +13,8 @@ namespace Microsoft.AspNetCore.Razor.Language bool suppressChecksum, bool suppressMetadataAttributes, bool suppressPrimaryMethodBody, - bool suppressNullabilityEnforcement) + bool suppressNullabilityEnforcement, + bool omitMinimizedComponentAttributeValues) { IndentWithTabs = indentWithTabs; IndentSize = indentSize; @@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language SuppressMetadataAttributes = suppressMetadataAttributes; SuppressPrimaryMethodBody = suppressPrimaryMethodBody; SuppressNullabilityEnforcement = suppressNullabilityEnforcement; + OmitMinimizedComponentAttributeValues = omitMinimizedComponentAttributeValues; } public override bool DesignTime { get; } @@ -36,5 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language public override bool SuppressChecksum { get; } public override bool SuppressNullabilityEnforcement { get; } + + public override bool OmitMinimizedComponentAttributeValues { get; } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs index 12f2f119c4..1422b410ff 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorCodeGenerationOptionsBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -39,6 +39,8 @@ namespace Microsoft.AspNetCore.Razor.Language public override bool SuppressNullabilityEnforcement { get; set; } + public override bool OmitMinimizedComponentAttributeValues { get; set; } + public override RazorCodeGenerationOptions Build() { return new DefaultRazorCodeGenerationOptions( @@ -49,7 +51,8 @@ namespace Microsoft.AspNetCore.Razor.Language SuppressChecksum, SuppressMetadataAttributes, SuppressPrimaryMethodBody, - SuppressNullabilityEnforcement); + SuppressNullabilityEnforcement, + OmitMinimizedComponentAttributeValues); } public override void SetDesignTime(bool designTime) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs index 36a8499ba9..b481dfeb07 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -17,7 +17,8 @@ namespace Microsoft.AspNetCore.Razor.Language rootNamespace: null, suppressMetadataAttributes: false, suppressPrimaryMethodBody: false, - suppressNullabilityEnforcement: false); + suppressNullabilityEnforcement: false, + omitMinimizedComponentAttributeValues: false); } public static RazorCodeGenerationOptions CreateDesignTimeDefault() @@ -30,7 +31,8 @@ namespace Microsoft.AspNetCore.Razor.Language suppressChecksum: false, suppressMetadataAttributes: true, suppressPrimaryMethodBody: false, - suppressNullabilityEnforcement: false); + suppressNullabilityEnforcement: false, + omitMinimizedComponentAttributeValues: false); } public static RazorCodeGenerationOptions Create(Action configure) @@ -114,5 +116,10 @@ namespace Microsoft.AspNetCore.Razor.Language /// Gets a value that determines if nullability type enforcement should be suppressed for user code. /// public virtual bool SuppressNullabilityEnforcement { get; } + + /// + /// Gets a value that determines if the components code writer may omit values for minimized attributes. + /// + public virtual bool OmitMinimizedComponentAttributeValues { get; } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs index ed6914aebe..48d725b614 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeGenerationOptionsBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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. namespace Microsoft.AspNetCore.Razor.Language @@ -59,6 +59,11 @@ namespace Microsoft.AspNetCore.Razor.Language /// public virtual bool SuppressNullabilityEnforcement { get; set; } + /// + /// Gets or sets a value that determines if the components code writer may omit values for minimized attributes. + /// + public virtual bool OmitMinimizedComponentAttributeValues { get; set; } + public abstract RazorCodeGenerationOptions Build(); public virtual void SetDesignTime(bool designTime) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs index 0308fe46c4..c0b3fd708e 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs @@ -9,10 +9,14 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests { public abstract class ComponentCodeGenerationTestBase : RazorBaselineIntegrationTestBase { + private RazorConfiguration _configuration; + internal override string FileKind => FileKinds.Component; internal override bool UseTwoPhaseCompilation => true; + internal override RazorConfiguration Configuration => _configuration ?? base.Configuration; + protected ComponentCodeGenerationTestBase() : base(generateBaselines: null) { @@ -364,6 +368,38 @@ namespace Test CompileToAssembly(generated); } + [Fact] + public void OmitsMinimizedAttributeValueParameter() + { + // Act + var generated = CompileToCSharp(@" +"); + + // Assert + AssertDocumentNodeMatchesBaseline(generated.CodeDocument); + AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); + CompileToAssembly(generated); + } + + [Fact] + public void IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5() + { + // Arrange + _configuration = RazorConfiguration.Create( + RazorLanguageVersion.Version_3_0, + base.Configuration.ConfigurationName, + base.Configuration.Extensions); + + // Act + var generated = CompileToCSharp(@" +"); + + // Assert + AssertDocumentNodeMatchesBaseline(generated.CodeDocument); + AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); + CompileToAssembly(generated); + } + [Fact] public void Component_WithFullyQualifiedTagNames() { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/Microsoft.AspNetCore.Razor.Language.Test.csproj b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/Microsoft.AspNetCore.Razor.Language.Test.csproj index d90b125693..368ca11ab8 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/Microsoft.AspNetCore.Razor.Language.Test.csproj +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/Microsoft.AspNetCore.Razor.Language.Test.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - $(TargetFrameworks);net461 + $(TargetFrameworks);$(DefaultNetFxTargetFramework) $(DefaultItemExcludes);TestFiles\**\* $(DefineConstants);GENERATE_BASELINES diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs new file mode 100644 index 0000000000..1024b82fc9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs @@ -0,0 +1,36 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Components; + public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __o = +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + "val" + +#line default +#line hidden +#nullable disable + ; + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt new file mode 100644 index 0000000000..ef767a96b4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt @@ -0,0 +1,22 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [12] ) - System + UsingDirective - (18:2,1 [32] ) - System.Collections.Generic + UsingDirective - (53:3,1 [17] ) - System.Linq + UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks + UsingDirective - (104:5,1 [37] ) - Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - + DesignTimeDirective - + CSharpCode - + IntermediateToken - - CSharp - #pragma warning disable 0414 + CSharpCode - + IntermediateToken - - CSharp - private static System.Object __o = null; + CSharpCode - + IntermediateToken - - CSharp - #pragma warning restore 0414 + MethodDeclaration - - protected override - void - BuildRenderTree + MarkupElement - (0:0,0 [73] x:\dir\subdir\Test\TestComponent.cshtml) - elem + HtmlAttribute - (5:0,5 [23] x:\dir\subdir\Test\TestComponent.cshtml) - normal-attr=" - " + CSharpExpressionAttributeValue - (19:0,19 [8] x:\dir\subdir\Test\TestComponent.cshtml) - + LazyIntermediateToken - (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - "val" + HtmlAttribute - (28:0,28 [15] x:\dir\subdir\Test\TestComponent.cshtml) - minimized-attr - + HtmlAttribute - (43:0,43 [22] x:\dir\subdir\Test\TestComponent.cshtml) - empty-string-atttr=" - " diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.mappings.txt new file mode 100644 index 0000000000..35f1e0834b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) +|"val"| +Generated Location: (893:25,21 [5] ) +|"val"| + diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs new file mode 100644 index 0000000000..1024b82fc9 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs @@ -0,0 +1,36 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Components; + public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static System.Object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __o = +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + "val" + +#line default +#line hidden +#nullable disable + ; + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt new file mode 100644 index 0000000000..ef767a96b4 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt @@ -0,0 +1,22 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [12] ) - System + UsingDirective - (18:2,1 [32] ) - System.Collections.Generic + UsingDirective - (53:3,1 [17] ) - System.Linq + UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks + UsingDirective - (104:5,1 [37] ) - Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - + DesignTimeDirective - + CSharpCode - + IntermediateToken - - CSharp - #pragma warning disable 0414 + CSharpCode - + IntermediateToken - - CSharp - private static System.Object __o = null; + CSharpCode - + IntermediateToken - - CSharp - #pragma warning restore 0414 + MethodDeclaration - - protected override - void - BuildRenderTree + MarkupElement - (0:0,0 [73] x:\dir\subdir\Test\TestComponent.cshtml) - elem + HtmlAttribute - (5:0,5 [23] x:\dir\subdir\Test\TestComponent.cshtml) - normal-attr=" - " + CSharpExpressionAttributeValue - (19:0,19 [8] x:\dir\subdir\Test\TestComponent.cshtml) - + LazyIntermediateToken - (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - "val" + HtmlAttribute - (28:0,28 [15] x:\dir\subdir\Test\TestComponent.cshtml) - minimized-attr - + HtmlAttribute - (43:0,43 [22] x:\dir\subdir\Test\TestComponent.cshtml) - empty-string-atttr=" - " diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.mappings.txt new file mode 100644 index 0000000000..35f1e0834b --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.mappings.txt @@ -0,0 +1,5 @@ +Source Location: (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) +|"val"| +Generated Location: (893:25,21 [5] ) +|"val"| + diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs new file mode 100644 index 0000000000..c99a988b76 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.codegen.cs @@ -0,0 +1,33 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Components; + public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 1998 + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __builder.OpenElement(0, "elem"); + __builder.AddAttribute(1, "normal-attr", +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + "val" + +#line default +#line hidden +#nullable disable + ); + __builder.AddAttribute(2, "minimized-attr", true); + __builder.AddAttribute(3, "empty-string-atttr", true); + __builder.CloseElement(); + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt new file mode 100644 index 0000000000..77da360ab0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/IncludesMinimizedAttributeValueParameterBeforeLanguageVersion5/TestComponent.ir.txt @@ -0,0 +1,15 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [14] ) - System + UsingDirective - (18:2,1 [34] ) - System.Collections.Generic + UsingDirective - (53:3,1 [19] ) - System.Linq + UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks + UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - + MethodDeclaration - - protected override - void - BuildRenderTree + MarkupElement - (0:0,0 [73] x:\dir\subdir\Test\TestComponent.cshtml) - elem + HtmlAttribute - (5:0,5 [23] x:\dir\subdir\Test\TestComponent.cshtml) - normal-attr=" - " + CSharpExpressionAttributeValue - (19:0,19 [8] x:\dir\subdir\Test\TestComponent.cshtml) - + LazyIntermediateToken - (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - "val" + HtmlAttribute - (28:0,28 [15] x:\dir\subdir\Test\TestComponent.cshtml) - minimized-attr - + HtmlAttribute - (43:0,43 [22] x:\dir\subdir\Test\TestComponent.cshtml) - empty-string-atttr=" - " diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs new file mode 100644 index 0000000000..81d863fb92 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.codegen.cs @@ -0,0 +1,33 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Components; + public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 1998 + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __builder.OpenElement(0, "elem"); + __builder.AddAttribute(1, "normal-attr", +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + "val" + +#line default +#line hidden +#nullable disable + ); + __builder.AddAttribute(2, "minimized-attr"); + __builder.AddAttribute(3, "empty-string-atttr"); + __builder.CloseElement(); + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt new file mode 100644 index 0000000000..77da360ab0 --- /dev/null +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/OmitsMinimizedAttributeValueParameter/TestComponent.ir.txt @@ -0,0 +1,15 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [14] ) - System + UsingDirective - (18:2,1 [34] ) - System.Collections.Generic + UsingDirective - (53:3,1 [19] ) - System.Linq + UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks + UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - + MethodDeclaration - - protected override - void - BuildRenderTree + MarkupElement - (0:0,0 [73] x:\dir\subdir\Test\TestComponent.cshtml) - elem + HtmlAttribute - (5:0,5 [23] x:\dir\subdir\Test\TestComponent.cshtml) - normal-attr=" - " + CSharpExpressionAttributeValue - (19:0,19 [8] x:\dir\subdir\Test\TestComponent.cshtml) - + LazyIntermediateToken - (21:0,21 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - "val" + HtmlAttribute - (28:0,28 [15] x:\dir\subdir\Test\TestComponent.cshtml) - minimized-attr - + HtmlAttribute - (43:0,43 [22] x:\dir\subdir\Test\TestComponent.cshtml) - empty-string-atttr=" - " diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/RewriteCssCommand.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/RewriteCssCommand.cs index 3babba81e0..745bfb0384 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/RewriteCssCommand.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/RewriteCssCommand.cs @@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.Razor.Tools var lastSimpleSelector = allSimpleSelectors.TakeWhile(s => s != firstDeepCombinator).LastOrDefault(); if (lastSimpleSelector != null) { - Edits.Add(new InsertSelectorScopeEdit { Position = FindPositionBeforeTrailingCombinator(lastSimpleSelector) }); + Edits.Add(new InsertSelectorScopeEdit { Position = FindPositionToInsertInSelector(lastSimpleSelector) }); } else if (firstDeepCombinator != null) { @@ -203,30 +203,62 @@ namespace Microsoft.AspNetCore.Razor.Tools } } - private int FindPositionBeforeTrailingCombinator(SimpleSelector lastSimpleSelector) + private int FindPositionToInsertInSelector(SimpleSelector lastSimpleSelector) { - // For a selector like "a > ::deep b", the parser splits it as "a >", "::deep", "b". - // The place we want to insert the scope is right after "a", hence we need to detect - // if the simple selector ends with " >" or similar, and if so, insert before that. - var text = lastSimpleSelector.Text; - var lastChar = text.Length > 0 ? text[^1] : default; - switch (lastChar) + var children = lastSimpleSelector.Children; + for (var i = 0; i < children.Count; i++) { - case '>': - case '+': - case '~': - var trailingCombinatorMatch = _trailingCombinatorRegex.Match(text); - if (trailingCombinatorMatch.Success) - { - var trailingCombinatorLength = trailingCombinatorMatch.Length; - return lastSimpleSelector.AfterEnd - trailingCombinatorLength; - } - break; + switch (children[i]) + { + // Selectors like "a > ::deep b" get parsed as [[a][>]][::deep][b], and we want to + // insert right after the "a". So if we're processing a SimpleSelector like [[a][>]], + // consider the ">" to signal the "insert before" position. + case TokenItem t when IsTrailingCombinator(t.TokenType): + + // Similarly selectors like "a::before" get parsed as [[a][::before]], and we want to + // insert right after the "a". So if we're processing a SimpleSelector like [[a][::before]], + // consider the pseudoelement to signal the "insert before" position. + case PseudoElementSelector: + case PseudoElementFunctionSelector: + case PseudoClassSelector s when IsSingleColonPseudoElement(s): + // Insert after the previous token if there is one, otherwise before the whole thing + return i > 0 ? children[i - 1].AfterEnd : lastSimpleSelector.Start; + } } + // Since we didn't find any children that signal the insert-before position, + // insert after the whole thing return lastSimpleSelector.AfterEnd; } + private static bool IsSingleColonPseudoElement(PseudoClassSelector selector) + { + // See https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements + // Normally, pseudoelements require a double-colon prefix. However the following "original set" + // of pseudoelements also support single-colon prefixes for back-compatibility with older versions + // of the W3C spec. Our CSS parser sees them as pseudoselectors rather than pseudoelements, so + // we have to special-case them. The single-colon option doesn't exist for other more modern + // pseudoelements. + var selectorText = selector.Text; + return string.Equals(selectorText, ":after", StringComparison.OrdinalIgnoreCase) + || string.Equals(selectorText, ":before", StringComparison.OrdinalIgnoreCase) + || string.Equals(selectorText, ":first-letter", StringComparison.OrdinalIgnoreCase) + || string.Equals(selectorText, ":first-line", StringComparison.OrdinalIgnoreCase); + } + + private static bool IsTrailingCombinator(CssTokenType tokenType) + { + switch (tokenType) + { + case CssTokenType.Plus: + case CssTokenType.Tilde: + case CssTokenType.Greater: + return true; + default: + return false; + } + } + protected override void VisitAtDirective(AtDirective item) { // Whenever we see "@keyframes something { ... }", we want to insert right after "something" diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/RewriteCssCommandTest.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/RewriteCssCommandTest.cs index 37b1c37a30..76ab33e6ca 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/RewriteCssCommandTest.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/test/RewriteCssCommandTest.cs @@ -41,6 +41,9 @@ namespace Microsoft.AspNetCore.Razor.Tools var result = RewriteCssCommand.AddScopeToSelectors("file.css", @" .first, .second { color: red; } .third { color: blue; } + :root { color: green; } + * { color: white; } + #some-id { color: yellow; } ", "TestScope", out var diagnostics); // Assert @@ -48,6 +51,9 @@ namespace Microsoft.AspNetCore.Razor.Tools Assert.Equal(@" .first[TestScope], .second[TestScope] { color: red; } .third[TestScope] { color: blue; } + :root[TestScope] { color: green; } + *[TestScope] { color: white; } + #some-id[TestScope] { color: yellow; } ", result); } @@ -81,6 +87,83 @@ namespace Microsoft.AspNetCore.Razor.Tools ", result); } + [Fact] + public void HandlesPseudoClasses() + { + // Arrange/act + var result = RewriteCssCommand.AddScopeToSelectors("file.css", @" + a:fake-pseudo-class { color: red; } + a:focus b:hover { color: green; } + tr:nth-child(4n + 1) { color: blue; } + a:has(b > c) { color: yellow; } + a:last-child > ::deep b { color: pink; } + a:not(#something) { color: purple; } +", "TestScope", out var diagnostics); + + // Assert + Assert.Empty(diagnostics); + Assert.Equal(@" + a:fake-pseudo-class[TestScope] { color: red; } + a:focus b:hover[TestScope] { color: green; } + tr:nth-child(4n + 1)[TestScope] { color: blue; } + a:has(b > c)[TestScope] { color: yellow; } + a:last-child[TestScope] > b { color: pink; } + a:not(#something)[TestScope] { color: purple; } +", result); + } + + [Fact] + public void HandlesPseudoElements() + { + // Arrange/act + var result = RewriteCssCommand.AddScopeToSelectors("file.css", @" + a::before { content: ""✋""; } + a::after::placeholder { content: ""🐯""; } + custom-element::part(foo) { content: ""🤷‍""; } + a::before > ::deep another { content: ""👞""; } + a::fake-PsEuDo-element { content: ""🐔""; } + ::selection { content: ""😾""; } + other, ::selection { content: ""👂""; } +", "TestScope", out var diagnostics); + + // Assert + Assert.Empty(diagnostics); + Assert.Equal(@" + a[TestScope]::before { content: ""✋""; } + a[TestScope]::after::placeholder { content: ""🐯""; } + custom-element[TestScope]::part(foo) { content: ""🤷‍""; } + a[TestScope]::before > another { content: ""👞""; } + a[TestScope]::fake-PsEuDo-element { content: ""🐔""; } + [TestScope]::selection { content: ""😾""; } + other[TestScope], [TestScope]::selection { content: ""👂""; } +", result); + } + + [Fact] + public void HandlesSingleColonPseudoElements() + { + // Arrange/act + var result = RewriteCssCommand.AddScopeToSelectors("file.css", @" + a:after { content: ""x""; } + a:before { content: ""x""; } + a:first-letter { content: ""x""; } + a:first-line { content: ""x""; } + a:AFTER { content: ""x""; } + a:not(something):before { content: ""x""; } +", "TestScope", out var diagnostics); + + // Assert + Assert.Empty(diagnostics); + Assert.Equal(@" + a[TestScope]:after { content: ""x""; } + a[TestScope]:before { content: ""x""; } + a[TestScope]:first-letter { content: ""x""; } + a[TestScope]:first-line { content: ""x""; } + a[TestScope]:AFTER { content: ""x""; } + a:not(something)[TestScope]:before { content: ""x""; } +", result); + } + [Fact] public void RespectsDeepCombinator() { diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorProjectEngineBuilderExtensions.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorProjectEngineBuilderExtensions.cs index e492643723..aa07cd9cf6 100644 --- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorProjectEngineBuilderExtensions.cs +++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/RazorProjectEngineBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -64,10 +64,8 @@ namespace Microsoft.CodeAnalysis.Razor { // Prior to 3.0 there were no C# version specific controlled features. Suppress nullability enforcement. options.SuppressNullabilityEnforcement = true; - return; } - - if (CSharpLanguageVersion < LanguageVersion.CSharp8) + else if (CSharpLanguageVersion < LanguageVersion.CSharp8) { // Having nullable flags < C# 8.0 would cause compile errors. options.SuppressNullabilityEnforcement = true; @@ -85,6 +83,12 @@ namespace Microsoft.CodeAnalysis.Razor // Roslyn project and acquires the effective C# version at that point. options.SuppressNullabilityEnforcement = false; } + + if (options.Configuration?.LanguageVersion.Major >= 5) + { + // This is a useful optimization but isn't supported by older framework versions + options.OmitMinimizedComponentAttributeValues = true; + } } } } diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj b/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj index b4fd5a0f6f..4b81fe11f8 100644 --- a/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj +++ b/src/Razor/Microsoft.CodeAnalysis.Razor/test/Microsoft.CodeAnalysis.Razor.Test.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - $(TargetFrameworks);net461 + $(TargetFrameworks);$(DefaultNetFxTargetFramework) $(DefaultItemExcludes);TestFiles\**\* true diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj index f307c2634a..8225d2b220 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/Microsoft.NET.Sdk.Razor.csproj @@ -15,6 +15,8 @@ $(NoWarn);NU5129 false + + false diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets index 922d3fb34e..8f1ceefb01 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Microsoft.NET.Sdk.Razor.Component.targets @@ -187,6 +187,7 @@ Copyright (c) .NET Foundation. All rights reserved. AddModules="@(AddModules)" AdditionalFiles="@(AdditionalFiles)" AllowUnsafeBlocks="$(AllowUnsafeBlocks)" + Analyzers="@(Analyzer)" ApplicationConfiguration="$(AppConfigForCompiler)" BaseAddress="$(BaseAddress)" CheckForOverflowUnderflow="$(CheckForOverflowUnderflow)" @@ -242,7 +243,7 @@ Copyright (c) .NET Foundation. All rights reserved. UseSharedCompilation="$(UseSharedCompilation)" Utf8Output="$(Utf8Output)" VsSessionGuid="$(VsSessionGuid)" - WarningLevel="$(WarningLevel)" + WarningLevel="0" WarningsAsErrors="$(WarningsAsErrors)" WarningsNotAsErrors="$(WarningsNotAsErrors)" PathMap="$(PathMap)" diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props index 3bc7a24d9e..795c769a06 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.props @@ -78,6 +78,11 @@ Copyright (c) .NET Foundation. All rights reserved. This property affects C# projects targeting 3.0 or later. --> .cs;.razor;.resx;.cshtml + + + $(CustomCollectWatchItems);_RazorSdkCustomCollectWatchItems diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets index 7930682638..b5b91fb8f2 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/build/netstandard2.0/Sdk.Razor.CurrentVersion.targets @@ -38,9 +38,10 @@ Copyright (c) .NET Foundation. All rights reserved. - <_TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV')) - <_TargetingNETCoreApp30OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' >= '3.0'">true - <_TargetingNET50OrLater Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' >= '5.0'">true + <_TargetingNETCoreApp30OrLater Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND + $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '3.0')) ">true + <_TargetingNET50OrLater Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND + $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '5.0')) ">true - true + true - - - - - + false + + diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs index ddd1b5dbd1..07f4572c5b 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs @@ -189,7 +189,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests { // The first phase won't include any metadata references for component discovery. This mirrors // what the build does. - var projectEngine = CreateProjectEngine(RazorConfiguration.Default, Array.Empty()); + var projectEngine = CreateProjectEngine(Configuration, Array.Empty()); RazorCodeDocument codeDocument; foreach (var item in AdditionalRazorItems) @@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests // Add the 'temp' compilation as a metadata reference var references = BaseCompilation.References.Concat(new[] { tempAssembly.Compilation.ToMetadataReference() }).ToArray(); - projectEngine = CreateProjectEngine(RazorConfiguration.Default, references); + projectEngine = CreateProjectEngine(Configuration, references); // Now update the any additional files foreach (var item in AdditionalRazorItems) diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj index 73f5cd3f3a..6b94a9dd92 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Microsoft.AspNetCore.Razor.Test.Common.csproj @@ -4,7 +4,7 @@ $(DefineConstants);GENERATE_BASELINES $(DefineConstants);__RemoveThisBitTo__GENERATE_BASELINES - netstandard2.0;net461 + $(DefaultNetFxTargetFramework);netstandard2.0 diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Razor.Test.ComponentShim.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Razor.Test.ComponentShim.csproj index 756371e76d..6c1b0a1a9a 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Razor.Test.ComponentShim.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Razor.Test.ComponentShim.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net461 + $(DefaultNetFxTargetFramework);netstandard2.0 diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj index 583b94d948..2bc4c2d591 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework);net461 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) true diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj index 583b94d948..2bc4c2d591 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X/Microsoft.AspNetCore.Razor.Test.MvcShim.Version2_X.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework);net461 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) true diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.Test.MvcShim.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.Test.MvcShim.csproj index 0d860cdd09..a113e28e88 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.Test.MvcShim.csproj +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.Test.MvcShim.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net461 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) true diff --git a/src/Razor/tools/RazorSyntaxGenerator/RazorSyntaxGenerator.csproj b/src/Razor/tools/RazorSyntaxGenerator/RazorSyntaxGenerator.csproj index 93665f7d14..fa22992ba9 100644 --- a/src/Razor/tools/RazorSyntaxGenerator/RazorSyntaxGenerator.csproj +++ b/src/Razor/tools/RazorSyntaxGenerator/RazorSyntaxGenerator.csproj @@ -7,6 +7,7 @@ RazorSyntaxGenerator Exe false + false diff --git a/src/Security/Authentication/Cookies/src/CookieExtensions.cs b/src/Security/Authentication/Cookies/src/CookieExtensions.cs index 7787ad8094..252bfe988c 100644 --- a/src/Security/Authentication/Cookies/src/CookieExtensions.cs +++ b/src/Security/Authentication/Cookies/src/CookieExtensions.cs @@ -15,15 +15,15 @@ namespace Microsoft.Extensions.DependencyInjection => builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme); public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme) - => builder.AddCookie(authenticationScheme, configureOptions: null); + => builder.AddCookie(authenticationScheme, configureOptions: null!); - public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, Action? configureOptions) + public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, Action configureOptions) => builder.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, configureOptions); - public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, Action? configureOptions) + public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, Action configureOptions) => builder.AddCookie(authenticationScheme, displayName: null, configureOptions: configureOptions); - public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action? configureOptions) + public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action configureOptions) { builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, PostConfigureCookieAuthenticationOptions>()); builder.Services.AddOptions(authenticationScheme).Validate(o => o.Cookie.Expiration == null, "Cookie.Expiration is ignored, use ExpireTimeSpan instead."); diff --git a/src/Security/Authentication/Cookies/src/PostConfigureCookieAuthenticationOptions.cs b/src/Security/Authentication/Cookies/src/PostConfigureCookieAuthenticationOptions.cs index 5881098800..4892287fb7 100644 --- a/src/Security/Authentication/Cookies/src/PostConfigureCookieAuthenticationOptions.cs +++ b/src/Security/Authentication/Cookies/src/PostConfigureCookieAuthenticationOptions.cs @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies if (string.IsNullOrEmpty(options.Cookie.Name)) { - options.Cookie.Name = CookieAuthenticationDefaults.CookiePrefix + name; + options.Cookie.Name = CookieAuthenticationDefaults.CookiePrefix + Uri.EscapeDataString(name); } if (options.TicketDataFormat == null) { diff --git a/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs b/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs index ed5e379d66..7d56d3d580 100644 --- a/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs +++ b/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs @@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.Authentication properties.Items[CorrelationProperty] = correlationId; - var cookieName = Options.CorrelationCookie.Name + Scheme.Name + "." + correlationId; + var cookieName = Options.CorrelationCookie.Name + correlationId; Response.Cookies.Append(cookieName, CorrelationMarker, cookieOptions); } @@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.Authentication properties.Items.Remove(CorrelationProperty); - var cookieName = Options.CorrelationCookie.Name + Scheme.Name + "." + correlationId; + var cookieName = Options.CorrelationCookie.Name + correlationId; var correlationCookie = Request.Cookies[cookieName]; if (string.IsNullOrEmpty(correlationCookie)) diff --git a/src/Security/Authentication/test/CookieTests.cs b/src/Security/Authentication/test/CookieTests.cs index 56bea6c65a..41d70c1be6 100644 --- a/src/Security/Authentication/test/CookieTests.cs +++ b/src/Security/Authentication/test/CookieTests.cs @@ -151,6 +151,38 @@ namespace Microsoft.AspNetCore.Authentication.Cookies Assert.Equal("no-cache", transaction.Response.Headers.Pragma.ToString()); } + [Fact] + public async Task CustomAuthSchemeEncodesCookieName() + { + var schemeName = "With spaces and 界"; + using var host = await CreateHostWithServices(s => s.AddAuthentication(schemeName).AddCookie(schemeName, o => + { + o.LoginPath = new PathString("/login"); + }), context => + { + var user = new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")); + user.AddClaim(new Claim("marker", "true")); + return context.SignInAsync(schemeName, + new ClaimsPrincipal(user), + new AuthenticationProperties()); + }); + + using var server = host.GetTestServer(); + var transaction = await SendAsync(server, "http://example.com/testpath"); + + var setCookie = transaction.SetCookie; + Assert.StartsWith(".AspNetCore.With%20spaces%20and%20%E7%95%8C=", setCookie); + Assert.Contains("; path=/", setCookie); + Assert.Contains("; httponly", setCookie); + Assert.Contains("; samesite=", setCookie); + Assert.DoesNotContain("; expires=", setCookie); + Assert.DoesNotContain("; domain=", setCookie); + Assert.DoesNotContain("; secure", setCookie); + Assert.True(transaction.Response.Headers.CacheControl.NoCache); + Assert.True(transaction.Response.Headers.CacheControl.NoStore); + Assert.Equal("no-cache", transaction.Response.Headers.Pragma.ToString()); + } + [Fact] public void SettingCookieExpirationOptionThrows() { diff --git a/src/Security/Authentication/test/FacebookTests.cs b/src/Security/Authentication/test/FacebookTests.cs index 2d1a849aa3..6ca835dff1 100644 --- a/src/Security/Authentication/test/FacebookTests.cs +++ b/src/Security/Authentication/test/FacebookTests.cs @@ -363,7 +363,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Facebook.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?')); diff --git a/src/Security/Authentication/test/GoogleTests.cs b/src/Security/Authentication/test/GoogleTests.cs index c53181047b..c10a3c1583 100644 --- a/src/Security/Authentication/test/GoogleTests.cs +++ b/src/Security/Authentication/test/GoogleTests.cs @@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Authentication.Google }); using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://example.com/challenge"); - Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.Google.")); + Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.")); } [Fact] @@ -392,7 +392,7 @@ namespace Microsoft.AspNetCore.Authentication.Google }); using var server = host.GetTestServer(); var sendTask = server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state", - ".AspNetCore.Correlation.Google.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); if (redirect) { var transaction = await sendTask; @@ -431,7 +431,7 @@ namespace Microsoft.AspNetCore.Authentication.Google }); using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state", - ".AspNetCore.Correlation.Google.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("https://example.com/custom-denied-page?rurl=http%3A%2F%2Fwww.google.com%2F", transaction.Response.Headers.GetValues("Location").First()); } @@ -474,7 +474,7 @@ namespace Microsoft.AspNetCore.Authentication.Google }); using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state", - ".AspNetCore.Correlation.Google.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.StartsWith("/error?FailureMessage=", transaction.Response.Headers.GetValues("Location").First()); Assert.True(accessDeniedCalled); @@ -510,7 +510,7 @@ namespace Microsoft.AspNetCore.Authentication.Google }); using var server = host.GetTestServer(); var sendTask = server.SendAsync("https://example.com/signin-google?error=itfailed&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state", - ".AspNetCore.Correlation.Google.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); if (redirect) { var transaction = await sendTask; @@ -552,11 +552,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -619,7 +619,7 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var sendTask = server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); if (redirect) { var transaction = await sendTask; @@ -671,7 +671,7 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var sendTask = server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); if (redirect) { var transaction = await sendTask; @@ -715,11 +715,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -755,11 +755,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); } @@ -802,7 +802,7 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/foo", transaction.Response.Headers.GetValues("Location").First()); @@ -876,11 +876,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); // Delete + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); // Delete Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -920,11 +920,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); // Delete + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); // Delete Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -964,11 +964,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); // Delete + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); // Delete Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -1001,11 +1001,11 @@ namespace Microsoft.AspNetCore.Authentication.Google using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Google.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]); // Delete + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); // Delete Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; diff --git a/src/Security/Authentication/test/MicrosoftAccountTests.cs b/src/Security/Authentication/test/MicrosoftAccountTests.cs index 8797357b46..3cafef86de 100644 --- a/src/Security/Authentication/test/MicrosoftAccountTests.cs +++ b/src/Security/Authentication/test/MicrosoftAccountTests.cs @@ -242,11 +242,11 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount using var server = host.GetTestServer(); var transaction = await server.SendAsync( "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state), - $".AspNetCore.Correlation.Microsoft.{correlationValue}=N"); + $".AspNetCore.Correlation.{correlationValue}=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.Contains($".AspNetCore.Correlation.Microsoft.{correlationValue}", transaction.SetCookie[0]); + Assert.Contains($".AspNetCore.Correlation.{correlationValue}", transaction.SetCookie[0]); Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); var authCookie = transaction.AuthenticationCookieValue; @@ -351,7 +351,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First()); Assert.Equal(2, transaction.SetCookie.Count); - Assert.StartsWith(".AspNetCore.Correlation.Microsoft.", transaction.SetCookie[0]); + Assert.StartsWith(".AspNetCore.Correlation.", transaction.SetCookie[0]); Assert.StartsWith(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); } diff --git a/src/Security/Authentication/test/OAuthTests.cs b/src/Security/Authentication/test/OAuthTests.cs index 5b3ab2eef9..c52fd671f2 100644 --- a/src/Security/Authentication/test/OAuthTests.cs +++ b/src/Security/Authentication/test/OAuthTests.cs @@ -283,7 +283,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", - ".AspNetCore.Correlation.Weblie.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal("https://www.example.com/access-denied?ReturnUrl=http%3A%2F%2Ftesthost%2Fredirect", transaction.Response.Headers.Location.ToString()); @@ -318,7 +318,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", - ".AspNetCore.Correlation.Weblie.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.NotAcceptable, transaction.Response.StatusCode); Assert.Null(transaction.Response.Headers.Location); @@ -354,7 +354,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", - ".AspNetCore.Correlation.Weblie.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.NotAcceptable, transaction.Response.StatusCode); Assert.Null(transaction.Response.Headers.Location); @@ -390,7 +390,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth using var server = host.GetTestServer(); var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=custom_error&state=protected_state", - ".AspNetCore.Correlation.Weblie.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.NotAcceptable, transaction.Response.StatusCode); Assert.Null(transaction.Response.Headers.Location); diff --git a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectAuthenticateTests.cs b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectAuthenticateTests.cs index 8502b0670a..29003637c4 100644 --- a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectAuthenticateTests.cs +++ b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectAuthenticateTests.cs @@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect var transaction = await server.SendAsync( "https://example.com/signin-oidc?error=itfailed&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state", - ".AspNetCore.Correlation.OpenIdConnect.correlationId=N"); + ".AspNetCore.Correlation.correlationId=N"); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.StartsWith("/error?FailureMessage=", transaction.Response.Headers.GetValues("Location").First()); } diff --git a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectEventTests.cs b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectEventTests.cs index 691bd9f730..97b25e1d96 100644 --- a/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectEventTests.cs +++ b/src/Security/Authentication/test/OpenIdConnect/OpenIdConnectEventTests.cs @@ -1309,7 +1309,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect private Task PostAsync(TestServer server, string path, string form) { var client = server.CreateClient(); - var cookie = ".AspNetCore.Correlation." + OpenIdConnectDefaults.AuthenticationScheme + ".correlationId=N"; + var cookie = ".AspNetCore.Correlation.correlationId=N"; client.DefaultRequestHeaders.Add("Cookie", cookie); return client.PostAsync("signin-oidc", new StringContent(form, Encoding.ASCII, "application/x-www-form-urlencoded")); diff --git a/src/Security/Authorization/Core/src/Microsoft.AspNetCore.Authorization.csproj b/src/Security/Authorization/Core/src/Microsoft.AspNetCore.Authorization.csproj index bada0ab62b..904fe35cf8 100644 --- a/src/Security/Authorization/Core/src/Microsoft.AspNetCore.Authorization.csproj +++ b/src/Security/Authorization/Core/src/Microsoft.AspNetCore.Authorization.csproj @@ -5,7 +5,7 @@ Commonly used types: Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute Microsoft.AspNetCore.Authorization.AuthorizeAttribute - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true $(NoWarn);CS1591 diff --git a/src/Security/Security.slnf b/src/Security/Security.slnf index d4e826e25f..7b6afc7319 100644 --- a/src/Security/Security.slnf +++ b/src/Security/Security.slnf @@ -1,15 +1,35 @@ -{ +{ "solution": { "path": "..\\..\\AspNetCore.sln", - "projects" : [ - "src\\Security\\CookiePolicy\\src\\Microsoft.AspNetCore.CookiePolicy.csproj", - "src\\Security\\CookiePolicy\\test\\Microsoft.AspNetCore.CookiePolicy.Test.csproj", - "src\\Security\\CookiePolicy\\samples\\CookiePolicySample\\CookiePolicySample.csproj", - "src\\Security\\Authorization\\Core\\src\\Microsoft.AspNetCore.Authorization.csproj", - "src\\Security\\Authorization\\Policy\\src\\Microsoft.AspNetCore.Authorization.Policy.csproj", - "src\\Security\\Authorization\\test\\Microsoft.AspNetCore.Authorization.Test.csproj", - "src\\Security\\Authentication\\test\\Microsoft.AspNetCore.Authentication.Test.csproj", - "src\\Security\\Authentication\\samples\\SocialSample\\SocialSample.csproj", + "projects": [ + "src\\DataProtection\\Abstractions\\src\\Microsoft.AspNetCore.DataProtection.Abstractions.csproj", + "src\\DataProtection\\Cryptography.Internal\\src\\Microsoft.AspNetCore.Cryptography.Internal.csproj", + "src\\DataProtection\\DataProtection\\src\\Microsoft.AspNetCore.DataProtection.csproj", + "src\\DefaultBuilder\\src\\Microsoft.AspNetCore.csproj", + "src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj", + "src\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj", + "src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj", + "src\\Hosting\\TestHost\\src\\Microsoft.AspNetCore.TestHost.csproj", + "src\\Http\\Authentication.Abstractions\\src\\Microsoft.AspNetCore.Authentication.Abstractions.csproj", + "src\\Http\\Authentication.Core\\src\\Microsoft.AspNetCore.Authentication.Core.csproj", + "src\\Http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj", + "src\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj", + "src\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj", + "src\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj", + "src\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj", + "src\\Http\\Metadata\\src\\Microsoft.AspNetCore.Metadata.csproj", + "src\\Http\\Routing.Abstractions\\src\\Microsoft.AspNetCore.Routing.Abstractions.csproj", + "src\\Http\\Routing\\src\\Microsoft.AspNetCore.Routing.csproj", + "src\\Http\\WebUtilities\\src\\Microsoft.AspNetCore.WebUtilities.csproj", + "src\\Middleware\\Diagnostics.Abstractions\\src\\Microsoft.AspNetCore.Diagnostics.Abstractions.csproj", + "src\\Middleware\\Diagnostics\\src\\Microsoft.AspNetCore.Diagnostics.csproj", + "src\\Middleware\\HostFiltering\\src\\Microsoft.AspNetCore.HostFiltering.csproj", + "src\\Middleware\\HttpOverrides\\src\\Microsoft.AspNetCore.HttpOverrides.csproj", + "src\\Middleware\\StaticFiles\\src\\Microsoft.AspNetCore.StaticFiles.csproj", + "src\\ObjectPool\\src\\Microsoft.Extensions.ObjectPool.csproj", + "src\\Security\\Authentication\\Certificate\\samples\\Certificate.Optional.Sample\\Certificate.Optional.Sample.csproj", + "src\\Security\\Authentication\\Certificate\\samples\\Certificate.Sample\\Certificate.Sample.csproj", + "src\\Security\\Authentication\\Certificate\\src\\Microsoft.AspNetCore.Authentication.Certificate.csproj", "src\\Security\\Authentication\\Cookies\\samples\\CookieSample\\CookieSample.csproj", "src\\Security\\Authentication\\Cookies\\samples\\CookieSessionSample\\CookieSessionSample.csproj", "src\\Security\\Authentication\\Cookies\\src\\Microsoft.AspNetCore.Authentication.Cookies.csproj", @@ -19,6 +39,10 @@ "src\\Security\\Authentication\\JwtBearer\\samples\\JwtBearerSample\\JwtBearerSample.csproj", "src\\Security\\Authentication\\JwtBearer\\src\\Microsoft.AspNetCore.Authentication.JwtBearer.csproj", "src\\Security\\Authentication\\MicrosoftAccount\\src\\Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj", + "src\\Security\\Authentication\\Negotiate\\Samples\\NegotiateAuthSample\\NegotiateAuthSample.csproj", + "src\\Security\\Authentication\\Negotiate\\src\\Microsoft.AspNetCore.Authentication.Negotiate.csproj", + "src\\Security\\Authentication\\Negotiate\\test\\Negotiate.FunctionalTest\\Microsoft.AspNetCore.Authentication.Negotiate.FunctionalTest.csproj", + "src\\Security\\Authentication\\Negotiate\\test\\Negotiate.Test\\Microsoft.AspNetCore.Authentication.Negotiate.Test.csproj", "src\\Security\\Authentication\\OAuth\\src\\Microsoft.AspNetCore.Authentication.OAuth.csproj", "src\\Security\\Authentication\\OpenIdConnect\\samples\\OpenIdConnect.AzureAdSample\\OpenIdConnect.AzureAdSample.csproj", "src\\Security\\Authentication\\OpenIdConnect\\samples\\OpenIdConnectSample\\OpenIdConnectSample.csproj", @@ -26,47 +50,23 @@ "src\\Security\\Authentication\\Twitter\\src\\Microsoft.AspNetCore.Authentication.Twitter.csproj", "src\\Security\\Authentication\\WsFederation\\samples\\WsFedSample\\WsFedSample.csproj", "src\\Security\\Authentication\\WsFederation\\src\\Microsoft.AspNetCore.Authentication.WsFederation.csproj", - "src\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj", - "src\\Hosting\\TestHost\\src\\Microsoft.AspNetCore.TestHost.csproj", - "src\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj", - "src\\Middleware\\Diagnostics\\src\\Microsoft.AspNetCore.Diagnostics.csproj", - "src\\Middleware\\StaticFiles\\src\\Microsoft.AspNetCore.StaticFiles.csproj", - "src\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj", + "src\\Security\\Authentication\\samples\\SocialSample\\SocialSample.csproj", + "src\\Security\\Authentication\\test\\Microsoft.AspNetCore.Authentication.Test.csproj", + "src\\Security\\Authorization\\Core\\src\\Microsoft.AspNetCore.Authorization.csproj", + "src\\Security\\Authorization\\Policy\\src\\Microsoft.AspNetCore.Authorization.Policy.csproj", + "src\\Security\\Authorization\\test\\Microsoft.AspNetCore.Authorization.Test.csproj", + "src\\Security\\CookiePolicy\\samples\\CookiePolicySample\\CookiePolicySample.csproj", + "src\\Security\\CookiePolicy\\src\\Microsoft.AspNetCore.CookiePolicy.csproj", + "src\\Security\\CookiePolicy\\test\\Microsoft.AspNetCore.CookiePolicy.Test.csproj", "src\\Security\\benchmarks\\Microsoft.AspNetCore.Security.Performance\\Microsoft.AspNetCore.Security.Performance.csproj", - "src\\DataProtection\\Abstractions\\src\\Microsoft.AspNetCore.DataProtection.Abstractions.csproj", - "src\\DataProtection\\DataProtection\\src\\Microsoft.AspNetCore.DataProtection.csproj", - "src\\DataProtection\\Cryptography.Internal\\src\\Microsoft.AspNetCore.Cryptography.Internal.csproj", - "src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj", - "src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj", - "src\\Http\\Authentication.Core\\src\\Microsoft.AspNetCore.Authentication.Core.csproj", - "src\\Http\\Authentication.Abstractions\\src\\Microsoft.AspNetCore.Authentication.Abstractions.csproj", - "src\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj", - "src\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj", - "src\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj", - "src\\Http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj", - "src\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj", - "src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", "src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj", - "src\\Middleware\\HttpOverrides\\src\\Microsoft.AspNetCore.HttpOverrides.csproj", - "src\\Http\\WebUtilities\\src\\Microsoft.AspNetCore.WebUtilities.csproj", - "src\\Middleware\\Diagnostics.Abstractions\\src\\Microsoft.AspNetCore.Diagnostics.Abstractions.csproj", - "src\\Http\\Routing\\src\\Microsoft.AspNetCore.Routing.csproj", - "src\\Http\\Routing.Abstractions\\src\\Microsoft.AspNetCore.Routing.Abstractions.csproj", - "src\\Servers\\IIS\\IISIntegration\\src\\Microsoft.AspNetCore.Server.IISIntegration.csproj", - "src\\Security\\Authentication\\Negotiate\\Samples\\NegotiateAuthSample\\NegotiateAuthSample.csproj", - "src\\Security\\Authentication\\Negotiate\\src\\Microsoft.AspNetCore.Authentication.Negotiate.csproj", - "src\\Security\\Authentication\\Negotiate\\test\\Negotiate.Test\\Microsoft.AspNetCore.Authentication.Negotiate.Test.csproj", - "src\\Security\\Authentication\\Negotiate\\test\\Negotiate.FunctionalTest\\Microsoft.AspNetCore.Authentication.Negotiate.FunctionalTest.csproj", - "src\\Security\\Authentication\\Negotiate\\test\\testassets\\Negotiate.Client\\Negotiate.Client.csproj", - "src\\Security\\Authentication\\Negotiate\\test\\testassets\\Negotiate.Server\\Negotiate.Server.csproj", - "src\\Security\\Authentication\\Certificate\\src\\Microsoft.AspNetCore.Authentication.Certificate.csproj", - "src\\Security\\Authentication\\Certificate\\samples\\Certificate.Sample\\Certificate.Sample.csproj", - "src\\Http\\Metadata\\src\\Microsoft.AspNetCore.Metadata.csproj", - "src\\DefaultBuilder\\src\\Microsoft.AspNetCore.csproj", - "src\\Middleware\\HostFiltering\\src\\Microsoft.AspNetCore.HostFiltering.csproj", - "src\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj", "src\\Servers\\HttpSys\\src\\Microsoft.AspNetCore.Server.HttpSys.csproj", - "src\\Security\\Authentication\\Certificate\\samples\\Certificate.Optional.Sample\\Certificate.Optional.Sample.csproj" + "src\\Servers\\IIS\\IISIntegration\\src\\Microsoft.AspNetCore.Server.IISIntegration.csproj", + "src\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj", + "src\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj", + "src\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj", + "src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", + "src\\WebEncoders\\src\\Microsoft.Extensions.WebEncoders.csproj" ] } -} +} \ No newline at end of file diff --git a/src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj b/src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj index 5cfbd655e9..b9614fcb02 100644 --- a/src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj +++ b/src/Servers/Connections.Abstractions/src/Microsoft.AspNetCore.Connections.Abstractions.csproj @@ -2,7 +2,7 @@ Core components of ASP.NET Core networking protocol stack. - netstandard2.0;netstandard2.1;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true true @@ -19,8 +19,16 @@ - + + + + + + diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index db33b281cd..45be8f76b3 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -303,8 +303,9 @@ - + + diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientDisconnectStress.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientDisconnectStress.cs index b72dda791e..605c1055ac 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientDisconnectStress.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientDisconnectStress.cs @@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData(HostingModel.InProcess)] [InlineData(HostingModel.OutOfProcess)] public async Task ClientDisconnectStress(HostingModel hostingModel) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs index b7491f805f..e4973e3de5 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs @@ -73,6 +73,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests [ConditionalFact] [RequiresNewHandler] [RequiresNewShim] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Unexplained casing behavior change https://github.com/dotnet/aspnetcore/issues/25107")] public async Task ServerAddressesIncludesBaseAddress() { var appName = "\u041C\u043E\u0451\u041F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435"; diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs index 5104520781..1efcdb5479 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs @@ -20,6 +20,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] public async Task IncludesAdditionalErrorPageTextInProcessHandlerLoadFailure_CorrectString() { @@ -56,6 +57,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] public async Task IncludesAdditionalErrorPageTextOutOfProcessHandlerLoadFailure_CorrectString() { @@ -78,6 +80,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresNewHandler] public async Task IncludesAdditionalErrorPageTextInProcessStartupFailure_CorrectString() diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/EventLogTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/EventLogTests.cs index 4ce5cef67b..1da3d1e4dc 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/EventLogTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/EventLogTests.cs @@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CheckStartupEventLogMessage() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(); @@ -28,6 +29,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CheckShutdownEventLogMessage() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/FrebTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/FrebTests.cs index 7573fc021d..6aaa57c6c7 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/FrebTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/FrebTests.cs @@ -36,6 +36,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.FailedRequestTracingModule)] public async Task CheckCommonFrebEvents() { @@ -49,6 +50,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewShim] [RequiresIIS(IISCapability.FailedRequestTracingModule)] public async Task FrebIncludesHResultFailures() @@ -65,6 +67,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.FailedRequestTracingModule)] public async Task CheckFailedRequestEvents() { @@ -80,6 +83,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess // I think this test is flaky due to freb file not being created quickly enough. // Adding extra logging, marking as flaky, and repeating should help [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [QuarantinedTest("https://github.com/dotnet/aspnetcore-internal/issues/2570")] [Repeat(10)] [RequiresIIS(IISCapability.FailedRequestTracingModule)] diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs index 0b5b5a7333..93286432c9 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs @@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("ConsoleErrorWrite")] [InlineData("ConsoleWrite")] public async Task CheckStdoutLoggingToPipe_DoesNotCrashProcess(string path) @@ -37,6 +38,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("ConsoleErrorWriteStartServer")] [InlineData("ConsoleWriteStartServer")] public async Task CheckStdoutLoggingToPipeWithFirstWrite(string path) @@ -61,6 +63,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CheckUnicodePipe() { var path = "CheckConsoleFunctions"; diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/MaxRequestBodySizeTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/MaxRequestBodySizeTests.cs index e4d951c63f..3883c82147 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/MaxRequestBodySizeTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/MaxRequestBodySizeTests.cs @@ -115,6 +115,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewHandler] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] public async Task SetIISLimitMaxRequestBodyLogsWarning() diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResetTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResetTests.cs index 89ec32af43..840d526ebc 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResetTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResetTests.cs @@ -24,7 +24,8 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests [Collection(PublishedSitesCollection.Name)] public class ResetTests : IISFunctionalTestBase { - private const string WindowsVersionForTrailers = "10.0.20180"; + // TODO: This is just a guess, there is no build available yet with this feature. + private const string WindowsVersionForTrailers = "10.0.20300"; public ResetTests(PublishedSitesFixture fixture) : base(fixture) { @@ -45,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests }; public static readonly IEnumerable> PostRequestHeaders = new[] -{ + { new KeyValuePair(HeaderNames.Method, "POST"), new KeyValuePair(HeaderNames.Scheme, "https"), new KeyValuePair(HeaderNames.Authority, "localhost:80"), @@ -355,7 +356,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersionForTrailers, SkipReason = "Reset support was added in Win10_20H2.")] public async Task Reset_AfterCompleteAsync_NoReset() { var deploymentParameters = GetHttpsDeploymentParameters(); @@ -387,7 +388,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersionForTrailers, SkipReason = "Reset support was added in Win10_20H2.")] public async Task Reset_CompleteAsyncDuringRequestBody_Resets() { var deploymentParameters = GetHttpsDeploymentParameters(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseTrailersTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseTrailersTests.cs index 8dd82d85aa..b419a66ea0 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseTrailersTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseTrailersTests.cs @@ -18,7 +18,8 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests [Collection(PublishedSitesCollection.Name)] public class ResponseTrailersTests : IISFunctionalTestBase { - private const string WindowsVersionForTrailers = "10.0.20180"; + // TODO: We're just guessing for now, there isn't a stable build with all the features yet. + private const string WindowsVersionForTrailers = "10.0.20300"; public ResponseTrailersTests(PublishedSitesFixture fixture) : base(fixture) { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ShutdownTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ShutdownTests.cs index 89deedee17..2296665f04 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ShutdownTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ShutdownTests.cs @@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task ShutdownTimeoutIsApplied() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs index 4dcd67f63c..e9cee3e958 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs @@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("CheckLargeStdErrWrites")] [InlineData("CheckLargeStdOutWrites")] [InlineData("CheckOversizedStdErrWrites")] @@ -35,6 +36,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("CheckLargeStdErrWrites")] [InlineData("CheckLargeStdOutWrites")] [InlineData("CheckOversizedStdErrWrites")] @@ -57,6 +59,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CheckValidConsoleFunctions() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 71ac04c80c..220489dba6 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -42,6 +42,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("bogus", "", @"Executable was not found at '.*?\\bogus.exe")] [InlineData("c:\\random files\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\dotnet.exe'")] [InlineData(".\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\.\\dotnet.exe'")] @@ -95,6 +96,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("dotnet")] [InlineData("dotnet.EXE")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] @@ -151,6 +153,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [SkipIfNotAdmin] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] public async Task DoesNotStartIfDisabled() { @@ -212,6 +215,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task DetectsOverriddenServer() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -229,6 +233,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task LogsStartupExceptionExitError() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -247,6 +252,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task LogsUnexpectedThreadExitError() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -264,6 +270,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task RemoveHostfxrFromApp_InProcessHostfxrAPIAbsent() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -329,6 +336,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewShim] public async Task RemoveHostfxrFromApp_InProcessHostfxrLoadFailure() { @@ -352,6 +360,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -371,6 +380,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task SingleExecutable_FailedToFindNativeDependencies() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -412,6 +422,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task RemoveInProcessReference_FailedToFindRequestHandler() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite); @@ -474,6 +485,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CheckInvalidHostingModelParameter() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(); @@ -496,6 +508,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess public static IEnumerable InvalidConfigTransformationsScenarios => InvalidConfigTransformations.ToTheoryData(); [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(InvalidConfigTransformationsScenarios))] public async Task ReportsWebConfigAuthoringErrors(string scenario) { @@ -701,6 +714,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresNewHandler] [InlineData("ASPNETCORE_ENVIRONMENT", "Development")] @@ -730,6 +744,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewHandler] public async Task ExceptionIsLoggedToEventLogAndPutInResponseWhenDeveloperExceptionPageIsEnabledViaWebConfig() { @@ -754,6 +769,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresNewHandler] [InlineData("ThrowInStartup")] @@ -778,6 +794,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresNewHandler] public async Task ExceptionIsNotLoggedToResponseWhenStartupHookIsDisabled() @@ -801,6 +818,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewHandler] public async Task ExceptionIsLoggedToEventLogDoesNotWriteToResponse() { @@ -824,6 +842,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewHandler] public async Task CanAddCustomStartupHook() { @@ -841,6 +860,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewHandler] public async Task CanAddCustomStartupHookWhenIISOneIsDisabled() { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs index a18346f099..b8bd9b0aeb 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs @@ -26,6 +26,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests .WithAllHostingModels(); [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] public async Task CheckStdoutLoggingToFile(TestVariant variant) { @@ -33,6 +34,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] public async Task CheckStdoutErrLoggingToFile(TestVariant variant) { @@ -59,6 +61,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests // Move to separate file [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] public async Task InvalidFilePathForLogs_ServerStillRuns(TestVariant variant) { @@ -128,6 +131,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [MemberData(nameof(TestVariants))] public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig(TestVariant variant) @@ -160,6 +164,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] public async Task DebugLogsAreWrittenToEventLog(TestVariant variant) @@ -172,6 +177,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] [QuarantinedTest("https://github.com/dotnet/aspnetcore-internal/issues/2200")] public async Task CheckUTF8File(TestVariant variant) @@ -206,6 +212,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [MemberData(nameof(TestVariants))] public async Task OnlyOneFileCreatedWithProcessStartTime(TestVariant variant) { @@ -222,6 +229,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CaptureLogsForOutOfProcessWhenProcessFailsToStart() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess); @@ -236,6 +244,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresNewShim] public async Task DisableRedirectionNoLogs() { @@ -252,6 +261,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task CaptureLogsForOutOfProcessWhenProcessFailsToStart30KbMax() { var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs index 15a9354108..054d192166 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs @@ -36,6 +36,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task FailsAndLogsWhenRunningTwoInProcessApps() { var parameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess); @@ -57,6 +58,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData(HostingModel.OutOfProcess)] [InlineData(HostingModel.InProcess)] public async Task FailsAndLogsEventLogForMixedHostingModel(HostingModel firstApp) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs index e94c4503fb..e0ef07f6d5 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs @@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [RequiresIIS(IISCapability.PoolEnvironmentVariables)] [RequiresNewShim] public async Task GlobalVersion_EnvironmentVariableWorks() @@ -87,6 +88,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("2.1.0")] [InlineData("2.1.0-preview")] public async Task GlobalVersion_NewVersionNumber(string version) @@ -108,6 +110,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("2.1.0")] [InlineData("2.1.0-preview")] public async Task GlobalVersion_MultipleRequestHandlers_PicksHighestOne(string version) @@ -131,6 +134,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess } [ConditionalTheory] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] [InlineData("2.1.0")] [InlineData("2.1.0-preview")] public async Task GlobalVersion_MultipleRequestHandlers_UpgradeWorks(string version) diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/IISExpressShutdownTests.cs b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/IISExpressShutdownTests.cs index b39eabff4f..31775aa19e 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/IISExpressShutdownTests.cs +++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/IISExpressShutdownTests.cs @@ -65,12 +65,14 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests } [ConditionalFact] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")] public async Task GracefulShutdown_DoesNotCrashProcess() { var parameters = Fixture.GetBaseDeploymentParameters(); var result = await DeployAsync(parameters); var response = await result.HttpClient.GetAsync("/HelloWorld"); + response.EnsureSuccessStatusCode(); StopServer(gracefulShutdown: true); Assert.True(result.HostProcess.ExitCode == 0); } @@ -82,6 +84,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests var result = await DeployAsync(parameters); var response = await result.HttpClient.GetAsync("/HelloWorld"); + response.EnsureSuccessStatusCode(); StopServer(gracefulShutdown: false); Assert.True(result.HostProcess.ExitCode == 1); } diff --git a/src/Servers/Kestrel/Core/src/CoreStrings.resx b/src/Servers/Kestrel/Core/src/CoreStrings.resx index 1dbd5c0435..293d84df90 100644 --- a/src/Servers/Kestrel/Core/src/CoreStrings.resx +++ b/src/Servers/Kestrel/Core/src/CoreStrings.resx @@ -632,4 +632,16 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l The non-HTTPS endpoint {endpointName} includes HTTPS-only configuration for {keyName}. + + Found certificate with private key and thumbprint {Thumbprint} in certificate store {StoreName}. + + + Searching for certificate with private key and thumbprint {Thumbprint} in the certificate store. + + + Failure to locate certificate from store. + + + Failed to open certificate store {StoreName}. + \ No newline at end of file diff --git a/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs b/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs index a65c0937ac..0f049922a8 100644 --- a/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs +++ b/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs @@ -6,7 +6,6 @@ using System.IO; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; using Microsoft.AspNetCore.Server.Kestrel.Https; using Microsoft.AspNetCore.Server.Kestrel.Https.Internal; using Microsoft.Extensions.DependencyInjection; @@ -209,7 +208,8 @@ namespace Microsoft.AspNetCore.Hosting } /// - /// Configure Kestrel to use HTTPS. + /// Configure Kestrel to use HTTPS. This does not use default certificates or other defaults specified via config or + /// . /// /// The to configure. /// Options to configure HTTPS. @@ -230,12 +230,44 @@ namespace Microsoft.AspNetCore.Hosting return listenOptions; } + /// + /// Configure Kestrel to use HTTPS. This does not use default certificates or other defaults specified via config or + /// . + /// + /// The to configure. + /// Callback to configure HTTPS options. + /// State for the . + /// The . + public static ListenOptions UseHttps(this ListenOptions listenOptions, ServerOptionsSelectionCallback serverOptionsSelectionCallback, object state) + { + return listenOptions.UseHttps(serverOptionsSelectionCallback, state, HttpsConnectionAdapterOptions.DefaultHandshakeTimeout); + } + + /// + /// Configure Kestrel to use HTTPS. This does not use default certificates or other defaults specified via config or + /// . + /// + /// The to configure. + /// Callback to configure HTTPS options. + /// State for the . + /// Specifies the maximum amount of time allowed for the TLS/SSL handshake. This must be positive and finite. + /// The . + public static ListenOptions UseHttps(this ListenOptions listenOptions, ServerOptionsSelectionCallback serverOptionsSelectionCallback, object state, TimeSpan handshakeTimeout) + { + // HttpsOptionsCallback is an internal delegate that is just the ServerOptionsSelectionCallback + a ConnectionContext parameter. + // Given that ConnectionContext will eventually be replaced by System.Net.Connections, it doesn't make much sense to make the HttpsOptionsCallback delegate public. + HttpsOptionsCallback adaptedCallback = (connection, stream, clientHelloInfo, state, cancellationToken) => + serverOptionsSelectionCallback(stream, clientHelloInfo, state, cancellationToken); + + return listenOptions.UseHttps(adaptedCallback, state, handshakeTimeout); + } + /// /// Configure Kestrel to use HTTPS. /// /// The to configure. /// Callback to configure HTTPS options. - /// State for the . + /// State for the . /// Specifies the maximum amount of time allowed for the TLS/SSL handshake. This must be positive and finite. /// The . internal static ListenOptions UseHttps(this ListenOptions listenOptions, HttpsOptionsCallback httpsOptionsCallback, object state, TimeSpan handshakeTimeout) diff --git a/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs b/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs index b131323693..6626fd04a0 100644 --- a/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs +++ b/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs @@ -4,11 +4,14 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Pipelines; using System.Net.Security; using System.Runtime.InteropServices; +using System.Security; using System.Security.Authentication; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -91,9 +94,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal { EnsureCertificateIsAllowedForServerAuth(_serverCertificate); + var certificate = _serverCertificate; + if (!certificate.HasPrivateKey) + { + // SslStream historically has logic to deal with certificate missing private keys. + // By resolving the SslStreamCertificateContext eagerly, we circumvent this logic so + // try to resolve the certificate from the store if there's no private key in the cert. + certificate = LocateCertificateWithPrivateKey(certificate); + } + // This might be do blocking IO but it'll resolve the certificate chain up front before any connections are // made to the server - _serverCertificateContext = SslStreamCertificateContext.Create(_serverCertificate, additionalCertificates: null); + _serverCertificateContext = SslStreamCertificateContext.Create(certificate, additionalCertificates: null); } var remoteCertificateValidationCallback = _options.ClientCertificateMode == ClientCertificateMode.NoCertificate ? @@ -215,6 +227,78 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal } } + // This logic is replicated from https://github.com/dotnet/runtime/blob/02b24db7cada5d5806c5cc513e61e44fb2a41944/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs#L195-L262 + // but with public APIs + private X509Certificate2 LocateCertificateWithPrivateKey(X509Certificate2 certificate) + { + Debug.Assert(!certificate.HasPrivateKey, "This should only be called with certificates that don't have a private key"); + + _logger.LocatingCertWithPrivateKey(certificate); + + X509Store OpenStore(StoreLocation storeLocation) + { + try + { + var store = new X509Store(StoreName.My, storeLocation); + store.Open(OpenFlags.ReadOnly); + return store; + } + catch (Exception exception) + { + if (exception is CryptographicException || exception is SecurityException) + { + _logger.FailedToOpenStore(storeLocation, exception); + return null; + } + + throw; + } + } + + try + { + var store = OpenStore(StoreLocation.LocalMachine); + + if (store != null) + { + using (store) + { + var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, validOnly: false); + + if (certs.Count > 0 && certs[0].HasPrivateKey) + { + _logger.FoundCertWithPrivateKey(certs[0], StoreLocation.LocalMachine); + return certs[0]; + } + } + } + + store = OpenStore(StoreLocation.CurrentUser); + + if (store != null) + { + using (store) + { + var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, validOnly: false); + + if (certs.Count > 0 && certs[0].HasPrivateKey) + { + _logger.FoundCertWithPrivateKey(certs[0], StoreLocation.CurrentUser); + return certs[0]; + } + } + } + } + catch (CryptographicException ex) + { + // Log as debug since this error is expected an swallowed + _logger.FailedToFindCertificateInStore(ex); + } + + // Return the cert, and it will fail later + return certificate; + } + private Task DoOptionsBasedHandshakeAsync(ConnectionContext context, SslStream sslStream, Core.Internal.TlsConnectionFeature feature, CancellationToken cancellationToken) { // Adapt to the SslStream signature @@ -396,7 +480,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal { var enableHttp2OnWindows81 = AppContext.TryGetSwitch(EnableWindows81Http2, out var enabled) && enabled; if (Environment.OSVersion.Version < new Version(6, 3) // Missing ALPN support - // Win8.1 and 2012 R2 don't support the right cipher configuration by default. + // Win8.1 and 2012 R2 don't support the right cipher configuration by default. || (Environment.OSVersion.Version < new Version(10, 0) && !enableHttp2OnWindows81)) { return true; @@ -409,7 +493,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal internal static class HttpsConnectionMiddlewareLoggerExtensions { - private static readonly Action _authenticationFailed = LoggerMessage.Define( logLevel: LogLevel.Debug, @@ -434,6 +517,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal eventId: new EventId(4, "Http2DefaultCiphersInsufficient"), formatString: CoreStrings.Http2DefaultCiphersInsufficient); + private static readonly Action _locatingCertWithPrivateKey = + LoggerMessage.Define( + logLevel: LogLevel.Debug, + eventId: new EventId(5, "LocateCertWithPrivateKey"), + formatString: CoreStrings.LocatingCertWithPrivateKey); + + private static readonly Action _foundCertWithPrivateKey = + LoggerMessage.Define( + logLevel: LogLevel.Debug, + eventId: new EventId(6, "FoundCertWithPrivateKey"), + formatString: CoreStrings.FoundCertWithPrivateKey); + + private static readonly Action _failedToFindCertificateInStore = + LoggerMessage.Define( + logLevel: LogLevel.Debug, + eventId: new EventId(7, "FailToLocateCertificate"), + formatString: CoreStrings.FailedToLocateCertificateFromStore); + + + private static readonly Action _failedToOpenCertificateStore = + LoggerMessage.Define( + logLevel: LogLevel.Debug, + eventId: new EventId(8, "FailToOpenStore"), + formatString: CoreStrings.FailedToOpenCertStore); + public static void AuthenticationFailed(this ILogger logger, Exception exception) => _authenticationFailed(logger, exception); public static void AuthenticationTimedOut(this ILogger logger) => _authenticationTimedOut(logger, null); @@ -441,5 +549,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal public static void HttpsConnectionEstablished(this ILogger logger, string connectionId, SslProtocols sslProtocol) => _httpsConnectionEstablished(logger, connectionId, sslProtocol, null); public static void Http2DefaultCiphersInsufficient(this ILogger logger) => _http2DefaultCiphersInsufficient(logger, null); + + public static void LocatingCertWithPrivateKey(this ILogger logger, X509Certificate2 certificate) => _locatingCertWithPrivateKey(logger, certificate.Thumbprint, null); + + public static void FoundCertWithPrivateKey(this ILogger logger, X509Certificate2 certificate, StoreLocation storeLocation) + { + var storeLocationString = storeLocation == StoreLocation.LocalMachine ? nameof(StoreLocation.LocalMachine) : nameof(StoreLocation.CurrentUser); + + _foundCertWithPrivateKey(logger, certificate.Thumbprint, storeLocationString, null); + } + + public static void FailedToFindCertificateInStore(this ILogger logger, Exception exception) => _failedToFindCertificateInStore(logger, exception); + + public static void FailedToOpenStore(this ILogger logger, StoreLocation storeLocation, Exception exception) + { + var storeLocationString = storeLocation == StoreLocation.LocalMachine ? nameof(StoreLocation.LocalMachine) : nameof(StoreLocation.CurrentUser); + + _failedToOpenCertificateStore(logger, storeLocationString, exception); + } } } diff --git a/src/Servers/Kestrel/samples/SampleApp/Startup.cs b/src/Servers/Kestrel/samples/SampleApp/Startup.cs index baed7b92b3..25d7eca283 100644 --- a/src/Servers/Kestrel/samples/SampleApp/Startup.cs +++ b/src/Servers/Kestrel/samples/SampleApp/Startup.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.IO; using System.Net; +using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -109,15 +110,21 @@ namespace SampleApp options.ListenAnyIP(basePort + 5, listenOptions => { - listenOptions.UseHttps(httpsOptions => + var localhostCert = CertificateLoader.LoadFromStoreCert("localhost", "My", StoreLocation.CurrentUser, allowInvalid: true); + + listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) => { - var localhostCert = CertificateLoader.LoadFromStoreCert("localhost", "My", StoreLocation.CurrentUser, allowInvalid: true); - httpsOptions.ServerCertificateSelector = (features, name) => + // Here you would check the name, select an appropriate cert, and provide a fallback or fail for null names. + if (clientHelloInfo.ServerName != null && clientHelloInfo.ServerName != "localhost") { - // Here you would check the name, select an appropriate cert, and provide a fallback or fail for null names. - return localhostCert; - }; - }); + throw new AuthenticationException($"The endpoint is not configured for sever name '{clientHelloInfo.ServerName}'."); + } + + return new ValueTask(new SslServerAuthenticationOptions + { + ServerCertificate = localhostCert + }); + }, state: null); }); options diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs index 0b65712c5e..6ad3338e2a 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs @@ -123,6 +123,42 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } } + [Fact] + public async Task HandshakeDetailsAreAvailableAfterAsyncCallback() + { + void ConfigureListenOptions(ListenOptions listenOptions) + { + listenOptions.UseHttps(async (stream, clientHelloInfo, state, cancellationToken) => + { + await Task.Yield(); + + return new SslServerAuthenticationOptions + { + ServerCertificate = _x509Certificate2, + }; + }, state: null); + } + + await using (var server = new TestServer(context => + { + var tlsFeature = context.Features.Get(); + Assert.NotNull(tlsFeature); + Assert.True(tlsFeature.Protocol > SslProtocols.None, "Protocol"); + Assert.True(tlsFeature.CipherAlgorithm > CipherAlgorithmType.Null, "Cipher"); + Assert.True(tlsFeature.CipherStrength > 0, "CipherStrength"); + Assert.True(tlsFeature.HashAlgorithm >= HashAlgorithmType.None, "HashAlgorithm"); // May be None on Linux. + Assert.True(tlsFeature.HashStrength >= 0, "HashStrength"); // May be 0 for some algorithms + Assert.True(tlsFeature.KeyExchangeAlgorithm >= ExchangeAlgorithmType.None, "KeyExchangeAlgorithm"); // Maybe None on Windows 7 + Assert.True(tlsFeature.KeyExchangeStrength >= 0, "KeyExchangeStrength"); // May be 0 on mac + + return context.Response.WriteAsync("hello world"); + }, new TestServiceContext(LoggerFactory), ConfigureListenOptions)) + { + var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false); + Assert.Equal("hello world", result); + } + } + [Fact] public async Task RequireCertificateFailsWhenNoCertificate() { @@ -166,22 +202,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } [Fact] - [QuarantinedTest("https://github.com/dotnet/runtime/issues/40402")] - public async Task ClientCertificateRequiredConfiguredInCallbackContinuesWhenNoCertificate() + public async Task AsyncCallbackSettingClientCertificateRequiredContinuesWhenNoCertificate() { void ConfigureListenOptions(ListenOptions listenOptions) { - listenOptions.UseHttps((connection, stream, clientHelloInfo, state, cancellationToken) => + listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) => new ValueTask(new SslServerAuthenticationOptions { ServerCertificate = _x509Certificate2, - // From the API Docs: "Note that this is only a request -- - // if no certificate is provided, the server still accepts the connection request." - // Not to mention this is equivalent to the test above. ClientCertificateRequired = true, RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true, CertificateRevocationCheckMode = X509RevocationMode.NoCheck - }), state: null, HttpsConnectionAdapterOptions.DefaultHandshakeTimeout); + }), state: null); } await using (var server = new TestServer(context => @@ -255,6 +287,39 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } } + [Fact] + public async Task UsesProvidedAsyncCallback() + { + var selectorCalled = 0; + void ConfigureListenOptions(ListenOptions listenOptions) + { + listenOptions.UseHttps(async (stream, clientHelloInfo, state, cancellationToken) => + { + await Task.Yield(); + + Assert.NotNull(stream); + Assert.Equal("localhost", clientHelloInfo.ServerName); + selectorCalled++; + + return new SslServerAuthenticationOptions + { + ServerCertificate = _x509Certificate2 + }; + }, state: null); + } + + await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions)) + { + using (var connection = server.CreateConnection()) + { + var stream = OpenSslStream(connection.Stream); + await stream.AuthenticateAsClientAsync("localhost"); + Assert.True(stream.RemoteCertificate.Equals(_x509Certificate2)); + Assert.Equal(1, selectorCalled); + } + } + } + [Fact] public async Task UsesProvidedServerCertificateSelectorEachTime() { diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsTests.cs index 4f2f7cde91..3ef0c16d2a 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsTests.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -13,7 +12,6 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Https; using Microsoft.AspNetCore.Server.Kestrel.Https.Internal; using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport; @@ -21,13 +19,14 @@ using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Testing; using Xunit; namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests { public class HttpsTests : LoggedTest { + private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate(); + private KestrelServerOptions CreateServerOptions() { var serverOptions = new KestrelServerOptions(); @@ -41,8 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public void UseHttpsDefaultsToDefaultCert() { var serverOptions = CreateServerOptions(); - var defaultCert = TestResources.GetTestCertificate(); - serverOptions.DefaultCertificate = defaultCert; + serverOptions.DefaultCertificate = _x509Certificate2; serverOptions.ListenLocalhost(5000, options => { @@ -62,22 +60,51 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests Assert.False(serverOptions.IsDevCertLoaded); } + [Fact] + public async Task UseHttpsWithAsyncCallbackDoeNotFallBackToDefaultCert() + { + var loggerProvider = new HandshakeErrorLoggerProvider(); + LoggerFactory.AddProvider(loggerProvider); + + var testContext = new TestServiceContext(LoggerFactory); + + await using (var server = new TestServer(context => Task.CompletedTask, + testContext, + listenOptions => + { + listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) => + new ValueTask(new SslServerAuthenticationOptions()), state: null); + })) + { + using (var connection = server.CreateConnection()) + using (var sslStream = new SslStream(connection.Stream, true, (sender, certificate, chain, errors) => true)) + { + var ex = await Assert.ThrowsAnyAsync(() => + sslStream.AuthenticateAsClientAsync("127.0.0.1", clientCertificates: null, + enabledSslProtocols: SslProtocols.Tls, + checkCertificateRevocation: false)); + } + } + + var errorException = Assert.Single(loggerProvider.ErrorLogger.ErrorExceptions); + Assert.IsType(errorException); + } + [Fact] public void ConfigureHttpsDefaultsNeverLoadsDefaultCert() { var serverOptions = CreateServerOptions(); - var testCert = TestResources.GetTestCertificate(); serverOptions.ConfigureHttpsDefaults(options => { Assert.Null(options.ServerCertificate); - options.ServerCertificate = testCert; + options.ServerCertificate = _x509Certificate2; options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; }); serverOptions.ListenLocalhost(5000, options => { options.UseHttps(opt => { - Assert.Equal(testCert, opt.ServerCertificate); + Assert.Equal(_x509Certificate2, opt.ServerCertificate); Assert.Equal(ClientCertificateMode.RequireCertificate, opt.ClientCertificateMode); }); }); @@ -90,14 +117,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests public void ConfigureCertSelectorNeverLoadsDefaultCert() { var serverOptions = CreateServerOptions(); - var testCert = TestResources.GetTestCertificate(); serverOptions.ConfigureHttpsDefaults(options => { Assert.Null(options.ServerCertificate); Assert.Null(options.ServerCertificateSelector); options.ServerCertificateSelector = (features, name) => { - return testCert; + return _x509Certificate2; }; options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; }); @@ -126,7 +152,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -139,7 +165,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests Assert.Equal(1, loggerProvider.FilterLogger.LastEventId.Id); Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel); - Assert.True(loggerProvider.ErrorLogger.TotalErrorsLogged == 0, + Assert.True(loggerProvider.ErrorLogger.ErrorMessages.Count == 0, userMessage: string.Join(Environment.NewLine, loggerProvider.ErrorLogger.ErrorMessages)); } @@ -154,7 +180,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -168,7 +194,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests Assert.Equal(1, loggerProvider.FilterLogger.LastEventId.Id); Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel); - Assert.True(loggerProvider.ErrorLogger.TotalErrorsLogged == 0, + Assert.True(loggerProvider.ErrorLogger.ErrorMessages.Count == 0, userMessage: string.Join(Environment.NewLine, loggerProvider.ErrorLogger.ErrorMessages)); } @@ -198,7 +224,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -242,7 +268,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -273,7 +299,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -299,7 +325,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests new TestServiceContext(LoggerFactory), listenOptions => { - listenOptions.UseHttps(TestResources.GetTestCertificate()); + listenOptions.UseHttps(_x509Certificate2); })) { using (var connection = server.CreateConnection()) @@ -316,10 +342,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests LoggerFactory.AddProvider(loggerProvider); var testContext = new TestServiceContext(LoggerFactory); - var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager); - - var handshakeStartedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - TimeSpan handshakeTimeout = default; await using (var server = new TestServer(context => Task.CompletedTask, testContext, @@ -327,26 +349,47 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests { listenOptions.UseHttps(o => { - o.ServerCertificate = new X509Certificate2(TestResources.GetTestCertificate()); - o.OnAuthenticate = (_, __) => - { - handshakeStartedTcs.SetResult(); - }; - - handshakeTimeout = o.HandshakeTimeout; + o.ServerCertificate = new X509Certificate2(_x509Certificate2); + o.HandshakeTimeout = TimeSpan.FromMilliseconds(100); }); })) { using (var connection = server.CreateConnection()) { - // HttpsConnectionAdapter dispatches via Task.Run() before starting the handshake. - // Wait for the handshake to start before advancing the system clock. - await handshakeStartedTcs.Task.DefaultTimeout(); + Assert.Equal(0, await connection.Stream.ReadAsync(new byte[1], 0, 1).DefaultTimeout()); + } + } - // Min amount of time between requests that triggers a handshake timeout. - testContext.MockSystemClock.UtcNow += handshakeTimeout + Heartbeat.Interval + TimeSpan.FromTicks(1); - heartbeatManager.OnHeartbeat(testContext.SystemClock.UtcNow); + await loggerProvider.FilterLogger.LogTcs.Task.DefaultTimeout(); + Assert.Equal(2, loggerProvider.FilterLogger.LastEventId); + Assert.Equal(LogLevel.Debug, loggerProvider.FilterLogger.LastLogLevel); + } + [Fact] + public async Task HandshakeTimesOutAndIsLoggedAsDebugWithAsyncCallback() + { + var loggerProvider = new HandshakeErrorLoggerProvider(); + LoggerFactory.AddProvider(loggerProvider); + + var testContext = new TestServiceContext(LoggerFactory); + + await using (var server = new TestServer(context => Task.CompletedTask, + testContext, + listenOptions => + { + listenOptions.UseHttps(async (stream, clientHelloInfo, state, cancellationToken) => + { + await Task.Yield(); + + return new SslServerAuthenticationOptions + { + ServerCertificate = _x509Certificate2, + }; + }, state: null, handshakeTimeout: TimeSpan.FromMilliseconds(100)); + })) + { + using (var connection = server.CreateConnection()) + { Assert.Equal(0, await connection.Stream.ReadAsync(new byte[1], 0, 1).DefaultTimeout()); } } @@ -394,7 +437,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests var loggerProvider = new HandshakeErrorLoggerProvider(); LoggerFactory.AddProvider(loggerProvider); - var testCert = TestResources.GetTestCertificate(); + var testCert = _x509Certificate2; var onAuthenticateCalled = false; await using (var server = new TestServer(context => Task.CompletedTask, @@ -430,7 +473,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests var loggerProvider = new HandshakeErrorLoggerProvider(); LoggerFactory.AddProvider(loggerProvider); - var testCert = TestResources.GetTestCertificate(); + var testCert = _x509Certificate2; var onAuthenticateCalled = false; await using (var server = new TestServer(context => Task.CompletedTask, @@ -511,11 +554,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests private class ApplicationErrorLogger : ILogger { - private List _errorMessages = new List(); - - public IEnumerable ErrorMessages => _errorMessages; - - public int TotalErrorsLogged => _errorMessages.Count; + public List ErrorMessages => new List(); + public List ErrorExceptions { get; } = new List(); public bool ObjectDisposedExceptionLogged { get; set; } @@ -524,7 +564,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests if (logLevel == LogLevel.Error) { var log = $"Log {logLevel}[{eventId}]: {formatter(state, exception)} {exception}"; - _errorMessages.Add(log); + ErrorMessages.Add(log); + + if (exception != null) + { + ErrorExceptions.Add(exception); + } } if (exception is ObjectDisposedException) diff --git a/src/Shared/runtime/Quic/Implementations/Mock/MockConnection.cs b/src/Shared/runtime/Quic/Implementations/Mock/MockConnection.cs index b97f4876bf..07995dd661 100644 --- a/src/Shared/runtime/Quic/Implementations/Mock/MockConnection.cs +++ b/src/Shared/runtime/Quic/Implementations/Mock/MockConnection.cs @@ -14,7 +14,7 @@ namespace System.Net.Quic.Implementations.Mock { private readonly bool _isClient; private bool _disposed; - private IPEndPoint? _remoteEndPoint; + private EndPoint? _remoteEndPoint; private IPEndPoint? _localEndPoint; private object _syncObject = new object(); private Socket? _socket; @@ -24,7 +24,7 @@ namespace System.Net.Quic.Implementations.Mock private long _nextOutboundUnidirectionalStream; // Constructor for outbound connections - internal MockConnection(IPEndPoint? remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) + internal MockConnection(EndPoint? remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) { _remoteEndPoint = remoteEndPoint; _localEndPoint = localEndPoint; @@ -59,7 +59,7 @@ namespace System.Net.Quic.Implementations.Mock internal override IPEndPoint LocalEndPoint => new IPEndPoint(_localEndPoint!.Address, _localEndPoint.Port); - internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint!.Address, _remoteEndPoint.Port); + internal override EndPoint RemoteEndPoint => _remoteEndPoint!; internal override SslApplicationProtocol NegotiatedApplicationProtocol => throw new NotImplementedException(); diff --git a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs index 5c62f1dbc6..d90b7beede 100644 --- a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs +++ b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. #nullable enable +using System.Buffers; +using System.Collections.Generic; using System.IO; using System.Net.Security; using System.Runtime.InteropServices; @@ -318,26 +320,72 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal return secConfig; } - public unsafe IntPtr SessionOpen(byte[] alpn) + public unsafe IntPtr SessionOpen(List alpnProtocols) + { + if (alpnProtocols.Count == 1) + { + return SessionOpen(alpnProtocols[0]); + } + + var memoryHandles = ArrayPool.Shared.Rent(alpnProtocols.Count); + var quicBuffers = ArrayPool.Shared.Rent(alpnProtocols.Count); + + try + { + for (int i = 0; i < alpnProtocols.Count; ++i) + { + ReadOnlyMemory alpnProtocol = alpnProtocols[i].Protocol; + MemoryHandle h = alpnProtocol.Pin(); + + memoryHandles[i] = h; + quicBuffers[i].Buffer = (byte*)h.Pointer; + quicBuffers[i].Length = (uint)alpnProtocol.Length; + } + + IntPtr session; + + fixed (MsQuicNativeMethods.QuicBuffer* pQuicBuffers = quicBuffers) + { + session = SessionOpen(pQuicBuffers, (uint)alpnProtocols.Count); + } + + ArrayPool.Shared.Return(quicBuffers); + ArrayPool.Shared.Return(memoryHandles); + + return session; + } + finally + { + foreach (MemoryHandle handle in memoryHandles) + { + handle.Dispose(); + } + } + } + + private unsafe IntPtr SessionOpen(SslApplicationProtocol alpnProtocol) + { + ReadOnlyMemory memory = alpnProtocol.Protocol; + using MemoryHandle h = memory.Pin(); + + var quicBuffer = new MsQuicNativeMethods.QuicBuffer() + { + Buffer = (byte*)h.Pointer, + Length = (uint)memory.Length + }; + + return SessionOpen(&quicBuffer, 1); + } + + private unsafe IntPtr SessionOpen(MsQuicNativeMethods.QuicBuffer *alpnBuffers, uint bufferCount) { IntPtr sessionPtr = IntPtr.Zero; - uint status; - - fixed (byte* pAlpn = alpn) - { - var alpnBuffer = new MsQuicNativeMethods.QuicBuffer - { - Length = (uint)alpn.Length, - Buffer = pAlpn - }; - - status = SessionOpenDelegate( - _registrationContext, - &alpnBuffer, - 1, - IntPtr.Zero, - ref sessionPtr); - } + uint status = SessionOpenDelegate( + _registrationContext, + alpnBuffers, + bufferCount, + IntPtr.Zero, + ref sessionPtr); QuicExceptionHelpers.ThrowIfFailed(status, "Could not open session."); diff --git a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs index 962e8046fc..8b0e28e290 100644 --- a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs +++ b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs @@ -1,5 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; +using System.Net.Security; namespace System.Net.Quic.Implementations.MsQuic.Internal { @@ -21,7 +23,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { if (!_opened) { - OpenSession(options.ClientAuthenticationOptions!.ApplicationProtocols![0].Protocol.ToArray(), + OpenSession(options.ClientAuthenticationOptions!.ApplicationProtocols!, (ushort)options.MaxBidirectionalStreams, (ushort)options.MaxUnidirectionalStreams); } @@ -36,7 +38,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal return connectionPtr; } - private void OpenSession(byte[] alpn, ushort bidirectionalStreamCount, ushort undirectionalStreamCount) + private void OpenSession(List alpn, ushort bidirectionalStreamCount, ushort undirectionalStreamCount) { _opened = true; _nativeObjPtr = MsQuicApi.Api.SessionOpen(alpn); @@ -49,7 +51,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { if (!_opened) { - OpenSession(options.ServerAuthenticationOptions!.ApplicationProtocols![0].Protocol.ToArray(), + OpenSession(options.ServerAuthenticationOptions!.ApplicationProtocols!, (ushort)options.MaxBidirectionalStreams, (ushort)options.MaxUnidirectionalStreams); } diff --git a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs index a68cbbe939..673e766822 100644 --- a/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs +++ b/src/Shared/runtime/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs @@ -10,8 +10,13 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { - throw new QuicException($"{message} Error Code: {MsQuicStatusCodes.GetError(status)}"); + throw CreateExceptionForHResult(status, message, innerException); } } + + internal static Exception CreateExceptionForHResult(uint status, string? message = null, Exception? innerException = null) + { + return new QuicException($"{message} Error Code: {MsQuicStatusCodes.GetError(status)}", innerException); + } } } diff --git a/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicConnection.cs index 632c755294..fb9a28691d 100644 --- a/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.IO; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; +using System.Net.Sockets; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -32,7 +33,7 @@ namespace System.Net.Quic.Implementations.MsQuic // Endpoint to either connect to or the endpoint already accepted. private IPEndPoint? _localEndPoint; - private readonly IPEndPoint _remoteEndPoint; + private readonly EndPoint _remoteEndPoint; private SslApplicationProtocol _negotiatedAlpnProtocol; @@ -92,7 +93,7 @@ namespace System.Net.Quic.Implementations.MsQuic MsQuicParameterHelpers.SetSecurityConfig(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.SEC_CONFIG, _securityConfig!.NativeObjPtr); } - internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint.Address, _remoteEndPoint.Port); + internal override EndPoint RemoteEndPoint => _remoteEndPoint; internal override SslApplicationProtocol NegotiatedApplicationProtocol => _negotiatedAlpnProtocol; @@ -155,7 +156,9 @@ namespace System.Net.Quic.Implementations.MsQuic { if (!_connected) { - _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException("Connection has been shutdown."))); + uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status; + Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport."); + _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); } _acceptQueue.Writer.Complete(); @@ -243,12 +246,28 @@ namespace System.Net.Quic.Implementations.MsQuic { ThrowIfDisposed(); + (string address, int port) = _remoteEndPoint switch + { + DnsEndPoint dnsEp => (dnsEp.Host, dnsEp.Port), + IPEndPoint ipEp => (ipEp.Address.ToString(), ipEp.Port), + _ => throw new Exception($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.") + }; + + // values taken from https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionStart.md + int af = _remoteEndPoint.AddressFamily switch + { + AddressFamily.Unspecified => 0, + AddressFamily.InterNetwork => 2, + AddressFamily.InterNetworkV6 => 23, + _ => throw new Exception($"Unsupported address family of '{_remoteEndPoint.AddressFamily}' for remote endpoint.") + }; + QuicExceptionHelpers.ThrowIfFailed( MsQuicApi.Api.ConnectionStartDelegate( _ptr, - (ushort)_remoteEndPoint.AddressFamily, - _remoteEndPoint.Address.ToString(), - (ushort)_remoteEndPoint.Port), + (ushort)af, + address, + (ushort)port), "Failed to connect to peer."); return new ValueTask(_connectTcs.Task); diff --git a/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicStream.cs index 48a135799b..3b01df503b 100644 --- a/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/Shared/runtime/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -225,6 +225,11 @@ namespace System.Net.Quic.Implementations.MsQuic throw new InvalidOperationException("Reading is not allowed on stream."); } + if (NetEventSource.IsEnabled) + { + NetEventSource.Info(this, $"[{GetHashCode()}] reading into Memory of '{destination.Length}' bytes."); + } + lock (_sync) { if (_readState == ReadState.ReadsCompleted) @@ -474,6 +479,11 @@ namespace System.Net.Quic.Implementations.MsQuic private uint HandleEvent(ref StreamEvent evt) { + if (NetEventSource.IsEnabled) + { + NetEventSource.Info(this, $"[{GetHashCode()}] handling event '{evt.Type}'."); + } + uint status = MsQuicStatusCodes.Success; try diff --git a/src/Shared/runtime/Quic/Implementations/QuicConnectionProvider.cs b/src/Shared/runtime/Quic/Implementations/QuicConnectionProvider.cs index da511640f2..7febd47be1 100644 --- a/src/Shared/runtime/Quic/Implementations/QuicConnectionProvider.cs +++ b/src/Shared/runtime/Quic/Implementations/QuicConnectionProvider.cs @@ -12,7 +12,7 @@ namespace System.Net.Quic.Implementations internal abstract IPEndPoint LocalEndPoint { get; } - internal abstract IPEndPoint RemoteEndPoint { get; } + internal abstract EndPoint RemoteEndPoint { get; } internal abstract ValueTask ConnectAsync(CancellationToken cancellationToken = default); diff --git a/src/Shared/runtime/Quic/Interop/MsQuicStatusCodes.cs b/src/Shared/runtime/Quic/Interop/MsQuicStatusCodes.cs index af7fd30300..c48fac85f9 100644 --- a/src/Shared/runtime/Quic/Interop/MsQuicStatusCodes.cs +++ b/src/Shared/runtime/Quic/Interop/MsQuicStatusCodes.cs @@ -26,13 +26,16 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal internal const uint HandshakeFailure = 0x80410000; internal const uint Aborted = 0x80004004; internal const uint AddressInUse = 0x80072740; - internal const uint ConnectionTimeout = 0x800704CF; - internal const uint ConnectionIdle = 0x800704D4; - internal const uint InternalError = 0x80004005; - internal const uint ServerBusy = 0x800704C9; - internal const uint ProtocolError = 0x800704CD; + internal const uint ConnectionTimeout = 0x80410006; + internal const uint ConnectionIdle = 0x80410005; internal const uint HostUnreachable = 0x800704D0; + internal const uint InternalError = 0x80410003; + internal const uint ConnectionRefused = 0x800704C9; + internal const uint ProtocolError = 0x80410004; internal const uint VerNegError = 0x80410001; + internal const uint TlsError = 0x80072B18; + internal const uint UserCanceled = 0x80410002; + internal const uint AlpnNegotiationFailure = 0x80410007; // TODO return better error messages here. public static string GetError(uint status) @@ -53,11 +56,15 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal AddressInUse => "ADDRESS_IN_USE", ConnectionTimeout => "CONNECTION_TIMEOUT", ConnectionIdle => "CONNECTION_IDLE", + HostUnreachable => "UNREACHABLE", InternalError => "INTERNAL_ERROR", - ServerBusy => "SERVER_BUSY", + ConnectionRefused => "CONNECTION_REFUSED", ProtocolError => "PROTOCOL_ERROR", VerNegError => "VER_NEG_ERROR", - _ => status.ToString() + TlsError => "TLS_ERROR", + UserCanceled => "USER_CANCELED", + AlpnNegotiationFailure => "ALPN_NEG_FAILURE", + _ => $"0x{status:X8}" }; } } @@ -79,9 +86,15 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal internal const uint ConnectionTimeout = 110; internal const uint ConnectionIdle = 200000011; internal const uint InternalError = 200000012; - internal const uint ServerBusy = 200000007; + internal const uint ConnectionRefused = 200000007; internal const uint ProtocolError = 200000013; internal const uint VerNegError = 200000014; + internal const uint EpollError = 200000015; + internal const uint DnsResolutionError = 200000016; + internal const uint SocketError = 200000017; + internal const uint TlsError = 200000018; + internal const uint UserCanceled = 200000019; + internal const uint AlpnNegotiationFailure = 200000020; // TODO return better error messages here. public static string GetError(uint status) @@ -103,10 +116,16 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal ConnectionTimeout => "CONNECTION_TIMEOUT", ConnectionIdle => "CONNECTION_IDLE", InternalError => "INTERNAL_ERROR", - ServerBusy => "SERVER_BUSY", + ConnectionRefused => "CONNECTION_REFUSED", ProtocolError => "PROTOCOL_ERROR", VerNegError => "VER_NEG_ERROR", - _ => status.ToString() + EpollError => "EPOLL_ERROR", + DnsResolutionError => "DNS_RESOLUTION_ERROR", + SocketError => "SOCKET_ERROR", + TlsError => "TLS_ERROR", + UserCanceled => "USER_CANCELED", + AlpnNegotiationFailure => "ALPN_NEG_FAILURE", + _ => $"0x{status:X8}" }; } } diff --git a/src/Shared/runtime/Quic/QuicClientConnectionOptions.cs b/src/Shared/runtime/Quic/QuicClientConnectionOptions.cs index c4ad3447cb..9852644101 100644 --- a/src/Shared/runtime/Quic/QuicClientConnectionOptions.cs +++ b/src/Shared/runtime/Quic/QuicClientConnectionOptions.cs @@ -24,7 +24,7 @@ namespace System.Net.Quic /// /// The endpoint to connect to. /// - public IPEndPoint? RemoteEndPoint { get; set; } + public EndPoint? RemoteEndPoint { get; set; } /// /// Limit on the number of bidirectional streams the peer connection can create diff --git a/src/Shared/runtime/Quic/QuicConnection.cs b/src/Shared/runtime/Quic/QuicConnection.cs index 999ce7aadd..6c82a237df 100644 --- a/src/Shared/runtime/Quic/QuicConnection.cs +++ b/src/Shared/runtime/Quic/QuicConnection.cs @@ -22,13 +22,13 @@ namespace System.Net.Quic /// The remote endpoint to connect to. /// TLS options /// The local endpoint to connect from. - public QuicConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) + public QuicConnection(EndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) : this(QuicImplementationProviders.Default, remoteEndPoint, sslClientAuthenticationOptions, localEndPoint) { } // !!! TEMPORARY: Remove "implementationProvider" before shipping - public QuicConnection(QuicImplementationProvider implementationProvider, IPEndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) + public QuicConnection(QuicImplementationProvider implementationProvider, EndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) : this(implementationProvider, new QuicClientConnectionOptions() { RemoteEndPoint = remoteEndPoint, ClientAuthenticationOptions = sslClientAuthenticationOptions, LocalEndPoint = localEndPoint }) { } @@ -50,7 +50,7 @@ namespace System.Net.Quic public IPEndPoint LocalEndPoint => _provider.LocalEndPoint; - public IPEndPoint RemoteEndPoint => _provider.RemoteEndPoint; + public EndPoint RemoteEndPoint => _provider.RemoteEndPoint; public SslApplicationProtocol NegotiatedApplicationProtocol => _provider.NegotiatedApplicationProtocol; diff --git a/src/Shared/runtime/Quic/QuicException.cs b/src/Shared/runtime/Quic/QuicException.cs index 16a26d8afc..9a2351e6a9 100644 --- a/src/Shared/runtime/Quic/QuicException.cs +++ b/src/Shared/runtime/Quic/QuicException.cs @@ -1,12 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable namespace System.Net.Quic { internal class QuicException : Exception { - public QuicException(string message) - : base (message) + public QuicException(string? message) + : base(message) + { + } + public QuicException(string? message, Exception? innerException) + : base(message, innerException) { } } diff --git a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj index 71e4f7fd20..504f2e4549 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj +++ b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj @@ -2,7 +2,7 @@ Client for ASP.NET Core SignalR - netstandard2.0;netstandard2.1 + $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1 Microsoft.AspNetCore.SignalR.Client @@ -27,9 +27,9 @@ - - - + + + diff --git a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj index 7dd94f7674..47444465b4 100644 --- a/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj +++ b/src/SignalR/clients/csharp/Client/src/Microsoft.AspNetCore.SignalR.Client.csproj @@ -2,7 +2,7 @@ Client for ASP.NET Core SignalR - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs index 4eac8c4642..cb3ca3d28a 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionFactory.cs @@ -82,11 +82,10 @@ namespace Microsoft.AspNetCore.Http.Connections.Client // Internal for testing internal static HttpConnectionOptions ShallowCopyHttpConnectionOptions(HttpConnectionOptions options) { - return new HttpConnectionOptions + var newOptions = new HttpConnectionOptions { HttpMessageHandlerFactory = options.HttpMessageHandlerFactory, Headers = options.Headers, - ClientCertificates = options.ClientCertificates, Cookies = options.Cookies, Url = options.Url, Transports = options.Transports, @@ -99,6 +98,14 @@ namespace Microsoft.AspNetCore.Http.Connections.Client DefaultTransferFormat = options.DefaultTransferFormat, WebSocketConfiguration = options.WebSocketConfiguration, }; + + // WASM doesn't support Crypto APIs and our setter throws if you try to assign null + if (options.ClientCertificates != null) + { + newOptions.ClientCertificates = options.ClientCertificates; + } + + return newOptions; } } } diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs index ef8b177eaf..cfbe155e9b 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnectionOptions.cs @@ -10,6 +10,7 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http.Connections.Client.Internal; namespace Microsoft.AspNetCore.Http.Connections.Client { @@ -28,7 +29,13 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public HttpConnectionOptions() { _headers = new Dictionary(); - _clientCertificates = new X509CertificateCollection(); + + // System.Security.Cryptography isn't supported on WASM currently + if (!Utils.IsRunningInBrowser()) + { + _clientCertificates = new X509CertificateCollection(); + } + _cookies = new CookieContainer(); Transports = HttpTransports.All; diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs index f3cda1c3ad..e0b8d08aa0 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/WebSocketsTransport.cs @@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal #if NETSTANDARD2_1 // Because we checked the CloseStatus from the 0 byte read above, we don't need to check again after reading var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None); -#elif NETSTANDARD2_0 +#elif NETSTANDARD2_0 || NET461 var isArray = MemoryMarshal.TryGetArray(memory, out var arraySegment); Debug.Assert(isArray); diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj index c0fedd3797..bae3bab800 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Microsoft.AspNetCore.Http.Connections.Client.csproj @@ -2,7 +2,7 @@ Client for ASP.NET Core Connection Handlers - netstandard2.0;netstandard2.1 + $(DefaultNetFxTargetFramework);netstandard2.0;netstandard2.1 @@ -19,6 +19,11 @@ + + + + + diff --git a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java index b0bcbb3648..0aa4e4c336 100644 --- a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java +++ b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java @@ -718,6 +718,7 @@ public class HubConnection implements AutoCloseable { /** * Invokes a hub method on the server using the specified method name and arguments. + * A Type can be retrieved using {@link TypeReference} * * @param returnType The expected return type. * @param method The name of the server method to invoke. @@ -1097,6 +1098,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1113,6 +1115,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1133,6 +1136,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1157,6 +1161,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1183,6 +1188,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1212,6 +1218,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1243,6 +1250,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. @@ -1277,6 +1285,7 @@ public class HubConnection implements AutoCloseable { /** * Registers a handler that will be invoked when the hub method with the specified method name is invoked. * Should be used for generic classes and Parameterized Collections, like List or Map. + * A Type can be retrieved using {@link TypeReference} * * @param target The name of the hub method to define. * @param callback The handler that will be raised when the hub method is invoked. diff --git a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TypeReference.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TypeReference.java new file mode 100644 index 0000000000..9fad029eec --- /dev/null +++ b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TypeReference.java @@ -0,0 +1,38 @@ +// 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. + +package com.microsoft.signalr; + +import java.lang.reflect.Type; +import java.lang.reflect.ParameterizedType; + +/** + * A utility for getting a Java Type from a literal Class. + */ +public class TypeReference { + + private final Type type; + + /** + * Creates a new instance of {@link TypeReference}. + * + * To get the Type of Class Foo, use the following syntax: + *
{@code
+     * Type fooType = (new TypeReference() { }).getType();
+     * }
+ */ + public TypeReference() { + Type superclass = getClass().getGenericSuperclass(); + if (superclass instanceof Class) { + throw new RuntimeException("Missing type parameter."); + } + this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; + } + + /** + * Gets the referenced type. + */ + public Type getType() { + return this.type; + } +} diff --git a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java index 89b5a0efdd..402a21c74b 100644 --- a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java +++ b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java @@ -18,8 +18,6 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.core.type.TypeReference; - import io.reactivex.Completable; import io.reactivex.Observable; import io.reactivex.Single; diff --git a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java index 92febe6ad0..1b707d6a53 100644 --- a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java +++ b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java @@ -13,8 +13,6 @@ import java.util.List; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.core.type.TypeReference; - class JsonHubProtocolTest { private JsonHubProtocol jsonHubProtocol = new JsonHubProtocol(); diff --git a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MessagePackHubProtocolTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MessagePackHubProtocolTest.java index 0b508d6e21..37df89fabf 100644 --- a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MessagePackHubProtocolTest.java +++ b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MessagePackHubProtocolTest.java @@ -19,8 +19,6 @@ import java.util.TreeMap; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.core.type.TypeReference; - class MessagePackHubProtocolTest { private MessagePackHubProtocol messagePackHubProtocol = new MessagePackHubProtocol(); diff --git a/src/SignalR/clients/ts/FunctionalTests/Startup.cs b/src/SignalR/clients/ts/FunctionalTests/Startup.cs index 8a3ccfa767..a53eec75d2 100644 --- a/src/SignalR/clients/ts/FunctionalTests/Startup.cs +++ b/src/SignalR/clients/ts/FunctionalTests/Startup.cs @@ -163,9 +163,21 @@ namespace FunctionalTests { if (context.Request.Path.Value.Contains("/negotiate")) { - context.Response.Cookies.Append("testCookie", "testValue"); - context.Response.Cookies.Append("testCookie2", "testValue2"); - context.Response.Cookies.Append("expiredCookie", "doesntmatter", new CookieOptions() { Expires = DateTimeOffset.Now.AddHours(-1) }); + var cookieOptions = new CookieOptions(); + var expiredCookieOptions = new CookieOptions() { Expires = DateTimeOffset.Now.AddHours(-1) }; + if (context.Request.IsHttps) + { + cookieOptions.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; + cookieOptions.Secure = true; + + expiredCookieOptions.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; + expiredCookieOptions.Secure = true; + } + context.Response.Cookies.Append("testCookie", "testValue", cookieOptions); + context.Response.Cookies.Append("testCookie2", "testValue2", cookieOptions); + + cookieOptions.Expires = DateTimeOffset.Now.AddHours(-1); + context.Response.Cookies.Append("expiredCookie", "doesntmatter", expiredCookieOptions); } await next.Invoke(); diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts index 668a738536..4eb412145a 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts @@ -60,6 +60,7 @@ console.log(`Using SignalR HTTPS Server: '${ENDPOINT_BASE_HTTPS_URL}'`); console.log(`Jasmine DEFAULT_TIMEOUT_INTERVAL: ${jasmine.DEFAULT_TIMEOUT_INTERVAL}`); export const ECHOENDPOINT_URL = ENDPOINT_BASE_URL + "/echo"; +export const HTTPS_ECHOENDPOINT_URL = ENDPOINT_BASE_HTTPS_URL + "/echo"; export function getHttpTransportTypes(): HttpTransportType[] { const transportTypes = []; @@ -131,3 +132,14 @@ export function eachHttpClient(action: (transport: HttpClient) => void) { return action(t); }); } + +// Run test in Node or Chrome, but not on macOS +export const shouldRunHttpsTests = + // Need to have an HTTPS URL + !!ENDPOINT_BASE_HTTPS_URL && + + // Run on Node, unless macOS + (process && process.platform !== "darwin") && + + // Only run under Chrome browser + (typeof navigator === "undefined" || navigator.userAgent.search("Chrome") !== -1); diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts index b3445891b3..b377c98112 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts @@ -5,7 +5,7 @@ // tslint:disable:no-floating-promises import { HttpTransportType, IHttpConnectionOptions, TransferFormat } from "@microsoft/signalr"; -import { DEFAULT_TIMEOUT_INTERVAL, eachHttpClient, eachTransport, ECHOENDPOINT_URL } from "./Common"; +import { DEFAULT_TIMEOUT_INTERVAL, eachHttpClient, eachTransport, ECHOENDPOINT_URL, HTTPS_ECHOENDPOINT_URL, shouldRunHttpsTests } from "./Common"; import { TestLogger } from "./TestLogger"; // We want to continue testing HttpConnection, but we don't export it anymore. So just pull it in directly from the source file. @@ -15,6 +15,8 @@ import "./LogBannerReporter"; jasmine.DEFAULT_TIMEOUT_INTERVAL = DEFAULT_TIMEOUT_INTERVAL; +const USED_ECHOENDPOINT_URL = shouldRunHttpsTests ? HTTPS_ECHOENDPOINT_URL : ECHOENDPOINT_URL; + const commonOptions: IHttpConnectionOptions = { logMessageContent: true, logger: TestLogger.instance, @@ -23,7 +25,7 @@ const commonOptions: IHttpConnectionOptions = { describe("connection", () => { it("can connect to the server without specifying transport explicitly", (done) => { const message = "Hello World!"; - const connection = new HttpConnection(ECHOENDPOINT_URL, { + const connection = new HttpConnection(USED_ECHOENDPOINT_URL, { ...commonOptions, }); @@ -53,7 +55,7 @@ describe("connection", () => { const message = "Hello World!"; // the url should be resolved relative to the document.location.host // and the leading '/' should be automatically added to the url - const connection = new HttpConnection(ECHOENDPOINT_URL, { + const connection = new HttpConnection(USED_ECHOENDPOINT_URL, { ...commonOptions, httpClient, transport: transportType, @@ -83,7 +85,7 @@ describe("connection", () => { const message = "Hello World!"; // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is not set. - const connection = new HttpConnection(ECHOENDPOINT_URL, { + const connection = new HttpConnection(USED_ECHOENDPOINT_URL, { httpClient, logger: TestLogger.instance, transport: transportType, @@ -119,7 +121,7 @@ describe("connection", () => { const message = "Hello World!"; // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is set to true (even if commonOptions changes). - const connection = new HttpConnection(ECHOENDPOINT_URL, { + const connection = new HttpConnection(USED_ECHOENDPOINT_URL, { httpClient, logMessageContent: true, logger: TestLogger.instance, @@ -167,7 +169,7 @@ describe("connection", () => { const message = "Hello World!"; // The server will set some response headers for the '/negotiate' endpoint - const connection = new HttpConnection(ECHOENDPOINT_URL, { + const connection = new HttpConnection(USED_ECHOENDPOINT_URL, { ...commonOptions, httpClient, transport: transportType, diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts index a802d79424..600617d5f3 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts @@ -8,7 +8,7 @@ import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, H import { MessagePackHubProtocol } from "@microsoft/signalr-protocol-msgpack"; import { getUserAgentHeader, Platform } from "@microsoft/signalr/dist/esm/Utils"; -import { DEFAULT_TIMEOUT_INTERVAL, eachTransport, eachTransportAndProtocolAndHttpClient, ENDPOINT_BASE_HTTPS_URL, ENDPOINT_BASE_URL } from "./Common"; +import { DEFAULT_TIMEOUT_INTERVAL, eachTransport, eachTransportAndProtocolAndHttpClient, ENDPOINT_BASE_HTTPS_URL, ENDPOINT_BASE_URL, shouldRunHttpsTests } from "./Common"; import "./LogBannerReporter"; import { TestLogger } from "./TestLogger"; @@ -18,6 +18,7 @@ import * as RX from "rxjs"; const TESTHUBENDPOINT_URL = ENDPOINT_BASE_URL + "/testhub"; const TESTHUBENDPOINT_HTTPS_URL = ENDPOINT_BASE_HTTPS_URL ? (ENDPOINT_BASE_HTTPS_URL + "/testhub") : undefined; +const HTTPORHTTPS_TESTHUBENDPOINT_URL = shouldRunHttpsTests ? TESTHUBENDPOINT_HTTPS_URL : TESTHUBENDPOINT_URL; const TESTHUB_NOWEBSOCKETS_ENDPOINT_URL = ENDPOINT_BASE_URL + "/testhub-nowebsockets"; const TESTHUB_REDIRECT_ENDPOINT_URL = ENDPOINT_BASE_URL + "/redirect?numRedirects=0&baseUrl=" + ENDPOINT_BASE_URL; @@ -28,17 +29,6 @@ const commonOptions: IHttpConnectionOptions = { logMessageContent: true, }; -// Run test in Node or Chrome, but not on macOS -const shouldRunHttpsTests = - // Need to have an HTTPS URL - !!TESTHUBENDPOINT_HTTPS_URL && - - // Run on Node, unless macOS - (process && process.platform !== "darwin") && - - // Only run under Chrome browser - (typeof navigator === "undefined" || navigator.userAgent.search("Chrome") !== -1); - function getConnectionBuilder(transportType?: HttpTransportType, url?: string, options?: IHttpConnectionOptions): HubConnectionBuilder { let actualOptions: IHttpConnectionOptions = options || {}; if (transportType) { @@ -599,7 +589,7 @@ describe("hubConnection", () => { } it("preserves cookies between requests", async (done) => { - const hubConnection = getConnectionBuilder(transportType).build(); + const hubConnection = getConnectionBuilder(transportType, HTTPORHTTPS_TESTHUBENDPOINT_URL).build(); await hubConnection.start(); const cookieValue = await hubConnection.invoke("GetCookie", "testCookie"); const cookieValue2 = await hubConnection.invoke("GetCookie", "testCookie2"); @@ -610,7 +600,7 @@ describe("hubConnection", () => { }); it("expired cookies are not preserved", async (done) => { - const hubConnection = getConnectionBuilder(transportType).build(); + const hubConnection = getConnectionBuilder(transportType, HTTPORHTTPS_TESTHUBENDPOINT_URL).build(); await hubConnection.start(); const cookieValue = await hubConnection.invoke("GetCookie", "expiredCookie"); expect(cookieValue).toBeNull(); diff --git a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj index 4277aaef64..02f97edfb6 100644 --- a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj +++ b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj @@ -2,7 +2,7 @@ Common primitives for ASP.NET Connection Handlers and clients - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true Microsoft.AspNetCore.Http.Connections @@ -19,16 +19,8 @@
- + - - - - - - - - diff --git a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj index fa1317d365..cae05aae11 100644 --- a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj +++ b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj @@ -2,7 +2,7 @@ Implements the SignalR Hub Protocol using System.Text.Json. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true Microsoft.AspNetCore.SignalR @@ -23,9 +23,4 @@ - - - - - diff --git a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj index 65817ce39e..8ed07be5dc 100644 --- a/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj +++ b/src/SignalR/common/Protocols.MessagePack/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj @@ -2,7 +2,7 @@ Implements the SignalR Hub Protocol over MsgPack. - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 Microsoft.AspNetCore.SignalR true enable diff --git a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj index ee6a01dfbf..00e59a9cee 100644 --- a/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj +++ b/src/SignalR/common/Protocols.NewtonsoftJson/src/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.csproj @@ -2,7 +2,7 @@ Implements the SignalR Hub Protocol using Newtonsoft.Json. - netstandard2.0 + $(DefaultNetFxTargetFramework);netstandard2.0 Microsoft.AspNetCore.SignalR true enable diff --git a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj index ff1a013cf8..1206aeed68 100644 --- a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj @@ -2,7 +2,7 @@ Common serialiation primitives for SignalR Clients Servers - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) true Microsoft.AspNetCore.SignalR @@ -25,16 +25,12 @@
- + - - - - - - + + diff --git a/src/SignalR/samples/ClientSample/ClientSample.csproj b/src/SignalR/samples/ClientSample/ClientSample.csproj index 82330ad3e9..d5f892ec75 100644 --- a/src/SignalR/samples/ClientSample/ClientSample.csproj +++ b/src/SignalR/samples/ClientSample/ClientSample.csproj @@ -1,7 +1,7 @@  - $(DefaultNetCoreTargetFramework);net461 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) Exe diff --git a/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj b/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj index ebe593e808..24e529ed1a 100644 --- a/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj +++ b/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj @@ -3,7 +3,7 @@ ASP.NET Core Logging Integration This site extension enables logging integration for ASP.NET Core applications on Azure App Service. - net461 + $(DefaultNetFxTargetFramework) false aspnet;logging;aspnetcore;AzureSiteExtension;keyvault;configuration;dataprotection false @@ -24,13 +24,27 @@ + - - - + + + @@ -43,8 +57,13 @@ - - + + - - + + + + - - + diff --git a/src/SiteExtensions/LoggingAggregate/test/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj b/src/SiteExtensions/LoggingAggregate/test/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj index 4711b09890..b22f270d0c 100644 --- a/src/SiteExtensions/LoggingAggregate/test/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj +++ b/src/SiteExtensions/LoggingAggregate/test/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests/Microsoft.AspNetCore.AzureAppServices.SiteExtension.Tests.csproj @@ -1,7 +1,7 @@ - net461 + $(DefaultNetFxTargetFramework) diff --git a/src/SiteExtensions/LoggingBranch/LB.csproj b/src/SiteExtensions/LoggingBranch/LB.csproj index fc4257f0b4..631f5d56a0 100644 --- a/src/SiteExtensions/LoggingBranch/LB.csproj +++ b/src/SiteExtensions/LoggingBranch/LB.csproj @@ -3,7 +3,7 @@ ASP.NET Core Extensions This extension enables additional functionality for ASP.NET Core on Azure WebSites, such as enabling Azure logging. - net461 + $(DefaultNetFxTargetFramework) false aspnet;logging;aspnetcore;AzureSiteExtension;keyvault;configuration;dataprotection content diff --git a/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/src/Microsoft.Web.Xdt.Extensions.csproj b/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/src/Microsoft.Web.Xdt.Extensions.csproj index 0844815979..21b53f618a 100644 --- a/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/src/Microsoft.Web.Xdt.Extensions.csproj +++ b/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/src/Microsoft.Web.Xdt.Extensions.csproj @@ -2,7 +2,7 @@ Additional functionality for Xdt transforms. - net461 + $(DefaultNetFxTargetFramework) true false false diff --git a/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/tests/Microsoft.Web.Xdt.Extensions.Tests.csproj b/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/tests/Microsoft.Web.Xdt.Extensions.Tests.csproj index d794280afc..46839e5c48 100644 --- a/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/tests/Microsoft.Web.Xdt.Extensions.Tests.csproj +++ b/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/tests/Microsoft.Web.Xdt.Extensions.Tests.csproj @@ -1,7 +1,7 @@ - net461 + $(DefaultNetFxTargetFramework) diff --git a/src/SiteExtensions/Sdk/SiteExtension.targets b/src/SiteExtensions/Sdk/SiteExtension.targets index c2bf7ea61a..792d83e090 100644 --- a/src/SiteExtensions/Sdk/SiteExtension.targets +++ b/src/SiteExtensions/Sdk/SiteExtension.targets @@ -9,11 +9,11 @@ <_TemplatesDirectory>$(MSBuildThisFileDirectory)..\content\ - <_DepsOutputDirectory>$(IntermediateOutputPath)\se\ - <_WorkingDirectory>$(_DepsOutputDirectory)\depswork + <_DepsOutputDirectory>$(IntermediateOutputPath)se\ + <_WorkingDirectory>$(_DepsOutputDirectory)depswork <_BasePackagePath>content\additionaldeps\ - <_RuntimeStoreManifestFile>$(_DepsOutputDirectory)\rs.csproj - <_RuntimeStoreOutput>$(_DepsOutputDirectory)\rs\ + <_RuntimeStoreManifestFile>$(_DepsOutputDirectory)rs.csproj + <_RuntimeStoreOutput>$(_DepsOutputDirectory)rs\ <_RsRestoreSources> $(RestoreAdditionalProjectSources); $(ArtifactsShippingPackagesDir); @@ -55,7 +55,7 @@ Project="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\HostingStartup.csproj" DepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\p\HostingStartup.deps.json" TrimmedDepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\%(HostingStartupPackageReference.Identity).deps.json" - PackagePath="$(_BasePackagePath)\shared\Microsoft.AspNetCore.App\$(AspNetCoreMajorMinorVersion).0\" + PackagePath="$(_BasePackagePath)shared\Microsoft.AspNetCore.App\$(AspNetCoreMajorMinorVersion).0\" /> diff --git a/src/SiteExtensions/build.cmd b/src/SiteExtensions/build.cmd index d0f42cd74e..687895d0c9 100644 --- a/src/SiteExtensions/build.cmd +++ b/src/SiteExtensions/build.cmd @@ -3,7 +3,7 @@ SET RepoRoot=%~dp0..\.. ECHO Building x64 Microsoft.AspNetCore.Runtime.SiteExtension CALL "%RepoRoot%\build.cmd" -arch x64 -projects "%~dp0Runtime\Microsoft.AspNetCore.Runtime.SiteExtension.pkgproj" ^ - "/bl:%RepoRoot%/artifacts/log/SiteExtensions-Runtime-x86.binlog" %* + "/bl:%RepoRoot%/artifacts/log/SiteExtensions-Runtime-x64.binlog" %* IF %ERRORLEVEL% NEQ 0 ( EXIT /b %ErrorLevel% ) diff --git a/src/Testing/src/Microsoft.AspNetCore.Testing.csproj b/src/Testing/src/Microsoft.AspNetCore.Testing.csproj index 7d95e026a7..7001a12439 100644 --- a/src/Testing/src/Microsoft.AspNetCore.Testing.csproj +++ b/src/Testing/src/Microsoft.AspNetCore.Testing.csproj @@ -2,7 +2,7 @@ Various helpers for writing tests that use ASP.NET Core. - netstandard2.0;net461 + $(DefaultNetFxTargetFramework);netstandard2.0 $(NoWarn);CS1591 true aspnetcore @@ -39,7 +39,7 @@ - + diff --git a/src/Tools/Extensions.ApiDescription.Server/src/Microsoft.Extensions.ApiDescription.Server.csproj b/src/Tools/Extensions.ApiDescription.Server/src/Microsoft.Extensions.ApiDescription.Server.csproj index db7bc7926a..712fa8362b 100644 --- a/src/Tools/Extensions.ApiDescription.Server/src/Microsoft.Extensions.ApiDescription.Server.csproj +++ b/src/Tools/Extensions.ApiDescription.Server/src/Microsoft.Extensions.ApiDescription.Server.csproj @@ -3,7 +3,7 @@ - netcoreapp2.1;net461 + netcoreapp2.1;$(DefaultNetFxTargetFramework) MSBuild tasks and targets for build-time Swagger and OpenApi document generation true diff --git a/src/Tools/Extensions.ApiDescription.Server/src/build/Microsoft.Extensions.ApiDescription.Server.targets b/src/Tools/Extensions.ApiDescription.Server/src/build/Microsoft.Extensions.ApiDescription.Server.targets index f6b037335a..45410bca53 100644 --- a/src/Tools/Extensions.ApiDescription.Server/src/build/Microsoft.Extensions.ApiDescription.Server.targets +++ b/src/Tools/Extensions.ApiDescription.Server/src/build/Microsoft.Extensions.ApiDescription.Server.targets @@ -1,9 +1,13 @@  + + <_IsMicrosoftNETCoreApp20OrOlder>false + <_IsMicrosoftNETCoreApp20OrOlder Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND + $([MSBuild]::VersionLessThanOrEquals('$(TargetFrameworkVersion)', '2.0') ">true + true - + $(OpenApiGenerateDocuments) @@ -22,7 +26,7 @@ Text="OpenAPI document generation is disabled. Add '<OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>' to the project." /> diff --git a/src/Tools/GetDocumentInsider/src/GetDocument.Insider.csproj b/src/Tools/GetDocumentInsider/src/GetDocument.Insider.csproj index cf667b1e85..0fce0f0528 100644 --- a/src/Tools/GetDocumentInsider/src/GetDocument.Insider.csproj +++ b/src/Tools/GetDocumentInsider/src/GetDocument.Insider.csproj @@ -5,11 +5,11 @@ false Exe Microsoft.Extensions.ApiDescription.Tool - netcoreapp2.1;net461 + netcoreapp2.1;$(DefaultNetFxTargetFramework) false - + @@ -19,7 +19,7 @@ - + diff --git a/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj b/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj index bedcf8c051..24f2823009 100644 --- a/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj +++ b/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj @@ -15,9 +15,6 @@ - - - diff --git a/src/Tools/dotnet-watch/src/assets/DotNetWatch.targets b/src/Tools/dotnet-watch/src/assets/DotNetWatch.targets index 4126ed6ec4..26316b06e1 100644 --- a/src/Tools/dotnet-watch/src/assets/DotNetWatch.targets +++ b/src/Tools/dotnet-watch/src/assets/DotNetWatch.targets @@ -11,8 +11,8 @@ them to a file. DependsOnTargets="_CollectWatchItems"> - <_IsMicrosoftNETCoreApp31OrNewer - Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.1'))">true + <_IsMicrosoftNETCoreApp31OrNewer Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND + $([MSBuild]::VersionGreaterThanOrEquals('$(TargetFrameworkVersion)', '3.1'))">true <_IsMicrosoftNETCoreApp31OrNewer Condition="'$(_IsMicrosoftNETCoreApp31OrNewer)' == ''">false @@ -41,6 +41,7 @@ Returns: @(Watch) <_CollectWatchItemsDependsOn Condition=" '$(TargetFramework)' != '' "> _CoreCollectWatchItems; + $(CustomCollectWatchItems); diff --git a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.gitignore b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.gitignore new file mode 100644 index 0000000000..ab929c6551 --- /dev/null +++ b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.gitignore @@ -0,0 +1 @@ +.net \ No newline at end of file diff --git a/src/WebEncoders/src/Microsoft.Extensions.WebEncoders.csproj b/src/WebEncoders/src/Microsoft.Extensions.WebEncoders.csproj index 920d4e2869..3ddf648cdd 100644 --- a/src/WebEncoders/src/Microsoft.Extensions.WebEncoders.csproj +++ b/src/WebEncoders/src/Microsoft.Extensions.WebEncoders.csproj @@ -2,7 +2,7 @@ Contains registration and configuration APIs to add the core framework encoders to a dependency injection container. - netstandard2.0;$(DefaultNetCoreTargetFramework) + $(DefaultNetFxTargetFramework);netstandard2.0;$(DefaultNetCoreTargetFramework) $(DefaultNetCoreTargetFramework) $(NoWarn);CS1591 true @@ -16,7 +16,7 @@ - + diff --git a/src/WebEncoders/test/Microsoft.Extensions.WebEncoders.Tests.csproj b/src/WebEncoders/test/Microsoft.Extensions.WebEncoders.Tests.csproj index 57884af976..628f6fa669 100755 --- a/src/WebEncoders/test/Microsoft.Extensions.WebEncoders.Tests.csproj +++ b/src/WebEncoders/test/Microsoft.Extensions.WebEncoders.Tests.csproj @@ -1,7 +1,7 @@ - $(DefaultNetCoreTargetFramework);net472 + $(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework) enable