Browse Source

Tests for sync.

pull/343/head
Sebastian Stehle 7 years ago
parent
commit
c41e69c387
  1. 8
      src/Squidex.Domain.Apps.Core.Model/Schemas/Json/JsonNestedFieldModel.cs
  2. 41
      src/Squidex.Domain.Apps.Core.Model/Schemas/Json/JsonSchemaModel.cs
  3. 22
      src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs
  4. 3
      src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs
  5. 15
      src/Squidex.Domain.Apps.Entities/Schemas/Commands/UpsertCommand.cs
  6. 3
      src/Squidex.Domain.Apps.Entities/Schemas/Commands/UpsertSchemaField.cs
  7. 27
      src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs
  8. 31
      src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureScriptsDto.cs
  9. 59
      src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs
  10. 29
      src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs
  11. 87
      src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertDto.cs
  12. 4
      src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs
  13. 2
      src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs
  14. 22
      src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs
  15. 13
      tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs
  16. 4
      tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs
  17. 6
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs
  18. 42
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaGrainTests.cs
  19. 1
      tools/Migrate_01/Rebuilder.cs

8
src/Squidex.Domain.Apps.Core.Model/Schemas/Json/JsonNestedFieldModel.cs

@ -20,17 +20,15 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
[JsonProperty]
public bool IsHidden { get; set; }
[JsonProperty]
public bool IsLocked { get; set; }
[JsonProperty]
public bool IsDisabled { get; set; }
[JsonProperty]
public FieldProperties Properties { get; set; }
public bool IsLocked
{
get { return false; }
}
public NestedField ToNestedField()
{
return Properties.CreateNestedField(Id, Name, this);

41
src/Squidex.Domain.Apps.Core.Model/Schemas/Json/JsonSchemaModel.cs

@ -6,8 +6,11 @@
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Core.Schemas.Json
{
@ -16,6 +19,12 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public string Category { get; set; }
[JsonProperty]
public bool IsSingleton { get; set; }
[JsonProperty]
public bool IsPublished { get; set; }
@ -25,15 +34,19 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
[JsonProperty]
public JsonFieldModel[] Fields { get; set; }
[JsonProperty]
public IReadOnlyDictionary<string, string> Scripts { get; set; }
[JsonProperty]
public IReadOnlyDictionary<string, string> PreviewUrls { get; set; }
public JsonSchemaModel()
{
}
public JsonSchemaModel(Schema schema)
{
Name = schema.Name;
Properties = schema.Properties;
SimpleMapper.Map(schema, this);
Fields =
schema.Fields.ToArray(x =>
@ -48,8 +61,6 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
Partitioning = x.Partitioning.Key,
Properties = x.RawProperties
});
IsPublished = schema.IsPublished;
}
private static JsonNestedFieldModel[] CreateChildren(IField field)
@ -62,6 +73,7 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
Id = x.Id,
Name = x.Name,
IsHidden = x.IsHidden,
IsLocked = x.IsLocked,
IsDisabled = x.IsDisabled,
Properties = x.RawProperties
});
@ -74,7 +86,24 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json
{
var fields = Fields.ToArray(f => f.ToField()) ?? Array.Empty<RootField>();
return new Schema(Name, fields, Properties, IsPublished);
var schema = new Schema(Name, fields, Properties, IsPublished, IsSingleton);
if (!string.IsNullOrWhiteSpace(Category))
{
schema = schema.ChangeCategory(Category);
}
if (Scripts?.Count > 0)
{
schema = schema.ConfigureScripts(Scripts);
}
if (PreviewUrls?.Count > 0)
{
schema = schema.ConfigurePreviewUrls(PreviewUrls);
}
return schema;
}
}
}

22
src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs

