Browse Source

Refactoring.

pull/596/head
Sebastian 5 years ago
parent
commit
231a0aa86c
  1. 30
      backend/Squidex.sln
  2. 2
      backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs
  3. 2
      backend/extensions/Squidex.Extensions/APM/Datadog/DatadogPlugin.cs
  4. 2
      backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs
  5. 2
      backend/extensions/Squidex.Extensions/Samples/AssetStore/MemoryAssetStorePlugin.cs
  6. 2
      backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj
  7. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
  8. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs
  9. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/AggregateValidator.cs
  10. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs
  11. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository_SnapshotStore.cs
  12. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
  13. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs
  14. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollectionAll.cs
  15. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollectionPublished.cs
  16. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs
  17. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs
  18. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/AppDomainObject.cs
  19. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs
  20. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/Commands/UploadAppImage.cs
  21. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppImageStore.cs
  22. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs
  23. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs
  24. 2
      backend/src/Squidex.Domain.Apps.Entities/Apps/Invitation/InvitationEventConsumer.cs
  25. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs
  26. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs
  27. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/AssetFolderDomainObject.cs
  28. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs
  29. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/Commands/UploadAssetCommand.cs
  30. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/DefaultAssetFileStore.cs
  31. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/FileTagAssetMetadataSource.cs
  32. 1
      backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetFileStore.cs
  33. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/ImageAssetMetadataSource.cs
  34. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetEnricher.cs
  35. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetLoader.cs
  36. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryParser.cs
  37. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs
  38. 2
      backend/src/Squidex.Domain.Apps.Entities/Assets/RepairFiles.cs
  39. 2
      backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs
  40. 2
      backend/src/Squidex.Domain.Apps.Entities/Backup/DefaultBackupArchiveStore.cs
  41. 2
      backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs
  42. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs
  43. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs
  44. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs
  45. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs
  46. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs
  47. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Middlewares.cs
  48. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Operations/ContentOperationContext.cs
  49. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs
  50. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentLoader.cs
  51. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs
  52. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs
  53. 2
      backend/src/Squidex.Domain.Apps.Entities/Notifications/NotificationEmailSender.cs
  54. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/Indexes/RulesIndex.cs
  55. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/Queries/RuleEnricher.cs
  56. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/RuleDequeuerGrain.cs
  57. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs
  58. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs
  59. 2
      backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs
  60. 2
      backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs
  61. 2
      backend/src/Squidex.Domain.Apps.Entities/Search/SearchManager.cs
  62. 1
      backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
  63. 2
      backend/src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj
  64. 2
      backend/src/Squidex.Domain.Users/DefaultUserPictureStore.cs
  65. 2
      backend/src/Squidex.Domain.Users/PwnedPasswordValidator.cs
  66. 2
      backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs
  67. 2
      backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3Options.cs
  68. 2
      backend/src/Squidex.Infrastructure.Amazon/Assets/SeekFakerStream.cs
  69. 164
      backend/src/Squidex.Infrastructure.Azure/Assets/AzureBlobAssetStore.cs
  70. 2
      backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Reader.cs
  71. 2
      backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Writer.cs
  72. 2
      backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs
  73. 2
      backend/src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs
  74. 150
      backend/src/Squidex.Infrastructure.MongoDb/Assets/MongoGridFsAssetStore.cs
  75. 2
      backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs
  76. 2
      backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs
  77. 2
      backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequestLogRepository.cs
  78. 2
      backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs
  79. 33
      backend/src/Squidex.Infrastructure/Assets/AssetAlreadyExistsException.cs
  80. 39
      backend/src/Squidex.Infrastructure/Assets/AssetFile.cs
  81. 33
      backend/src/Squidex.Infrastructure/Assets/AssetNotFoundException.cs
  82. 28
      backend/src/Squidex.Infrastructure/Assets/DelegateAssetFile.cs
  83. 197
      backend/src/Squidex.Infrastructure/Assets/FTPAssetStore.cs
  84. 152
      backend/src/Squidex.Infrastructure/Assets/FolderAssetStore.cs
  85. 101
      backend/src/Squidex.Infrastructure/Assets/HasherStream.cs
  86. 28
      backend/src/Squidex.Infrastructure/Assets/IAssetStore.cs
  87. 21
      backend/src/Squidex.Infrastructure/Assets/IAssetThumbnailGenerator.cs
  88. 18
      backend/src/Squidex.Infrastructure/Assets/ImageFormat.cs
  89. 31
      backend/src/Squidex.Infrastructure/Assets/ImageInfo.cs
  90. 197
      backend/src/Squidex.Infrastructure/Assets/ImageSharp/ImageSharpAssetThumbnailGenerator.cs
  91. 128
      backend/src/Squidex.Infrastructure/Assets/MemoryAssetStore.cs
  92. 47
      backend/src/Squidex.Infrastructure/Assets/NoopAssetStore.cs
  93. 20
      backend/src/Squidex.Infrastructure/Assets/ResizeMode.cs
  94. 72
      backend/src/Squidex.Infrastructure/Assets/ResizeOptions.cs
  95. 64
      backend/src/Squidex.Infrastructure/Assets/StreamExtensions.cs
  96. 65
      backend/src/Squidex.Infrastructure/BytesRange.cs
  97. 2
      backend/src/Squidex.Infrastructure/Commands/DomainObject.cs
  98. 2
      backend/src/Squidex.Infrastructure/Commands/DomainObjectBase.cs
  99. 2
      backend/src/Squidex.Infrastructure/Commands/LogCommandMiddleware.cs
  100. 2
      backend/src/Squidex.Infrastructure/Commands/LogSnapshotDomainObject.cs

30
backend/Squidex.sln

