Browse Source

Merge branch 'master' of github.com:Squidex/squidex

# Conflicts:
#	src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs
pull/400/head
Sebastian 7 years ago
parent
commit
840c8a67d2
  1. 2
      src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj
  2. 2
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/Builder.cs
  3. 2
      src/Squidex.Domain.Apps.Entities/Contents/ContentEntity.cs
  4. 35
      src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs
  5. 2
      src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj
  6. 4
      src/Squidex.Infrastructure/Squidex.Infrastructure.csproj
  7. 29
      src/Squidex/Areas/Api/Config/OpenApi/ODataExtensions.cs
  8. 10
      src/Squidex/Areas/Api/Config/OpenApi/ODataQueryParamsProcessor.cs
  9. 3
      src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs
  10. 12
      src/Squidex/Areas/Api/Config/OpenApi/SecurityProcessor.cs
  11. 31
      src/Squidex/Areas/Api/Config/OpenApi/VersionProcessor.cs
  12. 7
      src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs
  13. 17
      src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs
  14. 26
      src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs
  15. 17
      src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowTransitionDto.cs
  16. 11
      src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemaOpenApiGenerator.cs
  17. 9
      src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs
  18. 9
      src/Squidex/Areas/Api/Controllers/News/Service/FeaturesService.cs
  19. 13
      src/Squidex/Areas/Api/Views/Shared/Docs.cshtml
  20. 3
      src/Squidex/Docs/schemabody.md
  21. 39
      src/Squidex/Pipeline/OpenApi/NSwagHelper.cs
  22. 10
      src/Squidex/Squidex.csproj
  23. 3
      src/Squidex/app/features/content/shared/field-editor.component.html
  24. 9
      src/Squidex/app/features/content/shared/references-dropdown.component.ts
  25. 2
      src/Squidex/app/framework/services/message-bus.service.ts
  26. 3679
      src/Squidex/package-lock.json
  27. 80
      src/Squidex/package.json
  28. 2
      tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj
  29. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj
  30. 2
      tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj
  31. 2
      tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj
  32. 4
      tests/Squidex.Web.Tests/Squidex.Web.Tests.csproj

2
src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj

@ -9,7 +9,7 @@
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Fody" Version="5.0.6"> <PackageReference Include="Fody" Version="4.2.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>

2
src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/Builder.cs

@ -13,7 +13,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
{ {
public static JsonSchema Object() public static JsonSchema Object()
{ {
return new JsonSchema { Type = JsonObjectType.Object, AllowAdditionalItems = false }; return new JsonSchema { Type = JsonObjectType.Object };
} }
public static JsonSchema Guid() public static JsonSchema Guid()

2
src/Squidex.Domain.Apps.Entities/Contents/ContentEntity.cs

@ -49,6 +49,6 @@ namespace Squidex.Domain.Apps.Entities.Contents
public bool IsPending { get; set; } public bool IsPending { get; set; }
public HashSet<string> CacheDependencies { get; } = new HashSet<string>(); public HashSet<string> CacheDependencies { get; set; }
} }
} }

35
src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs

@ -61,7 +61,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
if (contents.Any()) if (contents.Any())
{ {
var appVersion = context.App?.Version.ToString(); var appVersion = context.App.Version.ToString();
var cache = new Dictionary<(Guid, Status), StatusInfo>(); var cache = new Dictionary<(Guid, Status), StatusInfo>();
@ -77,33 +77,30 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
await ResolveCanUpdateAsync(content, result); await ResolveCanUpdateAsync(content, result);
} }
if (appVersion != null) result.CacheDependencies = new HashSet<string>
{ {
result.CacheDependencies.Add(appVersion); appVersion
} };
results.Add(result); results.Add(result);
} }
if (context.App != null) foreach (var group in results.GroupBy(x => x.SchemaId.Id))
{ {
foreach (var group in results.GroupBy(x => x.SchemaId.Id)) var schema = await ContentQuery.GetSchemaOrThrowAsync(context, group.Key.ToString());
{
var schema = await ContentQuery.GetSchemaOrThrowAsync(context, group.Key.ToString());
var schemaIdentity = schema.Id.ToString(); var schemaIdentity = schema.Id.ToString();
var schemaVersion = schema.Version.ToString(); var schemaVersion = schema.Version.ToString();
foreach (var content in group) foreach (var content in group)
{ {
content.CacheDependencies.Add(schemaIdentity); content.CacheDependencies.Add(schemaIdentity);
content.CacheDependencies.Add(schemaVersion); content.CacheDependencies.Add(schemaVersion);
} }
if (ShouldEnrichWithReferences(context)) if (ShouldEnrichWithReferences(context))
{ {
await ResolveReferencesAsync(schema, group, context); await ResolveReferencesAsync(schema, group, context);
}
} }
} }
} }