@ -38,13 +38,6 @@ namespace Squidex.Domain.Apps.Core.EventSynchronization
return @event;
}
var events = SyncFields(source.FieldCollection, target.FieldCollection, serializer, idGenerator, null, options);
foreach (var @event in events)
{
yield return E(@event);
}
if (!source.Properties.EqualsJson(target.Properties, serializer))
{
yield return E(new SchemaUpdated { Properties = target.Properties });
@ -55,14 +48,14 @@ namespace Squidex.Domain.Apps.Core.EventSynchronization
yield return E(new SchemaCategoryChanged { Name = target.Category });
}
if (!source.PreviewUrls.EqualsDictionary(target.PreviewUrls))
if (!source.Scripts.EqualsDictionary(target.Scripts))
{
yield return E(new SchemaPreviewUrlsConfigured { PreviewUrls = target.PreviewUrls.ToDictionary(x => x.Key, x => x.Value) });
yield return E(new SchemaScriptsConfigured { Scripts = target.Scripts.ToDictionary(x => x.Key, x => x.Value) });
}
if (!source.Scripts.EqualsDictionary(target.Scripts))
if (!source.PreviewUrls.EqualsDictionary(target.PreviewUrls))
{
yield return E(new SchemaScriptsConfigured { Scripts = target.Scripts.ToDictionary(x => x.Key, x => x.Value) });
yield return E(new SchemaPreviewUrlsConfigured { PreviewUrls = target.PreviewUrls.ToDictionary(x => x.Key, x => x.Value) });
}
if (source.IsPublished != target.IsPublished)
@ -71,6 +64,13 @@ namespace Squidex.Domain.Apps.Core.EventSynchronization
E(new SchemaPublished()) :
E(new SchemaUnpublished());
}
var events = SyncFields(source.FieldCollection, target.FieldCollection, serializer, idGenerator, null, options);
foreach (var @event in events)
{
yield return E(@event);
}
}
}

3
src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs

@ -9,5 +9,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands
{
public sealed class SynchronizeSchema : UpsertCommand
{
public bool NoFieldDeletion { get; set; }
public bool NoFieldRecreation { get; set; }
}
}

15
src/Squidex.Domain.Apps.Entities/Schemas/Commands/UpsertCommand.cs

@ -35,6 +35,21 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands
schema = schema.Publish();
}
if (Scripts != null)
{
schema = schema.ConfigureScripts(Scripts);
}
if (PreviewUrls != null)
{
schema = schema.ConfigurePreviewUrls(PreviewUrls);
}
if (!string.IsNullOrWhiteSpace(Category))
{
schema = schema.ChangeCategory(Category);
}
var totalFields = 0;
if (Fields != null)

3
src/Squidex.Domain.Apps.Entities/Schemas/Commands/UpsertSchemaField.cs

@ -6,12 +6,13 @@
// ==========================================================================
using System.Collections.Generic;
using P = Squidex.Domain.Apps.Core.Partitioning;
namespace Squidex.Domain.Apps.Entities.Schemas.Commands
{
public sealed class UpsertSchemaField : UpsertSchemaFieldBase
{
public string Partitioning { get; set; } = "invariant";
public string Partitioning { get; set; } = P.Invariant.Key;
public List<UpsertSchemaNestedField> Nested { get; set; }
}

27
src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs

@ -76,6 +76,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas
Create(c);
});
case SynchronizeSchema synchronizeSchema:
return UpdateAsync(synchronizeSchema, c =>
{
GuardSchema.CanSynchronize(c);
Synchronize(c);
});
case DeleteField deleteField:
return UpdateAsync(deleteField, c =>
{
@ -203,14 +211,20 @@ namespace Squidex.Domain.Apps.Entities.Schemas
public void Synchronize(SynchronizeSchema command)
{
var options = new SchemaSynchronizationOptions
{
NoFieldDeletion = command.NoFieldDeletion,
NoFieldRecreation = command.NoFieldRecreation
};
var schemaSource = Snapshot.SchemaDef;
var schemaTarget = command.ToSchema(schemaSource.Name, schemaSource.IsSingleton);
var @events = schemaTarget.Synchronize(schemaSource, serializer, () => Snapshot.SchemaFieldsTotal + 1);
var @events = schemaSource.Synchronize(schemaTarget, serializer, () => Snapshot.SchemaFieldsTotal + 1, options);
foreach (var @event in @events)
{
RaiseEvent(@event);
RaiseEvent(SimpleMapper.Map(command, (SchemaEvent)@event));
}
}
@ -221,7 +235,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
public void Add(AddField command)
{
RaiseEvent(command, new FieldAdded { FieldId = NamedId.Of(Snapshot.SchemaFieldsTotal + 1, command.Name) });
RaiseEvent(command, new FieldAdded { FieldId = CreateFieldId(command) });
}
public void UpdateField(UpdateField command)
@ -321,9 +335,12 @@ namespace Squidex.Domain.Apps.Entities.Schemas
{
pe.ParentFieldId = NamedId.Of(field.Id, field.Name);
if (field is IArrayField arrayField && command is FieldCommand fc && @event is FieldEvent fe && arrayField.FieldsById.TryGetValue(fc.FieldId, out var nestedField))
if (command is FieldCommand fc && @event is FieldEvent fe)
{
fe.FieldId = NamedId.Of(nestedField.Id, nestedField.Name);
if (field is IArrayField arrayField && arrayField.FieldsById.TryGetValue(fc.FieldId, out var nestedField))
{
fe.FieldId = NamedId.Of(nestedField.Id, nestedField.Name);
}
}
}
}

31
src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureScriptsDto.cs

@ -5,41 +5,16 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class ConfigureScriptsDto
public sealed class ConfigureScriptsDto : Dictionary<string, string>
{
/// <summary>
/// The script that is executed for each query when querying contents.
/// </summary>
public string ScriptQuery { get; set; }
/// <summary>
/// The script that is executed when creating a content.
/// </summary>
public string ScriptCreate { get; set; }
/// <summary>
/// The script that is executed when updating a content.
/// </summary>
public string ScriptUpdate { get; set; }
/// <summary>
/// The script that is executed when deleting a content.
/// </summary>
public string ScriptDelete { get; set; }
/// <summary>
/// The script that is executed when change a content status.
/// </summary>
public string ScriptChange { get; set; }
public ConfigureScripts ToCommand()
{
return SimpleMapper.Map(this, new ConfigureScripts());
return new ConfigureScripts { Scripts = this };
}
}
}

59
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs

@ -5,15 +5,12 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class CreateSchemaDto
public sealed class CreateSchemaDto : UpsertDto
{
/// <summary>
/// The name of the schema.
@ -22,66 +19,14 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
[RegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")]
public string Name { get; set; }
/// <summary>
/// The optional properties.
/// </summary>
public SchemaPropertiesDto Properties { get; set; }
/// <summary>
/// Optional fields.
/// </summary>
public List<CreateSchemaFieldDto> Fields { get; set; }
/// <summary>
/// Set to true to allow a single content item only.
/// </summary>
public bool Singleton { get; set; }
/// <summary>
/// Set it to true to autopublish the schema.
/// </summary>
public bool Publish { get; set; }
public CreateSchema ToCommand()
{
var command = new CreateSchema();
SimpleMapper.Map(this, command);
if (Properties != null)
{
command.Properties = new SchemaProperties();
SimpleMapper.Map(Properties, command.Properties);
}
if (Fields != null)
{
command.Fields = new List<UpsertSchemaField>();
foreach (var fieldDto in Fields)
{
var rootProperties = fieldDto?.Properties.ToProperties();
var rootField = SimpleMapper.Map(fieldDto, new UpsertSchemaField { Properties = rootProperties });
if (fieldDto.Nested != null)
{
rootField.Nested = new List<UpsertSchemaNestedField>();
foreach (var nestedFieldDto in fieldDto.Nested)
{
var nestedProperties = nestedFieldDto?.Properties.ToProperties();
var nestedField = SimpleMapper.Map(nestedFieldDto, new UpsertSchemaNestedField { Properties = nestedProperties });
rootField.Nested.Add(nestedField);
}
}
command.Fields.Add(rootField);
}
}
return command;
return ToCommand(this, new CreateSchema());
}
}
}

