mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
43 changed files with 873 additions and 98 deletions
@ -0,0 +1,106 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Text.RegularExpressions; |
|||
using Squidex.Infrastructure; |
|||
|
|||
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds |
|||
{ |
|||
public sealed class StringReferenceExtractor |
|||
{ |
|||
private readonly List<Regex> contentsPatterns = new List<Regex>(); |
|||
private readonly List<Regex> assetsPatterns = new List<Regex>(); |
|||
|
|||
public StringReferenceExtractor(IUrlGenerator urlGenerator) |
|||
{ |
|||
AddAssetPattern(@"assets?:(?<Id>[a-z0-9\-_9]+)"); |
|||
AddAssetUrlPatterns(urlGenerator.AssetContentBase()); |
|||
AddAssetUrlPatterns(urlGenerator.AssetContentCDNBase()); |
|||
|
|||
AddContentPattern(@"contents?:(?<Id>[a-z0-9\-_9]+)"); |
|||
AddContentUrlPatterns(urlGenerator.ContentBase()); |
|||
AddContentUrlPatterns(urlGenerator.ContentCDNBase()); |
|||
} |
|||
|
|||
private void AddContentUrlPatterns(string baseUrl) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(baseUrl)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (!baseUrl.EndsWith('/')) |
|||
{ |
|||
baseUrl += "/"; |
|||
} |
|||
|
|||
baseUrl = Regex.Escape(baseUrl); |
|||
|
|||
AddContentPattern(baseUrl + @"(.+)\/(.+)\/(?<Id>[a-z0-9\-_9]+)"); |
|||
} |
|||
|
|||
private void AddAssetUrlPatterns(string baseUrl) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(baseUrl)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (!baseUrl.EndsWith('/')) |
|||
{ |
|||
baseUrl += "/"; |
|||
} |
|||
|
|||
baseUrl = Regex.Escape(baseUrl); |
|||
|
|||
AddAssetPattern(baseUrl + @"(?<Id>[a-z0-9\-_9]+)"); |
|||
AddAssetPattern(baseUrl + @"(.+)\/(?<Id>[a-z0-9\-_9]+)"); |
|||
} |
|||
|
|||
private void AddAssetPattern(string pattern) |
|||
{ |
|||
assetsPatterns.Add(new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture)); |
|||
} |
|||
|
|||
private void AddContentPattern(string pattern) |
|||
{ |
|||
contentsPatterns.Add(new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture)); |
|||
} |
|||
|
|||
public IEnumerable<DomainId> GetEmbeddedContentIds(string text) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(text)) |
|||
{ |
|||
yield break; |
|||
} |
|||
|
|||
foreach (var pattern in contentsPatterns) |
|||
{ |
|||
foreach (Match match in pattern.Matches(text)) |
|||
{ |
|||
yield return DomainId.Create(match.Groups["Id"].Value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public IEnumerable<DomainId> GetEmbeddedAssetIds(string text) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(text)) |
|||
{ |
|||
yield break; |
|||
} |
|||
|
|||
foreach (var pattern in assetsPatterns) |
|||
{ |
|||
foreach (Match match in pattern.Matches(text)) |
|||
{ |
|||
yield return DomainId.Create(match.Groups["Id"].Value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using GraphQL.Types; |
|||
using Squidex.Domain.Apps.Core; |
|||
using Squidex.Domain.Apps.Core.Schemas; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.Collections; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents |
|||
{ |
|||
internal sealed class EmbeddableStringGraphType : ObjectGraphType<string> |
|||
{ |
|||
public EmbeddableStringGraphType(Builder builder, FieldInfo fieldInfo, StringFieldProperties properties) |
|||
{ |
|||
// The name is used for equal comparison. Therefore it is important to treat it as readonly.
|
|||
Name = fieldInfo.EmbeddableStringType; |
|||
|
|||
AddField(ContentFields.StringFieldText); |
|||
AddField(ContentFields.StringFieldAssets); |
|||
|
|||
var referenceType = ResolveReferences(builder, fieldInfo, properties.SchemaIds); |
|||
|
|||
if (referenceType != null) |
|||
{ |
|||
AddField(new FieldType |
|||
{ |
|||
Name = "contents", |
|||
ResolvedType = new NonNullGraphType(new ListGraphType(new NonNullGraphType(referenceType))), |
|||
Resolver = ContentFields.ResolveStringFieldContents, |
|||
Description = FieldDescriptions.StringFieldReferences |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private static IGraphType? ResolveReferences(Builder builder, FieldInfo fieldInfo, ReadonlyList<DomainId>? schemaIds) |
|||
{ |
|||
IGraphType? contentType = null; |
|||
|
|||
if (schemaIds?.Count == 1) |
|||
{ |
|||
contentType = builder.GetContentType(schemaIds[0]); |
|||
} |
|||
|
|||
if (contentType == null) |
|||
{ |
|||
var union = new ReferenceUnionGraphType(builder, fieldInfo, schemaIds); |
|||
|
|||
if (!union.HasType) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
contentType = union; |
|||
} |
|||
|
|||
return contentType; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using GraphQL.Resolvers; |
|||
using GraphQL.Types; |
|||
|
|||
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents |
|||
{ |
|||
public record struct FieldGraphSchema(IGraphType? Type, IFieldResolver? Resolver, QueryArguments? Arguments); |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using FakeItEasy; |
|||
using Squidex.Domain.Apps.Core.ExtractReferenceIds; |
|||
using Squidex.Infrastructure; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds |
|||
{ |
|||
public class StringReferenceExtractorTests |
|||
{ |
|||
private readonly StringReferenceExtractor sut; |
|||
|
|||
public StringReferenceExtractorTests() |
|||
{ |
|||
var urlGenerator = A.Fake<IUrlGenerator>(); |
|||
|
|||
A.CallTo(() => urlGenerator.ContentBase()) |
|||
.Returns("https://cloud.squidex.io/api/content/"); |
|||
|
|||
A.CallTo(() => urlGenerator.ContentCDNBase()) |
|||
.Returns("https://contents.squidex.io/"); |
|||
|
|||
A.CallTo(() => urlGenerator.AssetContentBase()) |
|||
.Returns("https://cloud.squidex.io/api/assets/"); |
|||
|
|||
A.CallTo(() => urlGenerator.AssetContentCDNBase()) |
|||
.Returns("https://assets.squidex.io/"); |
|||
|
|||
sut = new StringReferenceExtractor(urlGenerator); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("before content:a_b-123|after")] |
|||
[InlineData("before contents:a_b-123|after")] |
|||
[InlineData("before https://cloud.squidex.io/api/content/my-app/my-schema/a_b-123|after")] |
|||
[InlineData("before https://contents.squidex.io/my-app/my-schema/a_b-123|after")] |
|||
public void Should_extract_content_id(string input) |
|||
{ |
|||
var ids = sut.GetEmbeddedContentIds(input); |
|||
|
|||
Assert.Contains(DomainId.Create("a_b-123"), ids.ToList()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData("before asset:a_b-123|after")] |
|||
[InlineData("before assets:a_b-123|after")] |
|||
[InlineData("before https://cloud.squidex.io/api/assets/a_b-123|after")] |
|||
[InlineData("before https://cloud.squidex.io/api/assets/my-app/a_b-123|after")] |
|||
[InlineData("before https://assets.squidex.io/a_b-123|after")] |
|||
[InlineData("before https://assets.squidex.io/my-app/a_b-123|after")] |
|||
public void Should_extract_asset_id(string input) |
|||
{ |
|||
var ids = sut.GetEmbeddedAssetIds(input); |
|||
|
|||
Assert.Contains(DomainId.Create("a_b-123"), ids.ToList()); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue