Browse Source

Update dotnet (#1301)

* Update dotnet

* Fix build.

* Fix tests.

* Update command.

* Fix tests

* Test

* Test another update.

* Revert change.

* Improve tests.

* Improve usage.

* Fix tests hopefully.

* Increase timeout.

* Ignore tests for now.

* Another test.
pull/1305/head
Sebastian Stehle 4 months ago
committed by GitHub
parent
commit
4d00e78657
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      .github/workflows/dev.yml
  2. 6
      Dockerfile
  3. 16
      backend/.editorconfig
  4. 321
      backend/Squidex.sln
  5. 43
      backend/Squidex.slnx
  6. 37
      backend/extensions/Squidex.Extensions/APM/Zipkin/ZipkinPlugin.cs
  7. 7
      backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs
  8. 37
      backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj
  9. 5
      backend/global.json
  10. 2
      backend/i18n/translator/Squidex.Translator/Squidex.Translator.csproj
  11. 6
      backend/src/Migrations/Migrations.csproj
  12. 3
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Apps/EFAppRepository.cs
  13. 2
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Assets/EFAssetFolderRepository_SnapshotStore.cs
  14. 2
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Assets/EFAssetRepository_SnapshotStore.cs
  15. 2
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Contents/Extensions.cs
  16. 2
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Schemas/EFSchemaRepository.cs
  17. 2
      backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Teams/EFTeamRepository.cs
  18. 2
      backend/src/Squidex.Data.EntityFramework/Infrastructure/BulkInserter.cs
  19. 4
      backend/src/Squidex.Data.EntityFramework/Infrastructure/Extensions.cs
  20. 2
      backend/src/Squidex.Data.EntityFramework/Infrastructure/States/EFSnapshotStore.cs
  21. 1628
      backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/20260323154443_MigrateToNet10.Designer.cs
  22. 46
      backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/20260323154443_MigrateToNet10.cs
  23. 7
      backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/MySqlDbContextModelSnapshot.cs
  24. 5
      backend/src/Squidex.Data.EntityFramework/Providers/MySql/Content/JsonFunction.cs
  25. 2
      backend/src/Squidex.Data.EntityFramework/Providers/MySql/JsonFunction.cs
  26. 1629
      backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/20260323155026_MigrateToNet10.Designer.cs
  27. 36
      backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/20260323155026_MigrateToNet10.cs
  28. 7
      backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/PostgresDbContextModelSnapshot.cs
  29. 2
      backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/PostgresAppDbContextDesignTimeFactory.cs
  30. 1631
      backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/20260323155035_MigrateToNet10.Designer.cs
  31. 36
      backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/20260323155035_MigrateToNet10.cs
  32. 7
      backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/SqlServerDbContextModelSnapshot.cs
  33. 2
      backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/SqlServerAppDbContextDesignTimeFactory.cs
  34. 10
      backend/src/Squidex.Data.EntityFramework/ServiceExtensions.cs
  35. 56
      backend/src/Squidex.Data.EntityFramework/Squidex.Data.EntityFramework.csproj
  36. 4
      backend/src/Squidex.Data.EntityFramework/docker-compose.yml
  37. 6
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetEntity.cs
  38. 6
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderEntity.cs
  39. 5
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository.cs
  40. 2
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository_SnapshotStore.cs
  41. 8
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetItemClassMap.cs
  42. 5
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository.cs
  43. 2
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository_SnapshotStore.cs
  44. 8
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentEntity.cs
  45. 9
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository.cs
  46. 2
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/AtlasTextIndex.cs
  47. 15
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/MongoTextIndexerState.cs
  48. 25
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/MongoTextStateClassMap.cs
  49. 27
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryClassMap.cs
  50. 10
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryEventRepository.cs
  51. 8
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/MongoAppEntityClassMap.cs
  52. 6
      backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/MongoEntityClassMap.cs
  53. 37
      backend/src/Squidex.Data.MongoDb/Domain/Users/IdentityUserForwardingSerializer.cs
  54. 116
      backend/src/Squidex.Data.MongoDb/Domain/Users/MongoIdentityClassMap.cs
  55. 16
      backend/src/Squidex.Data.MongoDb/Domain/Users/MongoRoleStore.cs
  56. 125
      backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUserStore.cs
  57. 11
      backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDomainIdSerializer.cs
  58. 37
      backend/src/Squidex.Data.MongoDb/Infrastructure/MongoClientFactory.cs
  59. 5
      backend/src/Squidex.Data.MongoDb/Infrastructure/MongoExtensions.cs
  60. 59
      backend/src/Squidex.Data.MongoDb/MongoClientFactory.cs
  61. 16
      backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs
  62. 29
      backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj
  63. 13
      backend/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj
  64. 3
      backend/src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs
  65. 12
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs
  66. 11
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
  67. 10
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ScriptExecutionContext.cs
  68. 21
      backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
  69. 4
      backend/src/Squidex.Domain.Apps.Core.Operations/Templates/Extensions/JsonArrayFluidValue.cs
  70. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs
  71. 32
      backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
  72. 6
      backend/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj
  73. 10
      backend/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj
  74. 5
      backend/src/Squidex.Infrastructure/CollectionExtensions.cs
  75. 2
      backend/src/Squidex.Infrastructure/DisposableObjectBase.cs
  76. 3
      backend/src/Squidex.Infrastructure/EventSourcing/EnvelopeExtensions.cs
  77. 2
      backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs
  78. 10
      backend/src/Squidex.Infrastructure/Queries/OData/ConstantWithTypeVisitor.cs
  79. 38
      backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj
  80. 5
      backend/src/Squidex.Shared/Squidex.Shared.csproj
  81. 15
      backend/src/Squidex.Web/Pipeline/ActionContextLogAppender.cs
  82. 4
      backend/src/Squidex.Web/Pipeline/UsagePipeWriter.cs
  83. 12
      backend/src/Squidex.Web/Squidex.Web.csproj
  84. 12
      backend/src/Squidex/Areas/IdentityServer/Config/ApplicationExtensions.cs
  85. 8
      backend/src/Squidex/Areas/IdentityServer/Config/ApplicationManager.cs
  86. 4
      backend/src/Squidex/Areas/IdentityServer/Config/DynamicApplicationStore.cs
  87. 10
      backend/src/Squidex/Areas/IdentityServer/Config/IdentityServerServices.cs
  88. 2
      backend/src/Squidex/Areas/IdentityServer/Controllers/Connect/AuthorizationController.cs
  89. 11
      backend/src/Squidex/Config/Domain/EventSourcingServices.cs
  90. 4
      backend/src/Squidex/Config/Web/WebServices.cs
  91. 88
      backend/src/Squidex/Squidex.csproj
  92. 6
      backend/tests/Squidex.Data.Tests.CodeGenerator/Squidex.Data.Tests.CodeGenerator.csproj
  93. 8
      backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/MySqlMigrationTests.cs
  94. 9
      backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/PostgresMigrationTests.cs
  95. 10
      backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/SqlServerMigrationTests.cs
  96. 14
      backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/MySqlFixture.cs
  97. 15
      backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/PostgresFixture.cs
  98. 17
      backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/SqlServerFixture.cs
  99. 1
      backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/TestEntity.cs
  100. 10
      backend/tests/Squidex.Data.Tests/MongoDb/Domain/Assets/AssetQueryTests.cs

8
.github/workflows/dev.yml

@ -40,7 +40,7 @@ jobs:
id: dotnet
uses: actions/setup-dotnet@v4.3.1
with:
dotnet-version: 8.0.x
dotnet-version: 10.0.x
# Note: Unless a concrete version is specified in the `global.json` file,
# the latest .NET version installed on the runner (including preinstalled
@ -52,7 +52,7 @@ jobs:
echo '{"sdk":{"version": "${{ steps.dotnet.outputs.dotnet-version }}"}}' > ./global.json
- name: Test - TestContainers
run: dotnet test backend/Squidex.sln --filter Category=TestContainer
run: dotnet test backend/Squidex.slnx --filter Category=TestContainer
test-mongo:
runs-on: ubuntu-latest
@ -67,7 +67,7 @@ jobs:
- name: Prepare - Setup dotnet
uses: actions/setup-dotnet@v4.3.1
with:
dotnet-version: 8.0.x
dotnet-version: 10.0.x
- name: Prepare - Setup Node
uses: actions/setup-node@v4.4.0
@ -175,7 +175,7 @@ jobs:
- name: Prepare - Setup dotnet
uses: actions/setup-dotnet@v4.3.1
with:
dotnet-version: 8.0.x
dotnet-version: 10.0.x
- name: Prepare - Setup Node
uses: actions/setup-node@v4.4.0

6
Dockerfile

@ -2,7 +2,7 @@
# Stage 1, Build Backend
#
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS backend
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0 AS backend
# FFMPEG for tests
RUN apt-get update \
@ -17,7 +17,7 @@ WORKDIR /source
# Copy nuget project files.
COPY backend/Directory.Build.props ./
COPY backend/*.sln ./
COPY backend/*.slnx ./
# Copy the main source project files
COPY backend/src/*/*.csproj ./
@ -79,7 +79,7 @@ RUN cp -a build /build/
#
# Stage 3, Build runtime
#
FROM mcr.microsoft.com/dotnet/aspnet:8.0-bookworm-slim
FROM mcr.microsoft.com/dotnet/aspnet:10.0
ARG SQUIDEX__RUNTIME__VERSION=7.0.0

16
backend/.editorconfig

@ -184,4 +184,18 @@ dotnet_diagnostic.SA1623.severity = none
dotnet_diagnostic.SYSLIB1045.severity = none
# xUnit1033: Test classes decorated with 'Xunit.IClassFixture<TFixture>' or 'Xunit.ICollectionFixture<TFixture>' should add a constructor argument of type TFixture
dotnet_diagnostic.xUnit1033.severity = none
dotnet_diagnostic.xUnit1033.severity = none
[*Tests*.cs]
# MA0040: Forward the CancellationToken parameter to methods that take one
dotnet_diagnostic.MA0040.severity = none
# xUnit1051: Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken
dotnet_diagnostic.xUnit1051.severity = none
# CA1816: Dispose methods should call SuppressFinalize
dotnet_diagnostic.CA1816.severity = none
[*Fixture.cs]
# CA1816: Dispose methods should call SuppressFinalize
dotnet_diagnostic.CA1816.severity = none

321
backend/Squidex.sln

@ -1,321 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex", "src\Squidex\Squidex.csproj", "{61F6BBCE-A080-4400-B194-70E2F5D2096E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "infrastructure", "infrastructure", "{8CF53B92-5EB1-461D-98F8-70DA9B603FBF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "domain", "domain", "{4C6B06C2-6D77-4E0E-AE32-D7050236433A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure", "src\Squidex.Infrastructure\Squidex.Infrastructure.csproj", "{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Events", "src\Squidex.Domain.Apps.Events\Squidex.Domain.Apps.Events.csproj", "{25F66C64-058A-4D44-BC0C-F12A054F9A91}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.Tests", "tests\Squidex.Infrastructure.Tests\Squidex.Infrastructure.Tests.csproj", "{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Core.Tests", "tests\Squidex.Domain.Apps.Core.Tests\Squidex.Domain.Apps.Core.Tests.csproj", "{FD0AFD44-7A93-4F9E-B5ED-72582392E435}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{94207AA6-4923-4183-A558-E0F8196B8CA3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Shared", "src\Squidex.Shared\Squidex.Shared.csproj", "{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Users", "src\Squidex.Domain.Users\Squidex.Domain.Users.csproj", "{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Users.Tests", "tests\Squidex.Domain.Users.Tests\Squidex.Domain.Users.Tests.csproj", "{42184546-E3CB-4D4F-9495-43979B9C63B9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{360C300D-0F7E-439D-A437-714C959E3CAD}"
ProjectSection(SolutionItems) = preProject
Squidex.ruleset = Squidex.ruleset
stylecop.json = stylecop.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Core.Model", "src\Squidex.Domain.Apps.Core.Model\Squidex.Domain.Apps.Core.Model.csproj", "{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Core.Operations", "src\Squidex.Domain.Apps.Core.Operations\Squidex.Domain.Apps.Core.Operations.csproj", "{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Entities", "src\Squidex.Domain.Apps.Entities\Squidex.Domain.Apps.Entities.csproj", "{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Entities.Tests", "tests\Squidex.Domain.Apps.Entities.Tests\Squidex.Domain.Apps.Entities.Tests.csproj", "{AA003372-CD8D-4DBC-962C-F61E0C93CF05}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Web.Tests", "tests\Squidex.Web.Tests\Squidex.Web.Tests.csproj", "{7E8CC864-4C6E-496F-A672-9F9AD8874835}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{FB8BC3A2-2010-4C3C-A87D-D4A98C05EE52}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Extensions", "extensions\Squidex.Extensions\Squidex.Extensions.csproj", "{F3C41B82-6A67-409A-B7FE-54543EE4F38B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{7EDE8CF1-B1E4-4005-B154-834B944E0D7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Web", "src\Squidex.Web\Squidex.Web.csproj", "{5B2D251F-46E3-486A-AE16-E3FE06B559ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migrations", "src\Migrations\Migrations.csproj", "{23615A39-F3FB-4575-A91C-535899DFB636}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{3378B841-53F8-48CC-87C1-1B30CF912BFD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Data.MongoDb", "src\Squidex.Data.MongoDb\Squidex.Data.MongoDb.csproj", "{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Data.Tests", "tests\Squidex.Data.Tests\Squidex.Data.Tests.csproj", "{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Data.EntityFramework", "src\Squidex.Data.EntityFramework\Squidex.Data.EntityFramework.csproj", "{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Data.Tests.CodeGenerator", "tests\Squidex.Data.Tests.CodeGenerator\Squidex.Data.Tests.CodeGenerator.csproj", "{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Debug|x64.ActiveCfg = Debug|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Debug|x86.ActiveCfg = Debug|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Release|Any CPU.Build.0 = Release|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Release|x64.ActiveCfg = Release|Any CPU
{61F6BBCE-A080-4400-B194-70E2F5D2096E}.Release|x86.ActiveCfg = Release|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Debug|x64.ActiveCfg = Debug|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Debug|x86.ActiveCfg = Debug|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Release|Any CPU.Build.0 = Release|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Release|x64.ActiveCfg = Release|Any CPU
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C}.Release|x86.ActiveCfg = Release|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Debug|x64.ActiveCfg = Debug|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Debug|x86.ActiveCfg = Debug|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Release|Any CPU.Build.0 = Release|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Release|x64.ActiveCfg = Release|Any CPU
{25F66C64-058A-4D44-BC0C-F12A054F9A91}.Release|x86.ActiveCfg = Release|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Debug|x64.ActiveCfg = Debug|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Debug|x86.ActiveCfg = Debug|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Release|Any CPU.Build.0 = Release|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Release|x64.ActiveCfg = Release|Any CPU
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B}.Release|x86.ActiveCfg = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Debug|x64.ActiveCfg = Debug|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Debug|x86.ActiveCfg = Debug|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|Any CPU.Build.0 = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|x64.ActiveCfg = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|x86.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x64.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x86.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|Any CPU.Build.0 = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x64.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x64.Build.0 = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x86.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x86.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x64.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x64.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x86.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x86.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|Any CPU.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x64.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x64.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x86.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x86.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x64.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x64.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x86.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x86.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|Any CPU.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x64.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x64.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x86.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x86.Build.0 = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|x64.ActiveCfg = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|x64.Build.0 = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|x86.ActiveCfg = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Debug|x86.Build.0 = Debug|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|Any CPU.Build.0 = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|x64.ActiveCfg = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|x64.Build.0 = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|x86.ActiveCfg = Release|Any CPU
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F}.Release|x86.Build.0 = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|x64.ActiveCfg = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|x64.Build.0 = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|x86.ActiveCfg = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Debug|x86.Build.0 = Debug|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|Any CPU.Build.0 = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|x64.ActiveCfg = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|x64.Build.0 = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|x86.ActiveCfg = Release|Any CPU
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31}.Release|x86.Build.0 = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|x64.Build.0 = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|x86.ActiveCfg = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Debug|x86.Build.0 = Debug|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|Any CPU.Build.0 = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|x64.ActiveCfg = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|x64.Build.0 = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|x86.ActiveCfg = Release|Any CPU
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5}.Release|x86.Build.0 = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|x64.Build.0 = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Debug|x86.Build.0 = Debug|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|Any CPU.Build.0 = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x64.ActiveCfg = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x64.Build.0 = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x86.ActiveCfg = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x86.Build.0 = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|x64.ActiveCfg = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|x64.Build.0 = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|x86.ActiveCfg = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|x86.Build.0 = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|Any CPU.Build.0 = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|x64.ActiveCfg = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|x64.Build.0 = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|x86.ActiveCfg = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Release|x86.Build.0 = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|x64.ActiveCfg = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|x64.Build.0 = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|x86.ActiveCfg = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Debug|x86.Build.0 = Debug|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|Any CPU.Build.0 = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|x64.ActiveCfg = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|x64.Build.0 = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|x86.ActiveCfg = Release|Any CPU
{F3C41B82-6A67-409A-B7FE-54543EE4F38B}.Release|x86.Build.0 = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|x64.ActiveCfg = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|x64.Build.0 = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|x86.ActiveCfg = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Debug|x86.Build.0 = Debug|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|Any CPU.Build.0 = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|x64.ActiveCfg = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|x64.Build.0 = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|x86.ActiveCfg = Release|Any CPU
{5B2D251F-46E3-486A-AE16-E3FE06B559ED}.Release|x86.Build.0 = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|x64.ActiveCfg = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|x64.Build.0 = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|x86.ActiveCfg = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Debug|x86.Build.0 = Debug|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|Any CPU.Build.0 = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x64.ActiveCfg = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x64.Build.0 = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x86.ActiveCfg = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x86.Build.0 = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x64.ActiveCfg = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x64.Build.0 = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x86.ActiveCfg = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x86.Build.0 = Debug|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|Any CPU.Build.0 = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x64.ActiveCfg = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x64.Build.0 = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x86.ActiveCfg = Release|Any CPU
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x86.Build.0 = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x64.Build.0 = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x86.Build.0 = Debug|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|Any CPU.Build.0 = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x64.ActiveCfg = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x64.Build.0 = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x86.ActiveCfg = Release|Any CPU
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x86.Build.0 = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|x64.ActiveCfg = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|x64.Build.0 = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|x86.ActiveCfg = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Debug|x86.Build.0 = Debug|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|Any CPU.Build.0 = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|x64.ActiveCfg = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|x64.Build.0 = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|x86.ActiveCfg = Release|Any CPU
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA}.Release|x86.Build.0 = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|x64.Build.0 = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Debug|x86.Build.0 = Debug|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|Any CPU.Build.0 = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|x64.ActiveCfg = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|x64.Build.0 = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|x86.ActiveCfg = Release|Any CPU
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{25F66C64-058A-4D44-BC0C-F12A054F9A91} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{FD0AFD44-7A93-4F9E-B5ED-72582392E435} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{42184546-E3CB-4D4F-9495-43979B9C63B9} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F0A83301-50A5-40EA-A1A2-07C7858F5A3F} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{AA003372-CD8D-4DBC-962C-F61E0C93CF05} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{7E8CC864-4C6E-496F-A672-9F9AD8874835} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F3C41B82-6A67-409A-B7FE-54543EE4F38B} = {FB8BC3A2-2010-4C3C-A87D-D4A98C05EE52}
{5B2D251F-46E3-486A-AE16-E3FE06B559ED} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{23615A39-F3FB-4575-A91C-535899DFB636} = {94207AA6-4923-4183-A558-E0F8196B8CA3}
{F754F05E-02FF-47B2-AB46-BB05C7E6B29D} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
{0348CFDA-4DA1-4DB5-9C6F-0D234FE3E4DA} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
{2E4CC21D-3AB9-4B8C-A13E-348AA3E2F328} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {02F2E872-3141-44F5-BD6A-33CD84E9FE08}
EndGlobalSection
EndGlobal

43
backend/Squidex.slnx

@ -0,0 +1,43 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Folder Name="/data/">
<Project Path="src/Squidex.Data.EntityFramework/Squidex.Data.EntityFramework.csproj" />
<Project Path="src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj" />
<Project Path="tests/Squidex.Data.Tests.CodeGenerator/Squidex.Data.Tests.CodeGenerator.csproj" />
<Project Path="tests/Squidex.Data.Tests/Squidex.Data.Tests.csproj" />
</Folder>
<Folder Name="/domain/">
<Project Path="src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj" />
<Project Path="src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj" />
<Project Path="src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj" />
<Project Path="src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj" />
<Project Path="tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj" />
<Project Path="tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj" />
</Folder>
<Folder Name="/extensions/">
<Project Path="extensions/Squidex.Extensions/Squidex.Extensions.csproj" />
</Folder>
<Folder Name="/infrastructure/">
<Project Path="src/Squidex.Infrastructure/Squidex.Infrastructure.csproj" />
<Project Path="tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj" />
</Folder>
<Folder Name="/shared/">
<Project Path="src/Squidex.Domain.Users/Squidex.Domain.Users.csproj" />
<Project Path="src/Squidex.Shared/Squidex.Shared.csproj" />
<Project Path="src/Squidex.Web/Squidex.Web.csproj" />
<Project Path="tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj" />
<Project Path="tests/Squidex.Web.Tests/Squidex.Web.Tests.csproj" />
</Folder>
<Folder Name="/Solution Items/">
<File Path="Squidex.ruleset" />
<File Path="stylecop.json" />
</Folder>
<Folder Name="/tools/">
<Project Path="src/Migrations/Migrations.csproj" />
</Folder>
<Project Path="src/Squidex/Squidex.csproj" />
</Solution>

37
backend/extensions/Squidex.Extensions/APM/Zipkin/ZipkinPlugin.cs

@ -1,37 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Trace;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.APM.Zipkin;
public sealed class ZipkinPlugin : IPlugin
{
private sealed class Configurator(IConfiguration config) : ITelemetryConfigurator
{
public void Configure(TracerProviderBuilder builder)
{
builder.AddZipkinExporter(options =>
{
config.GetSection("logging:zipkin").Bind(options);
});
}
}
public void ConfigureServices(IServiceCollection services, IConfiguration config)
{
if (config.GetValue<bool>("logging:zipkin:enabled"))
{
services.AddSingleton<ITelemetryConfigurator,
Configurator>();
}
}
}

7
backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs

@ -96,7 +96,10 @@ public sealed class KafkaProducer
break;
}
log.Log(level, "Kafka log {name}: {message}.", message.Name, message.Message);
if (log.IsEnabled(level))
{
log.Log(level, "Kafka log {name}: {message}.", message.Name, message.Message);
}
}
private static void LogError(ILogger<KafkaProducer> log, Error error)
@ -279,4 +282,4 @@ public sealed class KafkaProducer
return schema?.Tag == expected || (schema is UnionSchema union && union.Schemas.Any(x => x.Tag == expected));
}
}
#endif
#endif

37
backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -11,34 +11,35 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Algolia.Search" Version="6.17.0" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.3.0" />
<PackageReference Include="Azure.Search.Documents" Version="11.6.0" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.6.0" />
<PackageReference Include="Azure.Search.Documents" Version="11.7.0" />
<PackageReference Include="CoreTweet" Version="1.0.0.483" />
<PackageReference Include="Elasticsearch.Net" Version="7.17.5" />
<PackageReference Include="Google.Cloud.Diagnostics.Common" Version="5.2.0" />
<PackageReference Include="Google.Cloud.Logging.V2" Version="4.4.0" />
<PackageReference Include="Google.Cloud.Monitoring.V3" Version="3.11.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Google.Cloud.Diagnostics.Common" Version="5.3.0" />
<PackageReference Include="Google.Cloud.Logging.V2" Version="4.5.0" />
<PackageReference Include="Google.Cloud.Monitoring.V3" Version="3.16.0" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Azure.CognitiveServices.Vision.ComputerVision" Version="7.0.1" />
<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.28.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="Microsoft.OData.Core" Version="8.2.1" />
<PackageReference Include="NodaTime" Version="3.2.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.33.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.5" />
<PackageReference Include="Microsoft.OData.Core" Version="8.4.3" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="2.3.24" />
<PackageReference Include="NodaTime" Version="3.3.1" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="OpenSearch.Net" Version="1.8.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.OpenTelemetry.Exporter.Stackdriver" Version="0.0.0-alpha.0.395" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" />
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
</ItemGroup>
<ItemGroup Condition="'$(IncludeKafka)' == 'true'">

5
backend/global.json

@ -1,5 +0,0 @@
{
"sdk": {
"version": "8.0.416"
}
}

2
backend/i18n/translator/Squidex.Translator/Squidex.Translator.csproj

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>NU1608</NoWarn>

6
backend/src/Migrations/Migrations.csproj

@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
</ItemGroup>

3
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Apps/EFAppRepository.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using Squidex.Domain.Apps.Core.Apps;
@ -101,7 +100,7 @@ public sealed class EFAppRepository<TContext>(IDbContextFactory<TContext> dbCont
return byName.Values.ToList();
}
protected override Expression<Func<SetPropertyCalls<EFAppEntity>, SetPropertyCalls<EFAppEntity>>> BuildUpdate(EFAppEntity entity)
protected override Action<UpdateSettersBuilder<EFAppEntity>> BuildUpdate(EFAppEntity entity)
{
return u => u
.SetProperty(x => x.Document, entity.Document)

2
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Assets/EFAssetFolderRepository_SnapshotStore.cs

@ -113,7 +113,7 @@ public sealed partial class EFAssetFolderRepository<TContext> : ISnapshotStore<A
return dbContextFactory.CreateDbContextAsync(ct);
}
private static Expression<Func<SetPropertyCalls<EFAssetFolderEntity>, SetPropertyCalls<EFAssetFolderEntity>>> BuildUpdate(EFAssetFolderEntity entity)
private static Action<UpdateSettersBuilder<EFAssetFolderEntity>> BuildUpdate(EFAssetFolderEntity entity)
{
return b => b
.SetProperty(x => x.AppId, entity.AppId)

2
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Assets/EFAssetRepository_SnapshotStore.cs

@ -108,7 +108,7 @@ public sealed partial class EFAssetRepository<TContext> : ISnapshotStore<Asset>,
}
}
private static Expression<Func<SetPropertyCalls<EFAssetEntity>, SetPropertyCalls<EFAssetEntity>>> BuildUpdate(EFAssetEntity entity)
private static Action<UpdateSettersBuilder<EFAssetEntity>> BuildUpdate(EFAssetEntity entity)
{
return b => b
.SetProperty(x => x.AppId, entity.AppId)

2
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Contents/Extensions.cs

@ -54,7 +54,7 @@ internal static class Extensions
}
}
public static Expression<Func<SetPropertyCalls<T>, SetPropertyCalls<T>>> BuildUpdate<T>(T entity) where T : EFContentEntity
public static Action<UpdateSettersBuilder<T>> BuildUpdate<T>(T entity) where T : EFContentEntity
{
return b => b
.SetProperty(x => x.AppId, entity.AppId)

2
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Schemas/EFSchemaRepository.cs

@ -106,7 +106,7 @@ public sealed class EFSchemaRepository<TContext>(IDbContextFactory<TContext> dbC
}
}
protected override Expression<Func<SetPropertyCalls<EFSchemaEntity>, SetPropertyCalls<EFSchemaEntity>>> BuildUpdate(EFSchemaEntity entity)
protected override Action<UpdateSettersBuilder<EFSchemaEntity>> BuildUpdate(EFSchemaEntity entity)
{
return u => u
.SetProperty(x => x.Document, entity.Document)

2
backend/src/Squidex.Data.EntityFramework/Domain/Apps/Entities/Teams/EFTeamRepository.cs

@ -70,7 +70,7 @@ public sealed class EFTeamRepository<TContext>(IDbContextFactory<TContext> dbCon
}
}
protected override Expression<Func<SetPropertyCalls<EFTeamEntity>, SetPropertyCalls<EFTeamEntity>>> BuildUpdate(EFTeamEntity entity)
protected override Action<UpdateSettersBuilder<EFTeamEntity>> BuildUpdate(EFTeamEntity entity)
{
return u => u
.SetProperty(x => x.Document, entity.Document)

2
backend/src/Squidex.Data.EntityFramework/Infrastructure/BulkInserter.cs

@ -24,6 +24,6 @@ public sealed class BulkInserter : IDbFlowsBulkInserter, IDbEventStoreBulkInsert
public Task BulkUpsertAsync<T>(DbContext dbContext, IEnumerable<T> entities,
CancellationToken ct = default) where T : class
{
return dbContext.ExecuteBulkInsertAsync(entities, o => { }, new OnConflictOptions<T> { Update = e => e }, ct);
return dbContext.ExecuteBulkInsertAsync(entities, o => { }, new OnConflictOptions<T> { Update = (lhs, rhs) => lhs }, ct);
}
}

4
backend/src/Squidex.Data.EntityFramework/Infrastructure/Extensions.cs

@ -93,7 +93,7 @@ public static class Extensions
return Task.CompletedTask;
}
return dbContext.ExecuteBulkInsertAsync(source, o => { }, new OnConflictOptions<T> { Update = e => e }, ct);
return dbContext.ExecuteBulkInsertAsync(source, o => { }, new OnConflictOptions<T> { Update = (lhs, rhs) => lhs }, ct);
}
public static Task BulkInsertAsync<T>(this DbContext dbContext, List<T> source,
@ -173,7 +173,7 @@ public static class Extensions
}
public static async Task UpsertAsync<T>(this DbContext dbContext, T entity, long oldVersion,
Func<T, Expression<Func<SetPropertyCalls<T>, SetPropertyCalls<T>>>> update,
Func<T, Action<UpdateSettersBuilder<T>>> update,
CancellationToken ct) where T : class, IVersionedEntity<DomainId>
{
var dbSet = dbContext.Set<T>();

2
backend/src/Squidex.Data.EntityFramework/Infrastructure/States/EFSnapshotStore.cs

@ -114,7 +114,7 @@ public class EFSnapshotStore<TContext, T, TState>(IDbContextFactory<TContext> db
return dbContextFactory.CreateDbContextAsync(ct);
}
protected virtual Expression<Func<SetPropertyCalls<TState>, SetPropertyCalls<TState>>> BuildUpdate(TState entity)
protected virtual Action<UpdateSettersBuilder<TState>> BuildUpdate(TState entity)
{
return u => u
.SetProperty(x => x.Document, entity.Document)

1628
backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/20260323154443_MigrateToNet10.Designer.cs

File diff suppressed because it is too large

46
backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/20260323154443_MigrateToNet10.cs

@ -0,0 +1,46 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Squidex.Providers.MySql.App.Migrations
{
/// <inheritdoc />
public partial class MigrateToNet10 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "varchar(255)",
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(255)")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "OpenIddictAuthorizations",
keyColumn: "ApplicationId",
keyValue: null,
column: "ApplicationId",
value: "");
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "varchar(255)",
nullable: false,
oldClrType: typeof(string),
oldType: "varchar(255)",
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
}
}

7
backend/src/Squidex.Data.EntityFramework/Providers/MySql/App/Migrations/MySqlDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace Squidex.Providers.MySql.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.16")
.HasAnnotation("ProductVersion", "10.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
@ -226,7 +226,6 @@ namespace Squidex.Providers.MySql.Migrations
.HasColumnType("varchar(255)");
b.Property<string>("ApplicationId")
.IsRequired()
.HasColumnType("varchar(255)");
b.Property<string>("ConcurrencyToken")
@ -322,7 +321,7 @@ namespace Squidex.Providers.MySql.Migrations
b.ToTable("OpenIddictTokens", (string)null);
});
modelBuilder.Entity("Squidex.AI.Mongo.EFChatEntity", b =>
modelBuilder.Entity("Squidex.AI.EntityFramework.EFChatEntity", b =>
{
b.Property<string>("Id")
.HasMaxLength(255)
@ -1103,7 +1102,7 @@ namespace Squidex.Providers.MySql.Migrations
b.Property<long>("EventStreamOffset")
.HasColumnType("bigint");
b.Property<string>("Events")
b.PrimitiveCollection<string>("Events")
.IsRequired()
.HasColumnType("longtext");

5
backend/src/Squidex.Data.EntityFramework/Providers/MySql/Content/JsonFunction.cs

@ -1,5 +0,0 @@
namespace Squidex.Providers.MySql.Content;
public static class JsonFunction
{
}

2
backend/src/Squidex.Data.EntityFramework/Providers/MySql/JsonFunction.cs

@ -18,7 +18,7 @@ public static class JsonFunction
private const int TypeBoolean = 3;
private const int TypeNumber = 4;
private static readonly Dictionary<(int Type, CompareOperator Operator), string> Functions = new()
private static readonly Dictionary<(int Type, CompareOperator Operator), string> Functions = new ()
{
[(TypeAny, CompareOperator.Empty)] = "json_empty",
[(TypeAny, CompareOperator.Exists)] = "json_exists",

1629
backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/20260323155026_MigrateToNet10.Designer.cs

File diff suppressed because it is too large

36
backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/20260323155026_MigrateToNet10.cs

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Squidex.Providers.Postgres.App.Migrations
{
/// <inheritdoc />
public partial class MigrateToNet10 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "text",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "text",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true);
}
}
}

7
backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/Migrations/PostgresDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace Squidex.Providers.Postgres.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.16")
.HasAnnotation("ProductVersion", "10.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
@ -227,7 +227,6 @@ namespace Squidex.Providers.Postgres.Migrations
.HasColumnType("text");
b.Property<string>("ApplicationId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ConcurrencyToken")
@ -323,7 +322,7 @@ namespace Squidex.Providers.Postgres.Migrations
b.ToTable("OpenIddictTokens", (string)null);
});
modelBuilder.Entity("Squidex.AI.Mongo.EFChatEntity", b =>
modelBuilder.Entity("Squidex.AI.EntityFramework.EFChatEntity", b =>
{
b.Property<string>("Id")
.HasMaxLength(255)
@ -1104,7 +1103,7 @@ namespace Squidex.Providers.Postgres.Migrations
b.Property<long>("EventStreamOffset")
.HasColumnType("bigint");
b.Property<string[]>("Events")
b.PrimitiveCollection<string[]>("Events")
.IsRequired()
.HasColumnType("text[]");

2
backend/src/Squidex.Data.EntityFramework/Providers/Postgres/App/PostgresAppDbContextDesignTimeFactory.cs

@ -16,7 +16,7 @@ public sealed class PostgresAppDbContextDesignTimeFactory : IDesignTimeDbContext
{
public PostgresAppDbContext CreateDbContext(string[] args)
{
const string ConnectionString = "Server=localhost;Port=54320;Database=test;User=postgres;Password=postgres";
const string ConnectionString = "Server=localhost;Port=54320;Database=test;Username=postgres;Password=postgres";
var builder = new DbContextOptionsBuilder<PostgresAppDbContext>()
.UseNpgsql(ConnectionString, options =>

1631
backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/20260323155035_MigrateToNet10.Designer.cs

File diff suppressed because it is too large

36
backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/20260323155035_MigrateToNet10.cs

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Squidex.Providers.SqlServer.App.Migrations
{
/// <inheritdoc />
public partial class MigrateToNet10 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "nvarchar(450)",
nullable: true,
oldClrType: typeof(string),
oldType: "nvarchar(450)");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ApplicationId",
table: "OpenIddictAuthorizations",
type: "nvarchar(450)",
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "nvarchar(450)",
oldNullable: true);
}
}
}

7
backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/Migrations/SqlServerDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace Squidex.Providers.SqlServer.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.16")
.HasAnnotation("ProductVersion", "10.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -228,7 +228,6 @@ namespace Squidex.Providers.SqlServer.Migrations
.HasColumnType("nvarchar(450)");
b.Property<string>("ApplicationId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyToken")
@ -325,7 +324,7 @@ namespace Squidex.Providers.SqlServer.Migrations
b.ToTable("OpenIddictTokens", (string)null);
});
modelBuilder.Entity("Squidex.AI.Mongo.EFChatEntity", b =>
modelBuilder.Entity("Squidex.AI.EntityFramework.EFChatEntity", b =>
{
b.Property<string>("Id")
.HasMaxLength(255)
@ -1106,7 +1105,7 @@ namespace Squidex.Providers.SqlServer.Migrations
b.Property<long>("EventStreamOffset")
.HasColumnType("bigint");
b.Property<string>("Events")
b.PrimitiveCollection<string>("Events")
.IsRequired()
.HasColumnType("nvarchar(max)");

2
backend/src/Squidex.Data.EntityFramework/Providers/SqlServer/App/SqlServerAppDbContextDesignTimeFactory.cs

@ -16,7 +16,7 @@ public sealed class SqlServerAppDbContextDesignTimeFactory : IDesignTimeDbContex
{
public SqlServerAppDbContext CreateDbContext(string[] args)
{
const string ConnectionString = "Server=localhost;Port=14330;Database=test;User=sa;Password=sqlserver";
const string ConnectionString = "Server=localhost;Port=14330;Database=test;User=sa;Password=SqlServer2026!?";
var builder = new DbContextOptionsBuilder<SqlServerAppDbContext>()
.UseSqlServer(ConnectionString, options =>

10
backend/src/Squidex.Data.EntityFramework/ServiceExtensions.cs

@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -99,6 +100,9 @@ public static class ServiceExtensions
options.MigrationsHistoryTable($"{name}MigrationHistory");
options.UseMicrosoftJson(MySqlCommonJsonChangeTrackingOptions.FullHierarchyOptimizedSemantically);
});
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
});
services.AddSingleton(typeof(ISnapshotStore<>), typeof(MySqlSnapshotStore<>));
@ -130,6 +134,9 @@ public static class ServiceExtensions
{
options.MigrationsHistoryTable($"{name}MigrationHistory");
});
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
});
services.AddSingleton(typeof(ISnapshotStore<>), typeof(PostgresSnapshotStore<>));
@ -161,6 +168,9 @@ public static class ServiceExtensions
{
options.MigrationsHistoryTable($"{name}MigrationHistory");
});
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
});
services.AddSingleton(typeof(ISnapshotStore<>), typeof(SqlServerSnapshotStore<>));

56
backend/src/Squidex.Data.EntityFramework/Squidex.Data.EntityFramework.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>Squidex</RootNamespace>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
@ -19,41 +19,41 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite" Version="8.0.16" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.16" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" Version="8.0.11" />
<PackageReference Include="Npgsql.OpenTelemetry" Version="8.0.7" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.MySql" Version="0.2.3" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.PostgreSql" Version="0.2.3" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.SqlServer" Version="0.2.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Json.Microsoft" Version="8.0.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql.NetTopologySuite" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.5" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" Version="10.0.1" />
<PackageReference Include="Npgsql.OpenTelemetry" Version="10.0.2" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.MySql" Version="0.5.0" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.PostgreSql" Version="0.5.0" />
<PackageReference Include="PhenX.EntityFrameworkCore.BulkInsert.SqlServer" Version="0.5.0" />
<PackageReference Include="Microting.EntityFrameworkCore.MySql" Version="10.0.5" />
<PackageReference Include="Microting.EntityFrameworkCore.MySql.Json.Microsoft" Version="10.0.5" />
<PackageReference Include="Microting.EntityFrameworkCore.MySql.NetTopologySuite" Version="10.0.5" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.AI.EntityFramework" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.EntityFramework" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.TusAdapter" Version="7.37.0" />
<PackageReference Include="Squidex.Events.EntityFramework" Version="7.37.0" />
<PackageReference Include="Squidex.Flows.EntityFramework" Version="7.37.0" />
<PackageReference Include="Squidex.Hosting" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.EntityFramework" Version="7.37.0" />
<PackageReference Include="Squidex.OpenIdDict.EntityFramework" Version="5.8.4" />
<PackageReference Include="Squidex.AI.EntityFramework" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.EntityFramework" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.TusAdapter" Version="8.0.0" />
<PackageReference Include="Squidex.Events.EntityFramework" Version="8.0.0" />
<PackageReference Include="Squidex.Flows.EntityFramework" Version="8.0.0" />
<PackageReference Include="Squidex.Hosting" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging.EntityFramework" Version="8.0.0" />
<PackageReference Include="Squidex.OpenIdDict.EntityFramework" Version="7.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="YDotNet.Server.EntityFramework" Version="0.4.3" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" />
<PackageReference Include="YDotNet.Server.EntityFramework" Version="0.6.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />

4
backend/src/Squidex.Data.EntityFramework/docker-compose.yml

@ -9,7 +9,7 @@ services:
- "54320:5432"
migration_mysql:
image: mysql
image: mysql:8
environment:
- MYSQL_DATABASE=test
- MYSQL_USER=mysql
@ -23,7 +23,7 @@ services:
migration_sqlserver:
image: mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04
environment:
- SA_PASSWORD=sqlserver
- SA_PASSWORD=SqlServer2026!?
- ACCEPT_EULA=Y
ports:
- "14330:1433"

6
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetEntity.cs

@ -21,9 +21,7 @@ public record MongoAssetEntity : Asset, IVersionedEntity<DomainId>
public static void RegisterClassMap()
{
AssetItemClassMap.Register();
BsonClassMap.TryRegisterClassMap<MongoAssetEntity>(cm =>
BsonClassMap.RegisterClassMap<MongoAssetEntity>(cm =>
{
cm.MapProperty(x => x.DocumentId)
.SetElementName("_id")
@ -34,7 +32,7 @@ public record MongoAssetEntity : Asset, IVersionedEntity<DomainId>
.SetIsRequired(true);
});
BsonClassMap.TryRegisterClassMap<Asset>(cm =>
BsonClassMap.RegisterClassMap<Asset>(cm =>
{
cm.MapProperty(x => x.FileName)
.SetElementName("fn")

6
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderEntity.cs

@ -21,7 +21,7 @@ public record MongoAssetFolderEntity : AssetFolder, IVersionedEntity<DomainId>
public static void RegisterClassMap()
{
BsonClassMap.TryRegisterClassMap<MongoAssetFolderEntity>(cm =>
BsonClassMap.RegisterClassMap<MongoAssetFolderEntity>(cm =>
{
cm.MapProperty(x => x.DocumentId)
.SetElementName("_id")
@ -32,14 +32,12 @@ public record MongoAssetFolderEntity : AssetFolder, IVersionedEntity<DomainId>
.SetIsRequired(true);
});
BsonClassMap.TryRegisterClassMap<AssetFolder>(cm =>
BsonClassMap.RegisterClassMap<AssetFolder>(cm =>
{
cm.MapProperty(x => x.FolderName)
.SetElementName("fn")
.SetIsRequired(true);
});
AssetItemClassMap.Register();
}
public static MongoAssetFolderEntity Create(SnapshotWriteJob<AssetFolder> job)

5
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository.cs

@ -15,11 +15,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
public sealed partial class MongoAssetFolderRepository(IMongoDatabase database) : MongoRepositoryBase<MongoAssetFolderEntity>(database), IAssetFolderRepository
{
static MongoAssetFolderRepository()
{
MongoAssetFolderEntity.RegisterClassMap();
}
protected override string CollectionName()
{
return "States_AssetFolders2";

2
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository_SnapshotStore.cs

@ -57,7 +57,7 @@ public sealed partial class MongoAssetFolderRepository : ISnapshotStore<AssetFol
{
var entityJob = job.As(MongoAssetFolderEntity.Create(job));
await Collection.UpsertVersionedAsync(entityJob, Field.Of<AssetFolder>(x => nameof(x.Version)), ct);
await Collection.UpsertVersionedAsync(entityJob, Field.Of<MongoAssetFolderEntity>(x => nameof(x.Version)), ct);
}
}

8
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/AssetItemClassMap.cs → backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetItemClassMap.cs

@ -10,13 +10,11 @@ using Squidex.Domain.Apps.Core.Assets;
namespace Squidex.Domain.Apps.Entities.Assets;
internal static class AssetItemClassMap
internal static class MongoAssetItemClassMap
{
public static void Register()
public static void RegisterClassMap()
{
AppEntityClassMap.Register();
BsonClassMap.TryRegisterClassMap<AssetItem>(cm =>
BsonClassMap.RegisterClassMap<AssetItem>(cm =>
{
cm.MapProperty(x => x.ParentId)
.SetElementName("pi")

5
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository.cs

@ -24,11 +24,6 @@ public sealed partial class MongoAssetRepository : MongoRepositoryBase<MongoAsse
private readonly MongoCountCollection countCollection;
private readonly string shardKey;
static MongoAssetRepository()
{
MongoAssetEntity.RegisterClassMap();
}
public MongoAssetRepository(IMongoDatabase database, ILogger<MongoAssetRepository> log, string shardKey)
: base(database)
{

2
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository_SnapshotStore.cs

@ -57,7 +57,7 @@ public sealed partial class MongoAssetRepository : ISnapshotStore<Asset>, IDelet
{
var entityJob = job.As(MongoAssetEntity.Create(job));
await Collection.UpsertVersionedAsync(entityJob, Field.Of<Asset>(x => nameof(x.Version)), ct);
await Collection.UpsertVersionedAsync(entityJob, Field.Of<MongoAssetEntity>(x => nameof(x.Version)), ct);
}
}

8
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentEntity.cs

@ -34,9 +34,7 @@ public record MongoContentEntity : Content, IVersionedEntity<DomainId>
public static void RegisterClassMap()
{
AppEntityClassMap.Register();
BsonClassMap.TryRegisterClassMap<MongoContentEntity>(cm =>
BsonClassMap.RegisterClassMap<MongoContentEntity>(cm =>
{
cm.MapProperty(x => x.DocumentId)
.SetElementName("_id")
@ -71,7 +69,7 @@ public record MongoContentEntity : Content, IVersionedEntity<DomainId>
.SetIgnoreIfDefault(true);
});
BsonClassMap.TryRegisterClassMap<Content>(cm =>
BsonClassMap.RegisterClassMap<Content>(cm =>
{
cm.MapProperty(x => x.SchemaId)
.SetElementName("si")
@ -93,8 +91,6 @@ public record MongoContentEntity : Content, IVersionedEntity<DomainId>
.SetElementName("sj")
.SetIgnoreIfDefault(true);
});
EntityClassMap.Register();
}
public WriteContent ToState()

9
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository.cs

@ -49,15 +49,6 @@ public partial class MongoContentRepository(
public bool CanUseTransactions { get; private set; }
static MongoContentRepository()
{
BsonEscapedDictionarySerializer<JsonValue, JsonObject>.Register();
BsonEscapedDictionarySerializer<JsonValue, ContentFieldData>.Register();
BsonEscapedDictionarySerializer<ContentFieldData, ContentData>.Register();
BsonStringSerializer<Status>.Register();
MongoContentEntity.RegisterClassMap();
}
public async Task InitializeAsync(
CancellationToken ct)
{

2
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/AtlasTextIndex.cs

@ -25,7 +25,7 @@ public sealed class AtlasTextIndex(IMongoDatabase database, IHttpClientFactory a
private static readonly LuceneQueryVisitor QueryVisitor = new LuceneQueryVisitor(AtlasIndexDefinition.GetFieldPath);
private static readonly LuceneQueryAnalyzer QueryParser =
new LuceneQueryAnalyzer(LuceneVersion.LUCENE_48, "*",
new StandardAnalyzer(LuceneVersion.LUCENE_48, CharArraySet.EMPTY_SET));
new StandardAnalyzer(LuceneVersion.LUCENE_48, CharArraySet.Empty));
private readonly AtlasOptions atlasOptions = atlasOptions.Value;
private string index;

15
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/MongoTextIndexerState.cs

@ -5,13 +5,11 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Contents.Text.State;
using Squidex.Domain.Apps.Entities.MongoDb;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Contents.Text;
@ -21,19 +19,6 @@ public sealed class MongoTextIndexerState(
IContentRepository contentRepository)
: MongoRepositoryBase<TextContentState>(database), ITextIndexerState, IDeleter
{
static MongoTextIndexerState()
{
BsonUniqueContentIdSerializer.Register();
BsonClassMap.TryRegisterClassMap<TextContentState>(cm =>
{
cm.MapIdProperty(x => x.UniqueContentId);
cm.MapProperty(x => x.State)
.SetElementName("s");
});
}
int IDeleter.Order => -2000;
protected override string CollectionName()

25
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/MongoTextStateClassMap.cs

@ -0,0 +1,25 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Bson.Serialization;
using Squidex.Domain.Apps.Entities.Contents.Text.State;
namespace Squidex.Domain.Apps.Entities.Contents.Text;
internal static class MongoTextStateClassMap
{
public static void RegisterClassMap()
{
BsonClassMap.RegisterClassMap<TextContentState>(cm =>
{
cm.MapIdProperty(x => x.UniqueContentId);
cm.MapProperty(x => x.State)
.SetElementName("s");
});
}
}

27
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryClassMap.cs

@ -0,0 +1,27 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Bson.Serialization;
namespace Squidex.Domain.Apps.Entities.History;
internal static class MongoHistoryClassMap
{
public static void RegisterClassMap()
{
BsonClassMap.RegisterClassMap<HistoryEvent>(cm =>
{
cm.AutoMap();
cm.MapProperty(x => x.OwnerId)
.SetElementName("AppId");
cm.MapProperty(x => x.EventType)
.SetElementName("Message");
});
}
}

10
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryEventRepository.cs

@ -17,16 +17,6 @@ public sealed class MongoHistoryEventRepository(IMongoDatabase database) : Mongo
{
static MongoHistoryEventRepository()
{
BsonClassMap.TryRegisterClassMap<HistoryEvent>(cm =>
{
cm.AutoMap();
cm.MapProperty(x => x.OwnerId)
.SetElementName("AppId");
cm.MapProperty(x => x.EventType)
.SetElementName("Message");
});
}
protected override string CollectionName()

8
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/AppEntityClassMap.cs → backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/MongoAppEntityClassMap.cs

@ -10,13 +10,11 @@ using Squidex.Domain.Apps.Core;
namespace Squidex.Domain.Apps.Entities;
public static class AppEntityClassMap
public static class MongoAppEntityClassMap
{
public static void Register()
public static void RegisterClassMap()
{
EntityClassMap.Register();
BsonClassMap.TryRegisterClassMap<AppEntity>(cm =>
BsonClassMap.RegisterClassMap<AppEntity>(cm =>
{
cm.MapProperty(x => x.AppId)
.SetElementName("ai")

6
backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/EntityClassMap.cs → backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/MongoEntityClassMap.cs

@ -10,11 +10,11 @@ using Squidex.Infrastructure.Commands;
namespace Squidex.Domain.Apps.Entities;
internal static class EntityClassMap
internal static class MongoEntityClassMap
{
public static void Register()
public static void RegisterClassMap()
{
BsonClassMap.TryRegisterClassMap<Entity>(cm =>
BsonClassMap.RegisterClassMap<Entity>(cm =>
{
cm.MapProperty(x => x.Id)
.SetElementName("id")

37
backend/src/Squidex.Data.MongoDb/Domain/Users/IdentityUserForwardingSerializer.cs

@ -0,0 +1,37 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.AspNetCore.Identity;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
namespace Squidex.Domain.Users;
internal sealed class IdentityUserForwardingSerializer
: SerializerBase<IdentityUser>, IBsonDocumentSerializer
{
private static readonly IBsonSerializer<MongoUser> MongoUserSerializer =
BsonSerializer.LookupSerializer<MongoUser>();
public override IdentityUser Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
args.NominalType = typeof(MongoUser);
return MongoUserSerializer.Deserialize(context, args);
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, IdentityUser value)
{
args.NominalType = typeof(MongoUser);
MongoUserSerializer.Serialize(context, args, (MongoUser)value);
}
public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
{
return ((IBsonDocumentSerializer)MongoUserSerializer)
.TryGetMemberSerializationInfo(memberName, out serializationInfo);
}
}

116
backend/src/Squidex.Data.MongoDb/Domain/Users/MongoIdentityClassMap.cs

@ -0,0 +1,116 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
namespace Squidex.Domain.Users;
internal static class MongoIdentityClassMap
{
public static void RegisterClassMap()
{
BsonClassMap.RegisterClassMap<IdentityRole<string>>(cm =>
{
cm.AutoMap();
cm.MapMember(x => x.Id)
.SetSerializer(new StringSerializer(BsonType.ObjectId));
cm.UnmapMember(x => x.ConcurrencyStamp);
});
BsonClassMap.RegisterClassMap<Claim>(cm =>
{
cm.MapConstructor(typeof(Claim).GetConstructors()
.First(x =>
{
var parameters = x.GetParameters();
return parameters.Length == 2 &&
parameters[0].Name == "type" &&
parameters[0].ParameterType == typeof(string) &&
parameters[1].Name == "value" &&
parameters[1].ParameterType == typeof(string);
}))
.SetArguments(
[
nameof(Claim.Type),
nameof(Claim.Value),
]);
cm.MapMember(x => x.Type);
cm.MapMember(x => x.Value);
});
BsonClassMap.RegisterClassMap<UserLogin>(cm =>
{
cm.MapConstructor(typeof(UserLogin).GetConstructors()
.First(x =>
{
var parameters = x.GetParameters();
return parameters.Length == 3;
}))
.SetArguments(
[
nameof(UserLogin.LoginProvider),
nameof(UserLogin.ProviderKey),
nameof(UserLogin.ProviderDisplayName),
]);
cm.AutoMap();
});
BsonClassMap.RegisterClassMap<IdentityUserToken<string>>(cm =>
{
cm.AutoMap();
cm.UnmapMember(x => x.UserId);
});
BsonClassMap.RegisterClassMap<IdentityUser<string>>(cm =>
{
cm.AutoMap();
cm.MapMember(x => x.Id)
.SetSerializer(new StringSerializer(BsonType.ObjectId));
cm.MapMember(x => x.AccessFailedCount)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.EmailConfirmed)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.LockoutEnd)
.SetElementName("LockoutEndDateUtc").SetIgnoreIfNull(true);
cm.MapMember(x => x.LockoutEnabled)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.PasswordHash)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.PhoneNumber)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.PhoneNumberConfirmed)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.SecurityStamp)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.TwoFactorEnabled)
.SetIgnoreIfDefault(true);
});
BsonSerializer.RegisterSerializer(new IdentityUserForwardingSerializer());
}
}

16
backend/src/Squidex.Data.MongoDb/Domain/Users/MongoRoleStore.cs

@ -6,9 +6,6 @@
// ==========================================================================
using Microsoft.AspNetCore.Identity;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
using Squidex.Infrastructure;
@ -16,19 +13,6 @@ namespace Squidex.Domain.Users;
public sealed class MongoRoleStore(IMongoDatabase database) : MongoRepositoryBase<IdentityRole>(database), IRoleStore<IdentityRole>
{
static MongoRoleStore()
{
BsonClassMap.RegisterClassMap<IdentityRole<string>>(cm =>
{
cm.AutoMap();
cm.MapMember(x => x.Id)
.SetSerializer(new StringSerializer(BsonType.ObjectId));
cm.UnmapMember(x => x.ConcurrencyStamp);
});
}
protected override string CollectionName()
{
return "Identity_Roles";

125
backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUserStore.cs

@ -8,8 +8,6 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
using Squidex.Infrastructure;
@ -35,93 +33,7 @@ public sealed class MongoUserStore(IMongoDatabase database) :
private const string InternalLoginProvider = "[AspNetUserStore]";
private const string AuthenticatorKeyTokenName = "AuthenticatorKey";
private const string RecoveryCodeTokenName = "RecoveryCodes";
static MongoUserStore()
{
BsonClassMap.RegisterClassMap<Claim>(cm =>
{
cm.MapConstructor(typeof(Claim).GetConstructors()
.First(x =>
{
var parameters = x.GetParameters();
return parameters.Length == 2 &&
parameters[0].Name == "type" &&
parameters[0].ParameterType == typeof(string) &&
parameters[1].Name == "value" &&
parameters[1].ParameterType == typeof(string);
}))
.SetArguments(new[]
{
nameof(Claim.Type),
nameof(Claim.Value),
});
cm.MapMember(x => x.Type);
cm.MapMember(x => x.Value);
});
BsonClassMap.RegisterClassMap<UserLogin>(cm =>
{
cm.MapConstructor(typeof(UserLogin).GetConstructors()
.First(x =>
{
var parameters = x.GetParameters();
return parameters.Length == 3;
}))
.SetArguments(new[]
{
nameof(UserLogin.LoginProvider),
nameof(UserLogin.ProviderKey),
nameof(UserLogin.ProviderDisplayName),
});
cm.AutoMap();
});
BsonClassMap.RegisterClassMap<IdentityUserToken<string>>(cm =>
{
cm.AutoMap();
cm.UnmapMember(x => x.UserId);
});
BsonClassMap.RegisterClassMap<IdentityUser<string>>(cm =>
{
cm.AutoMap();
cm.MapMember(x => x.Id)
.SetSerializer(new StringSerializer(BsonType.ObjectId));
cm.MapMember(x => x.AccessFailedCount)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.EmailConfirmed)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.LockoutEnd)
.SetElementName("LockoutEndDateUtc").SetIgnoreIfNull(true);
cm.MapMember(x => x.LockoutEnabled)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.PasswordHash)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.PhoneNumber)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.PhoneNumberConfirmed)
.SetIgnoreIfDefault(true);
cm.MapMember(x => x.SecurityStamp)
.SetIgnoreIfNull(true);
cm.MapMember(x => x.TwoFactorEnabled)
.SetIgnoreIfDefault(true);
});
}
private IMongoCollection<IdentityUser> queryableCollection;
protected override string CollectionName()
{
@ -165,7 +77,7 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public IQueryable<IdentityUser> Users
{
get => Collection.AsQueryable();
get => (queryableCollection ??= Database.GetCollection<IdentityUser>(CollectionName())).AsQueryable();
}
public bool IsId(string id)
@ -181,7 +93,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityUser?> FindByIdAsync(string userId,
CancellationToken cancellationToken)
{
var result = await Collection.Find(x => x.Id == userId).FirstOrDefaultAsync(cancellationToken);
var result =
await Collection.Find(x => x.Id == userId)
.FirstOrDefaultAsync(cancellationToken);
return result;
}
@ -189,7 +103,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityUser?> FindByEmailAsync(string normalizedEmail,
CancellationToken cancellationToken)
{
var result = await Collection.Find(x => x.NormalizedEmail == normalizedEmail).FirstOrDefaultAsync(cancellationToken);
var result =
await Collection.Find(x => x.NormalizedEmail == normalizedEmail)
.FirstOrDefaultAsync(cancellationToken);
return result;
}
@ -197,7 +113,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityUser?> FindByNameAsync(string normalizedUserName,
CancellationToken cancellationToken)
{
var result = await Collection.Find(x => x.NormalizedEmail == normalizedUserName).FirstOrDefaultAsync(cancellationToken);
var result =
await Collection.Find(x => x.NormalizedEmail == normalizedUserName)
.FirstOrDefaultAsync(cancellationToken);
return result;
}
@ -205,7 +123,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityUser?> FindByLoginAsync(string loginProvider, string providerKey,
CancellationToken cancellationToken)
{
var result = await Collection.Find(Filter.ElemMatch(x => x.Logins, BuildFilter(loginProvider, providerKey))).FirstOrDefaultAsync(cancellationToken);
var result =
await Collection.Find(Filter.ElemMatch(x => x.Logins, BuildFilter(loginProvider, providerKey)))
.FirstOrDefaultAsync(cancellationToken);
return result;
}
@ -213,7 +133,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IList<IdentityUser>> GetUsersForClaimAsync(Claim claim,
CancellationToken cancellationToken)
{
var result = await Collection.Find(x => x.Claims.Exists(y => y.Type == claim.Type && y.Value == claim.Value)).ToListAsync(cancellationToken);
var result =
await Collection.Find(x => x.Claims.Exists(y => y.Type == claim.Type && y.Value == claim.Value))
.ToListAsync(cancellationToken);
return result.OfType<IdentityUser>().ToList();
}
@ -221,7 +143,9 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IList<IdentityUser>> GetUsersInRoleAsync(string roleName,
CancellationToken cancellationToken)
{
var result = await Collection.Find(x => x.Roles.Contains(roleName)).ToListAsync(cancellationToken);
var result =
await Collection.Find(x => x.Roles.Contains(roleName))
.ToListAsync(cancellationToken);
return result.OfType<IdentityUser>().ToList();
}
@ -231,7 +155,8 @@ public sealed class MongoUserStore(IMongoDatabase database) :
{
user.Id = ObjectId.GenerateNewId().ToString();
await Collection.InsertOneAsync((MongoUser)user, null, cancellationToken);
await Collection.InsertOneAsync((MongoUser)user, null,
cancellationToken);
return IdentityResult.Success;
}
@ -239,7 +164,8 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityResult> UpdateAsync(IdentityUser user,
CancellationToken cancellationToken)
{
await Collection.ReplaceOneAsync(x => x.Id == user.Id, (MongoUser)user, cancellationToken: cancellationToken);
await Collection.ReplaceOneAsync(x => x.Id == user.Id, (MongoUser)user,
cancellationToken: cancellationToken);
return IdentityResult.Success;
}
@ -247,7 +173,8 @@ public sealed class MongoUserStore(IMongoDatabase database) :
public async Task<IdentityResult> DeleteAsync(IdentityUser user,
CancellationToken cancellationToken)
{
await Collection.DeleteOneAsync(x => x.Id == user.Id, null, cancellationToken);
await Collection.DeleteOneAsync(x => x.Id == user.Id, null,
cancellationToken);
return IdentityResult.Success;
}

11
backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDomainIdSerializer.cs

@ -68,16 +68,7 @@ public sealed class BsonDomainIdSerializer : SerializerBase<DomainId>, IBsonPoly
case BsonType.Binary:
if (Guid.TryParse(value.ToString(), out var guid))
{
#pragma warning disable CS0618 // Type or member is obsolete
if (context.Writer.Settings.GuidRepresentation == GuidRepresentation.CSharpLegacy)
{
context.Writer.WriteBinaryData(new BsonBinaryData(guid.ToByteArray(), BsonBinarySubType.UuidLegacy, GuidRepresentation.CSharpLegacy));
}
else
{
context.Writer.WriteBinaryData(new BsonBinaryData(guid, GuidRepresentation.Standard));
}
#pragma warning restore CS0618 // Type or member is obsolete
context.Writer.WriteBinaryData(new BsonBinaryData(guid, GuidRepresentation.Standard));
}
else
{

37
backend/src/Squidex.Data.MongoDb/Infrastructure/MongoClientFactory.cs

@ -1,37 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Infrastructure;
public static class MongoClientFactory
{
public static MongoClient Create(string? connectionString, Action<MongoClientSettings>? configure = null)
{
BsonDefaultConventions.Register();
BsonDomainIdSerializer.Register();
BsonEscapedDictionarySerializer<JsonValue, JsonObject>.Register();
BsonInstantSerializer.Register();
BsonJsonValueSerializer.Register();
BsonStringSerializer<RefToken>.Register();
var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
// The current version of the linq provider has some issues with base classes.
#pragma warning disable CS0618 // Type or member is obsolete
clientSettings.LinqProvider = LinqProvider.V2;
#pragma warning restore CS0618 // Type or member is obsolete
// If we really need custom config.
configure?.Invoke(clientSettings);
return new MongoClient(clientSettings);
}
}

5
backend/src/Squidex.Data.MongoDb/Infrastructure/MongoExtensions.cs

@ -168,11 +168,6 @@ public static class MongoExtensions
var (key, snapshot, _, oldVersion) = job;
try
{
Expression<Func<T, bool>> filter2 =
oldVersion > EtagVersion.Any ?
x => x.DocumentId.Equals(key) && x.Version == oldVersion :
x => x.DocumentId.Equals(key);
var filter = filters.Eq(x => x.DocumentId, key);
if (oldVersion > EtagVersion.Any)

59
backend/src/Squidex.Data.MongoDb/MongoClientFactory.cs

@ -0,0 +1,59 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Text.Json;
using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Domain.Apps.Entities.History;
using Squidex.Domain.Apps.Entities.MongoDb;
using Squidex.Domain.Users;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex;
public static class MongoClientFactory
{
public static void SetupSerializer(JsonSerializerOptions jsonSerializerOptions, BsonType representation)
{
// Register the serializers first.
BsonDomainIdSerializer.Register();
BsonEscapedDictionarySerializer<JsonValue, JsonObject>.Register();
BsonInstantSerializer.Register();
BsonJsonValueSerializer.Register();
BsonStringSerializer<RefToken>.Register();
BsonUniqueContentIdSerializer.Register();
BsonJsonConvention.Register(jsonSerializerOptions, representation);
// Keep the order, because we have an inheritance between entities.
MongoEntityClassMap.RegisterClassMap();
MongoAppEntityClassMap.RegisterClassMap();
MongoAssetItemClassMap.RegisterClassMap();
MongoAssetEntity.RegisterClassMap();
MongoAssetFolderEntity.RegisterClassMap();
MongoContentEntity.RegisterClassMap();
MongoHistoryClassMap.RegisterClassMap();
MongoIdentityClassMap.RegisterClassMap();
MongoTextStateClassMap.RegisterClassMap();
BsonDefaultConventions.Register();
}
public static MongoClient Create(string? connectionString, Action<MongoClientSettings>? configure = null)
{
var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
// If we really need custom config.
configure?.Invoke(clientSettings);
return new MongoClient(clientSettings);
}
}

16
backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs

@ -70,7 +70,8 @@ public static class ServiceExtensions
services.AddSingletonAs(c =>
{
var options = c.GetRequiredService<IOptions<MongoEventStoreOptions>>();
var mongoClient = GetMongoClient(config, "eventStore:mongoDb");
var mongoClient = GetMongoClient(config, c.GetRequiredService<JsonSerializerOptions>(), "eventStore:mongoDb");
var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName);
return new MongoEventStore(mongoDatabase, options);
@ -85,7 +86,7 @@ public static class ServiceExtensions
services.AddMongoAssetStore(c =>
{
var mongoClient = GetMongoClient(config, "assetStore:mongoDb");
var mongoClient = GetMongoClient(config, c.GetRequiredService<JsonSerializerOptions>(), "assetStore:mongoDb");
var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName);
return new GridFSBucket<string>(mongoDatabase, new GridFSBucketOptions
@ -105,7 +106,7 @@ public static class ServiceExtensions
return GetDatabase(c, mongoDatabaseName);
});
services.AddSingletonAs(c => GetMongoClient(config, "store:mongoDb"))
services.AddSingletonAs(c => GetMongoClient(config, c.GetRequiredService<JsonSerializerOptions>(), "store:mongoDb"))
.As<IMongoClient>();
services.AddSingletonAs(c => GetDatabase(c, mongoDatabaseName))
@ -288,19 +289,24 @@ public static class ServiceExtensions
.As<IMigration>();
}
private static IMongoClient GetMongoClient(IConfiguration config, string prefix)
private static IMongoClient GetMongoClient(IConfiguration config, JsonSerializerOptions serializerOptions, string prefix)
{
var representation = config.GetValue<BsonType>("store:mongoDB:valueRepresentation");
var mongoConfiguration = config.GetRequiredValue($"{prefix}:configuration")!;
var mongoCertificate = config.GetValue<string>($"{prefix}:certificate");
var cacheKey = $"{mongoConfiguration}_{mongoCertificate}";
return Singletons<IMongoClient>.GetOrAdd(cacheKey, _ =>
{
MongoClientFactory.SetupSerializer(serializerOptions, representation);
return MongoClientFactory.Create(mongoConfiguration, settings =>
{
if (!string.IsNullOrWhiteSpace(mongoCertificate))
{
var certFile = new X509Certificate2(mongoCertificate);
var certFile = X509CertificateLoader.LoadCertificateFromFile(mongoCertificate);
settings.SslSettings = new SslSettings
{

29
backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>Squidex</RootNamespace>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
@ -16,25 +16,24 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MongoDB.Driver" Version="2.30.0" />
<PackageReference Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="1.5.0" />
<PackageReference Include="MongoDB.Driver.GridFS" Version="2.30.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="MongoDB.Driver" Version="3.7.1" />
<PackageReference Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="3.0.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.AI.Mongo" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.Mongo" Version="7.37.0" />
<PackageReference Include="Squidex.Events.Mongo" Version="7.37.0" />
<PackageReference Include="Squidex.Flows.Mongo" Version="7.37.0" />
<PackageReference Include="Squidex.Hosting" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.Mongo" Version="7.37.0" />
<PackageReference Include="Squidex.OpenIddict.MongoDb" Version="5.8.5" />
<PackageReference Include="Squidex.AI.Mongo" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.Mongo" Version="8.0.0" />
<PackageReference Include="Squidex.Events.Mongo" Version="8.0.0" />
<PackageReference Include="Squidex.Flows.Mongo" Version="8.0.0" />
<PackageReference Include="Squidex.Hosting" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging.Mongo" Version="8.0.0" />
<PackageReference Include="Squidex.OpenIddict.MongoDb" Version="7.2.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="YDotNet.Server.MongoDB" Version="0.4.3" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" />
<PackageReference Include="YDotNet.Server.MongoDB" Version="0.6.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />

13
backend/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>Squidex.Domain.Apps.Core</RootNamespace>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
@ -12,17 +12,16 @@
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="NetTopologySuite" Version="2.5.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.5" />
<PackageReference Include="NetTopologySuite" Version="2.6.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.Flows" Version="7.37.0" />
<PackageReference Include="Squidex.Flows" Version="8.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

3
backend/src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Globalization;
using NJsonSchema;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
@ -140,7 +141,7 @@ internal sealed class JsonTypeVisitor : IFieldVisitor<JsonSchemaProperty?, JsonT
{
var property = JsonTypeBuilder.DateTimeProperty();
property.Default = field.Properties.DefaultValue?.ToString();
property.Default = field.Properties.DefaultValue?.ToString("g", CultureInfo.InvariantCulture);
return property;
}

12
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs

@ -35,7 +35,7 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
return new StringValue(url);
}
return NilValue.Empty;
return EmptyValue.Instance;
}
var value = input.ToObjectValue();
@ -56,7 +56,7 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
}
}
return NilValue.Empty;
return EmptyValue.Instance;
}
private ValueTask<FluidValue> AssetContentUrl(FluidValue input, FilterArguments arguments, TemplateContext context)
@ -70,7 +70,7 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
return new StringValue(result);
}
return NilValue.Empty;
return EmptyValue.Instance;
}
var value = input.ToObjectValue();
@ -91,7 +91,7 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
}
}
return NilValue.Empty;
return EmptyValue.Instance;
}
private ValueTask<FluidValue> AssetContentSlugUrl(FluidValue input, FilterArguments arguments, TemplateContext context)
@ -105,7 +105,7 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
return new StringValue(result);
}
return NilValue.Empty;
return EmptyValue.Instance;
}
var value = input.ToObjectValue();
@ -123,6 +123,6 @@ public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExt
}
}
return NilValue.Empty;
return EmptyValue.Instance;
}
}

11
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

@ -54,7 +54,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti
context.Complete(JsonMapper.Map(value));
}));
var result = Execute(context, script);
var result = await ExecuteAsync(context, script);
return await context.WaitForCompletionAsync(() => JsonMapper.Map(result));
}
@ -102,7 +102,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti
}
}));
Execute(context, script);
await ExecuteAsync(context, script);
return await context.WaitForCompletionAsync(() => data);
}
@ -182,6 +182,13 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti
return context.Evaluate(parsed);
}
private Task<JsValue> ExecuteAsync(ScriptExecutionContext context, string script)
{
var parsed = parser.Parse(script);
return context.EvaluateAsync(parsed);
}
private static Exception MapException(Exception inner)
{
static Exception BuildException(string errorKey, string message, Exception? inner = null)

10
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ScriptExecutionContext.cs

@ -18,6 +18,8 @@ public abstract class ScriptExecutionContext(Engine engine) : ScriptVars
public abstract JsValue Evaluate(Prepared<Script> script);
public abstract Task<JsValue> EvaluateAsync(Prepared<Script> script);
public abstract void Schedule(Func<IScheduler, CancellationToken, Task> action);
}
@ -47,8 +49,7 @@ public sealed class ScriptExecutionContext<T> : ScriptExecutionContext, ISchedul
{
TryComplete();
var result = await tcs.Task.WithCancellation(cancellationToken);
var result = await tcs.Task.WithCancellation(default);
if (result == null)
{
return fallback();
@ -67,6 +68,11 @@ public sealed class ScriptExecutionContext<T> : ScriptExecutionContext, ISchedul
return Engine.Evaluate(script);
}
public override Task<JsValue> EvaluateAsync(Prepared<Script> script)
{
return Engine.EvaluateAsync(script, cancellationToken);
}
public override void Schedule(Func<IScheduler, CancellationToken, Task> action)
{
if (IsCompleted)

21
backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>Squidex.Domain.Apps.Core</RootNamespace>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
@ -18,22 +18,21 @@
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fluid.Core" Version="2.12.0" />
<PackageReference Include="Fluid.Core" Version="2.31.0" />
<PackageReference Include="GeoJSON.Net" Version="1.4.1" />
<PackageReference Include="Jint" Version="4.4.2" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Jint" Version="4.6.3" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="NJsonSchema" Version="11.0.2" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.5" />
<PackageReference Include="NJsonSchema" Version="11.5.2" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.AI" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.Subscriptions" Version="7.37.0" />
<PackageReference Include="Squidex.AI" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging.Subscriptions" Version="8.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="System.Linq.Async" Version="7.0.0" />
<PackageReference Include="ValueTaskSupplement" Version="1.1.0" />
</ItemGroup>
<ItemGroup>

4
backend/src/Squidex.Domain.Apps.Core.Operations/Templates/Extensions/JsonArrayFluidValue.cs

@ -44,7 +44,7 @@ public sealed class JsonArrayFluidValue(JsonArray value, TemplateOptions options
return value.ToString()!;
}
protected override FluidValue GetValue(string name, TemplateContext context)
public override ValueTask<FluidValue> GetValueAsync(string name, TemplateContext context)
{
switch (name)
{
@ -71,7 +71,7 @@ public sealed class JsonArrayFluidValue(JsonArray value, TemplateOptions options
return NilValue.Instance;
}
protected override FluidValue GetIndex(FluidValue index, TemplateContext context)
public override ValueTask<FluidValue> GetIndexAsync(FluidValue index, TemplateContext context)
{
var i = (int)index.ToNumberValue();

2
backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs

@ -103,7 +103,7 @@ public sealed class DefaultAppLogStore(IRequestLogStore requestLogStore) : IAppL
await foreach (var request in requestLogStore.QueryAllAsync(appId.ToString(), fromTime, toTime, ct))
{
csv.WriteField(request.Timestamp.ToString());
csv.WriteField(request.Timestamp.ToString("g", CultureInfo.InvariantCulture));
csv.WriteField(GetString(request, FieldRequestPath));
csv.WriteField(GetString(request, FieldRequestMethod));
csv.WriteField(GetDouble(request, FieldRequestElapsedMs));

32
backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<NeutralLanguage>en</NeutralLanguage>
@ -28,27 +28,26 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ConsoleTables" Version="2.7.0" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="FFMpegCore" Version="5.1.0" />
<PackageReference Include="GraphQL" Version="8.2.1" />
<PackageReference Include="GraphQL.DataLoader" Version="8.2.1" />
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00016" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="CsvHelper" Version="33.1.0" />
<PackageReference Include="FFMpegCore" Version="5.4.0" />
<PackageReference Include="GraphQL" Version="8.8.4" />
<PackageReference Include="GraphQL.DataLoader" Version="8.8.4" />
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00017" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.5" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="Notifo.SDK" Version="1.7.5" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.CLI.Core" Version="13.13.0" />
<PackageReference Include="YDotNet" Version="0.4.3" />
<PackageReference Include="YDotNet.Extensions" Version="0.4.3" />
<PackageReference Include="YDotNet.Server" Version="0.4.3" />
<PackageReference Include="YDotNet" Version="0.6.0" />
<PackageReference Include="YDotNet.Extensions" Version="0.6.0" />
<PackageReference Include="YDotNet.Server" Version="0.6.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="tusdotnet" Version="2.8.0" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" />
<PackageReference Include="tusdotnet" Version="2.11.1" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />
@ -66,4 +65,7 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Using Remove="Parlot.Fluent.Parsers" />
</ItemGroup>
</Project>

6
backend/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -14,11 +14,11 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
</ItemGroup>

10
backend/src/Squidex.Domain.Users/Squidex.Domain.Users.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -18,18 +18,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityModel" Version="7.0.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.11" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="OpenIddict.AspNetCore" Version="5.8.0" />
<PackageReference Include="OpenIddict.AspNetCore" Version="7.4.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="SharpPwned.NET" Version="2.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Linq.Queryable" Version="4.3.0" />
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />

5
backend/src/Squidex.Infrastructure/CollectionExtensions.cs

@ -195,11 +195,6 @@ public static class CollectionExtensions
}
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> enumerable)
{
return enumerable.OrderBy(x => Random.Shared.Next()).ToList();
}
public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T>? source)
{
return source ?? [];

2
backend/src/Squidex.Infrastructure/DisposableObjectBase.cs

@ -9,7 +9,7 @@ namespace Squidex.Infrastructure;
public abstract class DisposableObjectBase : IDisposable
{
private readonly object disposeLock = new object();
private readonly Lock disposeLock = new Lock();
private bool isDisposed;
public bool IsDisposed => isDisposed;

3
backend/src/Squidex.Infrastructure/EventSourcing/EnvelopeExtensions.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Globalization;
using NodaTime;
using NodaTime.Text;
using Squidex.Events;
@ -80,7 +81,7 @@ public static class EnvelopeExtensions
public static Envelope<T> SetTimestamp<T>(this Envelope<T> envelope, Instant value) where T : class, IEvent
{
envelope.Headers[CommonHeaders.Timestamp] = value.ToString();
envelope.Headers[CommonHeaders.Timestamp] = value.ToString("g", CultureInfo.InvariantCulture);
return envelope;
}

2
backend/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs

@ -275,7 +275,7 @@ public readonly struct JsonValue : IEquatable<JsonValue>
public static JsonValue Create(Instant value)
{
return new JsonValue(value.ToString());
return new JsonValue(value.ToString("g", CultureInfo.InvariantCulture));
}
public static JsonValue Create(double value)

10
backend/src/Squidex.Infrastructure/Queries/OData/ConstantWithTypeVisitor.cs

@ -186,13 +186,19 @@ public sealed class ConstantWithTypeVisitor : QueryNodeVisitor<ClrValue>
return Instant.FromDateTimeUtc(DateTime.SpecifyKind(dateTime, DateTimeKind.Utc));
}
if (value is Date date)
if (value is DateOnly date)
{
return Instant.FromUtc(date.Year, date.Month, date.Day, 0, 0);
}
var parseResult = InstantPattern.ExtendedIso.Parse(value.ToString()!);
#pragma warning disable CS0618 // Type or member is obsolete
if (value is Date date2)
{
return Instant.FromUtc(date2.Year, date2.Month, date2.Day, 0, 0);
}
#pragma warning restore CS0618 // Type or member is obsolete
var parseResult = InstantPattern.ExtendedIso.Parse(value.ToString()!);
if (!parseResult.Success)
{
throw new ODataException("Datetime is not in a valid format. Use ISO 8601");

38
backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<NeutralLanguage>en</NeutralLanguage>
@ -11,33 +11,31 @@
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="4.8.0" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="MailKit" Version="4.15.1" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="2.0.0" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="8.0.11" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="10.0.5" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageReference Include="Microsoft.OData.Core" Version="8.2.1" />
<PackageReference Include="NodaTime" Version="3.2.0" />
<PackageReference Include="OpenTelemetry.Api" Version="1.9.0" />
<PackageReference Include="Microsoft.OData.Core" Version="8.4.3" />
<PackageReference Include="NodaTime" Version="3.3.1" />
<PackageReference Include="OpenTelemetry.Api" Version="1.15.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.Assets" Version="7.37.0" />
<PackageReference Include="Squidex.Caching" Version="7.37.0" />
<PackageReference Include="Squidex.Events" Version="7.37.0" />
<PackageReference Include="Squidex.Hosting.Abstractions" Version="7.37.0" />
<PackageReference Include="Squidex.Log" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging" Version="7.37.0" />
<PackageReference Include="Squidex.Text" Version="7.37.0" />
<PackageReference Include="Squidex.Assets" Version="8.0.0" />
<PackageReference Include="Squidex.Caching" Version="8.0.0" />
<PackageReference Include="Squidex.Events" Version="8.0.0" />
<PackageReference Include="Squidex.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Squidex.Log" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging" Version="8.0.0" />
<PackageReference Include="Squidex.Text" Version="8.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="System.Reactive" Version="6.0.1" />
<PackageReference Include="System.Linq.Async" Version="7.0.0" />
<PackageReference Include="System.Reactive" Version="6.1.0" />
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" />
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />

5
backend/src/Squidex.Shared/Squidex.Shared.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -10,13 +10,12 @@
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />

15
backend/src/Squidex.Web/Pipeline/ActionContextLogAppender.cs

@ -7,12 +7,12 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Squidex.Log;
namespace Squidex.Web.Pipeline;
public sealed class ActionContextLogAppender(IHttpContextAccessor httpContextAccessor, IActionContextAccessor actionContextAccessor) : ILogAppender
public sealed class ActionContextLogAppender(IHttpContextAccessor httpContextAccessor) : ILogAppender
{
public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception? exception)
{
@ -23,8 +23,7 @@ public sealed class ActionContextLogAppender(IHttpContextAccessor httpContextAcc
return;
}
var actionContext = actionContextAccessor.ActionContext;
var actionDescriptor = httpContext.GetEndpoint()?.Metadata.GetMetadata<ActionDescriptor>();
try
{
if (string.IsNullOrEmpty(httpContext?.Request?.Method))
@ -34,7 +33,7 @@ public sealed class ActionContextLogAppender(IHttpContextAccessor httpContextAcc
var requestId = GetRequestId(httpContext);
var logContext = (requestId, context: httpContext, actionContext);
var logContext = (requestId, context: httpContext, actionDescriptor);
writer.WriteObject("web", logContext, (ctx, w) =>
{
@ -42,11 +41,9 @@ public sealed class ActionContextLogAppender(IHttpContextAccessor httpContextAcc
w.WriteProperty("requestPath", ctx.context.Request.Path);
w.WriteProperty("requestMethod", ctx.context.Request.Method);
var actionContext = ctx.actionContext;
if (actionContext != null)
if (ctx.actionDescriptor != null)
{
w.WriteObject("routeValues", actionContext.ActionDescriptor.RouteValues, (routeValues, r) =>
w.WriteObject("routeValues", ctx.actionDescriptor.RouteValues, (routeValues, r) =>
{
foreach (var (key, value) in routeValues)
{

4
backend/src/Squidex.Web/Pipeline/UsagePipeWriter.cs

@ -13,6 +13,10 @@ public sealed class UsagePipeWriter(PipeWriter inner) : PipeWriter
{
private long bytesWritten;
public override bool CanGetUnflushedBytes => inner.CanGetUnflushedBytes;
public override long UnflushedBytes => inner.UnflushedBytes;
public long BytesWritten
{
get => bytesWritten;

12
backend/src/Squidex.Web/Squidex.Web.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
@ -13,14 +13,14 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="GraphQL" Version="8.2.1" />
<PackageReference Include="GraphQL.SystemTextJson" Version="8.2.1" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="8.1.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="GraphQL" Version="8.8.4" />
<PackageReference Include="GraphQL.SystemTextJson" Version="8.8.4" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="8.3.3" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
</ItemGroup>

12
backend/src/Squidex/Areas/IdentityServer/Config/ApplicationExtensions.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Immutable;
using System.Security.Claims;
using System.Text.Json;
using OpenIddict.Abstractions;
@ -34,21 +35,26 @@ public static class ApplicationExtensions
return application;
}
private static JsonElement CreateParameter(IEnumerable<string> values)
private static JsonElement CreateParameter(IEnumerable<string?> values)
{
return (JsonElement)new OpenIddictParameter(values.ToArray());
return (JsonElement)new OpenIddictParameter(values.ToImmutableArray());
}
public static IEnumerable<Claim> Claims(this IReadOnlyDictionary<string, JsonElement> properties)
{
foreach (var (key, value) in properties)
{
var values = (string[]?)new OpenIddictParameter(value);
var values = (ImmutableArray<string?>?)new OpenIddictParameter(value);
if (values != null)
{
foreach (var claimValue in values)
{
if (claimValue == null)
{
continue;
}
if (key == SquidexClaimTypes.DisplayName)
{
yield return new Claim(OpenIdClaims.Name, claimValue);

8
backend/src/Squidex/Areas/IdentityServer/Config/ApplicationManager.cs

@ -12,11 +12,11 @@ using OpenIddict.Core;
namespace Squidex.Areas.IdentityServer.Config;
public sealed class ApplicationManager<T>(
IOptionsMonitor<OpenIddictCoreOptions> options,
IOpenIddictApplicationCache<T> cache,
IOpenIddictApplicationStoreResolver resolver,
ILogger<OpenIddictApplicationManager<T>> logger)
: OpenIddictApplicationManager<T>(cache, logger, options, resolver) where T : class
ILogger<OpenIddictApplicationManager<T>> logger,
IOptionsMonitor<OpenIddictCoreOptions> options,
IOpenIddictApplicationStore<T> store)
: OpenIddictApplicationManager<T>(cache, logger, options, store) where T : class
{
protected override ValueTask<bool> ValidateClientSecretAsync(string secret, string comparand,
CancellationToken cancellationToken = default)

4
backend/src/Squidex/Areas/IdentityServer/Config/DynamicApplicationStore.cs

@ -148,7 +148,7 @@ public class DynamicApplicationStore(IServiceProvider serviceProvider) : InMemor
Permissions =
{
Permissions.Endpoints.Authorization,
Permissions.Endpoints.Logout,
Permissions.Endpoints.EndSession,
Permissions.Endpoints.Token,
Permissions.GrantTypes.AuthorizationCode,
Permissions.GrantTypes.RefreshToken,
@ -175,7 +175,7 @@ public class DynamicApplicationStore(IServiceProvider serviceProvider) : InMemor
Permissions =
{
Permissions.Endpoints.Authorization,
Permissions.Endpoints.Logout,
Permissions.Endpoints.EndSession,
Permissions.Endpoints.Token,
Permissions.GrantTypes.Implicit,
Permissions.ResponseTypes.IdToken,

10
backend/src/Squidex/Areas/IdentityServer/Config/IdentityServerServices.cs

@ -114,10 +114,10 @@ public static class IdentityServerServices
builder.UseAspNetCore()
.DisableTransportSecurityRequirement()
.EnableAuthorizationEndpointPassthrough()
.EnableLogoutEndpointPassthrough()
.EnableEndSessionEndpointPassthrough()
.EnableStatusCodePagesIntegration()
.EnableTokenEndpointPassthrough()
.EnableUserinfoEndpointPassthrough();
.EnableUserInfoEndpointPassthrough();
builder.SetAccessTokenLifetime(TimeSpan.FromDays(30));
})
@ -164,16 +164,16 @@ public static class IdentityServerServices
options.IntrospectionEndpointUris.SetEndpoint(
BuildUrl("connect/introspect"));
options.LogoutEndpointUris.SetEndpoint(
options.EndSessionEndpointUris.SetEndpoint(
BuildUrl("connect/logout"));
options.TokenEndpointUris.SetEndpoint(
BuildUrl("connect/token"));
options.UserinfoEndpointUris.SetEndpoint(
options.UserInfoEndpointUris.SetEndpoint(
BuildUrl("connect/userinfo"));
options.CryptographyEndpointUris.SetEndpoint(
options.JsonWebKeySetEndpointUris.SetEndpoint(
BuildUrl(".well-known/jwks"));
options.ConfigurationEndpointUris.SetEndpoint(

2
backend/src/Squidex/Areas/IdentityServer/Controllers/Connect/AuthorizationController.cs

@ -115,7 +115,7 @@ public class AuthorizationController(
if (User.Identity?.IsAuthenticated != true)
{
if (request.HasPrompt(Prompts.None))
if (request.HasPromptValue(PromptValues.None))
{
var properties = new AuthenticationProperties(new Dictionary<string, string?>
{

11
backend/src/Squidex/Config/Domain/EventSourcingServices.cs

@ -5,8 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using EventStore.Client;
using Squidex.Events.GetEventStore;
using Squidex.Hosting.Configuration;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
@ -37,15 +35,6 @@ public static class EventSourcingServices
services.AddSquidexEntityFrameworkEventStore(config);
},
["GetEventStore"] = () =>
{
var configuration = config.GetRequiredValue("eventStore:getEventStore:configuration");
services.AddSingletonAs(_ => EventStoreClientSettings.Create(configuration))
.AsSelf();
services.AddGetEventStore(config);
},
});
services.AddTransientAs<Rebuilder>()

4
backend/src/Squidex/Config/Web/WebServices.cs

@ -9,6 +9,7 @@ using GraphQL;
using GraphQL.DI;
using GraphQL.Server.Transports.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.ResponseCompression;
@ -68,9 +69,6 @@ public static class WebServices
services.AddSingletonAs<HttpContextAccessor>()
.As<IHttpContextAccessor>();
services.AddSingletonAs<ActionContextAccessor>()
.As<IActionContextAccessor>();
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressInferBindingSourcesForParameters = true;

88
backend/src/Squidex/Squidex.csproj

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<NeutralLanguage>en</NeutralLanguage>
@ -29,66 +29,62 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="8.3.0" />
<PackageReference Include="Google.Cloud.Trace.V2" Version="3.6.0" />
<PackageReference Include="GraphQL" Version="8.2.1" />
<PackageReference Include="GraphQL.MicrosoftDI" Version="8.2.1" />
<PackageReference Include="GraphQL.SystemTextJson" Version="8.2.1" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="10.0.0" />
<PackageReference Include="Google.Cloud.Trace.V2" Version="3.7.0" />
<PackageReference Include="GraphQL" Version="8.8.4" />
<PackageReference Include="GraphQL.MicrosoftDI" Version="8.8.4" />
<PackageReference Include="GraphQL.SystemTextJson" Version="8.8.4" />
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.11" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.RulesetToEditorconfigConverter" Version="3.3.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="10.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="10.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.5" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="10.0.5" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.5" />
<PackageReference Include="Microsoft.CodeAnalysis.RulesetToEditorconfigConverter" Version="4.14.0" />
<PackageReference Include="Microsoft.Data.Edm" Version="5.8.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.KeyPerFile" Version="8.0.18" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.2.1" />
<PackageReference Include="Microsoft.OData.Core" Version="8.2.1" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.16.0" />
<PackageReference Include="Microsoft.OData.Core" Version="8.4.3" />
<PackageReference Include="NetTopologySuite.IO.GeoJSON4STJ" Version="4.0.0" />
<PackageReference Include="NJsonSchema" Version="11.0.2" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0" />
<PackageReference Include="NSwag.AspNetCore" Version="14.1.0" />
<PackageReference Include="NJsonSchema" Version="11.5.2" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.1" />
<PackageReference Include="NSwag.AspNetCore" Version="14.6.3" />
<PackageReference Include="OpenCover" Version="4.7.1221" PrivateAssets="all" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.1" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.15.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="ReportGenerator" Version="5.4.1" PrivateAssets="all" />
<PackageReference Include="Squidex.Assets.Azure" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.GoogleCloud" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.FTP" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.ImageSharp" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.S3" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.TusAdapter" Version="7.37.0" />
<PackageReference Include="Squidex.ClientLibrary" Version="21.8.0" />
<PackageReference Include="Squidex.Events.GetEventStore" Version="7.37.0" />
<PackageReference Include="Squidex.Hosting" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.All" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.Subscriptions" Version="7.37.0" />
<PackageReference Include="ReportGenerator" Version="5.5.4" PrivateAssets="all" />
<PackageReference Include="Squidex.Assets.Azure" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.GoogleCloud" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.FTP" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.ImageSharp" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.S3" Version="8.0.0" />
<PackageReference Include="Squidex.Assets.TusAdapter" Version="8.0.0" />
<PackageReference Include="Squidex.ClientLibrary" Version="22.2.0" />
<PackageReference Include="Squidex.Hosting" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging.All" Version="8.0.0" />
<PackageReference Include="Squidex.Messaging.Subscriptions" Version="8.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="YDotNet" Version="0.4.3" />
<PackageReference Include="YDotNet.Native" Version="0.4.3" />
<PackageReference Include="YDotNet.Server" Version="0.4.3" />
<PackageReference Include="YDotNet.Server.Redis" Version="0.4.3" />
<PackageReference Include="YDotNet.Server.WebSockets" Version="0.4.3" />
<PackageReference Include="YDotNet" Version="0.6.0" />
<PackageReference Include="YDotNet.Native" Version="0.6.0" />
<PackageReference Include="YDotNet.Server" Version="0.6.0" />
<PackageReference Include="YDotNet.Server.Redis" Version="0.6.0" />
<PackageReference Include="YDotNet.Server.WebSockets" Version="0.6.0" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.5" />
</ItemGroup>
<ItemGroup Condition="'$(IncludeMagick)' == 'true'">
<PackageReference Include="Squidex.Assets.ImageMagick" Version="7.37.0" />
<PackageReference Include="Squidex.Assets.ImageMagick" Version="8.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(IncludeKafka)' == 'true'">
<PackageReference Include="Squidex.Messaging.Kafka" Version="7.37.0" />
<PackageReference Include="Squidex.Messaging.Kafka" Version="8.0.0" />
</ItemGroup>
<PropertyGroup>
@ -170,4 +166,8 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Using Remove="Parlot.Fluent.Parsers" />
</ItemGroup>
</Project>

6
backend/tests/Squidex.Data.Tests.CodeGenerator/Squidex.Data.Tests.CodeGenerator.csproj

@ -16,12 +16,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Handlebars.Net" Version="2.1.6" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.26">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="5.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

8
backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/MySqlMigrationTests.cs

@ -18,14 +18,14 @@ namespace Squidex.EntityFramework.Migrations;
[Trait("Category", "TestContainer")]
public class MySqlMigrationTests : IAsyncLifetime
{
private readonly MySqlContainer mysql = new MySqlBuilder().Build();
private readonly MySqlContainer mysql = new MySqlBuilder("mysql:8.0").Build();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await mysql.StartAsync();
await mysql.StartAsync(TestContext.Current.CancellationToken);
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
await mysql.DisposeAsync();
}

9
backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/PostgresMigrationTests.cs

@ -19,16 +19,15 @@ namespace Squidex.EntityFramework.Migrations;
public class PostgresMigrationTests : IAsyncLifetime
{
private readonly PostgreSqlContainer postgreSql =
new PostgreSqlBuilder()
.WithImage("postgis/postgis")
new PostgreSqlBuilder("postgis/postgis")
.Build();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await postgreSql.StartAsync();
await postgreSql.StartAsync(TestContext.Current.CancellationToken);
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
await postgreSql.DisposeAsync();
}

10
backend/tests/Squidex.Data.Tests/EntityFramework/Migrations/SqlServerMigrationTests.cs

@ -18,14 +18,16 @@ namespace Squidex.EntityFramework.Migrations;
[Trait("Category", "TestContainer")]
public class SqlServerMigrationTests : IAsyncLifetime
{
private readonly MsSqlContainer sqlServer = new MsSqlBuilder().Build();
private readonly MsSqlContainer sqlServer =
new MsSqlBuilder("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04")
.Build();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await sqlServer.StartAsync();
await sqlServer.StartAsync(TestContext.Current.CancellationToken);
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
await sqlServer.DisposeAsync();
}

14
backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/MySqlFixture.cs

@ -6,6 +6,7 @@
// ==========================================================================
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using PhenX.EntityFrameworkCore.BulkInsert.MySql;
using Squidex.Domain.Apps.Core.TestHelpers;
@ -22,7 +23,7 @@ namespace Squidex.EntityFramework.TestHelpers;
public class MySqlFixture(string? reuseId = null) : IAsyncLifetime, ISqlContentFixture<TestDbContextMySql, MySqlContentDbContext>
{
private readonly MySqlContainer mysql =
new MySqlBuilder()
new MySqlBuilder("mysql:8.0")
.WithReuse(true)
.WithLabel("reuse-id", reuseId)
.WithCommand("--log-bin-trust-function-creators=1", "--local-infile=1")
@ -36,9 +37,9 @@ public class MySqlFixture(string? reuseId = null) : IAsyncLifetime, ISqlContentF
public IDbContextNamedFactory<MySqlContentDbContext> DbContextNamedFactory
=> services.GetRequiredService<IDbContextNamedFactory<MySqlContentDbContext>>();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await mysql.StartAsync();
await mysql.StartAsync(TestContext.Current.CancellationToken);
var connectionString = $"{mysql.GetConnectionString()};AllowLoadLocalInfile=true;MaxPoolSize=1000";
@ -60,6 +61,9 @@ public class MySqlFixture(string? reuseId = null) : IAsyncLifetime, ISqlContentF
{
options.UseMicrosoftJson(MySqlCommonJsonChangeTrackingOptions.FullHierarchyOptimizedSemantically);
});
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
})
.AddSingleton<ConnectionStringParser, MySqlConnectionStringParser>()
.AddSingletonAs<DatabaseCreator<TestDbContextMySql>>().Done()
@ -73,13 +77,13 @@ public class MySqlFixture(string? reuseId = null) : IAsyncLifetime, ISqlContentF
}
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
{
await service.ReleaseAsync(default);
}
await mysql.StopAsync();
await mysql.StopAsync(TestContext.Current.CancellationToken);
}
}

15
backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/PostgresFixture.cs

@ -6,6 +6,7 @@
// ==========================================================================
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using PhenX.EntityFrameworkCore.BulkInsert.PostgreSql;
using Squidex.Domain.Apps.Core.TestHelpers;
@ -22,8 +23,7 @@ namespace Squidex.EntityFramework.TestHelpers;
public class PostgresFixture(string? reuseId) : IAsyncLifetime, ISqlContentFixture<TestDbContextPostgres, PostgresContentDbContext>
{
private readonly PostgreSqlContainer postgreSql =
new PostgreSqlBuilder()
.WithImage("postgis/postgis")
new PostgreSqlBuilder("postgis/postgis")
.WithReuse(true)
.WithLabel("reuse-id", reuseId)
.Build();
@ -36,9 +36,9 @@ public class PostgresFixture(string? reuseId) : IAsyncLifetime, ISqlContentFixtu
public IDbContextNamedFactory<PostgresContentDbContext> DbContextNamedFactory
=> services.GetRequiredService<IDbContextNamedFactory<PostgresContentDbContext>>();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await postgreSql.StartAsync();
await postgreSql.StartAsync(TestContext.Current.CancellationToken);
var connectionString = postgreSql.GetConnectionString();
@ -56,6 +56,9 @@ public class PostgresFixture(string? reuseId) : IAsyncLifetime, ISqlContentFixtu
{
builder.UseBulkInsertPostgreSql();
builder.UseNpgsql(connectionString);
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
})
.AddSingleton<ConnectionStringParser, PostgresConnectionStringParser>()
.AddSingletonAs<DatabaseCreator<TestDbContextPostgres>>().Done()
@ -69,13 +72,13 @@ public class PostgresFixture(string? reuseId) : IAsyncLifetime, ISqlContentFixtu
}
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
{
await service.ReleaseAsync(default);
}
await postgreSql.StopAsync();
await postgreSql.StopAsync(TestContext.Current.CancellationToken);
}
}

17
backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/SqlServerFixture.cs

@ -7,6 +7,7 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using PhenX.EntityFrameworkCore.BulkInsert.SqlServer;
using Squidex.Domain.Apps.Core.TestHelpers;
@ -23,8 +24,7 @@ namespace Squidex.EntityFramework.TestHelpers;
public class SqlServerFixture(string? reuseId = null) : IAsyncLifetime, ISqlContentFixture<TestDbContextSqlServer, SqlServerContentDbContext>
{
private readonly MsSqlContainer sqlServer =
new MsSqlBuilder()
.WithImage("vibs2006/sql_server_fts")
new MsSqlBuilder("vibs2006/sql_server_fts")
.WithReuse(true)
.WithLabel("reuse-id", reuseId)
.Build();
@ -37,10 +37,10 @@ public class SqlServerFixture(string? reuseId = null) : IAsyncLifetime, ISqlCont
public IDbContextNamedFactory<SqlServerContentDbContext> DbContextNamedFactory
=> services.GetRequiredService<IDbContextNamedFactory<SqlServerContentDbContext>>();
public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
await sqlServer.StartAsync();
await sqlServer.ExecScriptAsync($"create database squidex;");
await sqlServer.StartAsync(TestContext.Current.CancellationToken);
await sqlServer.ExecScriptAsync($"create database squidex;", TestContext.Current.CancellationToken);
var connectionString = GetConnectionString();
@ -58,6 +58,9 @@ public class SqlServerFixture(string? reuseId = null) : IAsyncLifetime, ISqlCont
{
builder.UseBulkInsertSqlServer();
builder.UseSqlServer(connectionString);
builder.ConfigureWarnings(w =>
w.Ignore(RelationalEventId.PendingModelChangesWarning));
})
.AddSingleton<ConnectionStringParser, SqlServerConnectionStringParser>()
.AddSingletonAs<DatabaseCreator<TestDbContextSqlServer>>().Done()
@ -71,14 +74,14 @@ public class SqlServerFixture(string? reuseId = null) : IAsyncLifetime, ISqlCont
}
}
public async Task DisposeAsync()
public async ValueTask DisposeAsync()
{
foreach (var service in services.GetRequiredService<IEnumerable<IInitializable>>())
{
await service.ReleaseAsync(default);
}
await sqlServer.StopAsync();
await sqlServer.StopAsync(TestContext.Current.CancellationToken);
}
private string GetConnectionString()

1
backend/tests/Squidex.Data.Tests/EntityFramework/TestHelpers/TestEntity.cs

@ -6,7 +6,6 @@
// ==========================================================================
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using NetTopologySuite.Geometries;
#pragma warning disable MA0048 // File name must match type name

10
backend/tests/Squidex.Data.Tests/MongoDb/Domain/Assets/AssetQueryTests.cs

@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using NodaTime.Text;
@ -22,12 +24,6 @@ public class AssetQueryTests
{
private readonly DomainId appId = DomainId.NewGuid();
static AssetQueryTests()
{
MongoAssetEntity.RegisterClassMap();
MongoTestUtils.SetupBson();
}
[Fact]
public void Should_throw_exception_for_full_text_search()
{
@ -205,7 +201,7 @@ public class AssetQueryTests
new RenderArgs<MongoAssetEntity>(
BsonSerializer.SerializerRegistry.GetSerializer<MongoAssetEntity>(),
BsonSerializer.SerializerRegistry))
.ToString();
.ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Shell });
Assert.Equal(Cleanup(expected, arg), rendered);
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save