29
src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs

@ -0,0 +1,29 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class SynchronizeSchemaDto : UpsertDto
{
/// <summary>
/// True, when fields should not be deleted.
/// </summary>
public bool NoFieldDeletion { get; set; }
/// <summary>
/// True, when fields with different types should not be recreated.
/// </summary>
public bool NoFieldRecreation { get; set; }
public SynchronizeSchema ToCommand()
{
return ToCommand(this, new SynchronizeSchema());
}
}
}

87
src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertDto.cs

@ -0,0 +1,87 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public abstract class UpsertDto
{
/// <summary>
/// The optional properties.
/// </summary>
public SchemaPropertiesDto Properties { get; set; }
/// <summary>
/// Optional fields.
/// </summary>
public List<UpsertSchemaFieldDto> Fields { get; set; }
/// <summary>
/// The optional scripts.
/// </summary>
public Dictionary<string, string> Scripts { get; set; }
/// <summary>
/// The optional preview urls.
/// </summary>
public Dictionary<string, string> PreviewUrls { get; set; }
/// <summary>
/// The category.
/// </summary>
public string Category { get; set; }
/// <summary>
/// Set it to true to autopublish the schema.
/// </summary>
public bool Publish { get; set; }
public static TCommand ToCommand<TCommand, TDto>(TDto dto, TCommand command) where TCommand : UpsertCommand where TDto : UpsertDto
{
SimpleMapper.Map(dto, command);
if (dto.Properties != null)
{
command.Properties = new SchemaProperties();
SimpleMapper.Map(dto.Properties, command.Properties);
}
if (dto.Fields != null)
{
command.Fields = new List<UpsertSchemaField>();
foreach (var fieldDto in dto.Fields)
{
var rootProperties = fieldDto?.Properties.ToProperties();
var rootField = SimpleMapper.Map(fieldDto, new UpsertSchemaField { Properties = rootProperties });
if (fieldDto.Nested != null)
{
rootField.Nested = new List<UpsertSchemaNestedField>();
foreach (var nestedFieldDto in fieldDto.Nested)
{
var nestedProperties = nestedFieldDto?.Properties.ToProperties();
var nestedField = SimpleMapper.Map(nestedFieldDto, new UpsertSchemaNestedField { Properties = nestedProperties });
rootField.Nested.Add(nestedField);
}
}
command.Fields.Add(rootField);
}
}
return command;
}
}
}

4
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaFieldDto.cs → src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs

@ -10,7 +10,7 @@ using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class CreateSchemaFieldDto
public sealed class UpsertSchemaFieldDto
{
/// <summary>
/// The name of the field. Must be unique within the schema.
@ -48,6 +48,6 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
/// <summary>
/// The nested fields.
/// </summary>
public List<CreateSchemaNestedFieldDto> Nested { get; set; }
public List<UpsertSchemaNestedFieldDto> Nested { get; set; }
}
}

2
src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaNestedFieldDto.cs → src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs

@ -9,7 +9,7 @@ using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.Schemas.Models
{
public sealed class CreateSchemaNestedFieldDto
public sealed class UpsertSchemaNestedFieldDto
{
/// <summary>
/// The name of the field. Must be unique within the schema.

22
src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs

@ -147,6 +147,28 @@ namespace Squidex.Areas.Api.Controllers.Schemas
return NoContent();
}
/// <summary>
/// Synchronize a schema.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="name">The name of the schema.</param>
/// <param name="request">The schema object that needs to updated.</param>
/// <returns>
/// 204 => Schema has been updated.
/// 400 => Schema properties are not valid.
/// 404 => Schema or app not found.
/// </returns>
[HttpPut]
[Route("apps/{app}/schemas/{name}/sync")]
[ApiPermission(Permissions.AppSchemasUpdate)]
[ApiCosts(1)]
public async Task<IActionResult> PutSchemaSync(string app, string name, [FromBody] SynchronizeSchemaDto request)
{
await CommandBus.PublishAsync(request.ToCommand());
return NoContent();
}
/// <summary>
/// Update a schema category.
/// </summary>

13
tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs

@ -278,7 +278,18 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
[Fact]
public void Should_serialize_and_deserialize_schema()
{
var schemaSource = TestUtils.MixedSchema();
var schemaSource =
TestUtils.MixedSchema(true)
.ChangeCategory("Category")
.ConfigurePreviewUrls(new Dictionary<string, string>
{
["web"] = "Url"
})
.ConfigureScripts(new Dictionary<string, string>
{
["create"] = "<create-script>"
});
var schemaTarget = schemaSource.SerializeAndDeserialize();
schemaTarget.Should().BeEquivalentTo(schemaSource);

4
tests/Squidex.Domain.Apps.Core.Tests/TestUtils.cs

@ -59,9 +59,9 @@ namespace Squidex.Domain.Apps.Core
return new NewtonsoftJsonSerializer(serializerSettings);
}
public static Schema MixedSchema()
public static Schema MixedSchema(bool isSingleton = false)
{
var schema = new Schema("user")
var schema = new Schema("user", isSingleton: isSingleton)
.Publish()
.AddArray(101, "root-array", Partitioning.Language, f => f
.AddAssets(201, "nested-assets")

6
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs

@ -353,19 +353,19 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
{
Name = "field1",
Properties = ValidProperties(),
Partitioning = "invariant"
Partitioning = Partitioning.Invariant.Key
},
new UpsertSchemaField
{
Name = "field2",
Properties = ValidProperties(),
Partitioning = "invariant"
Partitioning = Partitioning.Invariant.Key
},
new UpsertSchemaField
{
Name = "field3",
Properties = new ArrayFieldProperties(),
Partitioning = "invariant",
Partitioning = Partitioning.Invariant.Key,
Nested = new List<UpsertSchemaNestedField>
{
new UpsertSchemaNestedField

42
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaGrainTests.cs

@ -142,7 +142,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas
{
Scripts = new Dictionary<string, string>
{
["Query"] = "<script-query>"
[Scripts.Query] = "<script-query>"
}
};
@ -637,6 +637,46 @@ namespace Squidex.Domain.Apps.Entities.Schemas
);
}
[Fact]
public async Task Synchronize_should_create_events_and_update_state()
{
var command = new SynchronizeSchema
{
Scripts = new Dictionary<string, string>
{
[Scripts.Query] = "<script-query>"
},
PreviewUrls = new Dictionary<string, string>
{
["Web"] = "web-url"
},
Fields = new List<UpsertSchemaField>
{
new UpsertSchemaField { Name = fieldId.Name, Properties = ValidProperties() }
},
Category = "My-Category"
};
await ExecuteCreateAsync();
var result = await sut.ExecuteAsync(CreateCommand(command));
result.ShouldBeEquivalent(new EntitySavedResult(4));
Assert.NotNull(GetField(1));
Assert.Equal(command.Category, sut.Snapshot.SchemaDef.Category);
Assert.Equal(command.Scripts, sut.Snapshot.SchemaDef.Scripts);
Assert.Equal(command.PreviewUrls, sut.Snapshot.SchemaDef.PreviewUrls);
LastEvents
.ShouldHaveSameEvents(
CreateEvent(new SchemaCategoryChanged { Name = command.Category }),
CreateEvent(new SchemaScriptsConfigured { Scripts = command.Scripts }),
CreateEvent(new SchemaPreviewUrlsConfigured { PreviewUrls = command.PreviewUrls }),
CreateEvent(new FieldAdded { FieldId = fieldId, Name = fieldId.Name, Properties = command.Fields[0].Properties, Partitioning = Partitioning.Invariant.Key })
);
}
private Task ExecuteCreateAsync()
{
return sut.ExecuteAsync(CreateCommand(new CreateSchema { Name = SchemaName }));

1
tools/Migrate_01/Rebuilder.cs

@ -10,7 +10,6 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Apps.State;
using Squidex.Domain.Apps.Entities.Assets;

Loading…
Cancel
Save