Browse Source

Started with first refactoring.

pull/349/head
Sebastian Stehle 7 years ago
parent
commit
c48a58fa90
  1. 3
      extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs
  2. 22
      extensions/Squidex.Extensions/Actions/Algolia/AlgoliaPlugin.cs
  3. 1
      extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs
  4. 22
      extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueuePlugin.cs
  5. 1
      extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs
  6. 22
      extensions/Squidex.Extensions/Actions/Discourse/DiscoursePlugin.cs
  7. 1
      extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs
  8. 22
      extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchPlugin.cs
  9. 1
      extensions/Squidex.Extensions/Actions/Email/EmailAction.cs
  10. 22
      extensions/Squidex.Extensions/Actions/Email/EmailPlugin.cs
  11. 1
      extensions/Squidex.Extensions/Actions/Fastly/FastlyAction.cs
  12. 22
      extensions/Squidex.Extensions/Actions/Fastly/FastlyPlugin.cs
  13. 1
      extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs
  14. 22
      extensions/Squidex.Extensions/Actions/Medium/MediumPlugin.cs
  15. 1
      extensions/Squidex.Extensions/Actions/Prerender/PrerenderAction.cs
  16. 22
      extensions/Squidex.Extensions/Actions/Prerender/PrerenderPlugin.cs
  17. 1
      extensions/Squidex.Extensions/Actions/Slack/SlackAction.cs
  18. 22
      extensions/Squidex.Extensions/Actions/Slack/SlackPlugin.cs
  19. 57
      extensions/Squidex.Extensions/Actions/TriggerTypes.cs
  20. 1
      extensions/Squidex.Extensions/Actions/Twitter/TweetAction.cs
  21. 22
      extensions/Squidex.Extensions/Actions/Twitter/TwitterPlugin.cs
  22. 1
      extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs
  23. 22
      extensions/Squidex.Extensions/Actions/Webhook/WebhookPlugin.cs
  24. 16
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/FormattableAttribute.cs
  25. 2
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionAttribute.cs
  26. 4
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionDefinition.cs
  27. 3
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandlerAttribute.cs
  28. 71
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionRegistry.cs
  29. 4
      src/Squidex.Infrastructure/Assets/ImageSharp/ImageSharpAssetThumbnailGenerator.cs
  30. 65
      src/Squidex.Infrastructure/Configuration/ConfigurationExtensions.cs
  31. 4
      src/Squidex.Infrastructure/Configuration/Options.cs
  32. 70
      src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs
  33. 18
      src/Squidex.Infrastructure/Plugins/IPlugin.cs
  34. 16
      src/Squidex.Infrastructure/Plugins/IWebPlugin.cs
  35. 59
      src/Squidex.Infrastructure/Plugins/PluginManager.cs
  36. 14
      src/Squidex.Infrastructure/Plugins/PluginOptions.cs
  37. 1
      src/Squidex.Infrastructure/Squidex.Infrastructure.csproj
  38. 16
      src/Squidex.Infrastructure/Translations/DeepLTranslator.cs
  39. 14
      src/Squidex.Infrastructure/Translations/DeepLTranslatorOptions.cs
  40. 2
      src/Squidex/Areas/Api/Config/Swagger/SwaggerServices.cs
  41. 3
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionConverter.cs
  42. 3
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs
  43. 26
      src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  44. 2
      src/Squidex/Config/Domain/AssetServices.cs
  45. 2
      src/Squidex/Config/Domain/EntitiesServices.cs
  46. 1
      src/Squidex/Config/Domain/EventPublishersServices.cs
  47. 2
      src/Squidex/Config/Domain/EventStoreServices.cs
  48. 18
      src/Squidex/Config/Domain/InfrastructureServices.cs
  49. 1
      src/Squidex/Config/Domain/LoggingServices.cs
  50. 3
      src/Squidex/Config/Domain/RuleServices.cs
  51. 1
      src/Squidex/Config/Domain/SerializationServices.cs
  52. 2
      src/Squidex/Config/Domain/StoreServices.cs
  53. 1
      src/Squidex/Config/Domain/SubscriptionServices.cs
  54. 1
      src/Squidex/Config/Orleans/OrleansServices.cs
  55. 1
      src/Squidex/Config/Web/WebServices.cs
  56. 76
      src/Squidex/Pipeline/Plugins/PluginExtensions.cs
  57. 1
      src/Squidex/Squidex.csproj
  58. 3
      src/Squidex/WebStartup.cs

3
extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Algolia namespace Squidex.Extensions.Actions.Algolia
@ -28,7 +29,7 @@ namespace Squidex.Extensions.Actions.Algolia
public string ApiKey { get; set; } public string ApiKey { get; set; }
[Required] [Required]
[Display(Name = "Index Name", Description = "THe name of the index.")] [Display(Name = "Index Name", Description = "The name of the index.")]
public string IndexName { get; set; } public string IndexName { get; set; }
} }
} }

