Browse Source

Upgrade/nswag (#393)

* Started to upgrade NSwag.

* OpenAPI fix.

* Fody downgraded.

* Serialization fix.

* Jscript fix.
pull/396/head
Sebastian Stehle 7 years ago
committed by GitHub
parent
commit
9405ef1032
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      extensions/Squidex.Extensions/Squidex.Extensions.csproj
  2. 40
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/Builder.cs
  3. 4
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/ContentSchemaBuilder.cs
  4. 6
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonSchemaExtensions.cs
  5. 30
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs
  6. 5
      src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
  7. 6
      src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
  8. 2
      src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj
  9. 6
      src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
  10. 2
      src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj
  11. 2
      src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj
  12. 2
      src/Squidex.Infrastructure.Azure/Squidex.Infrastructure.Azure.csproj
  13. 4
      src/Squidex.Infrastructure/Queries/Json/PropertyPathConverter.cs
  14. 35
      src/Squidex.Infrastructure/Queries/Json/PropertyPathValidator.cs
  15. 13
      src/Squidex.Infrastructure/Squidex.Infrastructure.csproj
  16. 21
      src/Squidex/Areas/Api/Config/OpenApi/ErrorDtoProcessor.cs
  17. 14
      src/Squidex/Areas/Api/Config/OpenApi/FixProcessor.cs
  18. 14
      src/Squidex/Areas/Api/Config/OpenApi/ODataQueryParamsProcessor.cs
  19. 8
      src/Squidex/Areas/Api/Config/OpenApi/OpenApiExtensions.cs
  20. 16
      src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs
  21. 18
      src/Squidex/Areas/Api/Config/OpenApi/ScopesProcessor.cs
  22. 16
      src/Squidex/Areas/Api/Config/OpenApi/SecurityProcessor.cs
  23. 14
      src/Squidex/Areas/Api/Config/OpenApi/TagByGroupNameProcessor.cs
  24. 12
      src/Squidex/Areas/Api/Config/OpenApi/ThemeProcessor.cs
  25. 15
      src/Squidex/Areas/Api/Config/OpenApi/XmlResponseTypesProcessor.cs
  26. 16
      src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs
  27. 4
      src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs
  28. 19
      src/Squidex/Areas/Api/Controllers/Contents/ContentOpenApiController.cs
  29. 76
      src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemaOpenApiGenerator.cs
  30. 47
      src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs
  31. 5
      src/Squidex/Areas/Api/Controllers/Docs/DocsController.cs
  32. 13
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs
  33. 4
      src/Squidex/Areas/Api/Startup.cs
  34. 30
      src/Squidex/Pipeline/OpenApi/NSwagHelper.cs
  35. 27
      src/Squidex/Squidex.csproj
  36. 4
      src/Squidex/WebStartup.cs
  37. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateJsonSchema/JsonSchemaTests.cs
  38. 4
      tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs
  39. 4
      tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj
  40. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj
  41. 4
      tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj
  42. 4
      tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj
  43. 8
      tests/Squidex.Web.Tests/Squidex.Web.Tests.csproj

6
extensions/Squidex.Extensions/Squidex.Extensions.csproj

@ -10,11 +10,11 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Algolia.Search" Version="5.3.1" /> <PackageReference Include="Algolia.Search" Version="5.3.1" />
<PackageReference Include="CoreTweet" Version="1.0.0.483" /> <PackageReference Include="CoreTweet" Version="1.0.0.483" />
<PackageReference Include="Elasticsearch.Net" Version="6.7.0" /> <PackageReference Include="Elasticsearch.Net" Version="6.8.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
<PackageReference Include="Microsoft.OData.Core" Version="7.5.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NodaTime" Version="2.4.5" /> <PackageReference Include="NodaTime" Version="2.4.6" />
<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" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.5.0" />

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

@ -11,54 +11,54 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
{ {
public static class Builder public static class Builder
{ {
public static JsonSchema4 Object() public static JsonSchema Object()
{ {
return new JsonSchema4 { Type = JsonObjectType.Object, AllowAdditionalItems = false }; return new JsonSchema { Type = JsonObjectType.Object, AllowAdditionalItems = false };
} }
public static JsonSchema4 Guid() public static JsonSchema Guid()
{ {
return new JsonSchema4 { Type = JsonObjectType.String, Format = JsonFormatStrings.Guid }; return new JsonSchema { Type = JsonObjectType.String, Format = JsonFormatStrings.Guid };
} }
public static JsonSchema4 String() public static JsonSchema String()
{ {
return new JsonSchema4 { Type = JsonObjectType.String }; return new JsonSchema { Type = JsonObjectType.String };
} }
public static JsonProperty ArrayProperty(JsonSchema4 item) public static JsonSchemaProperty ArrayProperty(JsonSchema item)
{ {
return new JsonProperty { Type = JsonObjectType.Array, Item = item }; return new JsonSchemaProperty { Type = JsonObjectType.Array, Item = item };
} }
public static JsonProperty BooleanProperty() public static JsonSchemaProperty BooleanProperty()
{ {
return new JsonProperty { Type = JsonObjectType.Boolean }; return new JsonSchemaProperty { Type = JsonObjectType.Boolean };
} }
public static JsonProperty DateTimeProperty(string description = null, bool isRequired = false) public static JsonSchemaProperty DateTimeProperty(string description = null, bool isRequired = false)
{ {
return new JsonProperty { Type = JsonObjectType.String, Format = JsonFormatStrings.DateTime, Description = description, IsRequired = isRequired }; return new JsonSchemaProperty { Type = JsonObjectType.String, Format = JsonFormatStrings.DateTime, Description = description, IsRequired = isRequired };
} }
public static JsonProperty GuidProperty(string description = null, bool isRequired = false) public static JsonSchemaProperty GuidProperty(string description = null, bool isRequired = false)
{ {
return new JsonProperty { Type = JsonObjectType.String, Format = JsonFormatStrings.Guid, Description = description, IsRequired = isRequired }; return new JsonSchemaProperty { Type = JsonObjectType.String, Format = JsonFormatStrings.Guid, Description = description, IsRequired = isRequired };
} }
public static JsonProperty NumberProperty(string description = null, bool isRequired = false) public static JsonSchemaProperty NumberProperty(string description = null, bool isRequired = false)
{ {
return new JsonProperty { Type = JsonObjectType.Number, Description = description, IsRequired = isRequired }; return new JsonSchemaProperty { Type = JsonObjectType.Number, Description = description, IsRequired = isRequired };
} }
public static JsonProperty ObjectProperty(JsonSchema4 item, string description = null, bool isRequired = false) public static JsonSchemaProperty ObjectProperty(JsonSchema item, string description = null, bool isRequired = false)
{ {
return new JsonProperty { Type = JsonObjectType.Object, Reference = item, Description = description, IsRequired = isRequired }; return new JsonSchemaProperty { Type = JsonObjectType.Object, Reference = item, Description = description, IsRequired = isRequired };
} }
public static JsonProperty StringProperty(string description = null, bool isRequired = false) public static JsonSchemaProperty StringProperty(string description = null, bool isRequired = false)
{ {
return new JsonProperty { Type = JsonObjectType.String, Description = description, IsRequired = isRequired }; return new JsonSchemaProperty { Type = JsonObjectType.String, Description = description, IsRequired = isRequired };
} }
} }
} }

4
src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/ContentSchemaBuilder.cs

@ -13,14 +13,14 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
{ {
public sealed class ContentSchemaBuilder public sealed class ContentSchemaBuilder
{ {
public JsonSchema4 CreateContentSchema(Schema schema, JsonSchema4 dataSchema) public JsonSchema CreateContentSchema(Schema schema, JsonSchema dataSchema)
{ {
Guard.NotNull(schema, nameof(schema)); Guard.NotNull(schema, nameof(schema));
Guard.NotNull(dataSchema, nameof(dataSchema)); Guard.NotNull(dataSchema, nameof(dataSchema));
var schemaName = schema.Properties.Label.WithFallback(schema.Name); var schemaName = schema.Properties.Label.WithFallback(schema.Name);
var contentSchema = new JsonSchema4 var contentSchema = new JsonSchema
{ {
Properties = Properties =
{ {

6
src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonSchemaExtensions.cs

@ -13,7 +13,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
{ {
public static class JsonSchemaExtensions public static class JsonSchemaExtensions
{ {
public static JsonSchema4 BuildJsonSchema(this Schema schema, PartitionResolver partitionResolver, SchemaResolver schemaResolver) public static JsonSchema BuildJsonSchema(this Schema schema, PartitionResolver partitionResolver, SchemaResolver schemaResolver)
{ {
Guard.NotNull(schemaResolver, nameof(schemaResolver)); Guard.NotNull(schemaResolver, nameof(schemaResolver));
Guard.NotNull(partitionResolver, nameof(partitionResolver)); Guard.NotNull(partitionResolver, nameof(partitionResolver));
@ -21,7 +21,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
var schemaName = schema.Name.ToPascalCase(); var schemaName = schema.Name.ToPascalCase();
var jsonTypeVisitor = new JsonTypeVisitor(schemaResolver); var jsonTypeVisitor = new JsonTypeVisitor(schemaResolver);
var jsonSchema = new JsonSchema4 { Type = JsonObjectType.Object }; var jsonSchema = new JsonSchema { Type = JsonObjectType.Object };
foreach (var field in schema.Fields.ForApi()) foreach (var field in schema.Fields.ForApi())
{ {
@ -52,7 +52,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
return jsonSchema; return jsonSchema;
} }
public static JsonProperty CreateProperty(IField field, JsonSchema4 reference) public static JsonSchemaProperty CreateProperty(IField field, JsonSchema reference)
{ {
var jsonProperty = Builder.ObjectProperty(reference); var jsonProperty = Builder.ObjectProperty(reference);

30
src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs

@ -11,9 +11,9 @@ using Squidex.Domain.Apps.Core.Schemas;
namespace Squidex.Domain.Apps.Core.GenerateJsonSchema namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
{ {
public delegate JsonSchema4 SchemaResolver(string name, JsonSchema4 schema); public delegate JsonSchema SchemaResolver(string name, JsonSchema schema);
public sealed class JsonTypeVisitor : IFieldVisitor<JsonProperty> public sealed class JsonTypeVisitor : IFieldVisitor<JsonSchemaProperty>
{ {
private readonly SchemaResolver schemaResolver; private readonly SchemaResolver schemaResolver;
@ -22,7 +22,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
this.schemaResolver = schemaResolver; this.schemaResolver = schemaResolver;
} }
public JsonProperty Visit(IArrayField field) public JsonSchemaProperty Visit(IArrayField field)
{ {
var item = Builder.Object(); var item = Builder.Object();
@ -42,28 +42,28 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
return Builder.ArrayProperty(item); return Builder.ArrayProperty(item);
} }
public JsonProperty Visit(IField<AssetsFieldProperties> field) public JsonSchemaProperty Visit(IField<AssetsFieldProperties> field)
{ {
var item = schemaResolver("AssetItem", Builder.Guid()); var item = schemaResolver("AssetItem", Builder.Guid());
return Builder.ArrayProperty(item); return Builder.ArrayProperty(item);
} }
public JsonProperty Visit(IField<BooleanFieldProperties> field) public JsonSchemaProperty Visit(IField<BooleanFieldProperties> field)
{ {
return Builder.BooleanProperty(); return Builder.BooleanProperty();
} }
public JsonProperty Visit(IField<DateTimeFieldProperties> field) public JsonSchemaProperty Visit(IField<DateTimeFieldProperties> field)
{ {
return Builder.DateTimeProperty(); return Builder.DateTimeProperty();
} }
public JsonProperty Visit(IField<GeolocationFieldProperties> field) public JsonSchemaProperty Visit(IField<GeolocationFieldProperties> field)
{ {
var geolocationSchema = Builder.Object(); var geolocationSchema = Builder.Object();
geolocationSchema.Properties.Add("latitude", new JsonProperty geolocationSchema.Properties.Add("latitude", new JsonSchemaProperty
{ {
Type = JsonObjectType.Number, Type = JsonObjectType.Number,
Minimum = -90, Minimum = -90,
@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
IsRequired = true IsRequired = true
}); });
geolocationSchema.Properties.Add("longitude", new JsonProperty geolocationSchema.Properties.Add("longitude", new JsonSchemaProperty
{ {
Type = JsonObjectType.Number, Type = JsonObjectType.Number,
Minimum = -180, Minimum = -180,
@ -84,12 +84,12 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
return Builder.ObjectProperty(reference); return Builder.ObjectProperty(reference);
} }
public JsonProperty Visit(IField<JsonFieldProperties> field) public JsonSchemaProperty Visit(IField<JsonFieldProperties> field)
{ {
return Builder.StringProperty(); return Builder.StringProperty();
} }
public JsonProperty Visit(IField<NumberFieldProperties> field) public JsonSchemaProperty Visit(IField<NumberFieldProperties> field)
{ {
var property = Builder.NumberProperty(); var property = Builder.NumberProperty();
@ -106,14 +106,14 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
return property; return property;
} }
public JsonProperty Visit(IField<ReferencesFieldProperties> field) public JsonSchemaProperty Visit(IField<ReferencesFieldProperties> field)
{ {
var item = schemaResolver("ReferenceItem", Builder.Guid()); var item = schemaResolver("ReferenceItem", Builder.Guid());
return Builder.ArrayProperty(item); return Builder.ArrayProperty(item);
} }
public JsonProperty Visit(IField<StringFieldProperties> field) public JsonSchemaProperty Visit(IField<StringFieldProperties> field)
{ {
var property = Builder.StringProperty(); var property = Builder.StringProperty();
@ -133,14 +133,14 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
return property; return property;
} }
public JsonProperty Visit(IField<TagsFieldProperties> field) public JsonSchemaProperty Visit(IField<TagsFieldProperties> field)
{ {
var item = schemaResolver("ReferenceItem", Builder.String()); var item = schemaResolver("ReferenceItem", Builder.String());
return Builder.ArrayProperty(item); return Builder.ArrayProperty(item);
} }
public JsonProperty Visit(IField<UIFieldProperties> field) public JsonSchemaProperty Visit(IField<UIFieldProperties> field)
{ {
return null; return null;
} }

5
src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

@ -8,6 +8,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Esprima;
using Jint; using Jint;
using Jint.Native; using Jint.Native;
using Jint.Native.Date; using Jint.Native.Date;
@ -125,6 +126,10 @@ namespace Squidex.Domain.Apps.Core.Scripting
{ {
throw new ValidationException($"Failed to execute script with javascript error: {ex.Message}", new ValidationError(ex.Message)); throw new ValidationException($"Failed to execute script with javascript error: {ex.Message}", new ValidationError(ex.Message));
} }
catch (ParserException ex)
{
throw new ValidationException($"Failed to execute script with javascript error: {ex.Message}", new ValidationError(ex.Message));
}
} }
private Engine CreateScriptEngine(ScriptContext context) private Engine CreateScriptEngine(ScriptContext context)

6
src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj

@ -15,9 +15,9 @@
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" /> <ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Jint" Version="3.0.0-beta-1469" /> <PackageReference Include="Jint" Version="3.0.0-beta-1580" />
<PackageReference Include="Microsoft.OData.Core" Version="7.5.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.0" />
<PackageReference Include="NJsonSchema" Version="9.14.1" /> <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" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.5.0" />

2
src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj

@ -16,7 +16,7 @@
<ProjectReference Include="..\Squidex.Domain.Apps.Entities\Squidex.Domain.Apps.Entities.csproj" /> <ProjectReference Include="..\Squidex.Domain.Apps.Entities\Squidex.Domain.Apps.Entities.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.OData.Core" Version="7.5.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.0" />
<PackageReference Include="MongoDB.Driver" Version="2.8.1" /> <PackageReference Include="MongoDB.Driver" Version="2.8.1" />
<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" />

6
src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj

@ -20,12 +20,12 @@
<PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00005" /> <PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00005" />
<PackageReference Include="Lucene.Net.Queries" Version="4.8.0-beta00005" /> <PackageReference Include="Lucene.Net.Queries" Version="4.8.0-beta00005" />
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00005" /> <PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00005" />
<PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="2.3.2"> <PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="2.3.6">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Orleans.Core" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.Core" Version="2.3.6" />
<PackageReference Include="NodaTime" Version="2.4.5" /> <PackageReference Include="NodaTime" Version="2.4.6" />
<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" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.5.0" />

2
src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj

@ -13,7 +13,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
<PackageReference Include="NodaTime" Version="2.4.5" /> <PackageReference Include="NodaTime" Version="2.4.6" />
<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" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" /> <PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" />

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.4.0" /> <PackageReference Include="IdentityServer4" Version="2.5.0" />
<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" />

2
src/Squidex.Infrastructure.Azure/Squidex.Infrastructure.Azure.csproj

@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Azure.DocumentDB.ChangeFeedProcessor" Version="2.2.7" /> <PackageReference Include="Microsoft.Azure.DocumentDB.ChangeFeedProcessor" Version="2.2.7" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.4.0" /> <PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.5.1" />
<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" />
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" /> <PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />

4
src/Squidex.Infrastructure/Queries/Json/PropertyPathConverter.cs

@ -6,7 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Collections.Generic; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json.Newtonsoft; using Squidex.Infrastructure.Json.Newtonsoft;
@ -23,7 +23,7 @@ namespace Squidex.Infrastructure.Queries.Json
protected override void WriteValue(JsonWriter writer, PropertyPath value, JsonSerializer serializer) protected override void WriteValue(JsonWriter writer, PropertyPath value, JsonSerializer serializer)
{ {
serializer.Serialize(writer, (IEnumerable<string>)value); serializer.Serialize(writer, value.ToList());
} }
} }
} }

35
src/Squidex.Infrastructure/Queries/Json/PropertyPathValidator.cs

@ -0,0 +1,35 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using NJsonSchema;
namespace Squidex.Infrastructure.Queries.Json
{
public static class PropertyPathValidator
{
public static bool TryGetProperty(this PropertyPath path, JsonSchema schema, out JsonSchema property)
{
foreach (var element in path)
{
if (schema.Properties.TryGetValue(element, out var p))
{
schema = p;
}
else
{
property = null;
return false;
}
}
property = schema;
return true;
}
}
}

13
src/Squidex.Infrastructure/Squidex.Infrastructure.csproj

@ -8,20 +8,21 @@
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentFTP" Version="24.0.0" /> <PackageReference Include="FluentFTP" Version="27.0.0" />
<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" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.OData.Core" Version="7.5.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.0" />
<PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="2.3.2"> <PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="2.3.6">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Orleans.Core" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.Core" Version="2.3.6" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.3.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NodaTime" Version="2.4.5" /> <PackageReference Include="NJsonSchema" Version="10.0.21" />
<PackageReference Include="NodaTime" Version="2.4.6" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0004" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0004" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

21
src/Squidex/Areas/Api/Config/Swagger/ErrorDtoProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/ErrorDtoProcessor.cs

@ -7,21 +7,20 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using NJsonSchema; using NJsonSchema;
using NSwag; using NSwag;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.ClientLibrary.Management; using Squidex.ClientLibrary.Management;
using Squidex.Pipeline.Swagger; using Squidex.Pipeline.OpenApi;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class ErrorDtoProcessor : IDocumentProcessor public sealed class ErrorDtoProcessor : IDocumentProcessor
{ {
public async Task ProcessAsync(DocumentProcessorContext context) public void Process(DocumentProcessorContext context)
{ {
var errorSchema = await GetErrorSchemaAsync(context); var errorSchema = GetErrorSchema(context);
foreach (var operation in context.Document.Paths.Values.SelectMany(x => x.Values)) foreach (var operation in context.Document.Paths.Values.SelectMany(x => x.Values))
{ {
@ -31,7 +30,7 @@ namespace Squidex.Areas.Api.Config.Swagger
} }
} }
private static void AddErrorResponses(SwaggerOperation operation, JsonSchema4 errorSchema) private static void AddErrorResponses(OpenApiOperation operation, JsonSchema errorSchema)
{ {
if (!operation.Responses.ContainsKey("500")) if (!operation.Responses.ContainsKey("500"))
{ {
@ -47,7 +46,7 @@ namespace Squidex.Areas.Api.Config.Swagger
} }
} }
private static void CleanupResponses(SwaggerOperation operation) private static void CleanupResponses(OpenApiOperation operation)
{ {
foreach (var (code, response) in operation.Responses.ToList()) foreach (var (code, response) in operation.Responses.ToList())
{ {
@ -60,11 +59,11 @@ namespace Squidex.Areas.Api.Config.Swagger
} }
} }
private Task<JsonSchema4> GetErrorSchemaAsync(DocumentProcessorContext context) private JsonSchema GetErrorSchema(DocumentProcessorContext context)
{ {
var errorType = typeof(ErrorDto); var errorType = typeof(ErrorDto);
return context.SchemaGenerator.GenerateWithReferenceAsync<JsonSchema4>(errorType, Enumerable.Empty<Attribute>(), context.SchemaResolver); return context.SchemaGenerator.Generate(errorType);
} }
} }
} }

14
src/Squidex/Areas/Api/Config/Swagger/FixProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/FixProcessor.cs

@ -5,19 +5,17 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Threading.Tasks;
using NJsonSchema; using NJsonSchema;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class FixProcessor : IOperationProcessor public sealed class FixProcessor : IOperationProcessor
{ {
private static readonly JsonSchema4 StringSchema = new JsonSchema4 { Type = JsonObjectType.String }; private static readonly JsonSchema StringSchema = new JsonSchema { Type = JsonObjectType.String };
public Task<bool> ProcessAsync(OperationProcessorContext context) public bool Process(OperationProcessorContext context)
{ {
foreach (var parameter in context.Parameters.Values) foreach (var parameter in context.Parameters.Values)
{ {
@ -27,7 +25,7 @@ namespace Squidex.Areas.Api.Config.Swagger
} }
} }
return TaskHelper.True; return true;
} }
} }
} }

14
src/Squidex/Areas/Api/Config/Swagger/ODataQueryParamsProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/ODataQueryParamsProcessor.cs

@ -5,14 +5,12 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Threading.Tasks;
using NJsonSchema; using NJsonSchema;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks; using Squidex.Pipeline.OpenApi;
using Squidex.Pipeline.Swagger;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class ODataQueryParamsProcessor : IOperationProcessor public sealed class ODataQueryParamsProcessor : IOperationProcessor
{ {
@ -28,7 +26,7 @@ namespace Squidex.Areas.Api.Config.Swagger
this.supportedPath = supportedPath; this.supportedPath = supportedPath;
} }
public Task<bool> ProcessAsync(OperationProcessorContext context) public bool Process(OperationProcessorContext context)
{ {
if (context.OperationDescription.Path == supportedPath) if (context.OperationDescription.Path == supportedPath)
{ {
@ -45,7 +43,7 @@ namespace Squidex.Areas.Api.Config.Swagger
operation.AddQueryParameter("$filter", JsonObjectType.String, "Optional OData filter definition."); operation.AddQueryParameter("$filter", JsonObjectType.String, "Optional OData filter definition.");
} }
return TaskHelper.True; return true;
} }
} }
} }

8
src/Squidex/Areas/Api/Config/Swagger/SwaggerExtensions.cs → src/Squidex/Areas/Api/Config/OpenApi/OpenApiExtensions.cs

@ -7,13 +7,13 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public static class SwaggerExtensions public static class OpenApiExtensions
{ {
public static void UseMySwagger(this IApplicationBuilder app) public static void UseMyOpenApi(this IApplicationBuilder app)
{ {
app.UseSwagger(); app.UseOpenApi();
} }
} }
} }

16
src/Squidex/Areas/Api/Config/Swagger/SwaggerServices.cs → src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs

@ -10,18 +10,18 @@ using Microsoft.Extensions.DependencyInjection;
using NJsonSchema; using NJsonSchema;
using NJsonSchema.Generation.TypeMappers; using NJsonSchema.Generation.TypeMappers;
using NodaTime; using NodaTime;
using NSwag.SwaggerGeneration; using NSwag.Generation;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using Squidex.Areas.Api.Controllers.Contents.Generator; using Squidex.Areas.Api.Controllers.Contents.Generator;
using Squidex.Areas.Api.Controllers.Rules.Models; using Squidex.Areas.Api.Controllers.Rules.Models;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public static class SwaggerServices public static class OpenApiServices
{ {
public static void AddMySwaggerSettings(this IServiceCollection services) public static void AddMyOpenApiSettings(this IServiceCollection services)
{ {
services.AddSingletonAs<ErrorDtoProcessor>() services.AddSingletonAs<ErrorDtoProcessor>()
.As<IDocumentProcessor>(); .As<IDocumentProcessor>();
@ -58,15 +58,15 @@ namespace Squidex.Areas.Api.Config.Swagger
settings.OperationProcessors.Add(new ODataQueryParamsProcessor("/apps/{app}/assets", "assets", false)); settings.OperationProcessors.Add(new ODataQueryParamsProcessor("/apps/{app}/assets", "assets", false));
}); });
services.AddTransient<SchemasSwaggerGenerator>(); services.AddTransient<SchemasOpenApiGenerator>();
} }
public static void ConfigureName<T>(this T settings) where T : SwaggerGeneratorSettings public static void ConfigureName<T>(this T settings) where T : OpenApiDocumentGeneratorSettings
{ {
settings.Title = "Squidex API"; settings.Title = "Squidex API";
} }
public static void ConfigureSchemaSettings<T>(this T settings) where T : SwaggerGeneratorSettings public static void ConfigureSchemaSettings<T>(this T settings) where T : OpenApiDocumentGeneratorSettings
{ {
settings.TypeMappers = new List<ITypeMapper> settings.TypeMappers = new List<ITypeMapper>
{ {

18
src/Squidex/Areas/Api/Config/Swagger/ScopesProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/ScopesProcessor.cs

@ -8,30 +8,28 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using NSwag; using NSwag;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class ScopesProcessor : IOperationProcessor public sealed class ScopesProcessor : IOperationProcessor
{ {
public Task<bool> ProcessAsync(OperationProcessorContext context) public bool Process(OperationProcessorContext context)
{ {
if (context.OperationDescription.Operation.Security == null) if (context.OperationDescription.Operation.Security == null)
{ {
context.OperationDescription.Operation.Security = new List<SwaggerSecurityRequirement>(); context.OperationDescription.Operation.Security = new List<OpenApiSecurityRequirement>();
} }
var permissionAttribute = context.MethodInfo.GetCustomAttribute<ApiPermissionAttribute>(); var permissionAttribute = context.MethodInfo.GetCustomAttribute<ApiPermissionAttribute>();
if (permissionAttribute != null) if (permissionAttribute != null)
{ {
context.OperationDescription.Operation.Security.Add(new SwaggerSecurityRequirement context.OperationDescription.Operation.Security.Add(new OpenApiSecurityRequirement
{ {
[Constants.SecurityDefinition] = permissionAttribute.PermissionIds [Constants.SecurityDefinition] = permissionAttribute.PermissionIds
}); });
@ -47,14 +45,14 @@ namespace Squidex.Areas.Api.Config.Swagger
{ {
var scopes = authorizeAttributes.Where(a => a.Roles != null).SelectMany(a => a.Roles.Split(',')).Distinct().ToList(); var scopes = authorizeAttributes.Where(a => a.Roles != null).SelectMany(a => a.Roles.Split(',')).Distinct().ToList();
context.OperationDescription.Operation.Security.Add(new SwaggerSecurityRequirement context.OperationDescription.Operation.Security.Add(new OpenApiSecurityRequirement
{ {
[Constants.SecurityDefinition] = scopes [Constants.SecurityDefinition] = scopes
}); });
} }
} }
return TaskHelper.True; return true;
} }
} }
} }

16
src/Squidex/Areas/Api/Config/Swagger/SecurityProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/SecurityProcessor.cs

@ -9,11 +9,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NSwag; using NSwag;
using NSwag.SwaggerGeneration.Processors.Security; using NSwag.Generation.Processors.Security;
using Squidex.Pipeline.Swagger; using Squidex.Pipeline.OpenApi;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class SecurityProcessor : SecurityDefinitionAppender public sealed class SecurityProcessor : SecurityDefinitionAppender
{ {
@ -22,11 +22,11 @@ namespace Squidex.Areas.Api.Config.Swagger
{ {
} }
private static SwaggerSecurityScheme CreateOAuthSchema(UrlsOptions urlOptions) private static OpenApiSecurityScheme CreateOAuthSchema(UrlsOptions urlOptions)
{ {
var security = new SwaggerSecurityScheme var security = new OpenApiSecurityScheme
{ {
Type = SwaggerSecuritySchemeType.OAuth2 Type = OpenApiSecuritySchemeType.OAuth2
}; };
var tokenUrl = urlOptions.BuildUrl($"{Constants.IdentityServerPrefix}/connect/token", false); var tokenUrl = urlOptions.BuildUrl($"{Constants.IdentityServerPrefix}/connect/token", false);
@ -35,7 +35,7 @@ namespace Squidex.Areas.Api.Config.Swagger
SetupDescription(security, tokenUrl); SetupDescription(security, tokenUrl);
security.Flow = SwaggerOAuth2Flow.Application; security.Flow = OpenApiOAuth2Flow.Application;
security.Scopes = new Dictionary<string, string> security.Scopes = new Dictionary<string, string>
{ {
@ -45,7 +45,7 @@ namespace Squidex.Areas.Api.Config.Swagger
return security; return security;
} }
private static void SetupDescription(SwaggerSecurityScheme securityScheme, string tokenUrl) private static void SetupDescription(OpenApiSecurityScheme securityScheme, string tokenUrl)
{ {
var securityDocs = NSwagHelper.LoadDocs("security"); var securityDocs = NSwagHelper.LoadDocs("security");
var securityText = securityDocs.Replace("<TOKEN_URL>", tokenUrl); var securityText = securityDocs.Replace("<TOKEN_URL>", tokenUrl);

14
src/Squidex/Areas/Api/Config/Swagger/TagByGroupNameProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/TagByGroupNameProcessor.cs

@ -7,17 +7,15 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class TagByGroupNameProcessor : IOperationProcessor public sealed class TagByGroupNameProcessor : IOperationProcessor
{ {
public Task<bool> ProcessAsync(OperationProcessorContext context) public bool Process(OperationProcessorContext context)
{ {
var groupName = context.ControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>()?.GroupName; var groupName = context.ControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>()?.GroupName;
@ -25,11 +23,11 @@ namespace Squidex.Areas.Api.Config.Swagger
{ {
context.OperationDescription.Operation.Tags = new List<string> { groupName }; context.OperationDescription.Operation.Tags = new List<string> { groupName };
return TaskHelper.True; return true;
} }
else else
{ {
return TaskHelper.False; return false;
} }
} }
} }

12
src/Squidex/Areas/Api/Config/Swagger/ThemeProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/ThemeProcessor.cs

@ -6,14 +6,12 @@
// ========================================================================== // ==========================================================================
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class ThemeProcessor : IDocumentProcessor public sealed class ThemeProcessor : IDocumentProcessor
{ {
@ -26,7 +24,7 @@ namespace Squidex.Areas.Api.Config.Swagger
url = urlOptions.Value.BuildUrl("images/logo-white.png", false); url = urlOptions.Value.BuildUrl("images/logo-white.png", false);
} }
public Task ProcessAsync(DocumentProcessorContext context) public void Process(DocumentProcessorContext context)
{ {
context.Document.BasePath = Constants.ApiPrefix; context.Document.BasePath = Constants.ApiPrefix;
@ -34,8 +32,6 @@ namespace Squidex.Areas.Api.Config.Swagger
{ {
["x-logo"] = new { url, backgroundColor = Background } ["x-logo"] = new { url, backgroundColor = Background }
}; };
return TaskHelper.Done;
} }
} }
} }

15
src/Squidex/Areas/Api/Config/Swagger/XmlResponseTypesProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/XmlResponseTypesProcessor.cs

@ -7,23 +7,22 @@
using System; using System;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using Namotion.Reflection;
using NJsonSchema.Infrastructure;
using NSwag; using NSwag;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class XmlResponseTypesProcessor : IOperationProcessor public sealed class XmlResponseTypesProcessor : IOperationProcessor
{ {
private static readonly Regex ResponseRegex = new Regex("(?<Code>[0-9]{3}) =&gt; (?<Description>.*)", RegexOptions.Compiled); private static readonly Regex ResponseRegex = new Regex("(?<Code>[0-9]{3}) =&gt; (?<Description>.*)", RegexOptions.Compiled);
public async Task<bool> ProcessAsync(OperationProcessorContext context) public bool Process(OperationProcessorContext context)
{ {
var operation = context.OperationDescription.Operation; var operation = context.OperationDescription.Operation;
var returnsDescription = await context.MethodInfo.GetXmlDocumentationTagAsync("returns"); var returnsDescription = context.MethodInfo.GetXmlDocsTag("returns");
if (!string.IsNullOrWhiteSpace(returnsDescription)) if (!string.IsNullOrWhiteSpace(returnsDescription))
{ {
@ -33,7 +32,7 @@ namespace Squidex.Areas.Api.Config.Swagger
if (!operation.Responses.TryGetValue(statusCode, out var response)) if (!operation.Responses.TryGetValue(statusCode, out var response))
{ {
response = new SwaggerResponse(); response = new OpenApiResponse();
operation.Responses[statusCode] = response; operation.Responses[statusCode] = response;
} }

16
src/Squidex/Areas/Api/Config/Swagger/XmlTagProcessor.cs → src/Squidex/Areas/Api/Config/OpenApi/XmlTagProcessor.cs

@ -7,18 +7,16 @@
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NJsonSchema.Infrastructure; using Namotion.Reflection;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Areas.Api.Config.Swagger namespace Squidex.Areas.Api.Config.OpenApi
{ {
public sealed class XmlTagProcessor : IDocumentProcessor public sealed class XmlTagProcessor : IDocumentProcessor
{ {
public Task ProcessAsync(DocumentProcessorContext context) public void Process(DocumentProcessorContext context)
{ {
foreach (var controllerType in context.ControllerTypes) foreach (var controllerType in context.ControllerTypes)
{ {
@ -30,7 +28,7 @@ namespace Squidex.Areas.Api.Config.Swagger
if (tag != null) if (tag != null)
{ {
var description = controllerType.GetXmlSummaryAsync().Result; var description = controllerType.GetXmlDocsSummary();
if (description != null) if (description != null)
{ {
@ -44,8 +42,6 @@ namespace Squidex.Areas.Api.Config.Swagger
} }
} }
} }
return TaskHelper.Done;
} }
} }
} }

4
src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs

@ -177,7 +177,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermission(Permissions.AppAssetsCreate)] [ApiPermission(Permissions.AppAssetsCreate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PostAsset(string app, [SwaggerIgnore] List<IFormFile> file) public async Task<IActionResult> PostAsset(string app, [OpenApiIgnore] List<IFormFile> file)
{ {
var assetFile = await CheckAssetFileAsync(file); var assetFile = await CheckAssetFileAsync(file);
@ -207,7 +207,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetDto), 200)] [ProducesResponseType(typeof(AssetDto), 200)]
[ApiPermission(Permissions.AppAssetsUpdate)] [ApiPermission(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAssetContent(string app, Guid id, [SwaggerIgnore] List<IFormFile> file) public async Task<IActionResult> PutAssetContent(string app, Guid id, [OpenApiIgnore] List<IFormFile> file)
{ {
var assetFile = await CheckAssetFileAsync(file); var assetFile = await CheckAssetFileAsync(file);

19
src/Squidex/Areas/Api/Controllers/Contents/ContentSwaggerController.cs → src/Squidex/Areas/Api/Controllers/Contents/ContentOpenApiController.cs

@ -15,17 +15,17 @@ using Squidex.Web;
namespace Squidex.Areas.Api.Controllers.Contents namespace Squidex.Areas.Api.Controllers.Contents
{ {
public sealed class ContentSwaggerController : ApiController public sealed class ContentOpenApiController : ApiController
{ {
private readonly IAppProvider appProvider; private readonly IAppProvider appProvider;
private readonly SchemasSwaggerGenerator schemasSwaggerGenerator; private readonly SchemasOpenApiGenerator schemasOpenApiGenerator;
public ContentSwaggerController(ICommandBus commandBus, IAppProvider appProvider, SchemasSwaggerGenerator schemasSwaggerGenerator) public ContentOpenApiController(ICommandBus commandBus, IAppProvider appProvider, SchemasOpenApiGenerator schemasOpenApiGenerator)
: base(commandBus) : base(commandBus)
{ {
this.appProvider = appProvider; this.appProvider = appProvider;
this.schemasSwaggerGenerator = schemasSwaggerGenerator; this.schemasOpenApiGenerator = schemasOpenApiGenerator;
} }
[HttpGet] [HttpGet]
@ -34,7 +34,10 @@ namespace Squidex.Areas.Api.Controllers.Contents
[AllowAnonymous] [AllowAnonymous]
public IActionResult Docs(string app) public IActionResult Docs(string app)
{ {
var vm = new DocsVM { Specification = $"~/content/{app}/swagger/v1/swagger.json" }; var vm = new DocsVM
{
Specification = $"~/content/{app}/swagger/v1/swagger.json"
};
return View(nameof(Docs), vm); return View(nameof(Docs), vm);
} }
@ -43,13 +46,13 @@ namespace Squidex.Areas.Api.Controllers.Contents
[Route("content/{app}/swagger/v1/swagger.json")] [Route("content/{app}/swagger/v1/swagger.json")]
[ApiCosts(0)] [ApiCosts(0)]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> GetSwagger(string app) public async Task<IActionResult> GetOpenApi(string app)
{ {
var schemas = await appProvider.GetSchemasAsync(AppId); var schemas = await appProvider.GetSchemasAsync(AppId);
var swaggerDocument = await schemasSwaggerGenerator.Generate(HttpContext, App, schemas); var openApiDocument = schemasOpenApiGenerator.Generate(HttpContext, App, schemas);
return Content(swaggerDocument.ToJson(), "application/json"); return Content(openApiDocument.ToJson(), "application/json");
} }
} }
} }

76
src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemaSwaggerGenerator.cs → src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemaOpenApiGenerator.cs

@ -1,4 +1,4 @@
// ========================================================================== // ==========================================================================
// Squidex Headless CMS // Squidex Headless CMS
// ========================================================================== // ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt) // Copyright (c) Squidex UG (haftungsbeschränkt)
@ -14,40 +14,40 @@ 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;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Pipeline.Swagger; using Squidex.Pipeline.OpenApi;
using Squidex.Shared; using Squidex.Shared;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api.Controllers.Contents.Generator namespace Squidex.Areas.Api.Controllers.Contents.Generator
{ {
public sealed class SchemaSwaggerGenerator public sealed class SchemaOpenApiGenerator
{ {
private static readonly string SchemaQueryDescription; private static readonly string SchemaQueryDescription;
private static readonly string SchemaBodyDescription; private static readonly string SchemaBodyDescription;
private readonly ContentSchemaBuilder schemaBuilder = new ContentSchemaBuilder(); private readonly ContentSchemaBuilder schemaBuilder = new ContentSchemaBuilder();
private readonly SwaggerDocument document; private readonly OpenApiDocument document;
private readonly JsonSchema4 contentSchema; private readonly JsonSchema contentSchema;
private readonly JsonSchema4 dataSchema; private readonly JsonSchema dataSchema;
private readonly string schemaPath; private readonly string schemaPath;
private readonly string schemaName; private readonly string schemaName;
private readonly string schemaType; private readonly string schemaType;
private readonly string appPath; private readonly string appPath;
private readonly JsonSchema4 statusSchema; private readonly JsonSchema statusSchema;
private readonly string appName; private readonly string appName;
static SchemaSwaggerGenerator() static SchemaOpenApiGenerator()
{ {
SchemaBodyDescription = NSwagHelper.LoadDocs("schemabody"); SchemaBodyDescription = NSwagHelper.LoadDocs("schemabody");
SchemaQueryDescription = NSwagHelper.LoadDocs("schemaquery"); SchemaQueryDescription = NSwagHelper.LoadDocs("schemaquery");
} }
public SchemaSwaggerGenerator( public SchemaOpenApiGenerator(
SwaggerDocument document, OpenApiDocument document,
string appName, string appName,
string appPath, string appPath,
Schema schema, Schema schema,
SchemaResolver schemaResolver, SchemaResolver schemaResolver,
JsonSchema4 statusSchema, JsonSchema statusSchema,
PartitionResolver partitionResolver) PartitionResolver partitionResolver)
{ {
this.document = document; this.document = document;
@ -69,12 +69,12 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
public void GenerateSchemaOperations() public void GenerateSchemaOperations()
{ {
document.Tags.Add( document.Tags.Add(
new SwaggerTag new OpenApiTag
{ {
Name = schemaName, Description = $"API to managed {schemaName} contents." Name = schemaName, Description = $"API to managed {schemaName} contents."
}); });
var schemaOperations = new List<SwaggerPathItem> var schemaOperations = new List<OpenApiPathItem>
{ {
GenerateSchemaGetsOperation(), GenerateSchemaGetsOperation(),
GenerateSchemaGetOperation(), GenerateSchemaGetOperation(),
@ -92,9 +92,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
} }
} }
private SwaggerPathItem GenerateSchemaGetsOperation() private OpenApiPathItem GenerateSchemaGetsOperation()
{ {
return AddOperation(SwaggerOperationMethod.Get, null, $"{appPath}/{schemaPath}", operation => return AddOperation(OpenApiOperationMethod.Get, null, $"{appPath}/{schemaPath}", operation =>
{ {
operation.OperationId = $"Query{schemaType}Contents"; operation.OperationId = $"Query{schemaType}Contents";
@ -115,9 +115,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaGetOperation() private OpenApiPathItem GenerateSchemaGetOperation()
{ {
return AddOperation(SwaggerOperationMethod.Get, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation => return AddOperation(OpenApiOperationMethod.Get, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation =>
{ {
operation.OperationId = $"Get{schemaType}Content"; operation.OperationId = $"Get{schemaType}Content";
@ -129,9 +129,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaCreateOperation() private OpenApiPathItem GenerateSchemaCreateOperation()
{ {
return AddOperation(SwaggerOperationMethod.Post, null, $"{appPath}/{schemaPath}", operation => return AddOperation(OpenApiOperationMethod.Post, null, $"{appPath}/{schemaPath}", operation =>
{ {
operation.OperationId = $"Create{schemaType}Content"; operation.OperationId = $"Create{schemaType}Content";
@ -147,9 +147,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaUpdateOperation() private OpenApiPathItem GenerateSchemaUpdateOperation()
{ {
return AddOperation(SwaggerOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation => return AddOperation(OpenApiOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation =>
{ {
operation.OperationId = $"Update{schemaType}Content"; operation.OperationId = $"Update{schemaType}Content";
@ -164,9 +164,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaUpdatePatchOperation() private OpenApiPathItem GenerateSchemaUpdatePatchOperation()
{ {
return AddOperation(SwaggerOperationMethod.Patch, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation => return AddOperation(OpenApiOperationMethod.Patch, schemaName, $"{appPath}/{schemaPath}/{{id}}", operation =>
{ {
operation.OperationId = $"Path{schemaType}Content"; operation.OperationId = $"Path{schemaType}Content";
@ -181,9 +181,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaStatusOperation() private OpenApiPathItem GenerateSchemaStatusOperation()
{ {
return AddOperation(SwaggerOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}/status", operation => return AddOperation(OpenApiOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}/status", operation =>
{ {
operation.OperationId = $"Change{schemaType}ContentStatus"; operation.OperationId = $"Change{schemaType}ContentStatus";
@ -198,9 +198,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaDiscardOperation() private OpenApiPathItem GenerateSchemaDiscardOperation()
{ {
return AddOperation(SwaggerOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}/discard", operation => return AddOperation(OpenApiOperationMethod.Put, schemaName, $"{appPath}/{schemaPath}/{{id}}/discard", operation =>
{ {
operation.OperationId = $"Discard{schemaType}Content"; operation.OperationId = $"Discard{schemaType}Content";
@ -213,9 +213,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem GenerateSchemaDeleteOperation() private OpenApiPathItem GenerateSchemaDeleteOperation()
{ {
return AddOperation(SwaggerOperationMethod.Delete, schemaName, $"{appPath}/{schemaPath}/{{id}}/", operation => return AddOperation(OpenApiOperationMethod.Delete, schemaName, $"{appPath}/{schemaPath}/{{id}}/", operation =>
{ {
operation.OperationId = $"Delete{schemaType}Content"; operation.OperationId = $"Delete{schemaType}Content";
@ -227,10 +227,10 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
}); });
} }
private SwaggerPathItem AddOperation(string method, string entityName, string path, Action<SwaggerOperation> updater) private OpenApiPathItem AddOperation(string method, string entityName, string path, Action<OpenApiOperation> updater)
{ {
var operations = document.Paths.GetOrAddNew(path); var operations = document.Paths.GetOrAddNew(path);
var operation = new SwaggerOperation(); var operation = new OpenApiOperation();
updater(operation); updater(operation);
@ -246,17 +246,17 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
return operations; return operations;
} }
private static JsonSchema4 CreateContentsSchema(string schemaName, JsonSchema4 contentSchema) private static JsonSchema CreateContentsSchema(string schemaName, JsonSchema contentSchema)
{ {
var schema = new JsonSchema4 var schema = new JsonSchema
{ {
Properties = Properties =
{ {
["total"] = new JsonProperty ["total"] = new JsonSchemaProperty
{ {
Type = JsonObjectType.Number, IsRequired = true, Description = $"The total number of {schemaName} contents." Type = JsonObjectType.Number, IsRequired = true, Description = $"The total number of {schemaName} contents."
}, },
["items"] = new JsonProperty ["items"] = new JsonSchemaProperty
{ {
Type = JsonObjectType.Array, IsRequired = true, Item = contentSchema, Description = $"The {schemaName} contents." Type = JsonObjectType.Array, IsRequired = true, Item = contentSchema, Description = $"The {schemaName} contents."
} }
@ -267,14 +267,14 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
return schema; return schema;
} }
private void AddSecurity(SwaggerOperation operation, string permission) private void AddSecurity(OpenApiOperation operation, string permission)
{ {
if (operation.Security == null) if (operation.Security == null)
{ {
operation.Security = new List<SwaggerSecurityRequirement>(); operation.Security = new List<OpenApiSecurityRequirement>();
} }
operation.Security.Add(new SwaggerSecurityRequirement operation.Security.Add(new OpenApiSecurityRequirement
{ {
[Constants.SecurityDefinition] = new[] { Permissions.ForApp(permission, appName, schemaPath).Id } [Constants.SecurityDefinition] = new[] { Permissions.ForApp(permission, appName, schemaPath).Id }
}); });

47
src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasSwaggerGenerator.cs → src/Squidex/Areas/Api/Controllers/Contents/Generator/SchemasOpenApiGenerator.cs

@ -8,35 +8,34 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NJsonSchema; using NJsonSchema;
using NJsonSchema.Generation;
using NSwag; using NSwag;
using NSwag.AspNetCore; using NSwag.Generation;
using NSwag.SwaggerGeneration; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors.Contexts;
using NSwag.SwaggerGeneration.Processors.Contexts; using Squidex.Areas.Api.Config.OpenApi;
using Squidex.Areas.Api.Config.Swagger;
using Squidex.Areas.Api.Controllers.Contents.Models; using Squidex.Areas.Api.Controllers.Contents.Models;
using Squidex.Domain.Apps.Entities.Apps; 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.Swagger; using Squidex.Pipeline.OpenApi;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api.Controllers.Contents.Generator namespace Squidex.Areas.Api.Controllers.Contents.Generator
{ {
public sealed class SchemasSwaggerGenerator public sealed class SchemasOpenApiGenerator
{ {
private readonly UrlsOptions urlOptions; private readonly UrlsOptions urlOptions;
private readonly SwaggerDocumentSettings settings = new SwaggerDocumentSettings(); private readonly OpenApiDocumentGeneratorSettings settings = new OpenApiDocumentGeneratorSettings();
private SwaggerJsonSchemaGenerator schemaGenerator; private OpenApiSchemaGenerator schemaGenerator;
private SwaggerDocument document; private OpenApiDocument document;
private JsonSchema4 statusSchema; private JsonSchema statusSchema;
private JsonSchemaResolver schemaResolver; private JsonSchemaResolver schemaResolver;
public SchemasSwaggerGenerator(IOptions<UrlsOptions> urlOptions, IEnumerable<IDocumentProcessor> documentProcessors) public SchemasOpenApiGenerator(IOptions<UrlsOptions> urlOptions, IEnumerable<IDocumentProcessor> documentProcessors)
{ {
this.urlOptions = urlOptions.Value; this.urlOptions = urlOptions.Value;
@ -48,14 +47,14 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
} }
} }
public async Task<SwaggerDocument> 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, urlOptions, app.Name);
schemaGenerator = new SwaggerJsonSchemaGenerator(settings); schemaGenerator = new OpenApiSchemaGenerator(settings);
schemaResolver = new SwaggerSchemaResolver(document, settings); schemaResolver = new OpenApiSchemaResolver(document, settings);
statusSchema = await GenerateStatusSchemaAsync(); statusSchema = GenerateStatusSchema();
GenerateSchemasOperations(schemas, app); GenerateSchemasOperations(schemas, app);
@ -69,17 +68,17 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
foreach (var processor in settings.DocumentProcessors) foreach (var processor in settings.DocumentProcessors)
{ {
await processor.ProcessAsync(context); processor.Process(context);
} }
return document; return document;
} }
private Task<JsonSchema4> GenerateStatusSchemaAsync() private JsonSchema GenerateStatusSchema()
{ {
var errorType = typeof(ChangeStatusDto); var statusDtoType = typeof(ChangeStatusDto);
return schemaGenerator.GenerateWithReferenceAsync<JsonSchema4>(errorType, Enumerable.Empty<Attribute>(), schemaResolver); return schemaGenerator.Generate(statusDtoType);
} }
private void GenerateSchemasOperations(IEnumerable<ISchemaEntity> schemas, IAppEntity app) private void GenerateSchemasOperations(IEnumerable<ISchemaEntity> schemas, IAppEntity app)
@ -90,16 +89,16 @@ namespace Squidex.Areas.Api.Controllers.Contents.Generator
{ {
var partition = app.PartitionResolver(); var partition = app.PartitionResolver();
new SchemaSwaggerGenerator(document, app.Name, appBasePath, schema, AppendSchema, statusSchema, partition) new SchemaOpenApiGenerator(document, app.Name, appBasePath, schema, AppendSchema, statusSchema, partition)
.GenerateSchemaOperations(); .GenerateSchemaOperations();
} }
} }
private JsonSchema4 AppendSchema(string name, JsonSchema4 schema) private JsonSchema AppendSchema(string name, JsonSchema schema)
{ {
name = char.ToUpperInvariant(name[0]) + name.Substring(1); name = char.ToUpperInvariant(name[0]) + name.Substring(1);
return new JsonSchema4 { Reference = document.Definitions.GetOrAdd(name, schema, (k, c) => c) }; return new JsonSchema { Reference = document.Definitions.GetOrAdd(name, schema, (k, c) => c) };
} }
} }
} }

5
src/Squidex/Areas/Api/Controllers/Docs/DocsController.cs

@ -22,7 +22,10 @@ namespace Squidex.Areas.Api.Controllers.Docs
[Route("docs/")] [Route("docs/")]
public IActionResult Docs() public IActionResult Docs()
{ {
var vm = new DocsVM { Specification = "~/swagger/v1/swagger.json" }; var vm = new DocsVM
{
Specification = "~/swagger/v1/swagger.json"
};
return View(nameof(Docs), vm); return View(nameof(Docs), vm);
} }

13
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs

@ -7,10 +7,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using NJsonSchema; using NJsonSchema;
using NSwag.SwaggerGeneration.Processors; using NSwag.Generation.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts; using NSwag.Generation.Processors.Contexts;
using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -28,7 +27,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
this.ruleRegistry = ruleRegistry; this.ruleRegistry = ruleRegistry;
} }
public async Task ProcessAsync(DocumentProcessorContext context) public void Process(DocumentProcessorContext context)
{ {
try try
{ {
@ -41,14 +40,14 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
JsonInheritanceConverter = new RuleActionConverter(), PropertyName = "actionType" JsonInheritanceConverter = new RuleActionConverter(), PropertyName = "actionType"
}; };
schema.Properties["actionType"] = new JsonProperty schema.Properties["actionType"] = new JsonSchemaProperty
{ {
Type = JsonObjectType.String, IsRequired = true Type = JsonObjectType.String, IsRequired = true
}; };
foreach (var action in ruleRegistry.Actions) foreach (var action in ruleRegistry.Actions)
{ {
var derivedSchema = await context.SchemaGenerator.GenerateAsync(action.Value.Type, context.SchemaResolver); var derivedSchema = context.SchemaGenerator.Generate(action.Value.Type);
var oldName = context.Document.Definitions.FirstOrDefault(x => x.Value == derivedSchema).Key; var oldName = context.Document.Definitions.FirstOrDefault(x => x.Value == derivedSchema).Key;
@ -68,7 +67,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
} }
} }
private static void RemoveFreezable(DocumentProcessorContext context, JsonSchema4 schema) private static void RemoveFreezable(DocumentProcessorContext context, JsonSchema schema)
{ {
context.Document.Definitions.Remove("Freezable"); context.Document.Definitions.Remove("Freezable");

4
src/Squidex/Areas/Api/Startup.cs

@ -6,7 +6,7 @@
// ========================================================================== // ==========================================================================
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Squidex.Areas.Api.Config.Swagger; using Squidex.Areas.Api.Config.OpenApi;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Areas.Api namespace Squidex.Areas.Api
@ -17,7 +17,7 @@ namespace Squidex.Areas.Api
{ {
app.Map(Constants.ApiPrefix, appApi => app.Map(Constants.ApiPrefix, appApi =>
{ {
appApi.UseMySwagger(); appApi.UseMyOpenApi();
appApi.UseMvc(); appApi.UseMvc();
}); });
} }

30
src/Squidex/Pipeline/Swagger/NSwagHelper.cs → src/Squidex/Pipeline/OpenApi/NSwagHelper.cs

@ -13,7 +13,7 @@ using NJsonSchema;
using NSwag; using NSwag;
using Squidex.Web; using Squidex.Web;
namespace Squidex.Pipeline.Swagger namespace Squidex.Pipeline.OpenApi
{ {
public static class NSwagHelper public static class NSwagHelper
{ {
@ -30,16 +30,16 @@ namespace Squidex.Pipeline.Swagger
} }
} }
public static SwaggerDocument CreateApiDocument(HttpContext context, UrlsOptions urlOptions, string appName) public static OpenApiDocument CreateApiDocument(HttpContext context, UrlsOptions urlOptions, string appName)
{ {
var scheme = var scheme =
string.Equals(context.Request.Scheme, "http", StringComparison.OrdinalIgnoreCase) ? string.Equals(context.Request.Scheme, "http", StringComparison.OrdinalIgnoreCase) ?
SwaggerSchema.Http : OpenApiSchema.Http :
SwaggerSchema.Https; OpenApiSchema.Https;
var document = new SwaggerDocument var document = new OpenApiDocument
{ {
Schemes = new List<SwaggerSchema> Schemes = new List<OpenApiSchema>
{ {
scheme scheme
}, },
@ -51,7 +51,7 @@ namespace Squidex.Pipeline.Swagger
{ {
"application/json" "application/json"
}, },
Info = new SwaggerInfo Info = new OpenApiInfo
{ {
Title = $"Squidex API for {appName} App" Title = $"Squidex API for {appName} App"
}, },
@ -66,9 +66,9 @@ namespace Squidex.Pipeline.Swagger
return document; return document;
} }
public static void AddQueryParameter(this SwaggerOperation 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 SwaggerParameter { Type = type, Name = name, Kind = SwaggerParameterKind.Query }; var parameter = new OpenApiParameter { Type = type, Name = name, Kind = OpenApiParameterKind.Query };
if (!string.IsNullOrWhiteSpace(description)) if (!string.IsNullOrWhiteSpace(description))
{ {
@ -78,9 +78,9 @@ namespace Squidex.Pipeline.Swagger
operation.Parameters.Add(parameter); operation.Parameters.Add(parameter);
} }
public static void AddPathParameter(this SwaggerOperation 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 SwaggerParameter { Type = type, Name = name, Kind = SwaggerParameterKind.Path }; var parameter = new OpenApiParameter { Type = type, Name = name, Kind = OpenApiParameterKind.Path };
if (!string.IsNullOrWhiteSpace(description)) if (!string.IsNullOrWhiteSpace(description))
{ {
@ -93,9 +93,9 @@ namespace Squidex.Pipeline.Swagger
operation.Parameters.Add(parameter); operation.Parameters.Add(parameter);
} }
public static void AddBodyParameter(this SwaggerOperation operation, string name, JsonSchema4 schema, string description) public static void AddBodyParameter(this OpenApiOperation operation, string name, JsonSchema schema, string description)
{ {
var parameter = new SwaggerParameter { Schema = schema, Name = name, Kind = SwaggerParameterKind.Body }; var parameter = new OpenApiParameter { Schema = schema, Name = name, Kind = OpenApiParameterKind.Body };
if (!string.IsNullOrWhiteSpace(description)) if (!string.IsNullOrWhiteSpace(description))
{ {
@ -108,9 +108,9 @@ namespace Squidex.Pipeline.Swagger
operation.Parameters.Add(parameter); operation.Parameters.Add(parameter);
} }
public static void AddResponse(this SwaggerOperation operation, string statusCode, string description, JsonSchema4 schema = null) public static void AddResponse(this OpenApiOperation operation, string statusCode, string description, JsonSchema schema = null)
{ {
var response = new SwaggerResponse { Description = description, Schema = schema }; var response = new OpenApiResponse { Description = description, Schema = schema };
operation.Responses.Add(statusCode, response); operation.Responses.Add(statusCode, response);
} }

27
src/Squidex/Squidex.csproj

@ -42,11 +42,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="2.0.1" /> <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.4.0" /> <PackageReference Include="IdentityServer4" Version="2.5.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.4.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.0" />
<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" />
@ -62,21 +62,22 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Data.Edm" Version="5.8.4" /> <PackageReference Include="Microsoft.Data.Edm" Version="5.8.4" />
<PackageReference Include="Microsoft.OData.Core" Version="7.5.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.0" />
<PackageReference Include="Microsoft.Orleans.Client" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.Client" Version="2.3.6" />
<PackageReference Include="Microsoft.Orleans.Core" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.Core" Version="2.3.6" />
<PackageReference Include="Microsoft.Orleans.Core.Abstractions" Version="2.3.2" /> <PackageReference Include="Microsoft.Orleans.Core.Abstractions" Version="2.3.6" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="2.3.2" /> <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="NJsonSchema" Version="9.14.1" /> <PackageReference Include="Namotion.Reflection" Version="1.0.5" />
<PackageReference Include="NSwag.AspNetCore" Version="12.3.1" /> <PackageReference Include="NJsonSchema" Version="10.0.21" />
<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" />
<PackageReference Include="Orleans.Providers.MongoDB" Version="2.4.0" /> <PackageReference Include="Orleans.Providers.MongoDB" Version="2.4.0" />
<PackageReference Include="Orleans.WebHostCompatibilityLayer" Version="2.3.1" /> <PackageReference Include="Orleans.WebHostCompatibilityLayer" Version="2.3.1" />
<PackageReference Include="OrleansDashboard" Version="2.3.1" /> <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.1.6" PrivateAssets="all" /> <PackageReference Include="ReportGenerator" Version="4.2.11" PrivateAssets="all" />
<PackageReference Include="Squidex.ClientLibrary" Version="2.10.0" /> <PackageReference Include="Squidex.ClientLibrary" Version="3.1.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" />

4
src/Squidex/WebStartup.cs

@ -12,7 +12,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Migrate_01; using Migrate_01;
using Squidex.Areas.Api; using Squidex.Areas.Api;
using Squidex.Areas.Api.Config.Swagger; using Squidex.Areas.Api.Config.OpenApi;
using Squidex.Areas.Api.Controllers.Contents; using Squidex.Areas.Api.Controllers.Contents;
using Squidex.Areas.Api.Controllers.News; using Squidex.Areas.Api.Controllers.News;
using Squidex.Areas.Api.Controllers.UI; using Squidex.Areas.Api.Controllers.UI;
@ -69,11 +69,11 @@ namespace Squidex
services.AddMyIdentityServer(); services.AddMyIdentityServer();
services.AddMyInfrastructureServices(config); services.AddMyInfrastructureServices(config);
services.AddMyLoggingServices(config); services.AddMyLoggingServices(config);
services.AddMyOpenApiSettings();
services.AddMyMigrationServices(); services.AddMyMigrationServices();
services.AddMyRuleServices(); services.AddMyRuleServices();
services.AddMySerializers(); services.AddMySerializers();
services.AddMyStoreServices(config); services.AddMyStoreServices(config);
services.AddMySwaggerSettings();
services.AddMySubscriptionServices(config); services.AddMySubscriptionServices(config);
services.Configure<ContentOptions>( services.Configure<ContentOptions>(

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateJsonSchema/JsonSchemaTests.cs

@ -24,7 +24,7 @@ namespace Squidex.Domain.Apps.Core.Operations.GenerateJsonSchema
{ {
var languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN); var languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN);
var jsonSchema = schema.BuildJsonSchema(languagesConfig.ToResolver(), (n, s) => new JsonSchema4 { Reference = s }); var jsonSchema = schema.BuildJsonSchema(languagesConfig.ToResolver(), (n, s) => new JsonSchema { Reference = s });
var jsonProperties = AllPropertyNames(jsonSchema); var jsonProperties = AllPropertyNames(jsonSchema);
void CheckField(IField field) void CheckField(IField field)
@ -58,16 +58,16 @@ namespace Squidex.Domain.Apps.Core.Operations.GenerateJsonSchema
{ {
var languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN); var languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN);
var jsonSchema = schema.BuildJsonSchema(languagesConfig.ToResolver(), (n, s) => new JsonSchema4 { Reference = s }); var jsonSchema = schema.BuildJsonSchema(languagesConfig.ToResolver(), (n, s) => new JsonSchema { Reference = s });
Assert.NotNull(new ContentSchemaBuilder().CreateContentSchema(schema, jsonSchema)); Assert.NotNull(new ContentSchemaBuilder().CreateContentSchema(schema, jsonSchema));
} }
private static HashSet<string> AllPropertyNames(JsonSchema4 schema) private static HashSet<string> AllPropertyNames(JsonSchema schema)
{ {
var result = new HashSet<string>(); var result = new HashSet<string>();
void AddProperties(JsonSchema4 current) void AddProperties(JsonSchema current)
{ {
if (current != null) if (current != null)
{ {

4
tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs

@ -36,7 +36,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
[Fact] [Fact]
public void Should_catch_script_syntax_errors() public void Should_catch_script_syntax_errors()
{ {
Assert.Throws<ValidationException>(() => sut.Execute(new ScriptContext(), "x => x")); Assert.Throws<ValidationException>(() => sut.Execute(new ScriptContext(), "invalid()"));
} }
[Fact] [Fact]
@ -68,7 +68,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
var content = new NamedContentData(); var content = new NamedContentData();
var context = new ScriptContext { Data = content }; var context = new ScriptContext { Data = content };
Assert.Throws<ValidationException>(() => sut.ExecuteAndTransform(context, "x => x")); Assert.Throws<ValidationException>(() => sut.ExecuteAndTransform(context, "invalid()"));
} }
[Fact] [Fact]

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

@ -14,8 +14,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.6.0" /> <PackageReference Include="FluentAssertions" Version="5.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.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" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />

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

@ -18,9 +18,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.6.0" /> <PackageReference Include="FluentAssertions" Version="5.7.0" />
<PackageReference Include="GraphQL" Version="2.4.0" /> <PackageReference Include="GraphQL" Version="2.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.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" />
<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" />

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

@ -13,8 +13,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.6.0" /> <PackageReference Include="FluentAssertions" Version="5.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.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" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />

4
tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj

@ -19,11 +19,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="5.6.0" /> <PackageReference Include="FluentAssertions" Version="5.7.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" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.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" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />

8
tests/Squidex.Web.Tests/Squidex.Web.Tests.csproj

@ -12,10 +12,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="5.1.1" /> <PackageReference Include="FakeItEasy" Version="5.1.1" />
<PackageReference Include="IdentityServer4" Version="2.4.0" /> <PackageReference Include="IdentityServer4" Version="2.5.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.4.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NJsonSchema" Version="9.14.1" /> <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" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />

Loading…
Cancel
Save