2
src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj

@ -14,7 +14,7 @@
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" /> <ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="IdentityServer4" Version="2.5.0" /> <PackageReference Include="IdentityServer4" Version="2.5.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" /> <PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="MongoDB.Driver" Version="2.8.1" /> <PackageReference Include="MongoDB.Driver" Version="2.8.1" />

4
src/Squidex.Infrastructure/Squidex.Infrastructure.csproj

@ -8,7 +8,7 @@
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentFTP" Version="27.0.0" /> <PackageReference Include="FluentFTP" Version="27.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" />
@ -29,7 +29,7 @@
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
<PackageReference Include="System.Linq" Version="4.3.0" /> <PackageReference Include="System.Linq" Version="4.3.0" />
<PackageReference Include="System.Reactive" Version="4.1.5" /> <PackageReference Include="System.Reactive" Version="4.1.6" />
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.5.1" /> <PackageReference Include="System.Reflection.TypeExtensions" Version="4.5.1" />
<PackageReference Include="System.Security.Claims" Version="4.3.0" /> <PackageReference Include="System.Security.Claims" Version="4.3.0" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" /> <PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" />

29
src/Squidex/Areas/Api/Config/OpenApi/ODataExtensions.cs

@ -0,0 +1,29 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using NJsonSchema;
using NSwag;
using Squidex.Pipeline.OpenApi;
namespace Squidex.Areas.Api.Config.OpenApi
{
public static class ODataExtensions
{
public static void AddOData(this OpenApiOperation operation, string entity, bool supportSearch)
{
if (supportSearch)
{
operation.AddQueryParameter("$search", JsonObjectType.String, "Optional OData full text search.");
}
operation.AddQueryParameter("$top", JsonObjectType.Number, $"Optional number of {entity} to take.");
operation.AddQueryParameter("$skip", JsonObjectType.Number, $"Optional number of {entity} to skip.");
operation.AddQueryParameter("$orderby", JsonObjectType.String, "Optional OData order definition.");
operation.AddQueryParameter("$filter", JsonObjectType.String, "Optional OData filter definition.");
}
}
}

10
src/Squidex/Areas/Api/Config/OpenApi/ODataQueryParamsProcessor.cs

@ -32,15 +32,7 @@ namespace Squidex.Areas.Api.Config.OpenApi
{ {
var operation = context.OperationDescription.Operation; var operation = context.OperationDescription.Operation;
if (supportSearch) operation.AddOData(entity, supportSearch);
{
operation.AddQueryParameter("$search", JsonObjectType.String, "Optional OData full text search.");
}
operation.AddQueryParameter("$top", JsonObjectType.Number, $"Optional number of {entity} to take.");
operation.AddQueryParameter("$skip", JsonObjectType.Number, $"Optional number of {entity} to skip.");
operation.AddQueryParameter("$orderby", JsonObjectType.String, "Optional OData order definition.");
operation.AddQueryParameter("$filter", JsonObjectType.String, "Optional OData filter definition.");
} }
return true; return true;

3
src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs

@ -32,6 +32,9 @@ namespace Squidex.Areas.Api.Config.OpenApi
services.AddSingletonAs<ThemeProcessor>() services.AddSingletonAs<ThemeProcessor>()
.As<IDocumentProcessor>(); .As<IDocumentProcessor>();
services.AddSingletonAs<VersionProcessor>()
.As<IDocumentProcessor>();
services.AddSingletonAs<XmlTagProcessor>() services.AddSingletonAs<XmlTagProcessor>()
.As<IDocumentProcessor>(); .As<IDocumentProcessor>();

12
src/Squidex/Areas/Api/Config/OpenApi/SecurityProcessor.cs

