mirror of https://github.com/Squidex/squidex.git
482 changed files with 53058 additions and 15991 deletions
@ -1,48 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders; |
|
||||
|
|
||||
namespace Squidex.Extensions.Samples.Middleware |
|
||||
{ |
|
||||
public class TemplateInstance : ITemplate |
|
||||
{ |
|
||||
public string Name { get; } = "custom2"; |
|
||||
|
|
||||
public Task RunAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Blogs") |
|
||||
.AddString("Title", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required()) |
|
||||
.AddString("Slug", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required() |
|
||||
.Disabled()) |
|
||||
.AddString("Text", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.RichText, |
|
||||
MaxLength = 1000, |
|
||||
MinLength = 200 |
|
||||
}) |
|
||||
.Required()) |
|
||||
.Build(); |
|
||||
|
|
||||
return publish(schema); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,63 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Commands; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Commands; |
|
||||
|
|
||||
namespace Squidex.Extensions.Samples.Middleware |
|
||||
{ |
|
||||
public sealed class TemplateMiddleware : ICustomCommandMiddleware |
|
||||
{ |
|
||||
public async Task HandleAsync(CommandContext context, NextDelegate next) |
|
||||
{ |
|
||||
await next(context); |
|
||||
|
|
||||
if (context.Command is CreateApp createApp && context.IsCompleted && createApp.Template == "custom") |
|
||||
{ |
|
||||
var appId = NamedId.Of(createApp.AppId, createApp.Name); |
|
||||
|
|
||||
var publish = new Func<IAppCommand, Task>(command => |
|
||||
{ |
|
||||
command.AppId = appId; |
|
||||
|
|
||||
return context.CommandBus.PublishAsync(command); |
|
||||
}); |
|
||||
|
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Pages") |
|
||||
.AddString("Title", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required()) |
|
||||
.AddString("Slug", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required() |
|
||||
.Disabled()) |
|
||||
.AddString("Text", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.RichText, |
|
||||
MaxLength = 1000, |
|
||||
MinLength = 200 |
|
||||
}) |
|
||||
.Required()) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,25 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates; |
|
||||
using Squidex.Infrastructure.Commands; |
|
||||
using Squidex.Infrastructure.Plugins; |
|
||||
|
|
||||
namespace Squidex.Extensions.Samples.Middleware |
|
||||
{ |
|
||||
public sealed class TemplatePlugin : IPlugin |
|
||||
{ |
|
||||
public void ConfigureServices(IServiceCollection services, IConfiguration config) |
|
||||
{ |
|
||||
services.AddSingleton<ICustomCommandMiddleware, TemplateMiddleware>(); |
|
||||
|
|
||||
services.AddSingleton<ITemplate, TemplateInstance>(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,82 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Domain.Apps.Core.Scripting.Internal; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class AssetCommandScriptVars : ScriptVars |
||||
|
{ |
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetParentId))] |
||||
|
public DomainId ParentId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileHash))] |
||||
|
public string? FileHash |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileName))] |
||||
|
public string? FileName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetSlug))] |
||||
|
public string? FileSlug |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetMimeType))] |
||||
|
public string? MimeType |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetParentPath))] |
||||
|
public Array? ParentPath |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetMetadata))] |
||||
|
public AssetMetadata? Metadata |
||||
|
{ |
||||
|
set => SetValue(value != null ? new AssetMetadataWrapper(value) : null); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetTags))] |
||||
|
public HashSet<string>? Tags |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileSize))] |
||||
|
public long FileSize |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetIsProtected))] |
||||
|
public bool? IsProtected |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.EntityRequestDeletePermanent))] |
||||
|
public bool? Permanent |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,83 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.ObjectModel; |
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class AssetEntityScriptVars : ScriptVars |
||||
|
{ |
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetParentId))] |
||||
|
public DomainId ParentId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileHash))] |
||||
|
public string? FileHash |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileName))] |
||||
|
public string? FileName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetSlug))] |
||||
|
public string? FileSlug |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetMimeType))] |
||||
|
public string? MimeType |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetParentPath))] |
||||
|
public Array? ParentPath |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetMetadata))] |
||||
|
public AssetMetadata? Metadata |
||||
|
{ |
||||
|
set => SetValue(value != null ? new ReadOnlyDictionary<string, IJsonValue>(value) : null); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetTags))] |
||||
|
public HashSet<string>? Tags |
||||
|
{ |
||||
|
set => SetValue(value != null ? new ReadOnlyCollection<string>(value.ToList()) : null); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileSize))] |
||||
|
public long FileSize |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetFileVersion))] |
||||
|
public long FileVersion |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AssetIsProtected))] |
||||
|
public bool? IsProtected |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Security.Claims; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class AssetScriptVars : ScriptVars |
||||
|
{ |
||||
|
[FieldDescription(nameof(FieldDescriptions.AppId))] |
||||
|
public DomainId AppId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.EntityId))] |
||||
|
public DomainId AssetId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AppName))] |
||||
|
public string AppName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.Operation))] |
||||
|
public string Operation |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.Command))] |
||||
|
public AssetCommandScriptVars Command |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.Asset))] |
||||
|
public AssetEntityScriptVars Asset |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.User))] |
||||
|
public ClaimsPrincipal? User |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Security.Claims; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class ContentScriptVars : DataScriptVars |
||||
|
{ |
||||
|
[FieldDescription(nameof(FieldDescriptions.AppId))] |
||||
|
public DomainId AppId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.SchemaId))] |
||||
|
public DomainId SchemaId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.EntityId))] |
||||
|
public DomainId ContentId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.AppName))] |
||||
|
public string AppName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentSchemaName))] |
||||
|
public string SchemaName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.Operation))] |
||||
|
public string Operation |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.EntityRequestDeletePermanent))] |
||||
|
public bool Permanent |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.User))] |
||||
|
public ClaimsPrincipal? User |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentStatus))] |
||||
|
public Status Status |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentStatusOld))] |
||||
|
public Status StatusOld |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentStatusOld))] |
||||
|
public Status OldStatus |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentData))] |
||||
|
public ContentData? DataOld |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentDataOld))] |
||||
|
public ContentData? OldData |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
[FieldDescription(nameof(FieldDescriptions.ContentData))] |
||||
|
public override ContentData? Data |
||||
|
{ |
||||
|
get => GetValue<ContentData?>(); |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public class DataScriptVars : ScriptVars |
||||
|
{ |
||||
|
public virtual ContentData? Data |
||||
|
{ |
||||
|
get => GetValue<ContentData?>(); |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Security.Claims; |
||||
|
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class EventScriptVars : ScriptVars |
||||
|
{ |
||||
|
public DomainId AppId |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
public string AppName |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
public ClaimsPrincipal User |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
|
||||
|
public EnrichedEvent Event |
||||
|
{ |
||||
|
set => SetValue(value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,125 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting.Internal |
||||
|
{ |
||||
|
internal sealed class AssetMetadataWrapper : IDictionary<string, object?> |
||||
|
{ |
||||
|
private readonly AssetMetadata metadata; |
||||
|
|
||||
|
public int Count |
||||
|
{ |
||||
|
get => metadata.Count; |
||||
|
} |
||||
|
|
||||
|
public ICollection<string> Keys |
||||
|
{ |
||||
|
get => metadata.Keys; |
||||
|
} |
||||
|
|
||||
|
public ICollection<object?> Values |
||||
|
{ |
||||
|
get => metadata.Values.Cast<object?>().ToList(); |
||||
|
} |
||||
|
|
||||
|
public object? this[string key] |
||||
|
{ |
||||
|
get => metadata[key]; |
||||
|
set => metadata[key] = JsonValue.Create(value); |
||||
|
} |
||||
|
|
||||
|
public bool IsReadOnly |
||||
|
{ |
||||
|
get => false; |
||||
|
} |
||||
|
|
||||
|
public AssetMetadataWrapper(AssetMetadata metadata) |
||||
|
{ |
||||
|
this.metadata = metadata; |
||||
|
} |
||||
|
|
||||
|
public bool TryGetValue(string key, [MaybeNullWhen(false)] out object? value) |
||||
|
{ |
||||
|
if (metadata.TryGetValue(key, out var temp)) |
||||
|
{ |
||||
|
value = temp; |
||||
|
return true; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
value = null; |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Add(string key, object? value) |
||||
|
{ |
||||
|
metadata.Add(key, JsonValue.Create(value)); |
||||
|
} |
||||
|
|
||||
|
public void Add(KeyValuePair<string, object?> item) |
||||
|
{ |
||||
|
Add(item.Key, item.Value); |
||||
|
} |
||||
|
|
||||
|
public bool Remove(string key) |
||||
|
{ |
||||
|
return metadata.Remove(key); |
||||
|
} |
||||
|
|
||||
|
public bool Remove(KeyValuePair<string, object?> item) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public void Clear() |
||||
|
{ |
||||
|
metadata.Clear(); |
||||
|
} |
||||
|
|
||||
|
public bool Contains(KeyValuePair<string, object?> item) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool ContainsKey(string key) |
||||
|
{ |
||||
|
return metadata.ContainsKey(key); |
||||
|
} |
||||
|
|
||||
|
public void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex) |
||||
|
{ |
||||
|
var i = arrayIndex; |
||||
|
|
||||
|
foreach (var item in metadata) |
||||
|
{ |
||||
|
if (i >= array.Length) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
array[i] = new KeyValuePair<string, object?>(item.Key, item.Value); |
||||
|
i++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public IEnumerator<KeyValuePair<string, object?>> GetEnumerator() |
||||
|
{ |
||||
|
return metadata.Select(x => new KeyValuePair<string, object?>(x.Key, x.Value)).GetEnumerator(); |
||||
|
} |
||||
|
|
||||
|
IEnumerator IEnumerable.GetEnumerator() |
||||
|
{ |
||||
|
return ((IEnumerable)metadata).GetEnumerator(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,144 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
using Squidex.Text; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class ArrayFieldBuilder : FieldBuilder<ArrayFieldBuilder, ArrayFieldProperties> |
|
||||
{ |
|
||||
private UpsertSchemaField TypedField |
|
||||
{ |
|
||||
get => (UpsertSchemaField)Field; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder(UpsertSchemaField field, ArrayFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddAssets(string name, Action<AssetFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<AssetsFieldProperties>(name); |
|
||||
|
|
||||
configure(new AssetFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddBoolean(string name, Action<BooleanFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<BooleanFieldProperties>(name); |
|
||||
|
|
||||
configure(new BooleanFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddDateTime(string name, Action<DateTimeFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<DateTimeFieldProperties>(name); |
|
||||
|
|
||||
configure(new DateTimeFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddComponent(string name, Action<ComponentFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ComponentFieldProperties>(name); |
|
||||
|
|
||||
configure(new ComponentFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddComponents(string name, Action<ComponentsFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ComponentsFieldProperties>(name); |
|
||||
|
|
||||
configure(new ComponentsFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddJson(string name, Action<JsonFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<JsonFieldProperties>(name); |
|
||||
|
|
||||
configure(new JsonFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddNumber(string name, Action<NumberFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<NumberFieldProperties>(name); |
|
||||
|
|
||||
configure(new NumberFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddReferences(string name, Action<ReferencesFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ReferencesFieldProperties>(name); |
|
||||
|
|
||||
configure(new ReferencesFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddString(string name, Action<StringFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<StringFieldProperties>(name); |
|
||||
|
|
||||
configure(new StringFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddTags(string name, Action<TagsFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<TagsFieldProperties>(name); |
|
||||
|
|
||||
configure(new TagsFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public ArrayFieldBuilder AddUI(string name, Action<UIFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<UIFieldProperties>(name); |
|
||||
|
|
||||
configure(new UIFieldBuilder(field, properties, Schema)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
private (UpsertSchemaNestedField, T) AddField<T>(string name) where T : FieldProperties, new() |
|
||||
{ |
|
||||
var properties = new T |
|
||||
{ |
|
||||
Label = name |
|
||||
}; |
|
||||
|
|
||||
var nestedField = new UpsertSchemaNestedField |
|
||||
{ |
|
||||
Name = name.ToCamelCase(), |
|
||||
Properties = properties |
|
||||
}; |
|
||||
|
|
||||
TypedField.Nested ??= Array.Empty<UpsertSchemaNestedField>(); |
|
||||
TypedField.Nested = TypedField.Nested.Union(new[] { nestedField }).ToArray(); |
|
||||
|
|
||||
return (nestedField, properties); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class AssetFieldBuilder : FieldBuilder<AssetFieldBuilder, AssetsFieldProperties> |
|
||||
{ |
|
||||
public AssetFieldBuilder(UpsertSchemaFieldBase field, AssetsFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class BooleanFieldBuilder : FieldBuilder<BooleanFieldBuilder, BooleanFieldProperties> |
|
||||
{ |
|
||||
public BooleanFieldBuilder(UpsertSchemaFieldBase field, BooleanFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class ComponentFieldBuilder : FieldBuilder<ComponentFieldBuilder, ComponentFieldProperties> |
|
||||
{ |
|
||||
public ComponentFieldBuilder(UpsertSchemaFieldBase field, ComponentFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class ComponentsFieldBuilder : FieldBuilder<ComponentsFieldBuilder, ComponentsFieldProperties> |
|
||||
{ |
|
||||
public ComponentsFieldBuilder(UpsertSchemaFieldBase field, ComponentsFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class DateTimeFieldBuilder : FieldBuilder<DateTimeFieldBuilder, DateTimeFieldProperties> |
|
||||
{ |
|
||||
public DateTimeFieldBuilder(UpsertSchemaFieldBase field, DateTimeFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,97 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public abstract class FieldBuilder |
|
||||
{ |
|
||||
protected UpsertSchemaFieldBase Field { get; init; } |
|
||||
|
|
||||
protected CreateSchema Schema { get; init; } |
|
||||
} |
|
||||
|
|
||||
public abstract class FieldBuilder<T, TProperties> : FieldBuilder where T : FieldBuilder where TProperties : FieldProperties |
|
||||
{ |
|
||||
private TProperties properties; |
|
||||
|
|
||||
protected FieldBuilder(UpsertSchemaFieldBase field, TProperties properties, CreateSchema schema) |
|
||||
{ |
|
||||
this.properties = properties; |
|
||||
|
|
||||
Field = field; |
|
||||
Schema = schema; |
|
||||
} |
|
||||
|
|
||||
public T Localizable() |
|
||||
{ |
|
||||
if (Field is UpsertSchemaField localizableField) |
|
||||
{ |
|
||||
localizableField.Partitioning = Partitioning.Language.Key; |
|
||||
} |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
|
|
||||
public T Disabled(bool isDisabled = true) |
|
||||
{ |
|
||||
Field.IsDisabled = isDisabled; |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
|
|
||||
public T Hidden(bool isHidden = true) |
|
||||
{ |
|
||||
Field.IsHidden = isHidden; |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
|
|
||||
public T Label(string? label) |
|
||||
{ |
|
||||
return Properties(x => x with { Label = label }); |
|
||||
} |
|
||||
|
|
||||
public T Hints(string? hints) |
|
||||
{ |
|
||||
return Properties(x => x with { Hints = hints }); |
|
||||
} |
|
||||
|
|
||||
public T Required(bool isRequired = true) |
|
||||
{ |
|
||||
return Properties(x => x with { IsRequired = isRequired }); |
|
||||
} |
|
||||
|
|
||||
public T Properties(Func<TProperties, TProperties> updater) |
|
||||
{ |
|
||||
properties = updater(properties); |
|
||||
|
|
||||
Field.Properties = properties; |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
|
|
||||
public T ShowInList() |
|
||||
{ |
|
||||
Schema.FieldsInLists ??= new FieldNames(); |
|
||||
Schema.FieldsInLists.Add(Field.Name); |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
|
|
||||
public T ShowInReferences() |
|
||||
{ |
|
||||
Schema.FieldsInReferences ??= new FieldNames(); |
|
||||
Schema.FieldsInReferences.Add(Field.Name); |
|
||||
|
|
||||
return (T)(object)this; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class JsonFieldBuilder : FieldBuilder<JsonFieldBuilder, JsonFieldProperties> |
|
||||
{ |
|
||||
public JsonFieldBuilder(UpsertSchemaFieldBase field, JsonFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class NumberFieldBuilder : FieldBuilder<NumberFieldBuilder, NumberFieldProperties> |
|
||||
{ |
|
||||
public NumberFieldBuilder(UpsertSchemaFieldBase field, NumberFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class ReferencesFieldBuilder : FieldBuilder<ReferencesFieldBuilder, ReferencesFieldProperties> |
|
||||
{ |
|
||||
public ReferencesFieldBuilder(UpsertSchemaFieldBase field, ReferencesFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,203 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
using Squidex.Text; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class SchemaBuilder |
|
||||
{ |
|
||||
private readonly CreateSchema command; |
|
||||
|
|
||||
public SchemaBuilder(CreateSchema command) |
|
||||
{ |
|
||||
this.command = command; |
|
||||
} |
|
||||
|
|
||||
public static SchemaBuilder Create(string name) |
|
||||
{ |
|
||||
var schemaName = name.ToKebabCase(); |
|
||||
|
|
||||
return new SchemaBuilder(new CreateSchema |
|
||||
{ |
|
||||
Name = schemaName |
|
||||
}).Published().WithLabel(name); |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder WithLabel(string? label) |
|
||||
{ |
|
||||
if (command.Properties == null) |
|
||||
{ |
|
||||
command.Properties = new SchemaProperties { Label = label }; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
command.Properties = command.Properties with { Label = label }; |
|
||||
} |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder WithScripts(SchemaScripts scripts) |
|
||||
{ |
|
||||
command.Scripts = scripts; |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder Published() |
|
||||
{ |
|
||||
command.IsPublished = true; |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder Singleton() |
|
||||
{ |
|
||||
command.Type = SchemaType.Singleton; |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddArray(string name, Action<ArrayFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ArrayFieldProperties>(name); |
|
||||
|
|
||||
configure(new ArrayFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddAssets(string name, Action<AssetFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<AssetsFieldProperties>(name); |
|
||||
|
|
||||
configure(new AssetFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddBoolean(string name, Action<BooleanFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<BooleanFieldProperties>(name); |
|
||||
|
|
||||
configure(new BooleanFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddComponent(string name, Action<ComponentFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ComponentFieldProperties>(name); |
|
||||
|
|
||||
configure(new ComponentFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddComponents(string name, Action<ComponentsFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ComponentsFieldProperties>(name); |
|
||||
|
|
||||
configure(new ComponentsFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddDateTime(string name, Action<DateTimeFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<DateTimeFieldProperties>(name); |
|
||||
|
|
||||
configure(new DateTimeFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddJson(string name, Action<JsonFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<JsonFieldProperties>(name); |
|
||||
|
|
||||
configure(new JsonFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddNumber(string name, Action<NumberFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<NumberFieldProperties>(name); |
|
||||
|
|
||||
configure(new NumberFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddReferences(string name, Action<ReferencesFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<ReferencesFieldProperties>(name); |
|
||||
|
|
||||
configure(new ReferencesFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddString(string name, Action<StringFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<StringFieldProperties>(name); |
|
||||
|
|
||||
configure(new StringFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddTags(string name, Action<TagsFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<TagsFieldProperties>(name); |
|
||||
|
|
||||
configure(new TagsFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
public SchemaBuilder AddUI(string name, Action<UIFieldBuilder> configure) |
|
||||
{ |
|
||||
var (field, properties) = AddField<UIFieldProperties>(name); |
|
||||
|
|
||||
configure(new UIFieldBuilder(field, properties, command)); |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
private (UpsertSchemaField, T) AddField<T>(string name) where T : FieldProperties, new() |
|
||||
{ |
|
||||
var properties = new T { Label = name }; |
|
||||
|
|
||||
var field = new UpsertSchemaField |
|
||||
{ |
|
||||
Name = name.ToCamelCase(), |
|
||||
Properties = properties, |
|
||||
}; |
|
||||
|
|
||||
if (command.Fields == null) |
|
||||
{ |
|
||||
command.Fields = new[] { field }; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
command.Fields = command.Fields.Union(Enumerable.Repeat(field, 1)).ToArray(); |
|
||||
} |
|
||||
|
|
||||
return (field, properties); |
|
||||
} |
|
||||
|
|
||||
public CreateSchema Build() |
|
||||
{ |
|
||||
return command; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class StringFieldBuilder : FieldBuilder<StringFieldBuilder, StringFieldProperties> |
|
||||
{ |
|
||||
public StringFieldBuilder(UpsertSchemaFieldBase field, StringFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas.Commands; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders |
|
||||
{ |
|
||||
public sealed class TagsFieldBuilder : FieldBuilder<TagsFieldBuilder, TagsFieldProperties> |
|
||||
{ |
|
||||
public TagsFieldBuilder(UpsertSchemaFieldBase field, TagsFieldProperties properties, CreateSchema schema) |
|
||||
: base(field, properties, schema) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,127 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Contents; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders; |
|
||||
using Squidex.Domain.Apps.Entities.Contents.Commands; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
|
||||
{ |
|
||||
public sealed class CreateBlog : ITemplate |
|
||||
{ |
|
||||
public string Name { get; } = "blog"; |
|
||||
|
|
||||
public Task RunAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
return Task.WhenAll( |
|
||||
CreatePagesAsync(publish), |
|
||||
CreatePostsAsync(publish)); |
|
||||
} |
|
||||
|
|
||||
private static async Task CreatePostsAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var postsId = await CreatePostsSchemaAsync(publish); |
|
||||
|
|
||||
await publish(new CreateContent |
|
||||
{ |
|
||||
SchemaId = postsId, |
|
||||
Data = |
|
||||
new ContentData() |
|
||||
.AddField("title", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("My first post with Squidex")) |
|
||||
.AddField("text", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("Just created a blog with Squidex. I love it!")), |
|
||||
Status = Status.Published |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private static async Task CreatePagesAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var pagesId = await CreatePagesSchemaAsync(publish); |
|
||||
|
|
||||
await publish(new CreateContent |
|
||||
{ |
|
||||
SchemaId = pagesId, |
|
||||
Data = |
|
||||
new ContentData() |
|
||||
.AddField("title", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("About Me")) |
|
||||
.AddField("text", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("I love Squidex and SciFi!")), |
|
||||
Status = Status.Published |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreatePostsSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Posts") |
|
||||
.AddString("Title", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The title of the post.")) |
|
||||
.AddString("Text", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.RichText |
|
||||
}) |
|
||||
.Required() |
|
||||
.Hints("The text of the post.")) |
|
||||
.AddString("Slug", f => f |
|
||||
.Disabled() |
|
||||
.Label("Slug (Autogenerated)") |
|
||||
.Hints("Autogenerated slug that can be used to identity the post.")) |
|
||||
.WithScripts(DefaultScripts.GenerateSlug) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
|
|
||||
return NamedId.Of(schema.SchemaId, schema.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreatePagesSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Pages") |
|
||||
.AddString("Title", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
MaxLength = 100 |
|
||||
}) |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The title of the page.")) |
|
||||
.AddString("Text", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.RichText |
|
||||
}) |
|
||||
.Required() |
|
||||
.Hints("The text of the page.")) |
|
||||
.AddString("Slug", f => f |
|
||||
.Disabled() |
|
||||
.Label("Slug (Autogenerated)") |
|
||||
.Hints("Autogenerated slug that can be used to identity the page.")) |
|
||||
.WithScripts(DefaultScripts.GenerateSlug) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
|
|
||||
return NamedId.Of(schema.SchemaId, schema.Name); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,269 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Assets; |
|
||||
using Squidex.Domain.Apps.Core.Contents; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders; |
|
||||
using Squidex.Domain.Apps.Entities.Contents.Commands; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Collections; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
|
||||
{ |
|
||||
public sealed class CreateProfile : ITemplate |
|
||||
{ |
|
||||
public string Name { get; } = "profile"; |
|
||||
|
|
||||
public Task RunAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
return Task.WhenAll( |
|
||||
CreateBasicsAsync(publish), |
|
||||
CreateEducationSchemaAsync(publish), |
|
||||
CreateExperienceSchemaAsync(publish), |
|
||||
CreateProjectsSchemaAsync(publish), |
|
||||
CreatePublicationsSchemaAsync(publish), |
|
||||
CreateSkillsSchemaAsync(publish)); |
|
||||
} |
|
||||
|
|
||||
private static async Task CreateBasicsAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var postsId = await CreateBasicsSchemaAsync(publish); |
|
||||
|
|
||||
await publish(new UpdateContent |
|
||||
{ |
|
||||
ContentId = postsId.Id, |
|
||||
Data = |
|
||||
new ContentData() |
|
||||
.AddField("firstName", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("John")) |
|
||||
.AddField("lastName", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("Doe")) |
|
||||
.AddField("profession", |
|
||||
new ContentFieldData() |
|
||||
.AddInvariant("Software Developer")), |
|
||||
SchemaId = postsId |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreateBasicsSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var command = |
|
||||
SchemaBuilder.Create("Basics") |
|
||||
.Singleton() |
|
||||
.AddString("First Name", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("Your first name.")) |
|
||||
.AddString("Last Name", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("Your last name.")) |
|
||||
.AddAssets("Image", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
ExpectedType = AssetType.Image, |
|
||||
MaxItems = 1, |
|
||||
MinItems = 1 |
|
||||
}) |
|
||||
.Hints("Your profile image.")) |
|
||||
.AddString("Profession", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.TextArea |
|
||||
}) |
|
||||
.Required() |
|
||||
.Hints("Describe your profession.")) |
|
||||
.AddString("Summary", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.TextArea |
|
||||
}) |
|
||||
.Hints("Write a short summary about yourself.")) |
|
||||
.AddString("Legal Terms", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.TextArea |
|
||||
}) |
|
||||
.Hints("The terms to fulfill legal requirements.")) |
|
||||
.AddString("Github Link", f => f |
|
||||
.Hints("An optional link to your Github account.")) |
|
||||
.AddString("Blog Link", f => f |
|
||||
.Hints("An optional link to your Blog.")) |
|
||||
.AddString("Twitter Link", f => f |
|
||||
.Hints("An optional link to your Twitter account.")) |
|
||||
.AddString("LinkedIn Link", f => f |
|
||||
.Hints("An optional link to your LinkedIn account.")) |
|
||||
.AddString("Email Address", f => f |
|
||||
.Hints("An optional email address to contact you.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(command); |
|
||||
|
|
||||
return NamedId.Of(command.SchemaId, command.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreateProjectsSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Projects") |
|
||||
.AddString("Name", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The name of your project.")) |
|
||||
.AddString("Description", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
Editor = StringFieldEditor.TextArea |
|
||||
}) |
|
||||
.Required() |
|
||||
.Hints("Describe your project.")) |
|
||||
.AddAssets("Image", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
ExpectedType = AssetType.Image, |
|
||||
MaxItems = 1, |
|
||||
MinItems = 1 |
|
||||
}) |
|
||||
.Required() |
|
||||
.Hints("An image or screenshot for your project.")) |
|
||||
.AddString("Label", f => f |
|
||||
.Properties(p => p with { Editor = StringFieldEditor.TextArea }) |
|
||||
.Hints("An optional label to categorize your project, e.g. 'Open Source'.")) |
|
||||
.AddString("Link", f => f |
|
||||
.Hints("An optional link to your project.")) |
|
||||
.AddNumber("Year", f => f |
|
||||
.Hints("The year, when you realized the project, used for sorting only.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
|
|
||||
return NamedId.Of(schema.SchemaId, schema.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreateExperienceSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Experience") |
|
||||
.AddString("Position", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("Your position in this job.")) |
|
||||
.AddString("Company", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The company or organization you worked for.")) |
|
||||
.AddAssets("Logo", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
ExpectedType = AssetType.Image, |
|
||||
MaxItems = 1, |
|
||||
MinItems = 1 |
|
||||
}) |
|
||||
.Hints("The logo of the company or organization you worked for.")) |
|
||||
.AddDateTime("From", f => f |
|
||||
.Required() |
|
||||
.Hints("The start date.")) |
|
||||
.AddDateTime("To", f => f |
|
||||
.Hints("The end date, keep empty if you still work there.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
|
|
||||
return NamedId.Of(schema.SchemaId, schema.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreateEducationSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var schema = |
|
||||
SchemaBuilder.Create("Education") |
|
||||
.AddString("Degree", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The degree you got or achieved.")) |
|
||||
.AddString("School", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The school or university.")) |
|
||||
.AddAssets("Logo", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
ExpectedType = AssetType.Image, |
|
||||
MaxItems = 1, |
|
||||
MinItems = 1 |
|
||||
}) |
|
||||
.Hints("The logo of the school or university.")) |
|
||||
.AddDateTime("From", f => f |
|
||||
.Required() |
|
||||
.Hints("The start date.")) |
|
||||
.AddDateTime("To", f => f |
|
||||
.Hints("The end date, keep empty if you still study there.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(schema); |
|
||||
|
|
||||
return NamedId.Of(schema.SchemaId, schema.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreatePublicationsSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var command = |
|
||||
SchemaBuilder.Create("Publications") |
|
||||
.AddString("Name", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The name or title of your publication.")) |
|
||||
.AddAssets("Cover", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
ExpectedType = AssetType.Image, |
|
||||
MaxItems = 1, |
|
||||
MinItems = 1 |
|
||||
}) |
|
||||
.Hints("The cover of your publication.")) |
|
||||
.AddString("Description", f => f |
|
||||
.Hints("Describe the content of your publication.")) |
|
||||
.AddString("Link", f => f |
|
||||
.Hints("Optional link to your publication.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(command); |
|
||||
|
|
||||
return NamedId.Of(command.SchemaId, command.Name); |
|
||||
} |
|
||||
|
|
||||
private static async Task<NamedId<DomainId>> CreateSkillsSchemaAsync(PublishTemplate publish) |
|
||||
{ |
|
||||
var command = |
|
||||
SchemaBuilder.Create("Skills") |
|
||||
.AddString("Name", f => f |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The name of the skill.")) |
|
||||
.AddString("Experience", f => f |
|
||||
.Properties(p => p with |
|
||||
{ |
|
||||
AllowedValues = ReadonlyList.Create( |
|
||||
"Beginner", |
|
||||
"Advanced", |
|
||||
"Professional", |
|
||||
"Expert"), |
|
||||
Editor = StringFieldEditor.Dropdown, |
|
||||
}) |
|
||||
.Required() |
|
||||
.ShowInList() |
|
||||
.Hints("The level of experience.")) |
|
||||
.Build(); |
|
||||
|
|
||||
await publish(command); |
|
||||
|
|
||||
return NamedId.Of(command.SchemaId, command.Name); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
|
||||
{ |
|
||||
public static class DefaultScripts |
|
||||
{ |
|
||||
private const string ScriptToGenerateSlug = @"
|
|
||||
var data = ctx.data; |
|
||||
|
|
||||
if (data.title && data.title.iv) { |
|
||||
data.slug = { iv: slugify(data.title.iv) }; |
|
||||
|
|
||||
replace(data); |
|
||||
}";
|
|
||||
|
|
||||
public static readonly SchemaScripts GenerateSlug = new SchemaScripts |
|
||||
{ |
|
||||
Create = ScriptToGenerateSlug, |
|
||||
Update = ScriptToGenerateSlug |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,121 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Squidex.CLI.Commands.Implementation; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Log; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
||||
|
{ |
||||
|
public sealed class StringLogger : ILogger, ILogLine |
||||
|
{ |
||||
|
private const int MaxActionLength = 40; |
||||
|
private readonly ISemanticLog log; |
||||
|
private readonly string template; |
||||
|
private readonly List<string> lines = new List<string>(); |
||||
|
private readonly List<string> errors = new List<string>(); |
||||
|
private string startedLine = string.Empty; |
||||
|
|
||||
|
public StringLogger(string template, ISemanticLog log) |
||||
|
{ |
||||
|
this.template = template; |
||||
|
|
||||
|
this.log = log; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
var mesage = string.Join('\n', lines); |
||||
|
|
||||
|
log.LogInformation(w => w |
||||
|
.WriteProperty("message", $"CLI executed or template {template}.") |
||||
|
.WriteProperty("template", template) |
||||
|
.WriteArray("steps", a => |
||||
|
{ |
||||
|
foreach (var line in lines) |
||||
|
{ |
||||
|
a.WriteValue(line); |
||||
|
} |
||||
|
})); |
||||
|
|
||||
|
if (errors.Count > 0) |
||||
|
{ |
||||
|
throw new DomainException($"Template failed with {errors[0]}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void StepStart(string message) |
||||
|
{ |
||||
|
if (message.Length > MaxActionLength - 3) |
||||
|
{ |
||||
|
var length = MaxActionLength - 3; |
||||
|
|
||||
|
message = message[..length]; |
||||
|
} |
||||
|
|
||||
|
startedLine = $"{message.PadRight(MaxActionLength, '.')}..."; |
||||
|
} |
||||
|
|
||||
|
public void StepSuccess(string? details = null) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(details)) |
||||
|
{ |
||||
|
AddToLine($"succeeded ({details})."); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
AddToLine("succeeded"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void StepFailed(string reason) |
||||
|
{ |
||||
|
AddToErrors(reason); |
||||
|
AddToLine($"failed: {reason.TrimEnd('.')}."); |
||||
|
} |
||||
|
|
||||
|
public void StepSkipped(string reason) |
||||
|
{ |
||||
|
AddToLine($"skipped: {reason.TrimEnd('.')}."); |
||||
|
} |
||||
|
|
||||
|
public void WriteLine() |
||||
|
{ |
||||
|
lines.Add(string.Empty); |
||||
|
} |
||||
|
|
||||
|
public void WriteLine(string message) |
||||
|
{ |
||||
|
lines.Add(message); |
||||
|
} |
||||
|
|
||||
|
public void WriteLine(string message, params object?[] args) |
||||
|
{ |
||||
|
lines.Add(string.Format(CultureInfo.InvariantCulture, message, args)); |
||||
|
} |
||||
|
|
||||
|
private void AddToErrors(string reason) |
||||
|
{ |
||||
|
errors.Add(reason); |
||||
|
} |
||||
|
|
||||
|
private void AddToLine(string message) |
||||
|
{ |
||||
|
startedLine += message; |
||||
|
|
||||
|
lines.Add(startedLine); |
||||
|
|
||||
|
startedLine = string.Empty; |
||||
|
} |
||||
|
|
||||
|
public ILogLine WriteSameLine() |
||||
|
{ |
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
||||
|
{ |
||||
|
public sealed record Template(string Name, string Title, string Description, bool IsStarter) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Text.RegularExpressions; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
||||
|
{ |
||||
|
public sealed class TemplatesClient |
||||
|
{ |
||||
|
private static readonly Regex Regex = new Regex("\\* \\[(?<Title>.*)\\]\\((?<Name>.*)\\/README\\.md\\): (?<Description>.*)", RegexOptions.Compiled | RegexOptions.ExplicitCapture); |
||||
|
private readonly IHttpClientFactory httpClientFactory; |
||||
|
private readonly TemplatesOptions options; |
||||
|
|
||||
|
public TemplatesClient(IHttpClientFactory httpClientFactory, IOptions<TemplatesOptions> options) |
||||
|
{ |
||||
|
this.httpClientFactory = httpClientFactory; |
||||
|
|
||||
|
this.options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public async Task<string?> GetRepositoryUrl(string name, |
||||
|
CancellationToken ct = default) |
||||
|
{ |
||||
|
using (var httpClient = httpClientFactory.CreateClient()) |
||||
|
{ |
||||
|
var result = new List<Template>(); |
||||
|
|
||||
|
foreach (var repository in options.Repositories.OrEmpty()) |
||||
|
{ |
||||
|
var url = $"{repository.ContentUrl}/README.md"; |
||||
|
|
||||
|
var text = await httpClient.GetStringAsync(url, ct); |
||||
|
|
||||
|
foreach (Match match in Regex.Matches(text)) |
||||
|
{ |
||||
|
var currentName = match.Groups["Name"].Value; |
||||
|
|
||||
|
if (currentName == name) |
||||
|
{ |
||||
|
return $"{repository.GitUrl ?? repository.ContentUrl}?folder={name}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task<List<Template>> GetTemplatesAsync( |
||||
|
CancellationToken ct = default) |
||||
|
{ |
||||
|
using (var httpClient = httpClientFactory.CreateClient()) |
||||
|
{ |
||||
|
var result = new List<Template>(); |
||||
|
|
||||
|
foreach (var repository in options.Repositories.OrEmpty()) |
||||
|
{ |
||||
|
var url = $"{repository.ContentUrl}/README.md"; |
||||
|
|
||||
|
var text = await httpClient.GetStringAsync(url, ct); |
||||
|
|
||||
|
foreach (Match match in Regex.Matches(text)) |
||||
|
{ |
||||
|
var title = match.Groups["Title"].Value; |
||||
|
|
||||
|
result.Add(new Template( |
||||
|
match.Groups["Name"].Value, |
||||
|
title, |
||||
|
match.Groups["Description"].Value, |
||||
|
title.StartsWith("Starter ", StringComparison.OrdinalIgnoreCase))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task<string?> GetDetailAsync(string name, |
||||
|
CancellationToken ct = default) |
||||
|
{ |
||||
|
Guard.NotNullOrEmpty(name); |
||||
|
|
||||
|
using (var httpClient = httpClientFactory.CreateClient()) |
||||
|
{ |
||||
|
foreach (var repository in options.Repositories.OrEmpty()) |
||||
|
{ |
||||
|
var url = $"{repository.ContentUrl}/{name}/README.md"; |
||||
|
|
||||
|
var response = await httpClient.GetAsync(url, ct); |
||||
|
|
||||
|
if (response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
return await response.Content.ReadAsStringAsync(ct); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Apps.Templates |
||||
|
{ |
||||
|
public sealed class TemplatesOptions |
||||
|
{ |
||||
|
public string? LocalUrl { get; set; } |
||||
|
|
||||
|
public TemplateRepository[] Repositories { get; set; } |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue