Files
aliasvault/apps/server/AliasVault.Client/AliasVault.Client.csproj

189 lines
11 KiB
XML

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<RootNamespace>AliasVault.Client</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<BuildVersion>$([System.DateTime]::UtcNow.ToString("yyyy-MM-dd HH:mm:ss"))</BuildVersion>
<WasmBuildNative>true</WasmBuildNative>
<LangVersion>14</LangVersion>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DocumentationFile>bin\Debug\net10.0\AliasVault.Client.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CacheBuster>dev</CacheBuster>
<NoWarn>NU1903</NoWarn>
<!-- No fingerprinting in debug mode -->
<BlazorScript>_framework/blazor.webassembly.js</BlazorScript>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- Enable .NET 10 static asset fingerprinting for cache busting (only in Release) -->
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
<BlazorScript>_framework/blazor.webassembly#[.{fingerprint}].js</BlazorScript>
<DebugSymbols>false</DebugSymbols>
<DocumentationFile>bin\Release\net10.0\AliasVault.Client.xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Optimize>True</Optimize>
<CacheBuster>$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</CacheBuster>
<WasmDebugLevel>0</WasmDebugLevel>
<!-- Suppress IL2037 linker errors for EF Core reflection-based APIs -->
<NoWarn>NU1903;IL2037</NoWarn>
</PropertyGroup>
<UsingTask TaskName="ReplaceText" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<InputFile ParameterType="System.String" Required="true" />
<OutputFile ParameterType="System.String" Required="true" />
<CacheBuster ParameterType="System.String" Required="true" />
<BuildVersion ParameterType="System.String" Required="true" />
<BlazorScript ParameterType="System.String" Required="true" />
<Minify ParameterType="System.Boolean" Required="false" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string content = File.ReadAllText(InputFile);
content = content.Replace("@CacheBuster", CacheBuster).Replace("@BuildVersion", BuildVersion).Replace("@BlazorScript", BlazorScript);
if (Minify)
{
// Extract and preserve script/style blocks
var scriptBlocks = new System.Collections.Generic.List<string>();
var styleBlocks = new System.Collections.Generic.List<string>();
content = System.Text.RegularExpressions.Regex.Replace(content, @"(<script[^>]*>)(.*?)(</script>)",
m => { scriptBlocks.Add(m.Groups[2].Value); return m.Groups[1].Value + "___SCRIPT_" + (scriptBlocks.Count - 1) + "___" + m.Groups[3].Value; },
System.Text.RegularExpressions.RegexOptions.Singleline);
content = System.Text.RegularExpressions.Regex.Replace(content, @"(<style[^>]*>)(.*?)(</style>)",
m => { styleBlocks.Add(m.Groups[2].Value); return m.Groups[1].Value + "___STYLE_" + (styleBlocks.Count - 1) + "___" + m.Groups[3].Value; },
System.Text.RegularExpressions.RegexOptions.Singleline);
// Extract and preserve the header comment (contains ASCII art and license)
var headerMatch = System.Text.RegularExpressions.Regex.Match(content, @"(<!--\s*╔[\s\S]*?Build:[\s\S]*?-->)");
string headerComment = headerMatch.Success ? headerMatch.Groups[1].Value : "";
if (headerMatch.Success)
{
content = content.Replace(headerComment, "___HEADER_COMMENT___");
}
// Remove all other HTML comments
content = System.Text.RegularExpressions.Regex.Replace(content, @"<!--.*?-->", "", System.Text.RegularExpressions.RegexOptions.Singleline);
// Collapse whitespace between tags
content = System.Text.RegularExpressions.Regex.Replace(content, @">\s+<", "><");
// Remove leading/trailing whitespace from lines and collapse newlines
content = System.Text.RegularExpressions.Regex.Replace(content, @"^\s+", "", System.Text.RegularExpressions.RegexOptions.Multiline);
content = System.Text.RegularExpressions.Regex.Replace(content, @"\s+$", "", System.Text.RegularExpressions.RegexOptions.Multiline);
content = System.Text.RegularExpressions.Regex.Replace(content, @"\r?\n", "");
content = System.Text.RegularExpressions.Regex.Replace(content, @" +", " ");
// Restore script blocks (minify each one)
for (int i = 0; i < scriptBlocks.Count; i++)
{
var script = scriptBlocks[i];
// Remove JS single-line comments (but not URLs with //)
script = System.Text.RegularExpressions.Regex.Replace(script, @"(?<!:)//[^\n]*", "");
// Remove JS multi-line comments
script = System.Text.RegularExpressions.Regex.Replace(script, @"/\*.*?\*/", "", System.Text.RegularExpressions.RegexOptions.Singleline);
// Collapse all whitespace including newlines
script = System.Text.RegularExpressions.Regex.Replace(script, @"\s+", " ");
script = script.Trim();
content = content.Replace("___SCRIPT_" + i + "___", script);
}
// Restore style blocks (minify each one)
for (int i = 0; i < styleBlocks.Count; i++)
{
var style = styleBlocks[i];
// Remove CSS comments
style = System.Text.RegularExpressions.Regex.Replace(style, @"/\*.*?\*/", "", System.Text.RegularExpressions.RegexOptions.Singleline);
style = System.Text.RegularExpressions.Regex.Replace(style, @"\s+", " ");
style = System.Text.RegularExpressions.Regex.Replace(style, @"\s*([{};:,>+~])\s*", "$1");
style = style.Trim();
content = content.Replace("___STYLE_" + i + "___", style);
}
// Restore header comment at the end (preserving its formatting)
if (headerMatch.Success)
{
content = content.Replace("___HEADER_COMMENT___", "\n" + headerComment + "\n");
}
}
File.WriteAllText(OutputFile, content);
Log.LogMessage(MessageImportance.High, (Minify ? "Minified and replaced" : "Replaced") + " content in " + OutputFile);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="NpmInstall" BeforeTargets="NpmBuild" Condition="!Exists('node_modules')">
<Exec Command="npm install" WorkingDirectory="$(ProjectDir)" />
</Target>
<Target Name="NpmBuild" BeforeTargets="GenerateCacheBustedIndexHtml">
<Exec Command="npm run build:js" WorkingDirectory="$(ProjectDir)" />
</Target>
<Target Name="GenerateCacheBustedIndexHtml" BeforeTargets="Build">
<ReplaceText InputFile="wwwroot/index.template.html" OutputFile="wwwroot/index.html" CacheBuster="$(CacheBuster)" BuildVersion="$(BuildVersion)" BlazorScript="$(BlazorScript)" Minify="true" />
</Target>
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="10.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="10.0.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.102">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\appsettings.Development.json" Condition="Exists('wwwroot\appsettings.Development.json')">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
<AdditionalFiles Include="..\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Databases\AliasClientDb\AliasClientDb.csproj" />
<ProjectReference Include="..\Shared\AliasVault.RazorComponents\AliasVault.RazorComponents.csproj" />
<ProjectReference Include="..\Shared\AliasVault.Shared.Core\AliasVault.Shared.Core.csproj" />
<ProjectReference Include="..\Shared\AliasVault.Shared\AliasVault.Shared.csproj" />
<ProjectReference Include="..\Utilities\Cryptography\AliasVault.Cryptography.Client\AliasVault.Cryptography.Client.csproj" />
<ProjectReference Include="..\Utilities\AliasVault.ImportExport\AliasVault.ImportExport.csproj" />
<ProjectReference Include="..\Utilities\AliasVault.TotpGenerator\AliasVault.TotpGenerator.csproj" />
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
<ServiceWorker Include="wwwroot\service-worker.published.js">
<PublishedContent>wwwroot/service-worker.published.js</PublishedContent>
</ServiceWorker>
</ItemGroup>
</Project>