@ -34,15 +34,23 @@ namespace Squidex.Areas.Api.Config.OpenApi
security.TokenUrl = tokenUrl; security.TokenUrl = tokenUrl;
SetupDescription(security, tokenUrl); SetupDescription(security, tokenUrl);
SetupFlow(security);
SetupScropes(security);
return security;
}
private static void SetupFlow(OpenApiSecurityScheme security)
{
security.Flow = OpenApiOAuth2Flow.Application; security.Flow = OpenApiOAuth2Flow.Application;
}
private static void SetupScropes(OpenApiSecurityScheme security)
{
security.Scopes = new Dictionary<string, string> security.Scopes = new Dictionary<string, string>
{ {
[Constants.ApiScope] = "Read and write access to the API" [Constants.ApiScope] = "Read and write access to the API"
}; };
return security;
} }
private static void SetupDescription(OpenApiSecurityScheme securityScheme, string tokenUrl) private static void SetupDescription(OpenApiSecurityScheme securityScheme, string tokenUrl)

31
src/Squidex/Areas/Api/Config/OpenApi/VersionProcessor.cs

@ -0,0 +1,31 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using NSwag.Generation.Processors;
using NSwag.Generation.Processors.Contexts;
using Squidex.Web;
namespace Squidex.Areas.Api.Config.OpenApi
{
public sealed class VersionProcessor : IDocumentProcessor
{
private readonly ExposedValues exposedValues;
public VersionProcessor(ExposedValues exposedValues)
{
this.exposedValues = exposedValues;
}
public void Process(DocumentProcessorContext context)
{
if (exposedValues.TryGetValue("version", out var version))
{
context.Document.Info.Version = version;
}
}
}
}

7
src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs

@ -43,12 +43,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
Initial, Initial,
Steps?.ToDictionary( Steps?.ToDictionary(
x => x.Key, x => x.Key,
x => new WorkflowStep( x => x.Value?.ToStep()),
x.Value?.Transitions.ToDictionary(
y => y.Key,
y => new WorkflowTransition(y.Value.Expression, y.Value.Role)),
x.Value.Color,
x.Value.NoUpdate)),
SchemaIds, SchemaIds,
Name); Name);

17
src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs

@ -46,16 +46,13 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
public static WorkflowDto FromWorkflow(Guid id, Workflow workflow, ApiController controller, string app) public static WorkflowDto FromWorkflow(Guid id, Workflow workflow, ApiController controller, string app)
{ {
var result = SimpleMapper.Map(workflow, new WorkflowDto { Id = id }); var result = SimpleMapper.Map(workflow, new WorkflowDto
{
result.Steps = workflow.Steps.ToDictionary( Steps = workflow.Steps.ToDictionary(
x => x.Key, x => x.Key,
x => SimpleMapper.Map(x.Value, new WorkflowStepDto x => WorkflowStepDto.FromWorkflowStep(x.Value)),
{ Id = id
Transitions = x.Value.Transitions.ToDictionary( });
y => y.Key,
y => new WorkflowTransitionDto { Expression = y.Value.Expression, Role = y.Value.Role })
}));
return result.CreateLinks(controller, app, id); return result.CreateLinks(controller, app, id);
} }

26
src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs

@ -7,7 +7,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Apps.Models namespace Squidex.Areas.Api.Controllers.Apps.Models
{ {
@ -28,5 +30,29 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
/// Indicates if updates should not be allowed. /// Indicates if updates should not be allowed.
/// </summary> /// </summary>
public bool NoUpdate { get; set; } public bool NoUpdate { get; set; }
public static WorkflowStepDto FromWorkflowStep(WorkflowStep step)
{
if (step == null)
{
return null;
}
return SimpleMapper.Map(step, new WorkflowStepDto
{
Transitions = step.Transitions.ToDictionary(
y => y.Key,
y => WorkflowTransitionDto.FromWorkflowTransition(y.Value))
});
}
public WorkflowStep ToStep()
{
return new WorkflowStep(
Transitions?.ToDictionary(
y => y.Key,
y => y.Value?.ToTransition()),
Color, NoUpdate);
}
} }
} }

17
src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowTransitionDto.cs

@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Squidex.Domain.Apps.Core.Contents;
namespace Squidex.Areas.Api.Controllers.Apps.Models namespace Squidex.Areas.Api.Controllers.Apps.Models
{ {
public sealed class WorkflowTransitionDto public sealed class WorkflowTransitionDto
@ -18,5 +20,20 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
/// The optional restricted role. /// The optional restricted role.
/// </summary> /// </summary>
public string Role { get; set; } public string Role { get; set; }
public static WorkflowTransitionDto FromWorkflowTransition(WorkflowTransition transition)
{
if (transition == null)
{
return null;
}
return new WorkflowTransitionDto { Expression = transition.Expression, Role = transition.Role };
}
public WorkflowTransition ToTransition()
{
return new WorkflowTransition(Expression, Role);
}
} }
} }

