diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/App_Schemas.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/App_Schemas.cs index 899969b0..d9b77a9f 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/App_Schemas.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/App_Schemas.cs @@ -7,6 +7,7 @@ using System; using System.IO; +using System.Linq; using System.Threading.Tasks; using CommandDotNet; using CommandDotNet.Attributes; @@ -14,6 +15,7 @@ using FluentValidation; using FluentValidation.Attributes; using Newtonsoft.Json; +using Squidex.CLI.Commands.Models; using Squidex.CLI.Configuration; using Squidex.ClientLibrary; using Squidex.ClientLibrary.Management; @@ -62,7 +64,18 @@ public async Task Get(GetArguments arguments) var schemasClient = service.CreateSchemasClient(); var schema = await schemasClient.GetSchemaAsync(app, arguments.Name); - Console.WriteLine(schema.JsonPrettyString()); + if (arguments.WithReferencedNames) + { + var allSchemas = await schemasClient.GetSchemasAsync(app); + + var result = new SchemaWithRefs(schema).EnrichSchemaNames(allSchemas); + + Console.WriteLine(result.JsonPrettyString()); + } + else + { + Console.WriteLine(schema.JsonPrettyString()); + } } [ApplicationMetadata(Name = "sync", Description = "Sync the schema.")] @@ -89,9 +102,9 @@ public async Task Sync(SyncArguments arguments) { try { - var sourceSchema = JsonConvert.DeserializeObject(schemaText); + var sourceSchema = SchemaWithRefs.Parse(schemaText); - schemaName = sourceSchema.Name; + schemaName = sourceSchema.Schema.Name; } catch (JsonException ex) { @@ -115,22 +128,36 @@ public async Task Sync(SyncArguments arguments) if (targetSchema == null) { - var create = JsonConvert.DeserializeObject(schemaText); + var request = SchemaWithRefs.Parse(schemaText); - create.Name = schemaName; + if (!arguments.NoRefFix && request.ReferencedSchemas.Any()) + { + var allSchemas = await schemasClient.GetSchemasAsync(app); - await schemasClient.PostSchemaAsync(app, create); + request.AdjustReferences(allSchemas); + } + + request.Schema.Name = schemaName; + + await schemasClient.PostSchemaAsync(app, request.Schema); Console.WriteLine("> Created schema because it does not exists in the target system."); } else { - var request = JsonConvert.DeserializeObject(schemaText); + var request = SchemaWithRefs.Parse(schemaText); + + if (!arguments.NoRefFix && request.ReferencedSchemas.Any()) + { + var allSchemas = await schemasClient.GetSchemasAsync(app); - request.NoFieldDeletion = arguments.NoFieldDeletion; - request.NoFieldRecreation = arguments.NoFieldRecreation; + request.AdjustReferences(allSchemas); + } + + request.Schema.NoFieldDeletion = arguments.NoFieldDeletion; + request.Schema.NoFieldRecreation = arguments.NoFieldRecreation; - await schemasClient.PutSchemaSyncAsync(app, schemaName, request); + await schemasClient.PutSchemaSyncAsync(app, schemaName, request.Schema); Console.WriteLine("> Synchronized schema"); } @@ -153,6 +180,9 @@ public sealed class GetArguments : IArgumentModel [Argument(Name = "name", Description = "The name of the schema.")] public string Name { get; set; } + [Option(LongName = "with-refs", ShortName = "r", Description = "Includes the names of the referenced schemas.")] + public bool WithReferencedNames { get; set; } + public sealed class GetArgumentsValidator : AbstractValidator { public GetArgumentsValidator() @@ -177,6 +207,9 @@ public sealed class SyncArguments : IArgumentModel [Option(LongName = "no-recreate", Description = "Do not recreate fields.")] public bool NoFieldRecreation { get; set; } + [Option(LongName = "no-ref-fix", Description = "Do not fix referenced.")] + public bool NoRefFix { get; set; } + public sealed class SyncArgumentsValidator : AbstractValidator { public SyncArgumentsValidator() diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefs.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefs.cs new file mode 100644 index 00000000..1314c90a --- /dev/null +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefs.cs @@ -0,0 +1,66 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json; +using Squidex.ClientLibrary; + +namespace Squidex.CLI.Commands.Models +{ + public sealed class SchemaWithRefs where T : class + { + public T Schema { get; set; } + + public Dictionary ReferencedSchemas { get; set; } + + public SchemaWithRefs() + { + } + + public SchemaWithRefs(T schema) + { + Schema = schema; + + ReferencedSchemas = new Dictionary(); + } + + public static SchemaWithRefs Parse(string json) + { + try + { + var imported = JsonConvert.DeserializeObject>(json); + + if (imported.Schema != null && imported.ReferencedSchemas != null) + { + return imported; + } + + return ParseDirectly(json); + } + catch + { + try + { + return ParseDirectly(json); + } + catch (IOException ex) + { + throw new SquidexException($"Cannot deserialize schema: {ex.Message}"); + } + } + } + + private static SchemaWithRefs ParseDirectly(string json) + { + var schema = JsonConvert.DeserializeObject(json); + + return new SchemaWithRefs(schema); + } + } +} diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefsExtensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefsExtensions.cs new file mode 100644 index 00000000..f96cd6b7 --- /dev/null +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Models/SchemaWithRefsExtensions.cs @@ -0,0 +1,96 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using Squidex.ClientLibrary.Management; + +namespace Squidex.CLI.Commands.Models +{ + public static class SchemaWithRefsExtensions + { + public static SchemaWithRefs EnrichSchemaNames(this SchemaWithRefs target, ICollection allSchemas) + { + if (target.Schema.Fields != null) + { + foreach (var field in target.Schema.Fields) + { + if (field.Properties is ReferencesFieldPropertiesDto reference) + { + var referenced = allSchemas.FirstOrDefault(x => x.Id == reference.SchemaId); + + if (referenced != null) + { + target.ReferencedSchemas[referenced.Id] = referenced.Name; + } + } + + if (field.Nested != null) + { + foreach (var nested in field.Nested) + { + if (nested.Properties is ReferencesFieldPropertiesDto nestedReference) + { + var referenced = allSchemas.FirstOrDefault(x => x.Id == nestedReference.SchemaId); + + if (referenced != null) + { + target.ReferencedSchemas[referenced.Id] = referenced.Name; + } + } + } + } + } + } + + return target; + } + + public static SchemaWithRefs AdjustReferences(this SchemaWithRefs target, ICollection allSchemas) where T : UpsertDto + { + if (target.Schema.Fields != null) + { + foreach (var field in target.Schema.Fields) + { + if (field.Properties is ReferencesFieldPropertiesDto reference) + { + if (target.ReferencedSchemas.TryGetValue(reference.SchemaId, out var name)) + { + var referenced = allSchemas.FirstOrDefault(x => x.Name == name); + + if (referenced != null) + { + reference.SchemaId = referenced.Id; + } + } + } + + if (field.Nested != null) + { + foreach (var nested in field.Nested) + { + if (nested.Properties is ReferencesFieldPropertiesDto nestedReference) + { + if (target.ReferencedSchemas.TryGetValue(nestedReference.SchemaId, out var name)) + { + var referenced = allSchemas.FirstOrDefault(x => x.Name == name); + + if (referenced != null) + { + nestedReference.SchemaId = referenced.Id; + } + } + } + } + } + } + } + + return target; + } + } +} diff --git a/cli/Squidex.CLI/Squidex.CLI/Program.cs b/cli/Squidex.CLI/Squidex.CLI/Program.cs index c4fa0337..513e11ed 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Program.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Program.cs @@ -11,8 +11,6 @@ using Microsoft.Extensions.DependencyInjection; using Squidex.CLI.Commands; using Squidex.CLI.Configuration; -using Squidex.ClientLibrary; -using Squidex.ClientLibrary.Management; namespace Squidex.CLI { @@ -32,21 +30,11 @@ public static int Main(string[] args) return appRunner.Run(args); } - catch (SquidexException ex) + catch (Exception ex) { Console.WriteLine("ERROR: {0}", ex.Message); return -1; } - catch (SquidexManagementException ex) - { - Console.WriteLine("ERROR: {0}", ex.Message); - return -1; - } - catch - { - Console.WriteLine("ERROR: Unexpected exception occurred."); - return -1; - } } } }