22
extensions/Squidex.Extensions/Actions/Algolia/AlgoliaPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Algolia
{
public sealed class AlgoliaPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<AlgoliaAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs

@ -8,6 +8,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;

22
extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueuePlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.AzureQueue
{
public sealed class AzureQueuePlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<AzureQueueAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs

@ -7,6 +7,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;

22
extensions/Squidex.Extensions/Actions/Discourse/DiscoursePlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Discourse
{
public sealed class DiscoursePlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<DiscourseAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs

@ -7,6 +7,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;

22
extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.ElasticSearch
{
public sealed class ElasticSearchPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<ElasticSearchAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Email/EmailAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Email namespace Squidex.Extensions.Actions.Email

22
extensions/Squidex.Extensions/Actions/Email/EmailPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Email
{
public sealed class EmailPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<EmailAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Fastly/FastlyAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Fastly namespace Squidex.Extensions.Actions.Fastly

22
extensions/Squidex.Extensions/Actions/Fastly/FastlyPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Fastly
{
public sealed class FastlyPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<FastlyAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Medium namespace Squidex.Extensions.Actions.Medium

22
extensions/Squidex.Extensions/Actions/Medium/MediumPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Medium
{
public sealed class MediumPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<MediumAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Prerender/PrerenderAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Prerender namespace Squidex.Extensions.Actions.Prerender

22
extensions/Squidex.Extensions/Actions/Prerender/PrerenderPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Prerender
{
public sealed class PrerenderPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<PrerenderAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Slack/SlackAction.cs

@ -7,6 +7,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;

22
extensions/Squidex.Extensions/Actions/Slack/SlackPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Slack
{
public sealed class SlackPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<SlackAction>();
}
}
}

57
extensions/Squidex.Extensions/Actions/TriggerTypes.cs

@ -1,57 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions
{
public static class TriggerTypes
{
private const string TriggerSuffix = "Trigger";
private const string TriggerSuffixV2 = "TriggerV2";
public static readonly IReadOnlyDictionary<string, RuleElement> All = new Dictionary<string, RuleElement>
{
[GetTriggerName(typeof(ContentChangedTriggerV2))] = new RuleElement
{
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'><path d='M21.875 28H6.125A6.087 6.087 0 0 1 0 21.875V6.125A6.087 6.087 0 0 1 6.125 0h15.75A6.087 6.087 0 0 1 28 6.125v15.75A6.088 6.088 0 0 1 21.875 28zM6.125 1.75A4.333 4.333 0 0 0 1.75 6.125v15.75a4.333 4.333 0 0 0 4.375 4.375h15.75a4.333 4.333 0 0 0 4.375-4.375V6.125a4.333 4.333 0 0 0-4.375-4.375H6.125z'/><path d='M13.125 12.25H7.35c-1.575 0-2.888-1.313-2.888-2.888V7.349c0-1.575 1.313-2.888 2.888-2.888h5.775c1.575 0 2.887 1.313 2.887 2.888v2.013c0 1.575-1.312 2.888-2.887 2.888zM7.35 6.212c-.613 0-1.138.525-1.138 1.138v2.012A1.16 1.16 0 0 0 7.35 10.5h5.775a1.16 1.16 0 0 0 1.138-1.138V7.349a1.16 1.16 0 0 0-1.138-1.138H7.35zM22.662 16.713H5.337c-.525 0-.875-.35-.875-.875s.35-.875.875-.875h17.237c.525 0 .875.35.875.875s-.35.875-.787.875zM15.138 21.262h-9.8c-.525 0-.875-.35-.875-.875s.35-.875.875-.875h9.713c.525 0 .875.35.875.875s-.35.875-.787.875z'/></svg>",
IconColor = "#3389ff",
Display = "Content changed",
Description = "For content changes like created, updated, published, unpublished..."
},
[GetTriggerName(typeof(AssetChangedTriggerV2))] = new RuleElement
{
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'><path d='M21.875 28H6.125A6.087 6.087 0 0 1 0 21.875V6.125A6.087 6.087 0 0 1 6.125 0h15.75A6.087 6.087 0 0 1 28 6.125v15.75A6.088 6.088 0 0 1 21.875 28zM6.125 1.75A4.333 4.333 0 0 0 1.75 6.125v15.75a4.333 4.333 0 0 0 4.375 4.375h15.75a4.333 4.333 0 0 0 4.375-4.375V6.125a4.333 4.333 0 0 0-4.375-4.375H6.125z'/><path d='M21.088 23.537H9.1c-.35 0-.612-.175-.787-.525s-.088-.7.088-.962l8.225-9.713c.175-.175.438-.35.7-.35s.525.175.7.35l5.25 7.525c.088.087.088.175.088.262.438 1.225.087 2.012-.175 2.45-.613.875-1.925.963-2.1.963zm-10.063-1.75h10.15c.175 0 .612-.088.7-.262.088-.088.088-.35 0-.7l-4.55-6.475-6.3 7.438zM9.1 13.737c-2.1 0-3.85-1.75-3.85-3.85S7 6.037 9.1 6.037s3.85 1.75 3.85 3.85-1.663 3.85-3.85 3.85zm0-5.949c-1.138 0-2.1.875-2.1 2.1s.962 2.1 2.1 2.1 2.1-.962 2.1-2.1-.875-2.1-2.1-2.1z'/></svg>",
IconColor = "#3389ff",
Display = "Asset changed",
Description = "For asset changes like uploaded, updated (reuploaded), renamed, deleted..."
},
[GetTriggerName(typeof(SchemaChangedTrigger))] = new RuleElement
{
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M9.6 0c-.6 0-1 .4-1 1s.4 1 1 1h12.8c.6 0 1.1-.4 1.1-1s-.4-1-1-1H9.6zM6.1 4.3c-.6 0-1 .4-1 1s.4 1 1 1h19.8c.5 0 .9-.4.9-1s-.4-1-1-1H6.1zM7 8.6c-3.9 0-7 3.1-7 7V25c0 3.9 3.1 7 7 7h18c3.9 0 7-3.1 7-7v-9.4c0-3.9-3.1-7-7-7H7zm0 2h18c2.8 0 5 2.2 5 5V25c0 2.8-2.2 5-5 5H7c-2.8 0-5-2.2-5-5v-9.4c0-2.8 2.2-5 5-5zM5.3 13v2c0 2.4 2 4.4 4.4 4.4h12.7c2.4 0 4.4-2 4.4-4.4v-2H25v2c0 1.5-1.2 2.6-2.6 2.6H9.6C8.2 17.7 7 16.5 7 15v-2H5.3z' id='path5869'/></svg>",
IconColor = "#3389ff",
Display = "Schema changed",
Description = "When a schema definition has been created, updated, published or deleted..."
},
[GetTriggerName(typeof(UsageTrigger))] = new RuleElement
{
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M21.2 11.4c-.2 0-.4-.1-.6-.2-.5-.3-.6-.9-.3-1.4L22 7.2c.3-.5.9-.6 1.4-.3.6.4.7 1.1.4 1.5L22.1 11c-.2.3-.5.4-.9.4zM16 20.9h-.2c-1-.1-2-.6-2.5-1.5l-6-8.7c-.3-.3-.3-.8 0-1.2.3-.3.8-.4 1.2-.2l9.2 5.4c.9.5 1.5 1.4 1.6 2.4.1 1-.2 2-.9 2.8-.6.7-1.5 1-2.4 1zm-4.6-7.5l3.4 5c.2.3.6.6 1 .6s.8-.1 1.1-.4c.3-.3.4-.7.3-1.1-.1-.4-.3-.7-.6-1zM25.9 32H6.1C2.8 32 0 29.2 0 25.9v-10C0 7.1 7.1 0 15.8 0 24.8 0 32 7.2 32 16.2v9.7c0 3.3-2.8 6.1-6.1 6.1zM15.8 2C8.2 2 2 8.2 2 15.8v10C2 28.1 3.9 30 6.1 30h19.7c2.3 0 4.1-1.9 4.1-4.1v-9.7C30 8.4 23.6 2 15.8 2z'/></svg>",
IconColor = "#3389ff",
Display = "Usage exceeded",
Description = "When monthly API calls exceed a specified limit for one time a month..."
}
};
private static string GetTriggerName(Type type)
{
return type.TypeName(false, TriggerSuffix, TriggerSuffixV2);
}
}
}

1
extensions/Squidex.Extensions/Actions/Twitter/TweetAction.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Twitter namespace Squidex.Extensions.Actions.Twitter

22
extensions/Squidex.Extensions/Actions/Twitter/TwitterPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Twitter
{
public sealed class TwitterPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<TweetAction>();
}
}
}

1
extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs

@ -7,6 +7,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;

22
extensions/Squidex.Extensions/Actions/Webhook/WebhookPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// 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 Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Webhook
{
public sealed class WebhookPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
RuleActionRegistry.Add<WebhookAction>();
}
}
}

16
src/Squidex.Domain.Apps.Core.Operations/HandleRules/FormattableAttribute.cs

@ -0,0 +1,16 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
namespace Squidex.Domain.Apps.Core.HandleRules
{
[AttributeUsage(AttributeTargets.Property)]
public sealed class FormattableAttribute : Attribute
{
}
}

2
extensions/Squidex.Extensions/Actions/RuleActionAttribute.cs → src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionAttribute.cs

@ -7,7 +7,7 @@
using System; using System;
namespace Squidex.Extensions.Actions namespace Squidex.Domain.Apps.Core.HandleRules
{ {
[AttributeUsage(AttributeTargets.Class, Inherited = false)] [AttributeUsage(AttributeTargets.Class, Inherited = false)]
public sealed class RuleActionAttribute : Attribute public sealed class RuleActionAttribute : Attribute

4
extensions/Squidex.Extensions/Actions/RuleElement.cs → src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionDefinition.cs

@ -7,9 +7,9 @@
using System; using System;
namespace Squidex.Extensions.Actions namespace Squidex.Domain.Apps.Core.HandleRules
{ {
public sealed class RuleElement public sealed class RuleActionDefinition
{ {
public Type Type { get; set; } public Type Type { get; set; }

3
extensions/Squidex.Extensions/Actions/RuleActionHandlerAttribute.cs → src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandlerAttribute.cs

@ -6,10 +6,9 @@
// ========================================================================== // ==========================================================================
using System; using System;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions namespace Squidex.Domain.Apps.Core.HandleRules
{ {
[AttributeUsage(AttributeTargets.Class, Inherited = false)] [AttributeUsage(AttributeTargets.Class, Inherited = false)]
public sealed class RuleActionHandlerAttribute : Attribute public sealed class RuleActionHandlerAttribute : Attribute

71
extensions/Squidex.Extensions/Actions/RuleElementRegistry.cs → src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionRegistry.cs

@ -12,21 +12,16 @@ using System.Reflection;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions namespace Squidex.Domain.Apps.Core.HandleRules
{ {
public static class RuleElementRegistry public static class RuleActionRegistry
{ {
private const string ActionSuffix = "Action"; private const string ActionSuffix = "Action";
private const string ActionSuffixV2 = "Action"; private const string ActionSuffixV2 = "Action";
private static readonly HashSet<Type> ActionHandlerTypes = new HashSet<Type>(); private static readonly HashSet<Type> ActionHandlerTypes = new HashSet<Type>();
private static readonly Dictionary<string, RuleElement> ActionTypes = new Dictionary<string, RuleElement>(); private static readonly Dictionary<string, RuleActionDefinition> ActionTypes = new Dictionary<string, RuleActionDefinition>();
public static IReadOnlyDictionary<string, RuleElement> Triggers public static IReadOnlyDictionary<string, RuleActionDefinition> Actions
{
get { return TriggerTypes.All; }
}
public static IReadOnlyDictionary<string, RuleElement> Actions
{ {
get { return ActionTypes; } get { return ActionTypes; }
} }
@ -36,10 +31,10 @@ namespace Squidex.Extensions.Actions
get { return ActionHandlerTypes; } get { return ActionHandlerTypes; }
} }
static RuleElementRegistry() static RuleActionRegistry()
{ {
var actionTypes = var actionTypes =
typeof(RuleElementRegistry).Assembly typeof(RuleActionRegistry).Assembly
.GetTypes() .GetTypes()
.Where(x => typeof(RuleAction).IsAssignableFrom(x)) .Where(x => typeof(RuleAction).IsAssignableFrom(x))
.Where(x => x.GetCustomAttribute<RuleActionAttribute>() != null) .Where(x => x.GetCustomAttribute<RuleActionAttribute>() != null)
@ -48,25 +43,47 @@ namespace Squidex.Extensions.Actions
foreach (var actionType in actionTypes) foreach (var actionType in actionTypes)
{ {
var name = GetActionName(actionType); Add(actionType);
var metadata = actionType.GetCustomAttribute<RuleActionAttribute>();
ActionTypes[name] =
new RuleElement
{
Type = actionType,
Display = metadata.Display,
Description = metadata.Description,
IconColor = metadata.IconColor,
IconImage = metadata.IconImage,
ReadMore = metadata.ReadMore
};
ActionHandlerTypes.Add(actionType.GetCustomAttribute<RuleActionHandlerAttribute>().HandlerType);
} }
} }
public static void Add<T>() where T : RuleAction
{
Add(typeof(T));
}
private static void Add(Type actionType)
{
var metadata = actionType.GetCustomAttribute<RuleActionAttribute>();
if (metadata == null)
{
return;
}
var handlerAttribute = actionType.GetCustomAttribute<RuleActionHandlerAttribute>();
if (handlerAttribute == null)
{
return;
}
var name = GetActionName(actionType);
ActionTypes[name] =
new RuleActionDefinition
{
Type = actionType,
Display = metadata.Display,
Description = metadata.Description,
IconColor = metadata.IconColor,
IconImage = metadata.IconImage,
ReadMore = metadata.ReadMore
};
ActionHandlerTypes.Add(actionType.GetCustomAttribute<RuleActionHandlerAttribute>().HandlerType);
}
public static TypeNameRegistry MapRuleActions(this TypeNameRegistry typeNameRegistry) public static TypeNameRegistry MapRuleActions(this TypeNameRegistry typeNameRegistry)
{ {
foreach (var actionType in ActionTypes.Values) foreach (var actionType in ActionTypes.Values)

4
src/Squidex.Infrastructure/Assets/ImageSharp/ImageSharpAssetThumbnailGenerator.cs

@ -19,8 +19,8 @@ namespace Squidex.Infrastructure.Assets.ImageSharp
{ {
public ImageSharpAssetThumbnailGenerator() public ImageSharpAssetThumbnailGenerator()
{ {
Configuration.Default.ImageFormatsManager.AddImageFormat(ImageFormats.Jpeg); SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.AddImageFormat(ImageFormats.Jpeg);
Configuration.Default.ImageFormatsManager.AddImageFormat(ImageFormats.Png); SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.AddImageFormat(ImageFormats.Png);
} }
public Task CreateThumbnailAsync(Stream source, Stream destination, int? width, int? height, string mode) public Task CreateThumbnailAsync(Stream source, Stream destination, int? width, int? height, string mode)

65
src/Squidex.Infrastructure/Configuration/ConfigurationExtensions.cs

@ -0,0 +1,65 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Configuration;
namespace Squidex.Infrastructure.Configuration
{
public static class ConfigurationExtensions
{
public static T GetOptionalValue<T>(this IConfiguration config, string path, T defaultValue = default)
{
var value = config.GetValue(path, defaultValue);
return value;
}
public static int GetOptionalValue(this IConfiguration config, string path, int defaultValue)
{
var value = config.GetValue<string>(path);
if (string.IsNullOrWhiteSpace(value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{
result = defaultValue;
}
return result;
}
public static string GetRequiredValue(this IConfiguration config, string path)
{
var value = config.GetValue<string>(path);
if (string.IsNullOrWhiteSpace(value))
{
var name = string.Join(" ", path.Split(':').Select(x => x.ToPascalCase()));
throw new ConfigurationException($"Configure the {name} with '{path}'.");
}
return value;
}
public static string ConfigureByOption(this IConfiguration config, string path, Options options)
{
var value = config.GetRequiredValue(path);
if (options.TryGetValue(value, out var action))
{
action();
}
else
{
throw new ConfigurationException($"Unsupported value '{value}' for '{path}', supported: {string.Join(" ", options.Keys)}.");
}
return value;
}
}
}

4
src/Squidex/Config/Options.cs → src/Squidex.Infrastructure/Configuration/Options.cs

@ -1,14 +1,14 @@
// ========================================================================== // ==========================================================================
// Squidex Headless CMS // Squidex Headless CMS
// ========================================================================== // ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt) // Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Squidex.Config namespace Squidex.Infrastructure.Configuration
{ {
public sealed class Options : Dictionary<string, Action> public sealed class Options : Dictionary<string, Action>
{ {

70
src/Squidex/Config/ServiceExtensions.cs → src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs

@ -1,20 +1,18 @@
// ========================================================================== // ==========================================================================
// Squidex Headless CMS // Squidex Headless CMS
// ========================================================================== // ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt) // Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure; using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Squidex.Config namespace Squidex.Infrastructure.DependencyInjection
{ {
public static class ServiceExtensions public static class DependencyInjectionExtensions
{ {
public sealed class InterfaceRegistrator<T> public sealed class InterfaceRegistrator<T>
{ {
@ -30,6 +28,16 @@ namespace Squidex.Config
return this; return this;
} }
public InterfaceRegistrator<T> AsOptional<TInterface>()
{
if (typeof(TInterface) != typeof(T))
{
services.TryAddSingleton(typeof(TInterface), c => c.GetRequiredService<T>());
}
return this;
}
public InterfaceRegistrator<T> As<TInterface>() public InterfaceRegistrator<T> As<TInterface>()
{ {
if (typeof(TInterface) != typeof(T)) if (typeof(TInterface) != typeof(T))
@ -89,55 +97,5 @@ namespace Squidex.Config
services.AddSingleton(typeof(IInitializable), c => c.GetRequiredService<T>()); services.AddSingleton(typeof(IInitializable), c => c.GetRequiredService<T>());
} }
} }
public static T GetOptionalValue<T>(this IConfiguration config, string path, T defaultValue = default)
{
var value = config.GetValue(path, defaultValue);
return value;
}
public static int GetOptionalValue(this IConfiguration config, string path, int defaultValue)
{
var value = config.GetValue<string>(path);
var result = defaultValue;
if (string.IsNullOrWhiteSpace(value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
{
result = defaultValue;
}
return result;
}
public static string GetRequiredValue(this IConfiguration config, string path)
{
var value = config.GetValue<string>(path);
if (string.IsNullOrWhiteSpace(value))
{
var name = string.Join(' ', path.Split(':').Select(x => x.ToPascalCase()));
throw new ConfigurationException($"Configure the {name} with '{path}'.");
}
return value;
}
public static string ConfigureByOption(this IConfiguration config, string path, Options options)
{
var value = config.GetRequiredValue(path);
if (options.TryGetValue(value, out var action))
{
action();
}
else
{
throw new ConfigurationException($"Unsupported value '{value}' for '{path}', supported: {string.Join(' ', options.Keys)}.");
}
return value;
}
} }
} }

18
src/Squidex.Infrastructure/Plugins/IPlugin.cs

@ -0,0 +1,18 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Squidex.Infrastructure.Plugins
{
public interface IPlugin
{
void ConfigureServices(IServiceCollection services, IConfiguration configuration);
}
}

16
src/Squidex.Infrastructure/Plugins/IWebPlugin.cs

@ -0,0 +1,16 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Microsoft.AspNetCore.Builder;
namespace Squidex.Infrastructure.Plugins
{
public interface IWebPlugin
{
void Configure(IApplicationBuilder app);
}
}

59
src/Squidex.Infrastructure/Plugins/PluginManager.cs

@ -0,0 +1,59 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Squidex.Infrastructure.Plugins
{
public sealed class PluginManager
{
private readonly HashSet<IPlugin> plugins = new HashSet<IPlugin>();
public void Add(Assembly assembly)
{
Guard.NotNull(assembly, nameof(assembly));
var pluginTypes =
assembly.GetTypes()
.Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract);
foreach (var pluginType in pluginTypes)
{
var plugin = (IPlugin)Activator.CreateInstance(pluginType);
plugins.Add(plugin);
}
}
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
Guard.NotNull(services, nameof(services));
Guard.NotNull(configuration, nameof(configuration));
foreach (var plugin in plugins)
{
plugin.ConfigureServices(services, configuration);
}
}
public void Configure(IApplicationBuilder app)
{
Guard.NotNull(app, nameof(app));
foreach (var plugin in plugins.OfType<IWebPlugin>())
{
plugin.Configure(app);
}
}
}
}

14
src/Squidex.Infrastructure/Plugins/PluginOptions.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Plugins
{
public sealed class PluginOptions
{
public string[] Plugins { get; set; }
}
}

1
src/Squidex.Infrastructure/Squidex.Infrastructure.csproj

@ -8,6 +8,7 @@
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />

16
src/Squidex.Infrastructure/Translations/DeepLTranslator.cs

@ -10,6 +10,7 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;
namespace Squidex.Infrastructure.Translations namespace Squidex.Infrastructure.Translations
@ -18,7 +19,7 @@ namespace Squidex.Infrastructure.Translations
{ {
private const string Url = "https://api.deepl.com/v2/translate"; private const string Url = "https://api.deepl.com/v2/translate";
private readonly HttpClient httpClient = new HttpClient(); private readonly HttpClient httpClient = new HttpClient();
private readonly string authKey; private readonly DeepLTranslatorOptions deepLOptions;
private readonly IJsonSerializer jsonSerializer; private readonly IJsonSerializer jsonSerializer;
private sealed class Response private sealed class Response
@ -31,12 +32,12 @@ namespace Squidex.Infrastructure.Translations
public string Text { get; set; } public string Text { get; set; }
} }
public DeepLTranslator(string authKey, IJsonSerializer jsonSerializer) public DeepLTranslator(IOptions<DeepLTranslatorOptions> deepLOptions, IJsonSerializer jsonSerializer)
{ {
Guard.NotNull(authKey, nameof(authKey)); Guard.NotNull(deepLOptions, nameof(deepLOptions));
Guard.NotNull(jsonSerializer, nameof(jsonSerializer)); Guard.NotNull(jsonSerializer, nameof(jsonSerializer));
this.authKey = authKey; this.deepLOptions = deepLOptions.Value;
this.jsonSerializer = jsonSerializer; this.jsonSerializer = jsonSerializer;
} }
@ -48,9 +49,14 @@ namespace Squidex.Infrastructure.Translations
return new Translation(TranslationResult.NotTranslated, sourceText); return new Translation(TranslationResult.NotTranslated, sourceText);
} }
if (string.IsNullOrWhiteSpace(deepLOptions.AuthKey))
{
return new Translation(TranslationResult.NotImplemented);
}
var parameters = new Dictionary<string, string> var parameters = new Dictionary<string, string>
{ {
["auth_key"] = authKey, ["auth_key"] = deepLOptions.AuthKey,
["text"] = sourceText, ["text"] = sourceText,
["target_lang"] = GetLanguageCode(targetLanguage) ["target_lang"] = GetLanguageCode(targetLanguage)
}; };

14
src/Squidex.Infrastructure/Translations/DeepLTranslatorOptions.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Infrastructure.Translations
{
public sealed class DeepLTranslatorOptions
{
public string AuthKey { get; set; }
}
}

2
src/Squidex/Areas/Api/Config/Swagger/SwaggerServices.cs

@ -14,8 +14,8 @@ using NSwag.SwaggerGeneration;
using NSwag.SwaggerGeneration.Processors; using NSwag.SwaggerGeneration.Processors;
using Squidex.Areas.Api.Controllers.Contents.Generator; using Squidex.Areas.Api.Controllers.Contents.Generator;
using Squidex.Areas.Api.Controllers.Rules.Models; using Squidex.Areas.Api.Controllers.Rules.Models;
using Squidex.Config;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.DependencyInjection;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.Swagger
{ {

3
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionConverter.cs

@ -8,6 +8,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Extensions.Actions; using Squidex.Extensions.Actions;
@ -15,7 +16,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
public sealed class RuleActionConverter : MyJsonInheritanceConverter<RuleAction> public sealed class RuleActionConverter : MyJsonInheritanceConverter<RuleAction>
{ {
private static readonly Dictionary<string, Type> Mapping = RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => x.Value.Type); private static readonly Dictionary<string, Type> Mapping = RuleActionRegistry.Actions.ToDictionary(x => x.Key, x => x.Value.Type);
public RuleActionConverter() public RuleActionConverter()
: base("actionType", Mapping) : base("actionType", Mapping)

3
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using NJsonSchema; using NJsonSchema;
using NSwag.SwaggerGeneration.Processors; using NSwag.SwaggerGeneration.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.SwaggerGeneration.Processors.Contexts;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Extensions.Actions; using Squidex.Extensions.Actions;
@ -36,7 +37,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
Type = JsonObjectType.String, IsRequired = true Type = JsonObjectType.String, IsRequired = true
}; };
foreach (var derived in RuleElementRegistry.Actions) foreach (var derived in RuleActionRegistry.Actions)
{ {
var derivedSchema = await context.SchemaGenerator.GenerateAsync(derived.Value.Type, context.SchemaResolver); var derivedSchema = await context.SchemaGenerator.GenerateAsync(derived.Value.Type, context.SchemaResolver);

26
src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using NodaTime; using NodaTime;
using Squidex.Areas.Api.Controllers.Rules.Models; using Squidex.Areas.Api.Controllers.Rules.Models;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Entities; using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Rules.Commands; using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.Rules.Repositories; using Squidex.Domain.Apps.Entities.Rules.Repositories;
@ -31,8 +32,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ApiExplorerSettings(GroupName = nameof(Rules))] [ApiExplorerSettings(GroupName = nameof(Rules))]
public sealed class RulesController : ApiController public sealed class RulesController : ApiController
{ {
private static readonly string RuleActionsEtag = string.Join(";", RuleElementRegistry.Actions.Select(x => x.Key)).Sha256Base64(); private static readonly string RuleActionsEtag = string.Join(";", RuleActionRegistry.Actions.Select(x => x.Key)).Sha256Base64();
private static readonly string RuleTriggersEtag = string.Join(";", RuleElementRegistry.Triggers.Select(x => x.Key)).Sha256Base64();
private readonly IAppProvider appProvider; private readonly IAppProvider appProvider;
private readonly IRuleEventRepository ruleEventsRepository; private readonly IRuleEventRepository ruleEventsRepository;
@ -58,33 +58,13 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ApiCosts(0)] [ApiCosts(0)]
public IActionResult GetActions() public IActionResult GetActions()
{ {
var response = RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto())); var response = RuleActionRegistry.Actions.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto()));
Response.Headers[HeaderNames.ETag] = RuleActionsEtag; Response.Headers[HeaderNames.ETag] = RuleActionsEtag;
return Ok(response); return Ok(response);
} }
/// <summary>
/// Get the supported rule triggers.
/// </summary>
/// <returns>
/// 200 => Rule triggers returned.
/// </returns>
[HttpGet]
[Route("rules/triggers/")]
[ProducesResponseType(typeof(Dictionary<string, RuleElementDto>), 200)]
[ApiPermission]
[ApiCosts(0)]
public IActionResult GetTriggers()
{
var response = RuleElementRegistry.Triggers.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto()));
Response.Headers[HeaderNames.ETag] = RuleTriggersEtag;
return Ok(response);
}
/// <summary> /// <summary>
/// Get rules. /// Get rules.
/// </summary> /// </summary>

2
src/Squidex/Config/Domain/AssetServices.cs

@ -12,6 +12,8 @@ using MongoDB.Driver.GridFS;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets; using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Assets.ImageSharp; using Squidex.Infrastructure.Assets.ImageSharp;
using Squidex.Infrastructure.Configuration;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.Log; using Squidex.Infrastructure.Log;
namespace Squidex.Config.Domain namespace Squidex.Config.Domain

2
src/Squidex/Config/Domain/EntitiesServices.cs

@ -42,6 +42,8 @@ using Squidex.Domain.Apps.Entities.Schemas.Indexes;
using Squidex.Domain.Apps.Entities.Tags; using Squidex.Domain.Apps.Entities.Tags;
using Squidex.Infrastructure.Assets; using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Configuration;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Migrations; using Squidex.Infrastructure.Migrations;
using Squidex.Pipeline; using Squidex.Pipeline;

1
src/Squidex/Config/Domain/EventPublishersServices.cs

@ -10,6 +10,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events; using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;

2
src/Squidex/Config/Domain/EventStoreServices.cs

@ -11,6 +11,8 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver; using MongoDB.Driver;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Configuration;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.Diagnostics;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.EventSourcing.Grains;

18
src/Squidex/Config/Domain/InfrastructureServices.cs

@ -18,8 +18,8 @@ using Squidex.Domain.Apps.Entities.Apps.Diagnostics;
using Squidex.Domain.Users; using Squidex.Domain.Users;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching; using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.Diagnostics;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.UsageTracking; using Squidex.Infrastructure.UsageTracking;
using Squidex.Shared.Users; using Squidex.Shared.Users;
@ -32,19 +32,6 @@ namespace Squidex.Config.Domain
{ {
public static void AddMyInfrastructureServices(this IServiceCollection services, IConfiguration config) public static void AddMyInfrastructureServices(this IServiceCollection services, IConfiguration config)
{ {
var deeplAuthKey = config.GetValue<string>("translations:deeplAuthKey");
if (!string.IsNullOrWhiteSpace(deeplAuthKey))
{
services.AddSingletonAs(c => new DeepLTranslator(deeplAuthKey, c.GetRequiredService<IJsonSerializer>()))
.As<ITranslator>();
}
else
{
services.AddSingletonAs<NoopTranslator>()
.As<ITranslator>();
}
services.AddHealthChecks() services.AddHealthChecks()
.AddCheck<GCHealthCheck>("GC", tags: new[] { "node" }) .AddCheck<GCHealthCheck>("GC", tags: new[] { "node" })
.AddCheck<OrleansHealthCheck>("Orleans", tags: new[] { "cluster" }) .AddCheck<OrleansHealthCheck>("Orleans", tags: new[] { "cluster" })
@ -59,6 +46,9 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<BackgroundUsageTracker>() services.AddSingletonAs<BackgroundUsageTracker>()
.AsSelf(); .AsSelf();
services.AddSingletonAs<DeepLTranslator>()
.As<ITranslator>();
services.AddSingletonAs(c => new CachingUsageTracker(c.GetRequiredService<BackgroundUsageTracker>(), c.GetRequiredService<IMemoryCache>())) services.AddSingletonAs(c => new CachingUsageTracker(c.GetRequiredService<BackgroundUsageTracker>(), c.GetRequiredService<IMemoryCache>()))
.As<IUsageTracker>(); .As<IUsageTracker>();

1
src/Squidex/Config/Domain/LoggingServices.cs

@ -9,6 +9,7 @@ using System;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.Log; using Squidex.Infrastructure.Log;
using Squidex.Pipeline; using Squidex.Pipeline;

3
src/Squidex/Config/Domain/RuleServices.cs

@ -13,6 +13,7 @@ using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Domain.Apps.Entities.Rules.UsageTracking; using Squidex.Domain.Apps.Entities.Rules.UsageTracking;
using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Extensions.Actions; using Squidex.Extensions.Actions;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Config.Domain namespace Squidex.Config.Domain
@ -45,7 +46,7 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<RuleService>() services.AddSingletonAs<RuleService>()
.AsSelf(); .AsSelf();
foreach (var actionHandler in RuleElementRegistry.ActionHandlers) foreach (var actionHandler in RuleActionRegistry.ActionHandlers)
{ {
services.AddSingleton(typeof(IRuleActionHandler), actionHandler); services.AddSingleton(typeof(IRuleActionHandler), actionHandler);
} }

1
src/Squidex/Config/Domain/SerializationServices.cs

@ -16,7 +16,6 @@ using Squidex.Domain.Apps.Core.Rules.Json;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.Schemas.Json; using Squidex.Domain.Apps.Core.Schemas.Json;
using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events;
using Squidex.Extensions.Actions;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Newtonsoft; using Squidex.Infrastructure.Json.Newtonsoft;

2
src/Squidex/Config/Domain/StoreServices.cs

@ -27,6 +27,8 @@ using Squidex.Domain.Users;
using Squidex.Domain.Users.MongoDb; using Squidex.Domain.Users.MongoDb;
using Squidex.Domain.Users.MongoDb.Infrastructure; using Squidex.Domain.Users.MongoDb.Infrastructure;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Configuration;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.Diagnostics;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;

1
src/Squidex/Config/Domain/SubscriptionServices.cs

@ -12,6 +12,7 @@ using Squidex.Domain.Apps.Entities.Apps.Services;
using Squidex.Domain.Apps.Entities.Apps.Services.Implementations; using Squidex.Domain.Apps.Entities.Apps.Services.Implementations;
using Squidex.Domain.Users; using Squidex.Domain.Users;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.DependencyInjection;
namespace Squidex.Config.Domain namespace Squidex.Config.Domain
{ {

1
src/Squidex/Config/Orleans/OrleansServices.cs

@ -15,6 +15,7 @@ using Orleans.Hosting;
using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Rules; using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Domain.Apps.Entities.Rules.UsageTracking; using Squidex.Domain.Apps.Entities.Rules.UsageTracking;
using Squidex.Infrastructure.Configuration;
using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.EventSourcing.Grains;
using Squidex.Infrastructure.Orleans; using Squidex.Infrastructure.Orleans;

1
src/Squidex/Config/Web/WebServices.cs

@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Squidex.Config.Domain; using Squidex.Config.Domain;
using Squidex.Infrastructure.DependencyInjection;
using Squidex.Pipeline; using Squidex.Pipeline;
using Squidex.Pipeline.Robots; using Squidex.Pipeline.Robots;

76
src/Squidex/Pipeline/Plugins/PluginExtensions.cs

@ -0,0 +1,76 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Reflection;
using McMaster.NETCore.Plugins;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Pipeline.Plugins
{
public static class PluginExtensions
{
private static readonly Type[] SharedTypes = { typeof(IPlugin) };
public static void AddPlugins(IMvcBuilder mvcBuilder, IConfiguration configuration)
{
var options = configuration.Get<PluginOptions>();
if (options.Plugins != null)
{
var pluginManager = new PluginManager();
foreach (var pluginPath in options.Plugins)
{
PluginLoader plugin = null;
if (pluginPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
{
plugin = PluginLoader.CreateFromAssemblyFile(pluginPath, SharedTypes);
}
else
{
plugin = PluginLoader.CreateFromConfigFile(pluginPath, SharedTypes);
}
if (plugin != null)
{
var pluginAssembly = plugin.LoadDefaultAssembly();
AddParts(mvcBuilder, pluginAssembly);
var relatedAssemblies = pluginAssembly.GetCustomAttributes<RelatedAssemblyAttribute>();
foreach (var relatedAssembly in relatedAssemblies)
{
var assembly = plugin.LoadAssembly(relatedAssembly.AssemblyFileName);
AddParts(mvcBuilder, assembly);
}
pluginManager.Add(pluginAssembly);
}
}
mvcBuilder.Services.AddSingleton(pluginManager);
}
}
private static void AddParts(IMvcBuilder mvcBuilder, Assembly assembly)
{
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var part in partFactory.GetApplicationParts(assembly))
{
mvcBuilder.PartManager.ApplicationParts.Add(part);
}
}
}
}

1
src/Squidex/Squidex.csproj

@ -68,6 +68,7 @@
<PackageReference Include="IdentityServer4" Version="2.3.2" /> <PackageReference Include="IdentityServer4" Version="2.3.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.3.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.3.0" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="0.2.4" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="2.2.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="2.2.2" />

3
src/Squidex/WebStartup.cs

@ -29,6 +29,7 @@ using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Extensions.Actions.Twitter; using Squidex.Extensions.Actions.Twitter;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.Diagnostics;
using Squidex.Infrastructure.Translations;
using Squidex.Pipeline; using Squidex.Pipeline;
using Squidex.Pipeline.Robots; using Squidex.Pipeline.Robots;
@ -72,6 +73,8 @@ namespace Squidex
config.GetSection("contents")); config.GetSection("contents"));
services.Configure<AssetOptions>( services.Configure<AssetOptions>(
config.GetSection("assets")); config.GetSection("assets"));
services.Configure<DeepLTranslatorOptions>(
config.GetSection("translations:deepL"));
services.Configure<ReadonlyOptions>( services.Configure<ReadonlyOptions>(
config.GetSection("mode")); config.GetSection("mode"));
services.Configure<TwitterOptions>( services.Configure<TwitterOptions>(

Loading…
Cancel
Save