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