11
src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemaOpenApiGenerator.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NJsonSchema; using NJsonSchema;
using NSwag; using NSwag;
using Squidex.Areas.Api.Config.OpenApi;
using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.GenerateJsonSchema; using Squidex.Domain.Apps.Core.GenerateJsonSchema;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
@ -102,14 +103,10 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
operation.Description = SchemaQueryDescription; operation.Description = SchemaQueryDescription;
operation.AddQueryParameter("$top", JsonObjectType.Number, "Optional number of contents to take (Default: 20)."); operation.AddOData("contents", true);
operation.AddQueryParameter("$skip", JsonObjectType.Number, "Optional number of contents to skip.");
operation.AddQueryParameter("$filter", JsonObjectType.String, "Optional OData filter.");
operation.AddQueryParameter("$search", JsonObjectType.String, "Optional OData full text search.");
operation.AddQueryParameter("$orderby", JsonObjectType.String, "Optional OData order definition.");
operation.AddQueryParameter("$orderby", JsonObjectType.String, "Optional OData order definition.");
operation.AddResponse("200", $"{schemaName} content retrieved.", CreateContentsSchema(schemaName, contentSchema)); operation.AddResponse("200", $"{schemaName} contents retrieved.", CreateContentsSchema(schemaName, contentSchema));
operation.AddResponse("400", $"{schemaName} query not valid.");
AddSecurity(operation, Permissions.AppContentsRead); AddSecurity(operation, Permissions.AppContentsRead);
}); });

9
src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs

@ -9,7 +9,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Namotion.Reflection; using Namotion.Reflection;
using NJsonSchema; using NJsonSchema;
using NJsonSchema.Generation; using NJsonSchema.Generation;
@ -23,23 +22,19 @@ using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Pipeline.OpenApi; using Squidex.Pipeline.OpenApi;
using Squidex.Web;
namespace Squidex.Areas.Api.Controllers.Contents.Generator namespace Squidex.Areas.Api.Controllers.Contents.Generator
{ {
public sealed class SchemasOpenApiGenerator public sealed class SchemasOpenApiGenerator
{ {
private readonly UrlsOptions urlOptions;
private readonly OpenApiDocumentGeneratorSettings settings = new OpenApiDocumentGeneratorSettings(); private readonly OpenApiDocumentGeneratorSettings settings = new OpenApiDocumentGeneratorSettings();
private OpenApiSchemaGenerator schemaGenerator; private OpenApiSchemaGenerator schemaGenerator;
private OpenApiDocument document; private OpenApiDocument document;
private JsonSchema statusSchema; private JsonSchema statusSchema;
private JsonSchemaResolver schemaResolver; private JsonSchemaResolver schemaResolver;
public SchemasOpenApiGenerator(IOptions<UrlsOptions> urlOptions, IEnumerable<IDocumentProcessor> documentProcessors) public SchemasOpenApiGenerator(IEnumerable<IDocumentProcessor> documentProcessors)
{ {
this.urlOptions = urlOptions.Value;
settings.ConfigureSchemaSettings(); settings.ConfigureSchemaSettings();
foreach (var processor in documentProcessors) foreach (var processor in documentProcessors)
@ -50,7 +45,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
public OpenApiDocument Generate(HttpContext httpContext, IAppEntity app, IEnumerable<ISchemaEntity> schemas) public OpenApiDocument Generate(HttpContext httpContext, IAppEntity app, IEnumerable<ISchemaEntity> schemas)
{ {
document = NSwagHelper.CreateApiDocument(httpContext, urlOptions, app.Name); document = NSwagHelper.CreateApiDocument(httpContext, app.Name);
schemaGenerator = new OpenApiSchemaGenerator(settings); schemaGenerator = new OpenApiSchemaGenerator(settings);
schemaResolver = new OpenApiSchemaResolver(document, settings); schemaResolver = new OpenApiSchemaResolver(document, settings);

9
src/Squidex/Areas/Api/Controllers/News/Service/FeaturesService.cs

@ -16,7 +16,7 @@ namespace Squidex.Areas.Api.Controllers.News.Service
{ {
public sealed class FeaturesService public sealed class FeaturesService
{ {
private const int FeatureVersion = 4; private const int FeatureVersion = 5;
private static readonly QueryContext Flatten = QueryContext.Default.Flatten(); private static readonly QueryContext Flatten = QueryContext.Default.Flatten();
private readonly SquidexClient<NewsEntity, FeatureDto> client; private readonly SquidexClient<NewsEntity, FeatureDto> client;
@ -43,7 +43,12 @@ namespace Squidex.Areas.Api.Controllers.News.Service
if (client != null && version < FeatureVersion) if (client != null && version < FeatureVersion)
{ {
var features = await client.GetAsync(filter: $"data/version/iv ge {FeatureVersion}", context: Flatten); var query = new ODataQuery
{
Filter = $"data/version/iv ge {FeatureVersion}"
};
var features = await client.GetAsync(query, Flatten);
result.Features.AddRange(features.Items.Select(x => x.Data)); result.Features.AddRange(features.Items.Select(x => x.Data));
} }

13
src/Squidex/Areas/Api/Views/Shared/Docs.cshtml

@ -17,8 +17,19 @@
</style> </style>
</head> </head>
<body> <body>
<redoc spec-url="@Url.Content(Model.Specification)"></redoc> <div id="redoc-container"></div>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script> <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
<script>
Redoc.init('@Url.Content(Model.Specification)', {
theme: {
colors: {
primary: {
main: '#3f83df'
}
}
},
}, document.getElementById('redoc-container'))
</script>
</body> </body>
</html> </html>

3
src/Squidex/Docs/schemabody.md

@ -1,7 +1,6 @@
The data of the content to be created or updated. The data of the content to be created or updated.
Please note that each field is an object with one entry per language. Please note that each field is an object with one entry per language.
If the field is not localizable you must use iv (Invariant Language) as a key. If the field is not localizable you must use `iv` (Invariant Language) as a key.
When you change the field to be localizable the value will become the value for the master language, depending what the master language is at this point of time.
Read more about it at: https://docs.squidex.io/04-guides/02-api.html Read more about it at: https://docs.squidex.io/04-guides/02-api.html

39
src/Squidex/Pipeline/OpenApi/NSwagHelper.cs

@ -11,7 +11,6 @@ using System.IO;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using NJsonSchema; using NJsonSchema;
using NSwag; using NSwag;
using Squidex.Web;
namespace Squidex.Pipeline.OpenApi namespace Squidex.Pipeline.OpenApi
{ {
@ -30,7 +29,7 @@ namespace Squidex.Pipeline.OpenApi
} }
} }
public static OpenApiDocument CreateApiDocument(HttpContext context, UrlsOptions urlOptions, string appName) public static OpenApiDocument CreateApiDocument(HttpContext context, string appName)
{ {
var scheme = var scheme =
string.Equals(context.Request.Scheme, "http", StringComparison.OrdinalIgnoreCase) ? string.Equals(context.Request.Scheme, "http", StringComparison.OrdinalIgnoreCase) ?
@ -55,7 +54,7 @@ namespace Squidex.Pipeline.OpenApi
{ {
Title = $"Squidex API for {appName} App" Title = $"Squidex API for {appName} App"
}, },
BasePath = Constants.ApiPrefix SchemaType = SchemaType.OpenApi3
}; };
if (!string.IsNullOrWhiteSpace(context.Request.Host.Value)) if (!string.IsNullOrWhiteSpace(context.Request.Host.Value))
@ -68,42 +67,36 @@ namespace Squidex.Pipeline.OpenApi
public static void AddQueryParameter(this OpenApiOperation operation, string name, JsonObjectType type, string description = null) public static void AddQueryParameter(this OpenApiOperation operation, string name, JsonObjectType type, string description = null)
{ {
var parameter = new OpenApiParameter { Type = type, Name = name, Kind = OpenApiParameterKind.Query }; var schema = new JsonSchema { Type = type };
if (!string.IsNullOrWhiteSpace(description)) operation.AddParameter(name, schema, OpenApiParameterKind.Query, description, false);
{
parameter.Description = description;
}
operation.Parameters.Add(parameter);
} }
public static void AddPathParameter(this OpenApiOperation operation, string name, JsonObjectType type, string description = null) public static void AddPathParameter(this OpenApiOperation operation, string name, JsonObjectType type, string description = null)
{ {
var parameter = new OpenApiParameter { Type = type, Name = name, Kind = OpenApiParameterKind.Path }; var schema = new JsonSchema { Type = type };
if (!string.IsNullOrWhiteSpace(description))
{
parameter.Description = description;
}
parameter.IsRequired = true;
parameter.IsNullableRaw = false;
operation.Parameters.Add(parameter); operation.AddParameter(name, schema, OpenApiParameterKind.Path, description, true);
} }
public static void AddBodyParameter(this OpenApiOperation operation, string name, JsonSchema schema, string description) public static void AddBodyParameter(this OpenApiOperation operation, string name, JsonSchema schema, string description)
{ {
var parameter = new OpenApiParameter { Schema = schema, Name = name, Kind = OpenApiParameterKind.Body }; operation.AddParameter(name, schema, OpenApiParameterKind.Body, description, true);
}
private static void AddParameter(this OpenApiOperation operation, string name, JsonSchema schema, OpenApiParameterKind kind, string description, bool isRequired)
{
var parameter = new OpenApiParameter { Schema = schema, Name = name, Kind = kind };
if (!string.IsNullOrWhiteSpace(description)) if (!string.IsNullOrWhiteSpace(description))
{ {
parameter.Description = description; parameter.Description = description;
} }
parameter.IsRequired = true; if (isRequired)
parameter.IsNullableRaw = false; {
parameter.IsRequired = true;
}
operation.Parameters.Add(parameter); operation.Parameters.Add(parameter);
} }

10
src/Squidex/Squidex.csproj

@ -44,9 +44,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="2.1.0" /> <PackageReference Include="AspNet.Security.OAuth.GitHub" Version="2.1.0" />
<PackageReference Include="EventStore.ClientAPI.NetCore" Version="4.1.0.23" /> <PackageReference Include="EventStore.ClientAPI.NetCore" Version="4.1.0.23" />
<PackageReference Include="IdentityServer4" Version="2.5.0" /> <PackageReference Include="IdentityServer4" Version="2.5.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.2" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="0.2.4" /> <PackageReference Include="McMaster.NETCore.Plugins" Version="0.2.4" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
@ -68,7 +68,7 @@
<PackageReference Include="Microsoft.Orleans.Core.Abstractions" Version="2.3.6" /> <PackageReference Include="Microsoft.Orleans.Core.Abstractions" Version="2.3.6" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.3.6" /> <PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.3.6" />
<PackageReference Include="MongoDB.Driver" Version="2.8.1" /> <PackageReference Include="MongoDB.Driver" Version="2.8.1" />
<PackageReference Include="Namotion.Reflection" Version="1.0.5" /> <PackageReference Include="Namotion.Reflection" Version="1.0.6" />
<PackageReference Include="NJsonSchema" Version="10.0.21" /> <PackageReference Include="NJsonSchema" Version="10.0.21" />
<PackageReference Include="NSwag.AspNetCore" Version="13.0.4" /> <PackageReference Include="NSwag.AspNetCore" Version="13.0.4" />
<PackageReference Include="OpenCover" Version="4.7.922" PrivateAssets="all" /> <PackageReference Include="OpenCover" Version="4.7.922" PrivateAssets="all" />
@ -76,8 +76,8 @@
<PackageReference Include="Orleans.WebHostCompatibilityLayer" Version="2.3.1" /> <PackageReference Include="Orleans.WebHostCompatibilityLayer" Version="2.3.1" />
<PackageReference Include="OrleansDashboard" Version="2.3.6" /> <PackageReference Include="OrleansDashboard" Version="2.3.6" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="ReportGenerator" Version="4.2.11" PrivateAssets="all" /> <PackageReference Include="ReportGenerator" Version="4.2.15" PrivateAssets="all" />
<PackageReference Include="Squidex.ClientLibrary" Version="3.1.0" /> <PackageReference Include="Squidex.ClientLibrary" Version="3.7.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Linq" Version="4.3.0" /> <PackageReference Include="System.Linq" Version="4.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />

3
src/Squidex/app/features/content/shared/field-editor.component.html

@ -92,8 +92,7 @@
<sqx-references-dropdown <sqx-references-dropdown
[formControl]="control" [formControl]="control"
[language]="language" [language]="language"
[schemaId]="field.properties['schemaId']" [schemaId]="field.properties['schemaId']">
[isRequired]="field.properties['isRequired']">
</sqx-references-dropdown> </sqx-references-dropdown>
</ng-container> </ng-container>
</ng-container> </ng-container>

9
src/Squidex/app/features/content/shared/references-dropdown.component.ts

@ -59,9 +59,6 @@ export class ReferencesDropdownComponent extends StatefulControlComponent<State,
@Input() @Input()
public schemaId: string; public schemaId: string;
@Input()
public isRequired = false;
@Input() @Input()
public set language(value: AppLanguageDto) { public set language(value: AppLanguageDto) {
this.languageField = value; this.languageField = value;
@ -156,11 +153,7 @@ export class ReferencesDropdownComponent extends StatefulControlComponent<State,
return { name, id: content.id }; return { name, id: content.id };
}); });
if (!this.isRequired) { return [{ name: '- No Reference -' }, ...names];
return [{ name: '- No Reference -' }, ...names];
}
return names;
} }
public trackByContent(content: ContentDto) { public trackByContent(content: ContentDto) {

2
src/Squidex/app/framework/services/message-bus.service.ts

@ -23,7 +23,7 @@ export class MessageBus {
private message$ = new Subject<Message>(); private message$ = new Subject<Message>();
public emit<T>(message: T): void { public emit<T>(message: T): void {
const channel = (<any>message.constructor).name; const channel = ((<any>message)['constructor']).name;
this.message$.next({ channel: channel, data: message }); this.message$.next({ channel: channel, data: message });
} }

3679
src/Squidex/package-lock.json

File diff suppressed because it is too large

80
src/Squidex/package.json

@ -15,90 +15,90 @@
"build:clean": "rimraf wwwroot/build" "build:clean": "rimraf wwwroot/build"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "8.0.2", "@angular/animations": "8.2.1",
"@angular/common": "8.0.2", "@angular/common": "8.2.1",
"@angular/core": "8.0.2", "@angular/core": "8.2.1",
"@angular/forms": "8.0.2", "@angular/forms": "8.2.1",
"@angular/http": "7.2.15", "@angular/http": "7.2.15",
"@angular/platform-browser": "8.0.2", "@angular/platform-browser": "8.2.1",
"@angular/platform-browser-dynamic": "8.0.2", "@angular/platform-browser-dynamic": "8.2.1",
"@angular/platform-server": "8.0.2", "@angular/platform-server": "8.2.1",
"@angular/router": "8.0.2", "@angular/router": "8.2.1",
"angular2-chartjs": "0.5.1", "angular2-chartjs": "0.5.1",
"babel-polyfill": "6.26.0", "babel-polyfill": "6.26.0",
"bootstrap": "4.3.1", "bootstrap": "4.3.1",
"core-js": "3.1.4", "core-js": "3.2.1",
"graphiql": "0.13.2", "graphiql": "0.13.2",
"graphql": "14.3.1", "graphql": "14.4.2",
"marked": "0.6.2", "marked": "0.7.0",
"moment": "2.24.0", "moment": "2.24.0",
"mousetrap": "1.6.3", "mousetrap": "1.6.3",
"ng2-dnd": "5.0.2", "ng2-dnd": "5.0.2",
"ngx-color-picker": "8.0.1", "ngx-color-picker": "8.1.0",
"oidc-client": "1.8.2", "oidc-client": "1.8.2",
"pikaday": "1.8.0", "pikaday": "1.8.0",
"progressbar.js": "1.0.1", "progressbar.js": "1.0.1",
"react": "16.8.6", "react": "16.9.0",
"react-dom": "16.8.6", "react-dom": "16.9.0",
"rxjs": "6.5.2", "rxjs": "6.5.2",
"slugify": "1.3.4", "slugify": "1.3.4",
"sortablejs": "1.9.0", "sortablejs": "1.9.0",
"tslib": "1.10.0", "tslib": "1.10.0",
"zone.js": "0.9.1" "zone.js": "0.10.1"
}, },
"devDependencies": { "devDependencies": {
"@angular/compiler": "8.0.2", "@angular/compiler": "8.2.1",
"@angular/compiler-cli": "8.0.2", "@angular/compiler-cli": "8.2.1",
"@ngtools/webpack": "8.0.3", "@ngtools/webpack": "8.2.1",
"@types/core-js": "2.5.2", "@types/core-js": "2.5.2",
"@types/jasmine": "3.3.13", "@types/jasmine": "3.4.0",
"@types/marked": "0.6.5", "@types/marked": "0.6.5",
"@types/mousetrap": "1.6", "@types/mousetrap": "1.6",
"@types/node": "12.0.10", "@types/node": "12.7.1",
"@types/react": "16.8.22", "@types/react": "16.9.1",
"@types/react-dom": "16.8.4", "@types/react-dom": "16.8.5",
"@types/sortablejs": "1.7.2", "@types/sortablejs": "1.7.2",
"browserslist": "^4.6.3", "browserslist": "4.6.6",
"caniuse-lite": "^1.0.30000976", "caniuse-lite": "1.0.30000989",
"circular-dependency-plugin": "5.0.2", "circular-dependency-plugin": "5.2.0",
"codelyzer": "5.1.0", "codelyzer": "5.1.0",
"cpx": "1.5.0", "cpx": "1.5.0",
"css-loader": "3.0.0", "css-loader": "3.2.0",
"file-loader": "4.0.0", "file-loader": "4.2.0",
"html-loader": "0.5.5", "html-loader": "0.5.5",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"ignore-loader": "0.1.2", "ignore-loader": "0.1.2",
"istanbul-instrumenter-loader": "3.0.1", "istanbul-instrumenter-loader": "3.0.1",
"jasmine-core": "3.4.0", "jasmine-core": "3.4.0",
"karma": "4.1.0", "karma": "4.2.0",
"karma-chrome-launcher": "2.2.0", "karma-chrome-launcher": "3.0.0",
"karma-cli": "2.0.0", "karma-cli": "2.0.0",
"karma-coverage-istanbul-reporter": "2.0.5", "karma-coverage-istanbul-reporter": "2.1.0",
"karma-htmlfile-reporter": "0.3.8", "karma-htmlfile-reporter": "0.3.8",
"karma-jasmine": "2.0.1", "karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.2", "karma-jasmine-html-reporter": "1.4.2",
"karma-mocha-reporter": "2.2.5", "karma-mocha-reporter": "2.2.5",
"karma-sourcemap-loader": "0.3.7", "karma-sourcemap-loader": "0.3.7",
"karma-webpack": "4.0.2", "karma-webpack": "4.0.2",
"mini-css-extract-plugin": "0.7.0", "mini-css-extract-plugin": "0.8.0",
"node-sass": "4.12.0", "node-sass": "4.12.0",
"optimize-css-assets-webpack-plugin": "5.0.1", "optimize-css-assets-webpack-plugin": "5.0.3",
"raw-loader": "1.0.0", "raw-loader": "1.0.0",
"rimraf": "2.6.3", "rimraf": "2.6.3",
"rxjs-tslint": "0.1.7", "rxjs-tslint": "0.1.7",
"sass-lint": "1.13.1", "sass-lint": "1.13.1",
"sass-loader": "7.1.0", "sass-loader": "7.2.0",
"style-loader": "0.23.1", "style-loader": "1.0.0",
"ts-loader": "6.0.4", "ts-loader": "6.0.4",
"tsconfig-paths-webpack-plugin": "3.2.0", "tsconfig-paths-webpack-plugin": "3.2.0",
"tslint": "5.18.0", "tslint": "5.18.0",
"tslint-webpack-plugin": "2.0.4", "tslint-webpack-plugin": "2.1.0",
"typemoq": "2.1.0", "typemoq": "2.1.0",
"typescript": "3.4.3", "typescript": "3.5.3",
"uglifyjs-webpack-plugin": "2.1.3", "uglifyjs-webpack-plugin": "2.2.0",
"underscore": "1.9.1", "underscore": "1.9.1",
"webpack": "4.35.0", "webpack": "4.39.1",
"webpack-cli": "3.3.4", "webpack-cli": "3.3.6",
"webpack-dev-server": "3.7.2" "webpack-dev-server": "3.8.0"
} }
} }

2
tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj

@ -14,7 +14,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.7.0" /> <PackageReference Include="FluentAssertions" Version="5.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

2
tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj

@ -18,7 +18,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.7.0" /> <PackageReference Include="FluentAssertions" Version="5.8.0" />
<PackageReference Include="GraphQL" Version="2.4.0" /> <PackageReference Include="GraphQL" Version="2.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MongoDB.Driver" Version="2.8.1" /> <PackageReference Include="MongoDB.Driver" Version="2.8.1" />

2
tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj

@ -13,7 +13,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.7.0" /> <PackageReference Include="FluentAssertions" Version="5.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

2
tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj

@ -19,7 +19,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.7.0" /> <PackageReference Include="FluentAssertions" Version="5.8.0" />
<PackageReference Include="Google.Cloud.Storage.V1" Version="2.3.0" /> <PackageReference Include="Google.Cloud.Storage.V1" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />

4
tests/Squidex.Web.Tests/Squidex.Web.Tests.csproj

@ -12,8 +12,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="IdentityServer4" Version="2.5.0" /> <PackageReference Include="IdentityServer4" Version="2.5.2" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NJsonSchema" Version="10.0.21" /> <PackageReference Include="NJsonSchema" Version="10.0.21" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />

Loading…
Cancel
Save