mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
166 changed files with 1179 additions and 583 deletions
@ -0,0 +1,103 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using NodaTime; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.ConvertContent; |
||||
|
|
||||
|
public sealed class AddDefaultValues : IContentDataConverter, IContentItemConverter, IContentFieldConverter |
||||
|
{ |
||||
|
private readonly PartitionResolver partitionResolver; |
||||
|
private readonly IClock clock; |
||||
|
private Instant now; |
||||
|
|
||||
|
public bool IgnoreRequiredFields { get; init; } |
||||
|
|
||||
|
public bool IgnoreNonMasterFields { get; init; } |
||||
|
|
||||
|
public AddDefaultValues(PartitionResolver partitionResolver, IClock? clock = null) |
||||
|
{ |
||||
|
this.partitionResolver = partitionResolver; |
||||
|
|
||||
|
this.clock = clock ?? SystemClock.Instance; |
||||
|
} |
||||
|
|
||||
|
public void ConvertDataBefore(Schema schema, ContentData data) |
||||
|
{ |
||||
|
foreach (var field in schema.Fields) |
||||
|
{ |
||||
|
if (data.TryGetValue(field.Name, out var fieldData) && fieldData != null) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if ((field.RawProperties.IsRequired && IgnoreRequiredFields) || !DefaultValueChecker.HasDefaultValue(field)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
data[field.Name] = new ContentFieldData(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData source) |
||||
|
{ |
||||
|
var partitioning = partitionResolver(field.Partitioning); |
||||
|
|
||||
|
foreach (var partitionKey in partitioning.AllKeys) |
||||
|
{ |
||||
|
if (!partitioning.IsMaster(partitionKey) && IgnoreNonMasterFields) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
Enrich(field, source, partitionKey); |
||||
|
} |
||||
|
|
||||
|
return source; |
||||
|
} |
||||
|
|
||||
|
public JsonObject ConvertItemBefore(IField parentField, JsonObject source, IEnumerable<IField> schema) |
||||
|
{ |
||||
|
foreach (var field in schema) |
||||
|
{ |
||||
|
Enrich(field, source, field.Name); |
||||
|
} |
||||
|
|
||||
|
return source; |
||||
|
} |
||||
|
|
||||
|
private void Enrich(IField field, Dictionary<string, JsonValue> fieldData, string key) |
||||
|
{ |
||||
|
if (fieldData.TryGetValue(key, out _) || (field.RawProperties.IsRequired && IgnoreRequiredFields)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var defaultValue = DefaultValueFactory.CreateDefaultValue(field, GetNow(), key); |
||||
|
|
||||
|
if (defaultValue == default) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
fieldData[key] = defaultValue; |
||||
|
} |
||||
|
|
||||
|
private Instant GetNow() |
||||
|
{ |
||||
|
if (now == default) |
||||
|
{ |
||||
|
now = clock.GetCurrentInstant(); |
||||
|
} |
||||
|
|
||||
|
return now; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.ConvertContent; |
||||
|
|
||||
|
internal sealed class DefaultValueChecker : IFieldPropertiesVisitor<bool, None> |
||||
|
{ |
||||
|
private static readonly DefaultValueChecker Instance = new DefaultValueChecker(); |
||||
|
|
||||
|
private DefaultValueChecker() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public static bool HasDefaultValue(IField field) |
||||
|
{ |
||||
|
Guard.NotNull(field); |
||||
|
|
||||
|
return field.RawProperties.Accept(Instance, None.Value); |
||||
|
} |
||||
|
|
||||
|
public bool Visit(ArrayFieldProperties properties, None args) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(AssetsFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(BooleanFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(ComponentFieldProperties properties, None args) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(ComponentsFieldProperties properties, None args) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(DateTimeFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null || properties.CalculatedDefaultValue != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(GeolocationFieldProperties properties, None args) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(JsonFieldProperties properties, None args) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(NumberFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(ReferencesFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(StringFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(TagsFieldProperties properties, None args) |
||||
|
{ |
||||
|
return properties.DefaultValue != null || properties.DefaultValues != null; |
||||
|
} |
||||
|
|
||||
|
public bool Visit(UIFieldProperties properties, None args) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
@ -1,57 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using NodaTime; |
|
||||
using Squidex.Domain.Apps.Core.Contents; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.DefaultValues; |
|
||||
|
|
||||
public static class DefaultValueExtensions |
|
||||
{ |
|
||||
public static void GenerateDefaultValues(this ContentData data, Schema schema, PartitionResolver partitionResolver) |
|
||||
{ |
|
||||
Guard.NotNull(schema); |
|
||||
Guard.NotNull(partitionResolver); |
|
||||
|
|
||||
foreach (var field in schema.Fields) |
|
||||
{ |
|
||||
var fieldData = data.GetOrCreate(field.Name, _ => new ContentFieldData()); |
|
||||
|
|
||||
if (fieldData != null) |
|
||||
{ |
|
||||
var partitioning = partitionResolver(field.Partitioning); |
|
||||
|
|
||||
foreach (var partitionKey in partitioning.AllKeys) |
|
||||
{ |
|
||||
Enrich(field, fieldData, partitionKey); |
|
||||
} |
|
||||
|
|
||||
if (fieldData.Count > 0) |
|
||||
{ |
|
||||
data[field.Name] = fieldData; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void Enrich(IField field, ContentFieldData fieldData, string partitionKey) |
|
||||
{ |
|
||||
var defaultValue = DefaultValueFactory.CreateDefaultValue(field, SystemClock.Instance.GetCurrentInstant(), partitionKey); |
|
||||
|
|
||||
if (field.RawProperties.IsRequired || defaultValue == default) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (!fieldData.TryGetValue(partitionKey, out _)) |
|
||||
{ |
|
||||
fieldData.AddLocalized(partitionKey, defaultValue); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,13 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Web; |
||||
|
|
||||
|
[AttributeUsage(AttributeTargets.Class)] |
||||
|
public sealed class OpenApiRequestAttribute : Attribute |
||||
|
{ |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using NJsonSchema; |
||||
|
using NJsonSchema.Generation; |
||||
|
using Squidex.Web; |
||||
|
|
||||
|
namespace Squidex.Areas.Api.Config.OpenApi; |
||||
|
|
||||
|
public sealed class RequiredSchemaProcessor : ISchemaProcessor |
||||
|
{ |
||||
|
public void Process(SchemaProcessorContext context) |
||||
|
{ |
||||
|
if (context.ContextualType.GetAttribute<OpenApiRequestAttribute>() != null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
FixRequired(context.Schema); |
||||
|
|
||||
|
foreach (var schema in context.Schema.AllOf) |
||||
|
{ |
||||
|
FixRequired(schema); |
||||
|
} |
||||
|
|
||||
|
foreach (var schema in context.Schema.OneOf) |
||||
|
{ |
||||
|
FixRequired(schema); |
||||
|
} |
||||
|
|
||||
|
static void FixRequired(JsonSchema schema) |
||||
|
{ |
||||
|
foreach (var property in schema.Properties.Values) |
||||
|
{ |
||||
|
if (!property.IsNullable(SchemaType.OpenApi3)) |
||||
|
{ |
||||
|
property.IsRequired = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue