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