@ -20,8 +20,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.Mong
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.RabbitMq", "src\Squidex.Infrastructure.RabbitMq\Squidex.Infrastructure.RabbitMq.csproj", "{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.GoogleCloud", "src\Squidex.Infrastructure.GoogleCloud\Squidex.Infrastructure.GoogleCloud.csproj", "{945871B1-77B8-43FB-B53C-27CF385AB756}"
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}"
@ -61,8 +59,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{7EDE8C
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}") = "Squidex.Infrastructure.Amazon", "src\Squidex.Infrastructure.Amazon\Squidex.Infrastructure.Amazon.csproj", "{32DA4B56-7EFA-4E34-A29D-30E00579A894}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migrations", "src\Migrations\Migrations.csproj", "{23615A39-F3FB-4575-A91C-535899DFB636}"
EndProject
Global
@ -135,18 +131,6 @@ Global
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x64.Build.0 = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x86.ActiveCfg = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x86.Build.0 = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|Any CPU.Build.0 = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|x64.ActiveCfg = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|x64.Build.0 = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|x86.ActiveCfg = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Debug|x86.Build.0 = Debug|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|Any CPU.ActiveCfg = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|Any CPU.Build.0 = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|x64.ActiveCfg = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|x64.Build.0 = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|x86.ActiveCfg = Release|Any CPU
{945871B1-77B8-43FB-B53C-27CF385AB756}.Release|x86.Build.0 = 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
@ -315,18 +299,6 @@ Global
{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
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|x64.ActiveCfg = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|x64.Build.0 = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|x86.ActiveCfg = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Debug|x86.Build.0 = Debug|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Release|Any CPU.Build.0 = Release|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Release|x64.ActiveCfg = Release|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Release|x64.Build.0 = Release|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.Release|x86.ActiveCfg = Release|Any CPU
{32DA4B56-7EFA-4E34-A29D-30E00579A894}.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
@ -350,7 +322,6 @@ Global
{FD0AFD44-7A93-4F9E-B5ED-72582392E435} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{6A811927-3C37-430A-90F4-503E37123956} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{945871B1-77B8-43FB-B53C-27CF385AB756} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{27CF800D-890F-4882-BF05-44EC3233537D} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
@ -365,7 +336,6 @@ Global
{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}
{32DA4B56-7EFA-4E34-A29D-30E00579A894} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{23615A39-F3FB-4575-A91C-535899DFB636} = {94207AA6-4923-4183-A558-E0F8196B8CA3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution

2
backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs

@ -13,8 +13,8 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Plugins;
using Squidex.Log;
namespace Squidex.Extensions.APM.ApplicationInsights
{

2
backend/extensions/Squidex.Extensions/APM/Datadog/DatadogPlugin.cs

@ -12,8 +12,8 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Plugins;
using Squidex.Log;
namespace Squidex.Extensions.APM.Datadog
{

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

@ -20,7 +20,7 @@ using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Log;
using Squidex.Log;
using Schema = Avro.Schema;
namespace Squidex.Extensions.Actions.Kafka

2
backend/extensions/Squidex.Extensions/Samples/AssetStore/MemoryAssetStorePlugin.cs

@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Assets;
using Squidex.Assets;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Samples.AssetStore

2
backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj

@ -19,7 +19,7 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.8" />
<PackageReference Include="Microsoft.OData.Core" Version="7.7.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NodaTime" Version="3.0.1" />
<PackageReference Include="NodaTime" Version="3.0.3" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />

2
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs

@ -17,9 +17,9 @@ using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Tasks;
using Squidex.Log;
using JobList = System.Collections.Generic.List<(Squidex.Domain.Apps.Core.Rules.RuleJob Job, System.Exception? Exception)>;
namespace Squidex.Domain.Apps.Core.HandleRules

2
backend/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs

@ -14,8 +14,8 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent.Validators;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
#pragma warning disable SA1028, IDE0004 // Code must not contain trailing whitespace

2
backend/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/AggregateValidator.cs

@ -9,8 +9,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{

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

@ -13,8 +13,8 @@ using MongoDB.Driver;
using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{

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

@ -12,10 +12,10 @@ using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Domain.Apps.Entities.Assets.State;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{

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

@ -14,12 +14,12 @@ using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
using Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.MongoDb.Queries;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Tasks;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{

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

@ -12,10 +12,10 @@ using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Domain.Apps.Entities.Assets.State;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollectionAll.cs

@ -19,9 +19,9 @@ using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Queries;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
{

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollectionPublished.cs

@ -18,9 +18,9 @@ using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Queries;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
{

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs

@ -12,9 +12,9 @@ using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.State;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
{

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

@ -7,9 +7,9 @@
using System.Threading.Tasks;
using Orleans;
using Squidex.Assets;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;

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

@ -18,9 +18,9 @@ using Squidex.Domain.Apps.Events.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Entities.Apps

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

@ -8,11 +8,11 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Domain.Apps.Entities.Apps.Indexes;
using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json.Objects;

2
backend/src/Squidex.Domain.Apps.Entities/Apps/Commands/UploadAppImage.cs

@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Infrastructure.Assets;
using Squidex.Assets;
namespace Squidex.Domain.Apps.Entities.Apps.Commands
{

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

@ -8,8 +8,8 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Entities.Apps
{

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

@ -15,7 +15,7 @@ using System.Threading.Tasks;
using CsvHelper;
using CsvHelper.Configuration;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log.Store;
using Squidex.Infrastructure.Log;
namespace Squidex.Domain.Apps.Entities.Apps
{

2
backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs

@ -14,11 +14,11 @@ using Squidex.Caching;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.Security;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
using Squidex.Shared;
using Squidex.Text;

2
backend/src/Squidex.Domain.Apps.Entities/Apps/Invitation/InvitationEventConsumer.cs

@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Entities.Notifications;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Entities.Apps.Invitation

2
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs

@ -9,9 +9,9 @@ using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Orleans;
using Squidex.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands;
namespace Squidex.Domain.Apps.Entities.Assets

2
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs

@ -18,10 +18,10 @@ using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
using IAssetTagService = Squidex.Domain.Apps.Core.Tags.ITagService;
namespace Squidex.Domain.Apps.Entities.Assets

2
backend/src/Squidex.Domain.Apps.Entities/Assets/AssetFolderDomainObject.cs

@ -15,9 +15,9 @@ using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Assets
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/BackupAssets.cs

@ -8,12 +8,12 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Domain.Apps.Core.Tags;
using Squidex.Domain.Apps.Entities.Assets.State;
using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;

2
backend/src/Squidex.Domain.Apps.Entities/Assets/Commands/UploadAssetCommand.cs

@ -5,8 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Assets;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Entities.Assets.Commands
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/DefaultAssetFileStore.cs

@ -8,8 +8,8 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Entities.Assets
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/FileTagAssetMetadataSource.cs

@ -9,10 +9,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Json.Objects;
using TagLib;
using TagLib.Image;

1
backend/src/Squidex.Domain.Apps.Entities/Assets/IAssetFileStore.cs

@ -8,6 +8,7 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Assets

2
backend/src/Squidex.Domain.Apps.Entities/Assets/ImageAssetMetadataSource.cs

@ -9,10 +9,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Entities.Assets
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetEnricher.cs

@ -12,8 +12,8 @@ using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Tags;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Assets.Queries
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetLoader.cs

@ -8,7 +8,7 @@
using System.Threading.Tasks;
using Orleans;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Assets.Queries
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/Queries/AssetQueryParser.cs

@ -15,12 +15,12 @@ using NJsonSchema;
using Squidex.Domain.Apps.Core.Tags;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Queries.Json;
using Squidex.Infrastructure.Queries.OData;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
using Squidex.Text;
namespace Squidex.Domain.Apps.Entities.Assets.Queries

2
backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs

@ -13,8 +13,8 @@ using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Assets
{

2
backend/src/Squidex.Domain.Apps.Entities/Assets/RepairFiles.cs

@ -9,9 +9,9 @@ using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Entities.Assets

2
backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs

@ -18,10 +18,10 @@ using Squidex.Domain.Apps.Entities.Backup.State;
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.Tasks;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Entities.Backup

2
backend/src/Squidex.Domain.Apps.Entities/Backup/DefaultBackupArchiveStore.cs

@ -8,8 +8,8 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Entities.Backup
{

2
backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs

@ -20,11 +20,11 @@ using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.States;
using Squidex.Infrastructure.Tasks;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Entities.Backup

2
backend/src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs

@ -19,9 +19,9 @@ using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs

@ -15,7 +15,7 @@ using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/CachingGraphQLService.cs

@ -15,7 +15,7 @@ using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs

@ -18,7 +18,7 @@ using Squidex.Domain.Apps.Entities.Contents.Queries;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs

@ -17,7 +17,7 @@ using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types;
using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
using GraphQLSchema = GraphQL.Types.Schema;
#pragma warning disable IDE0003

2
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Middlewares.cs

@ -10,7 +10,7 @@ using GraphQL;
using GraphQL.Instrumentation;
using GraphQL.Types;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Operations/ContentOperationContext.cs

@ -20,8 +20,8 @@ using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
#pragma warning disable IDE0016 // Use 'throw' expression

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs

@ -11,8 +11,8 @@ using System.Linq;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents.Queries
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentLoader.cs

@ -8,7 +8,7 @@
using System.Threading.Tasks;
using Orleans;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Contents.Queries
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryParser.cs

@ -22,12 +22,12 @@ using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Queries.Json;
using Squidex.Infrastructure.Queries.OData;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
using Squidex.Text;
namespace Squidex.Domain.Apps.Entities.Contents.Queries

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs

@ -12,9 +12,9 @@ using System.Threading.Tasks;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
using Squidex.Shared;
#pragma warning disable RECS0147

2
backend/src/Squidex.Domain.Apps.Entities/Notifications/NotificationEmailSender.cs

@ -11,7 +11,7 @@ using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Email;
using Squidex.Infrastructure.Log;
using Squidex.Log;
using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Entities.Notifications

2
backend/src/Squidex.Domain.Apps.Entities/Rules/Indexes/RulesIndex.cs

@ -12,7 +12,7 @@ using Orleans;
using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Rules.Indexes
{

2
backend/src/Squidex.Domain.Apps.Entities/Rules/Queries/RuleEnricher.cs

@ -11,8 +11,8 @@ using System.Threading.Tasks;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Rules.Queries
{

2
backend/src/Squidex.Domain.Apps.Entities/Rules/RuleDequeuerGrain.cs

@ -16,8 +16,8 @@ using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Tasks;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Rules
{

2
backend/src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs

@ -15,9 +15,9 @@ using Squidex.Domain.Apps.Events.Rules;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Rules
{

2
backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs

@ -14,11 +14,11 @@ using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.States;
using Squidex.Infrastructure.Tasks;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Rules.Runner
{

2
backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs

@ -14,9 +14,9 @@ using Squidex.Caching;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
using Squidex.Log;
using Squidex.Text;
namespace Squidex.Domain.Apps.Entities.Schemas.Indexes

2
backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs

@ -17,10 +17,10 @@ using Squidex.Domain.Apps.Events.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Schemas
{

2
backend/src/Squidex.Domain.Apps.Entities/Search/SearchManager.cs

@ -10,7 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Domain.Apps.Entities.Search
{

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

@ -31,7 +31,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Orleans.Core" Version="3.3.0" />
<PackageReference Include="NodaTime" Version="3.0.1" />
<PackageReference Include="Notifo.SDK" Version="1.0.0-alpha8" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

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

@ -13,7 +13,7 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NodaTime" Version="3.0.1" />
<PackageReference Include="NodaTime" Version="3.0.3" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />

2
backend/src/Squidex.Domain.Users/DefaultUserPictureStore.cs

@ -8,8 +8,8 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Users
{

2
backend/src/Squidex.Domain.Users/PwnedPasswordValidator.cs

@ -10,8 +10,8 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using SharpPwned.NET;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Translations;
using Squidex.Log;
namespace Squidex.Domain.Users
{

2
backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs

@ -14,7 +14,7 @@ using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
namespace Squidex.Infrastructure.Assets
namespace Squidex.Assets
{
public sealed class AmazonS3AssetStore : DisposableObjectBase, IAssetStore, IInitializable
{

2
backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3Options.cs

@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Assets
namespace Squidex.Assets
{
public sealed class AmazonS3Options
{

2
backend/src/Squidex.Infrastructure.Amazon/Assets/SeekFakerStream.cs

@ -8,7 +8,7 @@
using System;
using System.IO;
namespace Squidex.Infrastructure.Assets
namespace Squidex.Assets
{
public sealed class SeekFakerStream : Stream
{

164
backend/src/Squidex.Infrastructure.Azure/Assets/AzureBlobAssetStore.cs

@ -1,164 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
namespace Squidex.Infrastructure.Assets
{
public class AzureBlobAssetStore : IAssetStore, IInitializable
{
private readonly string containerName;
private readonly string connectionString;
private CloudBlobContainer blobContainer;
public AzureBlobAssetStore(string connectionString, string containerName)
{
Guard.NotNullOrEmpty(containerName, nameof(containerName));
Guard.NotNullOrEmpty(connectionString, nameof(connectionString));
this.connectionString = connectionString;
this.containerName = containerName;
}
public async Task InitializeAsync(CancellationToken ct = default)
{
try
{
var storageAccount = CloudStorageAccount.Parse(connectionString);
var blobClient = storageAccount.CreateCloudBlobClient();
var blobReference = blobClient.GetContainerReference(containerName);
await blobReference.CreateIfNotExistsAsync(ct);
blobContainer = blobReference;
}
catch (Exception ex)
{
throw new ConfigurationException($"Cannot connect to blob container '{containerName}'.", ex);
}
}
public string? GeneratePublicUrl(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
if (blobContainer.Properties.PublicAccess != BlobContainerPublicAccessType.Blob)
{
var blob = blobContainer.GetBlockBlobReference(fileName);
return blob.Uri.ToString();
}
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
var blob = blobContainer.GetBlockBlobReference(fileName);
await blob.FetchAttributesAsync(ct);
return blob.Properties.Length;
}
catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 404)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(sourceFileName, nameof(sourceFileName));
Guard.NotNullOrEmpty(targetFileName, nameof(targetFileName));
try
{
var sourceBlob = blobContainer.GetBlockBlobReference(sourceFileName);
var targetBlob = blobContainer.GetBlobReference(targetFileName);
await targetBlob.StartCopyAsync(sourceBlob.Uri, null, AccessCondition.GenerateIfNotExistsCondition(), null, null, ct);
while (targetBlob.CopyState.Status == CopyStatus.Pending)
{
ct.ThrowIfCancellationRequested();
await Task.Delay(50, ct);
await targetBlob.FetchAttributesAsync(null, null, null, ct);
}
if (targetBlob.CopyState.Status != CopyStatus.Success)
{
throw new StorageException($"Copy of temporary file failed: {targetBlob.CopyState.Status}");
}
}
catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 409)
{
throw new AssetAlreadyExistsException(targetFileName, ex);
}
catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 404)
{
throw new AssetNotFoundException(sourceFileName, ex);
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNull(stream, nameof(stream));
try
{
var blob = blobContainer.GetBlockBlobReference(fileName);
using (var blobStream = await blob.OpenReadAsync(null, null, null, ct))
{
await blobStream.CopyToAsync(stream, range, ct);
}
}
catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 404)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
try
{
var tempBlob = blobContainer.GetBlockBlobReference(fileName);
await tempBlob.UploadFromStreamAsync(stream, overwrite ? null : AccessCondition.GenerateIfNotExistsCondition(), null, null, ct);
}
catch (StorageException ex) when (ex.RequestInformation.HttpStatusCode == 409)
{
throw new AssetAlreadyExistsException(fileName, ex);
}
}
public Task DeleteAsync(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
var blob = blobContainer.GetBlockBlobReference(fileName);
return blob.DeleteIfExistsAsync();
}
}
}

2
backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Reader.cs

@ -10,7 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Infrastructure.EventSourcing
{

2
backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Writer.cs

@ -12,7 +12,7 @@ using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using NodaTime;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Infrastructure.EventSourcing
{

2
backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs

@ -13,7 +13,7 @@ using System.Threading.Tasks;
using EventStore.ClientAPI;
using EventStore.ClientAPI.Exceptions;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Infrastructure.EventSourcing
{

2
backend/src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs

@ -14,7 +14,7 @@ using System.Threading.Tasks;
using Google;
using Google.Cloud.Storage.V1;
namespace Squidex.Infrastructure.Assets
namespace Squidex.Assets
{
public sealed class GoogleCloudAssetStore : IAssetStore, IInitializable
{

150
backend/src/Squidex.Infrastructure.MongoDb/Assets/MongoGridFsAssetStore.cs

@ -1,150 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;
namespace Squidex.Infrastructure.Assets
{
public sealed class MongoGridFsAssetStore : IAssetStore, IInitializable
{
private static readonly GridFSDownloadOptions DownloadDefault = new GridFSDownloadOptions();
private static readonly GridFSDownloadOptions DownloadSeekable = new GridFSDownloadOptions { Seekable = true };
private readonly IGridFSBucket<string> bucket;
public MongoGridFsAssetStore(IGridFSBucket<string> bucket)
{
Guard.NotNull(bucket, nameof(bucket));
this.bucket = bucket;
}
public async Task InitializeAsync(CancellationToken ct = default)
{
try
{
await bucket.Database.ListCollectionsAsync(cancellationToken: ct);
}
catch (MongoException ex)
{
throw new ConfigurationException($"Cannot connect to Mongo GridFS bucket '{bucket.Options.BucketName}'.", ex);
}
}
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
var name = GetFileName(fileName, nameof(fileName));
var query = await bucket.FindAsync(Builders<GridFSFileInfo<string>>.Filter.Eq(x => x.Id, name), cancellationToken: ct);
var file = await query.FirstOrDefaultAsync(cancellationToken: ct);
if (file == null)
{
throw new AssetNotFoundException(fileName);
}
return file.Length;
}
public async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(targetFileName, nameof(targetFileName));
try
{
var sourceName = GetFileName(sourceFileName, nameof(sourceFileName));
await using (var readStream = await bucket.OpenDownloadStreamAsync(sourceName, cancellationToken: ct))
{
await UploadAsync(targetFileName, readStream, false, ct);
}
}
catch (GridFSFileNotFoundException ex)
{
throw new AssetNotFoundException(sourceFileName, ex);
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
try
{
var name = GetFileName(fileName, nameof(fileName));
var options = range.IsDefined ? DownloadSeekable : DownloadDefault;
using (var readStream = await bucket.OpenDownloadStreamAsync(name, options, ct))
{
await readStream.CopyToAsync(stream, range, ct);
}
}
catch (GridFSFileNotFoundException ex)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
try
{
var name = GetFileName(fileName, nameof(fileName));
if (overwrite)
{
await DeleteAsync(fileName);
}
await bucket.UploadFromStreamAsync(name, name, stream, cancellationToken: ct);
}
catch (MongoWriteException ex) when (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
{
throw new AssetAlreadyExistsException(fileName);
}
catch (MongoBulkWriteException<BsonDocument> ex) when (ex.WriteErrors.Any(x => x.Category == ServerErrorCategory.DuplicateKey))
{
throw new AssetAlreadyExistsException(fileName);
}
}
public async Task DeleteAsync(string fileName)
{
try
{
var name = GetFileName(fileName, nameof(fileName));
await bucket.DeleteAsync(name);
}
catch (GridFSFileNotFoundException)
{
return;
}
}
private static string GetFileName(string fileName, string parameterName)
{
Guard.NotNullOrEmpty(fileName, parameterName);
return fileName;
}
}
}

2
backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs

@ -11,8 +11,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Log;
using EventFilter = MongoDB.Driver.FilterDefinition<Squidex.Infrastructure.EventSourcing.MongoEventCommit>;
namespace Squidex.Infrastructure.EventSourcing

2
backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs

@ -10,7 +10,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Infrastructure.EventSourcing
{

2
backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequestLogRepository.cs

@ -13,7 +13,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using NodaTime;
using Squidex.Infrastructure.Log.Store;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.Log

2
backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs

@ -12,8 +12,8 @@ using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.MongoDb;
using Squidex.Log;
namespace Squidex.Infrastructure.States
{

33
backend/src/Squidex.Infrastructure/Assets/AssetAlreadyExistsException.cs

@ -1,33 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Runtime.Serialization;
namespace Squidex.Infrastructure.Assets
{
[Serializable]
public class AssetAlreadyExistsException : Exception
{
public AssetAlreadyExistsException(string fileName, Exception? inner = null)
: base(FormatMessage(fileName), inner)
{
}
protected AssetAlreadyExistsException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
private static string FormatMessage(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
return $"An asset with name '{fileName}' already exists.";
}
}
}

39
backend/src/Squidex.Infrastructure/Assets/AssetFile.cs

@ -1,39 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
namespace Squidex.Infrastructure.Assets
{
public abstract class AssetFile : IDisposable
{
public string FileName { get; }
public string MimeType { get; }
public long FileSize { get; }
protected AssetFile(string fileName, string mimeType, long fileSize)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNullOrEmpty(mimeType, nameof(mimeType));
Guard.GreaterEquals(fileSize, 0, nameof(fileSize));
FileName = fileName;
FileSize = fileSize;
MimeType = mimeType;
}
public virtual void Dispose()
{
}
public abstract Stream OpenRead();
}
}

33
backend/src/Squidex.Infrastructure/Assets/AssetNotFoundException.cs

@ -1,33 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Runtime.Serialization;
namespace Squidex.Infrastructure.Assets
{
[Serializable]
public class AssetNotFoundException : Exception
{
public AssetNotFoundException(string fileName, Exception? inner = null)
: base(FormatMessage(fileName), inner)
{
}
protected AssetNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
private static string FormatMessage(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
return $"An asset with name '{fileName}' does not exist.";
}
}
}

28
backend/src/Squidex.Infrastructure/Assets/DelegateAssetFile.cs

@ -1,28 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
namespace Squidex.Infrastructure.Assets
{
public sealed class DelegateAssetFile : AssetFile
{
private readonly Func<Stream> openStream;
public DelegateAssetFile(string fileName, string mimeType, long fileSize, Func<Stream> openStream)
: base(fileName, mimeType, fileSize)
{
this.openStream = openStream;
}
public override Stream OpenRead()
{
return openStream();
}
}
}

197
backend/src/Squidex.Infrastructure/Assets/FTPAssetStore.cs

@ -1,197 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using FluentFTP;
using Squidex.Infrastructure.Log;
namespace Squidex.Infrastructure.Assets
{
[ExcludeFromCodeCoverage]
public sealed class FTPAssetStore : IAssetStore, IInitializable
{
private readonly string path;
private readonly ISemanticLog log;
private readonly Func<IFtpClient> factory;
public FTPAssetStore(Func<IFtpClient> factory, string path, ISemanticLog log)
{
Guard.NotNull(factory, nameof(factory));
Guard.NotNullOrEmpty(path, nameof(path));
Guard.NotNull(log, nameof(log));
this.factory = factory;
this.path = path;
this.log = log;
}
public async Task InitializeAsync(CancellationToken ct = default)
{
using (var client = factory())
{
await client.ConnectAsync(ct);
if (!await client.DirectoryExistsAsync(path, ct))
{
await client.CreateDirectoryAsync(path, ct);
}
}
log.LogInformation(w => w
.WriteProperty("action", "FTPAssetStoreConfigured")
.WriteProperty("path", path));
}
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
using (var client = GetFtpClient())
{
try
{
var size = await client.GetFileSizeAsync(fileName, ct);
if (size < 0)
{
throw new AssetNotFoundException(fileName);
}
return size;
}
catch (FtpException ex) when (IsNotFound(ex))
{
throw new AssetNotFoundException(fileName, ex);
}
}
}
public async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(sourceFileName, nameof(sourceFileName));
Guard.NotNullOrEmpty(targetFileName, nameof(targetFileName));
using (var client = GetFtpClient())
{
var tempPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
using (var stream = new FileStream(tempPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose))
{
try
{
var found = await client.DownloadAsync(stream, sourceFileName, token: ct);
if (!found)
{
throw new AssetNotFoundException(sourceFileName);
}
}
catch (FtpException ex) when (IsNotFound(ex))
{
throw new AssetNotFoundException(sourceFileName, ex);
}
await UploadAsync(client, targetFileName, stream, false, ct);
}
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNull(stream, nameof(stream));
using (var client = GetFtpClient())
{
try
{
using (var ftpStream = await client.OpenReadAsync(fileName, range.From ?? 0, ct))
{
await ftpStream.CopyToAsync(stream, range, ct, false);
}
}
catch (FtpException ex) when (IsNotFound(ex))
{
throw new AssetNotFoundException(fileName, ex);
}
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNull(stream, nameof(stream));
using (var client = GetFtpClient())
{
await UploadAsync(client, fileName, stream, overwrite, ct);
}
}
private static async Task UploadAsync(IFtpClient client, string fileName, Stream stream, bool overwrite, CancellationToken ct)
{
if (!overwrite && await client.FileExistsAsync(fileName, ct))
{
throw new AssetAlreadyExistsException(fileName);
}
var mode = overwrite ? FtpRemoteExists.Overwrite : FtpRemoteExists.Skip;
await client.UploadAsync(stream, fileName, mode, true, null, ct);
}
public async Task DeleteAsync(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
using (var client = GetFtpClient())
{
try
{
await client.DeleteFileAsync(fileName);
}
catch (FtpException ex)
{
if (!IsNotFound(ex))
{
throw;
}
}
}
}
private IFtpClient GetFtpClient()
{
var client = factory();
client.Connect();
client.SetWorkingDirectory(path);
return client;
}
private static bool IsNotFound(Exception exception)
{
if (exception is FtpCommandException command)
{
return command.CompletionCode == "550";
}
return exception.InnerException != null && IsNotFound(exception.InnerException);
}
}
}

152
backend/src/Squidex.Infrastructure/Assets/FolderAssetStore.cs

@ -1,152 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Infrastructure.Log;
namespace Squidex.Infrastructure.Assets
{
public sealed class FolderAssetStore : IAssetStore, IInitializable
{
private const int BufferSize = 81920;
private readonly ISemanticLog log;
private readonly DirectoryInfo directory;
public FolderAssetStore(string path, ISemanticLog log)
{
Guard.NotNullOrEmpty(path, nameof(path));
Guard.NotNull(log, nameof(log));
this.log = log;
directory = new DirectoryInfo(path);
}
public Task InitializeAsync(CancellationToken ct = default)
{
try
{
if (!directory.Exists)
{
directory.Create();
}
log.LogInformation(w => w
.WriteProperty("action", "FolderAssetStoreConfigured")
.WriteProperty("path", directory.FullName));
return Task.CompletedTask;
}
catch (Exception ex)
{
throw new ConfigurationException($"Cannot access directory {directory.FullName}", ex);
}
}
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
var file = GetFile(fileName, nameof(fileName));
try
{
return Task.FromResult(file.Length);
}
catch (FileNotFoundException ex)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
var targetFile = GetFile(targetFileName, nameof(targetFileName));
var sourceFile = GetFile(sourceFileName, nameof(sourceFileName));
try
{
sourceFile.CopyTo(targetFile.FullName);
return Task.CompletedTask;
}
catch (IOException) when (targetFile.Exists)
{
throw new AssetAlreadyExistsException(targetFileName);
}
catch (FileNotFoundException ex)
{
throw new AssetNotFoundException(sourceFileName, ex);
}
}
public async Task DownloadAsync(string fileName, Stream stream, BytesRange range, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
var file = GetFile(fileName, nameof(fileName));
try
{
using (var fileStream = file.OpenRead())
{
await fileStream.CopyToAsync(stream, range, ct);
}
}
catch (FileNotFoundException ex)
{
throw new AssetNotFoundException(fileName, ex);
}
}
public async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNull(stream, nameof(stream));
var file = GetFile(fileName, nameof(fileName));
try
{
using (var fileStream = file.Open(overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.Write))
{
await stream.CopyToAsync(fileStream, BufferSize, ct);
}
}
catch (IOException) when (file.Exists)
{
throw new AssetAlreadyExistsException(file.Name);
}
}
public Task DeleteAsync(string fileName)
{
var file = GetFile(fileName, nameof(fileName));
file.Delete();
return Task.CompletedTask;
}
private FileInfo GetFile(string fileName, string parameterName)
{
Guard.NotNullOrEmpty(fileName, parameterName);
return new FileInfo(GetPath(fileName));
}
private string GetPath(string name)
{
return Path.Combine(directory.FullName, name);
}
}
}

101
backend/src/Squidex.Infrastructure/Assets/HasherStream.cs

@ -1,101 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Security.Cryptography;
namespace Squidex.Infrastructure.Assets
{
public sealed class HasherStream : Stream
{
private readonly Stream inner;
private readonly IncrementalHash hasher;
public override bool CanRead
{
get { return inner.CanRead; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { return inner.Length; }
}
public override long Position
{
get { return inner.Position; }
set { throw new NotSupportedException(); }
}
public HasherStream(Stream inner, HashAlgorithmName hashAlgorithmName)
{
Guard.NotNull(inner, nameof(inner));
if (!inner.CanRead)
{
throw new ArgumentException("Inner stream must be readable.");
}
this.inner = inner;
hasher = IncrementalHash.CreateHash(hashAlgorithmName);
}
public override int Read(byte[] buffer, int offset, int count)
{
var read = inner.Read(buffer, offset, count);
if (read > 0)
{
hasher.AppendData(buffer, offset, read);
}
return read;
}
public byte[] GetHashAndReset()
{
return hasher.GetHashAndReset();
}
public string GetHashStringAndReset()
{
return Convert.ToBase64String(GetHashAndReset());
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
}

28
backend/src/Squidex.Infrastructure/Assets/IAssetStore.cs

@ -1,28 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Squidex.Infrastructure.Assets
{
public interface IAssetStore
{
string? GeneratePublicUrl(string fileName);
Task<long> GetSizeAsync(string fileName, CancellationToken ct = default);
Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default);
Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default);
Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default);
Task DeleteAsync(string fileName);
}
}

21
backend/src/Squidex.Infrastructure/Assets/IAssetThumbnailGenerator.cs

@ -1,21 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.IO;
using System.Threading.Tasks;
namespace Squidex.Infrastructure.Assets
{
public interface IAssetThumbnailGenerator
{
Task<ImageInfo?> GetImageInfoAsync(Stream source);
Task<ImageInfo> FixOrientationAsync(Stream source, Stream destination);
Task CreateThumbnailAsync(Stream source, Stream destination, ResizeOptions options);
}
}

18
backend/src/Squidex.Infrastructure/Assets/ImageFormat.cs

@ -1,18 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Assets
{
public enum ImageFormat
{
Auto,
PNG,
JPEG,
TGA,
GIF
}
}

31
backend/src/Squidex.Infrastructure/Assets/ImageInfo.cs

@ -1,31 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Assets
{
public sealed class ImageInfo
{
public string? Format { get; set; }
public int PixelWidth { get; }
public int PixelHeight { get; }
public bool IsRotatedOrSwapped { get; }
public ImageInfo(int pixelWidth, int pixelHeight, bool isRotatedOrSwapped)
{
Guard.GreaterThan(pixelWidth, 0, nameof(pixelWidth));
Guard.GreaterThan(pixelHeight, 0, nameof(pixelHeight));
PixelWidth = pixelWidth;
PixelHeight = pixelHeight;
IsRotatedOrSwapped = isRotatedOrSwapped;
}
}
}

197
backend/src/Squidex.Infrastructure/Assets/ImageSharp/ImageSharpAssetThumbnailGenerator.cs

@ -1,197 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Processing;
using ISResizeMode = SixLabors.ImageSharp.Processing.ResizeMode;
using ISResizeOptions = SixLabors.ImageSharp.Processing.ResizeOptions;
namespace Squidex.Infrastructure.Assets.ImageSharp
{
public sealed class ImageSharpAssetThumbnailGenerator : IAssetThumbnailGenerator
{
private readonly SemaphoreSlim maxTasks = new SemaphoreSlim(Math.Max(Environment.ProcessorCount / 4, 1));
public async Task CreateThumbnailAsync(Stream source, Stream destination, ResizeOptions options)
{
Guard.NotNull(source, nameof(source));
Guard.NotNull(destination, nameof(destination));
Guard.NotNull(options, nameof(options));
if (!options.IsValid)
{
await source.CopyToAsync(destination);
return;
}
var w = options.Width ?? 0;
var h = options.Height ?? 0;
await maxTasks.WaitAsync();
try
{
using (var image = Image.Load(source, out var format))
{
var encoder = GetEncoder(options, format);
image.Mutate(x => x.AutoOrient());
if (w > 0 || h > 0)
{
var isCropUpsize = options.Mode == ResizeMode.CropUpsize;
if (!Enum.TryParse<ISResizeMode>(options.Mode.ToString(), true, out var resizeMode))
{
resizeMode = ISResizeMode.Max;
}
if (isCropUpsize)
{
resizeMode = ISResizeMode.Crop;
}
if (w >= image.Width && h >= image.Height && resizeMode == ISResizeMode.Crop && !isCropUpsize)
{
resizeMode = ISResizeMode.BoxPad;
}
var resizeOptions = new ISResizeOptions { Size = new Size(w, h), Mode = resizeMode };
if (options.FocusX.HasValue && options.FocusY.HasValue)
{
resizeOptions.CenterCoordinates = new PointF(
+(options.FocusX.Value / 2f) + 0.5f,
-(options.FocusY.Value / 2f) + 0.5f
);
}
image.Mutate(x => x.Resize(resizeOptions));
}
await image.SaveAsync(destination, encoder);
}
}
finally
{
maxTasks.Release();
}
}
private static IImageEncoder GetEncoder(ResizeOptions options, IImageFormat? format)
{
var encoder = Configuration.Default.ImageFormatsManager.FindEncoder(format);
if (encoder == null)
{
throw new NotSupportedException();
}
if (options.Quality.HasValue && (encoder is JpegEncoder || !options.KeepFormat) && options.Format == ImageFormat.Auto)
{
encoder = new JpegEncoder { Quality = options.Quality.Value };
}
else if (options.Format == ImageFormat.JPEG)
{
encoder = new JpegEncoder();
}
else if (options.Format == ImageFormat.PNG)
{
encoder = new PngEncoder();
}
else if (options.Format == ImageFormat.TGA)
{
encoder = new TgaEncoder();
}
else if (options.Format == ImageFormat.GIF)
{
encoder = new GifEncoder();
}
return encoder;
}
public Task<ImageInfo?> GetImageInfoAsync(Stream source)
{
Guard.NotNull(source, nameof(source));
ImageInfo? result = null;
try
{
var image = Image.Identify(source, out var format);
if (image != null)
{
result = GetImageInfo(image);
result.Format = format.Name;
}
}
catch
{
result = null;
}
return Task.FromResult(result);
}
public async Task<ImageInfo> FixOrientationAsync(Stream source, Stream destination)
{
Guard.NotNull(source, nameof(source));
Guard.NotNull(destination, nameof(destination));
await maxTasks.WaitAsync();
try
{
using (var image = Image.Load(source, out var format))
{
var encoder = Configuration.Default.ImageFormatsManager.FindEncoder(format);
if (encoder == null)
{
throw new NotSupportedException();
}
image.Mutate(x => x.AutoOrient());
await image.SaveAsync(destination, encoder);
return GetImageInfo(image);
}
}
finally
{
maxTasks.Release();
}
}
private static ImageInfo GetImageInfo(IImageInfo image)
{
var isRotatedOrSwapped = false;
if (image.Metadata.ExifProfile != null)
{
var value = image.Metadata.ExifProfile.GetValue(ExifTag.Orientation);
isRotatedOrSwapped = value?.Value > 1;
}
return new ImageInfo(image.Width, image.Height, isRotatedOrSwapped);
}
}
}

128
backend/src/Squidex.Infrastructure/Assets/MemoryAssetStore.cs

@ -1,128 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.Assets
{
public class MemoryAssetStore : IAssetStore
{
private readonly ConcurrentDictionary<string, MemoryStream> streams = new ConcurrentDictionary<string, MemoryStream>();
private readonly AsyncLock readerLock = new AsyncLock();
private readonly AsyncLock writerLock = new AsyncLock();
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public async Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
if (!streams.TryGetValue(fileName, out var sourceStream))
{
throw new AssetNotFoundException(fileName);
}
using (await readerLock.LockAsync())
{
return sourceStream.Length;
}
}
public virtual async Task CopyAsync(string sourceFileName, string targetFileName, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(sourceFileName, nameof(sourceFileName));
Guard.NotNullOrEmpty(targetFileName, nameof(targetFileName));
if (!streams.TryGetValue(sourceFileName, out var sourceStream))
{
throw new AssetNotFoundException(sourceFileName);
}
using (await readerLock.LockAsync())
{
await UploadAsync(targetFileName, sourceStream, false, ct);
}
}
public virtual async Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNull(stream, nameof(stream));
if (!streams.TryGetValue(fileName, out var sourceStream))
{
throw new AssetNotFoundException(fileName);
}
using (await readerLock.LockAsync())
{
try
{
await sourceStream.CopyToAsync(stream, range, ct);
}
finally
{
sourceStream.Position = 0;
}
}
}
public virtual async Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
Guard.NotNull(stream, nameof(stream));
var memoryStream = new MemoryStream();
async Task CopyAsync()
{
using (await writerLock.LockAsync())
{
try
{
await stream.CopyToAsync(memoryStream, 81920, ct);
}
finally
{
memoryStream.Position = 0;
}
}
}
if (overwrite)
{
await CopyAsync();
streams[fileName] = memoryStream;
}
else if (streams.TryAdd(fileName, memoryStream))
{
await CopyAsync();
}
else
{
throw new AssetAlreadyExistsException(fileName);
}
}
public virtual Task DeleteAsync(string fileName)
{
Guard.NotNullOrEmpty(fileName, nameof(fileName));
streams.TryRemove(fileName, out _);
return Task.CompletedTask;
}
}
}

47
backend/src/Squidex.Infrastructure/Assets/NoopAssetStore.cs

@ -1,47 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Squidex.Infrastructure.Assets
{
public sealed class NoopAssetStore : IAssetStore
{
public string? GeneratePublicUrl(string fileName)
{
return null;
}
public Task<long> GetSizeAsync(string fileName, CancellationToken ct = default)
{
throw new NotSupportedException();
}
public Task CopyAsync(string sourceFileName, string fileName, CancellationToken ct = default)
{
throw new NotSupportedException();
}
public Task DownloadAsync(string fileName, Stream stream, BytesRange range = default, CancellationToken ct = default)
{
throw new NotSupportedException();
}
public Task UploadAsync(string fileName, Stream stream, bool overwrite = false, CancellationToken ct = default)
{
throw new NotSupportedException();
}
public Task DeleteAsync(string fileName)
{
throw new NotSupportedException();
}
}
}

20
backend/src/Squidex.Infrastructure/Assets/ResizeMode.cs

@ -1,20 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Assets
{
public enum ResizeMode
{
Crop,
CropUpsize,
Pad,
BoxPad,
Max,
Min,
Stretch
}
}

72
backend/src/Squidex.Infrastructure/Assets/ResizeOptions.cs

@ -1,72 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Text;
namespace Squidex.Infrastructure.Assets
{
public sealed class ResizeOptions
{
public ImageFormat Format { get; set; }
public ResizeMode Mode { get; set; }
public int? Width { get; set; }
public int? Height { get; set; }
public int? Quality { get; set; }
public float? FocusX { get; set; }
public float? FocusY { get; set; }
public bool KeepFormat { get; set; }
public bool IsValid
{
get { return Width > 0 || Height > 0 || Quality > 0 || Format != ImageFormat.Auto; }
}
public override string ToString()
{
var sb = new StringBuilder();
sb.Append(Width);
sb.Append("_");
sb.Append(Height);
sb.Append("_");
sb.Append(Mode);
if (Quality.HasValue)
{
sb.Append("_");
sb.Append(Quality);
}
if (FocusX.HasValue)
{
sb.Append("_focusX_");
sb.Append(FocusX);
}
if (FocusY.HasValue)
{
sb.Append("_focusY_");
sb.Append(FocusY);
}
if (Format != ImageFormat.Auto)
{
sb.Append("_format_");
sb.Append(Format.ToString());
}
return sb.ToString();
}
}
}

64
backend/src/Squidex.Infrastructure/Assets/StreamExtensions.cs

@ -1,64 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Buffers;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Squidex.Infrastructure.Assets
{
public static class StreamExtensions
{
private static readonly ArrayPool<byte> Pool = ArrayPool<byte>.Create();
public static async Task CopyToAsync(this Stream source, Stream target, BytesRange range, CancellationToken ct, bool skip = true)
{
var buffer = Pool.Rent(8192);
try
{
if (skip && range.From > 0)
{
source.Seek(range.From.Value, SeekOrigin.Begin);
}
var bytesLeft = range.Length;
while (true)
{
if (bytesLeft <= 0)
{
return;
}
ct.ThrowIfCancellationRequested();
var readLength = (int)Math.Min(buffer.Length, bytesLeft);
var read = await source.ReadAsync(buffer, 0, readLength, ct);
bytesLeft -= read;
if (read == 0)
{
return;
}
ct.ThrowIfCancellationRequested();
await target.WriteAsync(buffer, 0, read, ct);
}
}
finally
{
Pool.Return(buffer);
}
}
}
}

65
backend/src/Squidex.Infrastructure/BytesRange.cs

@ -1,65 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
namespace Squidex.Infrastructure
{
public readonly struct BytesRange
{
public readonly long? From;
public readonly long? To;
public long Length
{
get
{
if (To < 0 || From < 0)
{
return 0;
}
var result = (To ?? long.MaxValue) - (From ?? 0);
if (result == long.MaxValue)
{
return long.MaxValue;
}
return Math.Max(0, result + 1);
}
}
public bool IsDefined
{
get { return (From >= 0 || To >= 0) && Length > 0; }
}
public BytesRange(long? from, long? to)
{
From = from;
To = to;
}
public override string? ToString()
{
if (Length == 0)
{
return null;
}
if (From.HasValue || To.HasValue)
{
return $"bytes={From}-{To}";
}
return null;
}
}
}

2
backend/src/Squidex.Infrastructure/Commands/DomainObject.cs

@ -7,8 +7,8 @@
using System.Threading.Tasks;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Infrastructure.Commands
{

2
backend/src/Squidex.Infrastructure/Commands/DomainObjectBase.cs

@ -9,9 +9,9 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.States;
using Squidex.Infrastructure.Tasks;
using Squidex.Log;
namespace Squidex.Infrastructure.Commands
{

2
backend/src/Squidex.Infrastructure/Commands/LogCommandMiddleware.cs

@ -7,7 +7,7 @@
using System;
using System.Threading.Tasks;
using Squidex.Infrastructure.Log;
using Squidex.Log;
namespace Squidex.Infrastructure.Commands
{

2
backend/src/Squidex.Infrastructure/Commands/LogSnapshotDomainObject.cs

@ -9,8 +9,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.States;
using Squidex.Log;
namespace Squidex.Infrastructure.Commands
{

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

Loading…
Cancel
Save