Remove Elsa.OrchardCore module.
Deleted the entire Elsa.OrchardCore module, including all its associated activities, handlers, services, and extensions. This removes support for integrations with Orchard Core application instances.
This commit is contained in:
parent
28ad3b3ed7
commit
7aabfb6d0b
7
Elsa.sln
7
Elsa.sln
|
|
@ -302,8 +302,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "trace-lens", "trace-lens",
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integrations", "integrations", "{EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.OrchardCore", "src\modules\Elsa.OrchardCore\Elsa.OrchardCore.csproj", "{B0460856-7E6D-4B1E-B243-8E20662FC32E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "agents", "agents", "{50470834-4CD8-479A-8B58-0A1869BA5D37}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Agents.Core", "src\modules\Elsa.Agents.Core\Elsa.Agents.Core.csproj", "{5BD671F0-9603-4C2F-8364-54B02986EAA2}"
|
||||
|
|
@ -755,10 +753,6 @@ Global
|
|||
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{47FBCB04-0C2D-453C-BE2F-7052CAC22524}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B0460856-7E6D-4B1E-B243-8E20662FC32E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B0460856-7E6D-4B1E-B243-8E20662FC32E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0460856-7E6D-4B1E-B243-8E20662FC32E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0460856-7E6D-4B1E-B243-8E20662FC32E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5BD671F0-9603-4C2F-8364-54B02986EAA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -1005,7 +999,6 @@ Global
|
|||
{6DDB9ECF-D454-4894-A262-A6BB3026E61E} = {B32DB9B2-AD6C-48A5-8682-4373CB045185}
|
||||
{16B570BC-E293-4A19-B20E-5C97BAF8476B} = {B32DB9B2-AD6C-48A5-8682-4373CB045185}
|
||||
{EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
|
||||
{B0460856-7E6D-4B1E-B243-8E20662FC32E} = {EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}
|
||||
{50470834-4CD8-479A-8B58-0A1869BA5D37} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
|
||||
{5BD671F0-9603-4C2F-8364-54B02986EAA2} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
|
||||
{154525CD-3726-45B7-9A9C-553BBC60EB10} = {50470834-4CD8-479A-8B58-0A1869BA5D37}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.OrchardCore.Stimuli;
|
||||
using Elsa.OrchardCore.WebhookPayloads;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
public class ContentItemEvent : Trigger<ContentItemEventPayload>, INotification
|
||||
{
|
||||
/// <summary>
|
||||
/// The content type to handle the event for.
|
||||
/// </summary>
|
||||
[Input(Description = "The content type to handle the event for.")]
|
||||
public string ContentType { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The event to handle.
|
||||
/// </summary>
|
||||
[Input(Description = "The event to handle the event for.")]
|
||||
public string EventType { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
if (!context.IsTriggerOfWorkflow())
|
||||
{
|
||||
context.CreateBookmark(GetStimulus(context.ExpressionExecutionContext), OnResumeAsync);
|
||||
return;
|
||||
}
|
||||
|
||||
await ExecuteInternalAsync(context);
|
||||
}
|
||||
|
||||
protected override object GetTriggerPayload(TriggerIndexingContext context) => new ContentItemEventStimulus(ContentType, EventType);
|
||||
private async ValueTask OnResumeAsync(ActivityExecutionContext context) => await ExecuteInternalAsync(context);
|
||||
private object GetStimulus(ExpressionExecutionContext context) => new ContentItemEventStimulus(ContentType, EventType);
|
||||
|
||||
private async Task ExecuteInternalAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var payload = context.GetWorkflowInput<ContentItemEventPayload>();
|
||||
context.SetResult(payload);
|
||||
await context.CompleteActivityAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Expressions.Helpers;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Patches a content item", Kind = ActivityKind.Task)]
|
||||
public class CreateContentItem : CodeActivity<JsonObject>
|
||||
{
|
||||
[Input(Description = "The content type of the content item to create.")]
|
||||
public Input<string> ContentType { get; set; } = default!;
|
||||
|
||||
[Input(Description = "The properties to apply to the content item.")]
|
||||
public Input<object> Properties { get; set; } = default!;
|
||||
|
||||
[Input(Description = "Whether to publish the content item.")]
|
||||
public Input<bool> Publish { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var contentType = ContentType.Get(context);
|
||||
var publish = Publish.Get(context);
|
||||
var properties = Properties.Get(context).ConvertTo<JsonObject>()!;
|
||||
var apiClient = context.GetRequiredService<IRestApiClient>();
|
||||
var request = new CreateContentItemRequest
|
||||
{
|
||||
ContentType = contentType,
|
||||
Properties = properties,
|
||||
Publish = publish
|
||||
};
|
||||
var contentItem = await apiClient.CreateContentItemAsync(request, context.CancellationToken);
|
||||
context.SetResult(contentItem);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Localizes a content item", Kind = ActivityKind.Task)]
|
||||
public class LocalizeContentItem : CodeActivity<JsonObject>
|
||||
{
|
||||
[Input(Description = "The ID of the content item to localize.")]
|
||||
public Input<string> ContentItemId { get; set; } = default!;
|
||||
|
||||
[Input(Description = "The culture code to use when creating a localized version.")]
|
||||
public Input<string> CultureCode { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var contentItemId = ContentItemId.Get(context);
|
||||
var cultureCode = CultureCode.Get(context);
|
||||
var apiClient = context.GetRequiredService<IRestApiClient>();
|
||||
var request = new LocalizeContentItemRequest
|
||||
{
|
||||
CultureCode = cultureCode
|
||||
};
|
||||
var localizedContentItem = await apiClient.LocalizeContentItemAsync(contentItemId, request, context.CancellationToken);
|
||||
context.SetResult(localizedContentItem);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Patches a content item", Kind = ActivityKind.Task)]
|
||||
public class PatchContentItem : CodeActivity<JsonObject>
|
||||
{
|
||||
[Input(Description = "The ID of the content item to patch.")]
|
||||
public Input<string> ContentItemId { get; set; } = default!;
|
||||
|
||||
[Input(Description = "The patch to apply to the content item.")]
|
||||
public Input<JsonObject> Patch { get; set; } = default!;
|
||||
|
||||
[Input(Description = "Whether to publish the patched content item.")]
|
||||
public Input<bool> Publish { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var contentItemId = ContentItemId.Get(context);
|
||||
var publish = Publish.Get(context);
|
||||
var patch = Patch.Get(context);
|
||||
var apiClient = context.GetRequiredService<IRestApiClient>();
|
||||
var request = new PatchContentItemRequest
|
||||
{
|
||||
Patch = patch,
|
||||
Publish = publish
|
||||
};
|
||||
var patchedContentItem = await apiClient.PatchContentItemAsync(contentItemId, request, context.CancellationToken);
|
||||
context.SetResult(patchedContentItem);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Returns tag content items for the specified set of tags. If a tag doesn't exist, it is created.", Kind = ActivityKind.Task)]
|
||||
public class ResolveTags : CodeActivity<JsonObject>
|
||||
{
|
||||
[Input(Description = "The tags to resolve.")]
|
||||
public Input<ICollection<string>> Tags { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var tags = Tags.Get(context);
|
||||
var apiClient = context.GetRequiredService<IRestApiClient>();
|
||||
var request = new ResolveTagsRequest
|
||||
{
|
||||
Tags = tags
|
||||
};
|
||||
var result = await apiClient.ResolveTagsAsync(request, context.CancellationToken);
|
||||
context.SetResult(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Send a GraphQL query to Orchard Core", DisplayName = "GraphQL Query", Kind = ActivityKind.Task)]
|
||||
public class SendGraphQLQuery : CodeActivity<object>
|
||||
{
|
||||
/// <summary>
|
||||
/// The content type to handle the event for.
|
||||
/// </summary>
|
||||
[Input(Description = "The GraphQL query string to send.")]
|
||||
public Input<string> Query { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var query = Query.Get(context);
|
||||
var client = context.GetRequiredService<IGraphQLClient>();
|
||||
var targetType = Result.GetTargetType(context);
|
||||
var output = await client.SendQueryAsync(query, targetType, context.CancellationToken);
|
||||
context.SetResult(output);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Http;
|
||||
using Elsa.OrchardCore.Client;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.OrchardCore.Activities;
|
||||
|
||||
[Activity("OrchardCore", "Orchard Core", "Patches a content item", Kind = ActivityKind.Task)]
|
||||
public class UploadMedia : CodeActivity<JsonObject>
|
||||
{
|
||||
[Input(Description = "The files to upload into the Media Library.")]
|
||||
public Input<ICollection<HttpFile>> Files { get; set; } = default!;
|
||||
|
||||
[Input(Description = "The path to the media library folder to upload.")]
|
||||
public Input<string?> FolderPath { get; set; } = default!;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var files = Files.Get(context);
|
||||
var folderPath = FolderPath.GetOrDefault(context);
|
||||
var apiClient = context.GetRequiredService<IRestApiClient>();
|
||||
var response = await apiClient.UploadFilesAsync(files, folderPath, context.CancellationToken);
|
||||
context.SetResult(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
using Elsa.OrchardCore.Activities;
|
||||
using Elsa.OrchardCore.Models;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Models;
|
||||
using Humanizer;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.OrchardCore.ActivityProviders;
|
||||
|
||||
/// <summary>
|
||||
/// An activity provider that generates activity types based on Orchard content type events.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class OrchardContentItemsEventActivityProvider(IOptions<OrchardCoreOptions> options, IActivityFactory activityFactory, IActivityDescriber activityDescriber) : IActivityProvider
|
||||
{
|
||||
public async ValueTask<IEnumerable<ActivityDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var contentTypes = options.Value.ContentTypes;
|
||||
var matrix =
|
||||
from contentType in contentTypes
|
||||
from eventType in WebhookEventTypes.GetWebhookEventDescriptors()
|
||||
select new
|
||||
{
|
||||
contentType,
|
||||
eventType
|
||||
};
|
||||
var activities = (await Task.WhenAll(matrix.Select(async x => await CreateActivityDescriptorAsync(x.contentType, x.eventType, cancellationToken)))).ToList();
|
||||
return activities;
|
||||
}
|
||||
|
||||
private async Task<ActivityDescriptor> CreateActivityDescriptorAsync(string contentType, WebhookEventDescriptor eventDescriptor, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var eventType = eventDescriptor.EventType;
|
||||
var humanizedEventName = eventType.Humanize();
|
||||
var description = $"Handles {humanizedEventName} events for {contentType} content items";
|
||||
var name = $"{contentType}{eventType}";
|
||||
var displayName = $"{contentType} {eventType}";
|
||||
var fullTypeName = OrchardCoreActivityNameHelper.GetContentItemEventActivityFullTypeName(contentType, eventType);
|
||||
var activityType = typeof(ContentItemEvent);
|
||||
var activityDescriptor = await activityDescriber.DescribeActivityAsync(activityType, cancellationToken);
|
||||
|
||||
activityDescriptor.TypeName = fullTypeName;
|
||||
activityDescriptor.Name = name;
|
||||
activityDescriptor.DisplayName = displayName;
|
||||
activityDescriptor.Category = "Orchard Core";
|
||||
activityDescriptor.Description = description;
|
||||
activityDescriptor.Constructor = context =>
|
||||
{
|
||||
var activity = (ContentItemEvent)activityFactory.Create(activityType, context);
|
||||
activity.Type = fullTypeName;
|
||||
activity.ContentType = contentType;
|
||||
activity.EventType = eventType;
|
||||
return activity;
|
||||
};
|
||||
|
||||
foreach (var inputDescriptor in activityDescriptor.Inputs)
|
||||
inputDescriptor.IsBrowsable = false;
|
||||
|
||||
return activityDescriptor;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public interface IGraphQLClient
|
||||
{
|
||||
Task<object> SendQueryAsync(string query, Type? targetType, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Http;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public interface IRestApiClient
|
||||
{
|
||||
Task<JsonObject> GetContentItemAsync(string contentItemId, CancellationToken cancellationToken = default);
|
||||
Task<JsonObject> PatchContentItemAsync(string contentItemId, PatchContentItemRequest request, CancellationToken cancellationToken = default);
|
||||
Task<JsonObject> LocalizeContentItemAsync(string contentItemId, LocalizeContentItemRequest request, CancellationToken cancellationToken = default);
|
||||
Task<JsonObject> CreateContentItemAsync(CreateContentItemRequest request, CancellationToken cancellationToken = default);
|
||||
Task<JsonObject> UploadFilesAsync(IEnumerable<HttpFile> files, string? folderPath = null, CancellationToken cancellationToken = default);
|
||||
Task<JsonObject> ResolveTagsAsync(ResolveTagsRequest request, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public interface ISecurityTokenClient
|
||||
{
|
||||
Task<SecurityToken> GetSecurityTokenAsync(string clientId, string clientSecret, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public interface ISecurityTokenService
|
||||
{
|
||||
Task<SecurityToken> GetTokenAsync(CancellationToken cancellationToken = default);
|
||||
Task<SecurityToken> RefreshTokenAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class AuthenticatingDelegatingHandler(ISecurityTokenService tokenService) : DelegatingHandler
|
||||
{
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
var token = await tokenService.GetTokenAsync(cancellationToken);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
|
||||
|
||||
var response = await base.SendAsync(request, cancellationToken);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
// Token might be expired; refresh it
|
||||
token = await tokenService.RefreshTokenAsync(cancellationToken);
|
||||
|
||||
// Retry the request with the new token
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
|
||||
response = await base.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.OrchardCore.Client.Extensions;
|
||||
|
||||
[PublicAPI]
|
||||
public static class OrchardCoreClientServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddOrchardCoreClient(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<ISecurityTokenService, DefaultSecurityTokenService>();
|
||||
services.AddTransient<AuthenticatingDelegatingHandler>();
|
||||
|
||||
services.AddHttpClient<ISecurityTokenClient, DefaultSecurityTokenClient>((sp, httpClient) =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptions<OrchardCoreClientOptions>>().Value;
|
||||
httpClient.BaseAddress = options.BaseAddress;
|
||||
});
|
||||
|
||||
services.AddHttpClient<IGraphQLClient, DefaultGraphQlClient>((sp, httpClient) =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptions<OrchardCoreClientOptions>>().Value;
|
||||
httpClient.BaseAddress = options.BaseAddress;
|
||||
}).AddHttpMessageHandler<AuthenticatingDelegatingHandler>();
|
||||
|
||||
services.AddHttpClient<IRestApiClient, DefaultRestApiClient>((sp, httpClient) =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptions<OrchardCoreClientOptions>>().Value;
|
||||
httpClient.BaseAddress = options.BaseAddress;
|
||||
}).AddHttpMessageHandler<AuthenticatingDelegatingHandler>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class CreateContentItemRequest
|
||||
{
|
||||
public string ContentType { get; set; } = default!;
|
||||
public JsonNode Properties { get; set; } = default!;
|
||||
public bool Publish { get; set; }
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class LocalizeContentItemRequest
|
||||
{
|
||||
public string CultureCode { get; set; } = default!;
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class PatchContentItemRequest
|
||||
{
|
||||
public JsonNode Patch { get; set; } = default!;
|
||||
public bool Publish { get; set; }
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class ResolveTagsRequest
|
||||
{
|
||||
public ICollection<string> Tags { get; set; } = [];
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="AccessToken"></param>
|
||||
/// <param name="TokenType"></param>
|
||||
/// <param name="ExpiresIn"></param>
|
||||
public record SecurityToken(string AccessToken, string TokenType, int ExpiresIn);
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Options related to connecting to an Orchard Core tenant.
|
||||
/// </summary>
|
||||
public class OrchardCoreClientOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The base address of the Orchard Core tenant to interact with.
|
||||
/// </summary>
|
||||
public Uri BaseAddress { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The client ID.
|
||||
/// </summary>
|
||||
public string ClientId { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The client secret.
|
||||
/// </summary>
|
||||
public string ClientSecret { get; set; } = default!;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Expressions.Helpers;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class DefaultGraphQlClient(HttpClient httpClient) : IGraphQLClient
|
||||
{
|
||||
public async Task<object> SendQueryAsync(string query, Type? targetType = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = new StringContent(query, System.Text.Encoding.UTF8, "application/graphql");
|
||||
var response = await httpClient.PostAsync("api/graphql", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
|
||||
targetType ??= typeof(JsonObject);
|
||||
return ObjectConverter.ConvertTo(json, targetType);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Elsa.Http;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class DefaultRestApiClient(HttpClient httpClient) : IRestApiClient
|
||||
{
|
||||
public async Task<JsonObject> GetContentItemAsync(string contentItemId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = await httpClient.GetAsync($"api/content/{contentItemId}", cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<JsonObject> PatchContentItemAsync(string contentItemId, PatchContentItemRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = JsonContent.Create(request);
|
||||
var response = await httpClient.PatchAsync($"api/content-items/{contentItemId}", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<JsonObject> LocalizeContentItemAsync(string contentItemId, LocalizeContentItemRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = JsonContent.Create(request);
|
||||
var response = await httpClient.PostAsync($"api/content-items/{contentItemId}/localize", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
return JsonSerializer.Deserialize<JsonObject>(json);
|
||||
}
|
||||
|
||||
public async Task<JsonObject> CreateContentItemAsync(CreateContentItemRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = JsonContent.Create(request);
|
||||
var response = await httpClient.PostAsync("api/content-items", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<JsonObject> UploadFilesAsync(IEnumerable<HttpFile> files, string? folderPath = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = new MultipartFormDataContent();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
var streamContent = file.GetStreamContent();
|
||||
content.Add(streamContent);
|
||||
}
|
||||
|
||||
var response = await httpClient.PostAsync($"api/media/upload?path={folderPath}", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<JsonObject> ResolveTagsAsync(ResolveTagsRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = JsonContent.Create(request);
|
||||
var response = await httpClient.PostAsync("api/tags/resolve", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using System.Text.Json;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class DefaultSecurityTokenClient(HttpClient httpClient) : ISecurityTokenClient
|
||||
{
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||
};
|
||||
|
||||
public async Task<SecurityToken> GetSecurityTokenAsync(string clientId, string clientSecret, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var content = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
{
|
||||
["grant_type"] = "client_credentials",
|
||||
["client_id"] = clientId,
|
||||
["client_secret"] = clientSecret
|
||||
});
|
||||
|
||||
var response = await httpClient.PostAsync("/connect/token", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
return JsonSerializer.Deserialize<SecurityToken>(responseContent, _jsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.OrchardCore.Client;
|
||||
|
||||
public class DefaultSecurityTokenService(IMemoryCache memoryCache, ISecurityTokenClient securityTokenClient, IOptions<OrchardCoreClientOptions> options) : ISecurityTokenService
|
||||
{
|
||||
private readonly string _cacheKey = $"{nameof(DefaultSecurityTokenService)}:{Guid.NewGuid()}";
|
||||
|
||||
public async Task<SecurityToken> GetTokenAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return (await memoryCache.GetOrCreateAsync(_cacheKey, async entry =>
|
||||
{
|
||||
var securityToken = await RequestSecurityTokenAsync(cancellationToken);
|
||||
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(securityToken.ExpiresIn);
|
||||
return securityToken;
|
||||
}))!;
|
||||
}
|
||||
|
||||
public Task<SecurityToken> RefreshTokenAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return RequestSecurityTokenAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private Task<SecurityToken> RequestSecurityTokenAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var clientId = options.Value.ClientId;
|
||||
var clientSecret = options.Value.ClientSecret;
|
||||
return securityTokenClient.GetSecurityTokenAsync(clientId, clientSecret, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>
|
||||
Provides integrations with an Orchard Core application instances through activities and via HTTP.
|
||||
</Description>
|
||||
<PackageTags>elsa module orchardcore</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Elsa.Http\Elsa.Http.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Webhooks\Elsa.Webhooks.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Workflows.Core\Elsa.Workflows.Core.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Workflows.Management\Elsa.Workflows.Management.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Workflows.Runtime\Elsa.Workflows.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=client_005Ccontracts/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=client_005Cdelegatinghandlers/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=client_005Cmodels/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=client_005Coptions/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=client_005Cservices/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=constants/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=helpers/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=options/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using Elsa.Features.Services;
|
||||
using Elsa.OrchardCore.Features;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Adds extensions to <see cref="IModule"/> that enables the <see cref="OrchardCoreFeature"/> feature.
|
||||
/// </summary>
|
||||
public static class ModuleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables and configures the <see cref="OrchardCoreFeature"/> feature.
|
||||
/// </summary>
|
||||
public static IModule UseOrchardCore(this IModule module, Action<OrchardCoreFeature>? configure = default)
|
||||
{
|
||||
module.Configure(configure);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Attributes;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.OrchardCore.ActivityProviders;
|
||||
using Elsa.OrchardCore.Client.Extensions;
|
||||
using Elsa.OrchardCore.WebhookPayloads;
|
||||
using Elsa.Webhooks.Features;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.OrchardCore.Features;
|
||||
|
||||
[DependsOn(typeof(WebhooksFeature))]
|
||||
public class OrchardCoreFeature(IModule module) : FeatureBase(module)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Module.AddVariableTypeAndAlias<ContentItemEventPayload>("ContentItemPublished", "Orchard");
|
||||
Module.AddActivitiesFrom<OrchardCoreFeature>();
|
||||
Services
|
||||
.AddActivityProvider<OrchardContentItemsEventActivityProvider>()
|
||||
.AddHandlersFrom<OrchardCoreFeature>()
|
||||
;
|
||||
}
|
||||
|
||||
public override void Apply()
|
||||
{
|
||||
Services.AddOrchardCoreClient();
|
||||
Services.AddOptions<OrchardCoreOptions>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using Elsa.Expressions.Helpers;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.OrchardCore.Stimuli;
|
||||
using Elsa.OrchardCore.WebhookPayloads;
|
||||
using Elsa.Webhooks.Notifications;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using JetBrains.Annotations;
|
||||
using WebhooksCore;
|
||||
|
||||
namespace Elsa.OrchardCore.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes Orchard activities based on the received webhook.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class InvokeOrchardWebhookEventActivities(IStimulusSender stimulusSender) : INotificationHandler<WebhookEventReceived>
|
||||
{
|
||||
public async Task HandleAsync(WebhookEventReceived notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var webhookEvent = notification.WebhookEvent;
|
||||
var webhookEventType = webhookEvent.EventType;
|
||||
var webhookEventDescriptors = WebhookEventTypes.GetWebhookEventDescriptors().ToDictionary(x => x.WebhookEventType, x => x);
|
||||
|
||||
if(!webhookEventDescriptors.TryGetValue(webhookEventType, out var webhookEventDescriptor))
|
||||
return;
|
||||
|
||||
var eventType = webhookEventDescriptor.EventType;
|
||||
var contentItemEventPayload = (ContentItemEventPayload)webhookEvent.Payload.ConvertTo(webhookEventDescriptor.PayloadType)!;
|
||||
var contentType = contentItemEventPayload.ContentType;
|
||||
var fullTypeName = OrchardCoreActivityNameHelper.GetContentItemEventActivityFullTypeName(contentType, eventType);
|
||||
var stimulus = new ContentItemEventStimulus(contentType, eventType);
|
||||
var metadata = new StimulusMetadata
|
||||
{
|
||||
Input = new Dictionary<string, object>
|
||||
{
|
||||
[nameof(WebhookEvent)] = webhookEvent,
|
||||
[nameof(ContentItemEventPayload)] = contentItemEventPayload
|
||||
}
|
||||
};
|
||||
await stimulusSender.SendAsync(fullTypeName, stimulus, metadata, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
namespace Elsa.OrchardCore;
|
||||
|
||||
public static class OrchardCoreActivityNameHelper
|
||||
{
|
||||
public static string GetContentItemEventActivityFullTypeName(string contentType, string eventName)
|
||||
{
|
||||
return $"OrchardCore.ContentItem.{contentType}.{eventName}";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Models;
|
||||
|
||||
public class WebhookEventDescriptor
|
||||
{
|
||||
public string WebhookEventType { get; set; }
|
||||
public string EventType { get; set; }
|
||||
public Type PayloadType { get; set; }
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Elsa.OrchardCore;
|
||||
|
||||
public class OrchardCoreOptions
|
||||
{
|
||||
public ISet<string> ContentTypes { get; set; } = new HashSet<string>();
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
namespace Elsa.OrchardCore.Stimuli;
|
||||
|
||||
public record ContentItemEventStimulus(string ContentType, string EventType);
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
using Elsa.OrchardCore.Models;
|
||||
using Elsa.OrchardCore.WebhookPayloads;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.OrchardCore;
|
||||
|
||||
[UsedImplicitly]
|
||||
public static class WebhookEventTypes
|
||||
{
|
||||
public static IEnumerable<WebhookEventDescriptor> GetWebhookEventDescriptors()
|
||||
{
|
||||
yield return GetWebhookEventDescriptor("content-item.created", "Created", typeof(ContentItemEventPayload));
|
||||
yield return GetWebhookEventDescriptor("content-item.published", "Published", typeof(ContentItemEventPayload));
|
||||
yield return GetWebhookEventDescriptor("content-item.unpublished", "Unpublished", typeof(ContentItemEventPayload));
|
||||
yield return GetWebhookEventDescriptor("content-item.removed", "Removed", typeof(ContentItemEventPayload));
|
||||
}
|
||||
|
||||
private static WebhookEventDescriptor GetWebhookEventDescriptor(string webhookEventType, string eventType, Type payloadType)
|
||||
{
|
||||
return new WebhookEventDescriptor
|
||||
{
|
||||
WebhookEventType = webhookEventType,
|
||||
EventType = eventType,
|
||||
PayloadType = payloadType
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
namespace Elsa.OrchardCore.WebhookPayloads;
|
||||
|
||||
public record ContentItemEventPayload(
|
||||
string ContentType,
|
||||
string DisplayText,
|
||||
string Author,
|
||||
string Owner,
|
||||
string ContentItemId);
|
||||
Loading…
Reference in a new issue