Skip to content

Commit dd1c4fb

Browse files
committed
Merge branch 'v14/dev' into release/14.0
2 parents 4ca2c81 + 2080fd5 commit dd1c4fb

File tree

3,337 files changed

+16139
-295418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,337 files changed

+16139
-295418
lines changed

Directory.Packages.props

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@
7676
<PackageVersion Include="Serilog.Sinks.Map" Version="1.0.2" />
7777
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.2" />
7878
<PackageVersion Include="SixLabors.ImageSharp.Web" Version="3.1.0" />
79-
<PackageVersion Include="Smidge.InMemory" Version="4.3.0" />
80-
<PackageVersion Include="Smidge.Nuglify" Version="4.3.0" />
8179
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
8280
</ItemGroup>
8381
<!-- Transitive pinned versions (only required because our direct dependencies have vulnerable versions of transitive dependencies) -->

build/azure-pipelines.yml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,6 @@ stages:
8585
retryCountOnTaskFailure: 3
8686
inputs:
8787
versionSpec: $(nodeVersion)
88-
- task: Cache@2
89-
displayName: Cache node_modules
90-
inputs:
91-
key: '"npm_client" | "$(Agent.OS)" | $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/package-lock.json'
92-
restoreKeys: |
93-
"npm_client" | "$(Agent.OS)"
94-
"npm_client"
95-
path: $(npm_config_cache)
96-
- script: npm ci --no-fund --no-audit --prefer-offline
97-
workingDirectory: src/Umbraco.Web.UI.Client
98-
displayName: Run npm ci (Backoffice)
99-
- task: gulp@0
100-
displayName: Run gulp build (Backoffice)
101-
inputs:
102-
gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js
103-
targets: coreBuild
104-
workingDirectory: src/Umbraco.Web.UI.Client
10588
- script: npm ci --no-fund --no-audit --prefer-offline
10689
displayName: Run npm ci (Login)
10790
workingDirectory: src/Umbraco.Web.UI.Login
@@ -111,6 +94,10 @@ stages:
11194
- script: npm ci --no-fund --no-audit --prefer-offline
11295
displayName: Run npm ci (Bellissima)
11396
workingDirectory: src/Umbraco.Web.UI.New.Client
97+
- script: npm run generate:api-local
98+
displayName: Generate API models (Bellissima)
99+
workingDirectory: src/Umbraco.Web.UI.New.Client
100+
enabled: false
114101
- script: npm run build:for:cms
115102
displayName: Run build (Bellissima)
116103
workingDirectory: src/Umbraco.Web.UI.New.Client
@@ -238,7 +225,7 @@ stages:
238225
- task: Cache@2
239226
displayName: Cache node_modules
240227
inputs:
241-
key: '"npm_client" | "$(Agent.OS)"| $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/package-lock.json | $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client/package-lock.json'
228+
key: '"npm_client" | "$(Agent.OS)"| $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client/package-lock.json'
242229
restoreKeys: |
243230
"npm_client" | "$(Agent.OS)"
244231
"npm_client"

src/Umbraco.Cms.Api.Common/OpenApi/OperationIdSelector.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
11
using Asp.Versioning;
22
using Microsoft.AspNetCore.Mvc.ApiExplorer;
33
using Microsoft.AspNetCore.Mvc.Controllers;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Options;
6+
using Umbraco.Cms.Core.DependencyInjection;
47
using Umbraco.Extensions;
58

69
namespace Umbraco.Cms.Api.Common.OpenApi;
710

811
public class OperationIdSelector : IOperationIdSelector
912
{
13+
private readonly UmbracoOperationIdSettings _umbracoOperationIdSettings;
14+
15+
[Obsolete("Use non obsolete constructor")]
16+
public OperationIdSelector() : this(StaticServiceProvider.Instance.GetRequiredService<IOptions<UmbracoOperationIdSettings>>())
17+
{
18+
}
19+
20+
public OperationIdSelector(IOptions<UmbracoOperationIdSettings> umbracoOperationIdSettings)
21+
{
22+
_umbracoOperationIdSettings = umbracoOperationIdSettings.Value;
23+
}
24+
1025
public virtual string? OperationId(ApiDescription apiDescription, ApiVersioningOptions apiVersioningOptions)
1126
{
12-
if (apiDescription.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor
13-
|| controllerActionDescriptor.ControllerTypeInfo.Namespace?.StartsWith("Umbraco.Cms.Api") is not true)
27+
if (apiDescription.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
28+
{
29+
return null;
30+
}
31+
32+
var controllerTypeInfoNamespace = controllerActionDescriptor.ControllerTypeInfo.Namespace;
33+
if (controllerTypeInfoNamespace is not null && _umbracoOperationIdSettings.NameSpacePrefixes.Any(prefix => controllerTypeInfoNamespace.StartsWith(prefix)) is false)
1434
{
1535
return null;
1636
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Umbraco.Cms.Api.Common.OpenApi;
2+
3+
public class UmbracoOperationIdSettings
4+
{
5+
private HashSet<string> _nameSpacePrefixes = new HashSet<string>()
6+
{
7+
"Umbraco.Cms.Api"
8+
};
9+
10+
public IReadOnlySet<string> NameSpacePrefixes
11+
{
12+
get => _nameSpacePrefixes;
13+
}
14+
15+
public bool AddNameSpacePrefix(string prefix) => _nameSpacePrefixes.Add(prefix);
16+
}

src/Umbraco.Cms.Api.Management/Configuration/ConfigureUmbracoManagementApiSwaggerGenOptions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public void Configure(SwaggerGenOptions swaggerGenOptions)
3434
swaggerGenOptions.UseOneOfForPolymorphism();
3535
swaggerGenOptions.UseAllOfForInheritance();
3636

37+
// Ensure all types that implements the IOpenApiDiscriminator have a $type property in the OpenApi schema with the default value (The class name) that is expected by the server
38+
swaggerGenOptions.SelectDiscriminatorNameUsing(type => typeof(IOpenApiDiscriminator).IsAssignableFrom(type) ? "$type" : null);
39+
swaggerGenOptions.SelectDiscriminatorValueUsing(type => typeof(IOpenApiDiscriminator).IsAssignableFrom(type) ? type.Name : null);
40+
41+
3742
swaggerGenOptions.AddSecurityDefinition(
3843
ManagementApiConfiguration.ApiSecurityName,
3944
new OpenApiSecurityScheme
@@ -55,7 +60,7 @@ public void Configure(SwaggerGenOptions swaggerGenOptions)
5560

5661
// Sets Security requirement on backoffice apis
5762
swaggerGenOptions.OperationFilter<BackOfficeSecurityRequirementsOperationFilter>();
63+
swaggerGenOptions.OperationFilter<NotificationHeaderFilter>();
5864
swaggerGenOptions.SchemaFilter<RequireNonNullablePropertiesSchemaFilter>();
5965
}
60-
6166
}

src/Umbraco.Cms.Api.Management/Controllers/DataType/DataTypeControllerBase.cs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,48 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType;
1616
public abstract class DataTypeControllerBase : ManagementApiControllerBase
1717
{
1818
protected IActionResult DataTypeOperationStatusResult(DataTypeOperationStatus status) =>
19-
status switch
19+
OperationStatusResult(status, problemDetailsBuilder => status switch
2020
{
21-
DataTypeOperationStatus.InvalidConfiguration => BadRequest(new ProblemDetailsBuilder()
21+
DataTypeOperationStatus.InvalidConfiguration => BadRequest(problemDetailsBuilder
2222
.WithTitle("Invalid data type configuration")
2323
.WithDetail("The supplied data type configuration was not valid. Please see the log for more details.")
2424
.Build()),
25-
DataTypeOperationStatus.NotFound => DataTypeNotFound(),
26-
DataTypeOperationStatus.InvalidName => BadRequest(new ProblemDetailsBuilder()
25+
DataTypeOperationStatus.NotFound => DataTypeNotFound(problemDetailsBuilder),
26+
DataTypeOperationStatus.InvalidName => BadRequest(problemDetailsBuilder
2727
.WithTitle("Invalid data type name")
2828
.WithDetail("The data type name must be non-empty and no longer than 255 characters.")
2929
.Build()),
30-
DataTypeOperationStatus.ParentNotContainer => BadRequest(new ProblemDetailsBuilder()
30+
DataTypeOperationStatus.ParentNotContainer => BadRequest(problemDetailsBuilder
3131
.WithTitle("parent id is not a container")
3232
.WithDetail("The parent id does not represent a container.")
3333
.Build()),
34-
DataTypeOperationStatus.DuplicateKey => BadRequest(new ProblemDetailsBuilder()
34+
DataTypeOperationStatus.DuplicateKey => BadRequest(problemDetailsBuilder
3535
.WithTitle("The id is already used")
3636
.WithDetail("The data type id must be unique.")
3737
.Build()),
38-
DataTypeOperationStatus.CancelledByNotification => BadRequest(new ProblemDetailsBuilder()
38+
DataTypeOperationStatus.CancelledByNotification => BadRequest(problemDetailsBuilder
3939
.WithTitle("Cancelled by notification")
4040
.WithDetail("A notification handler prevented the data type operation.")
4141
.Build()),
42-
DataTypeOperationStatus.PropertyEditorNotFound => NotFound(
43-
new ProblemDetailsBuilder()
44-
.WithTitle("The targeted property editor was not found.")
45-
.Build()),
46-
DataTypeOperationStatus.ParentNotFound => NotFound(new ProblemDetailsBuilder()
47-
.WithTitle("The targeted parent for the data type operation was not found.")
48-
.Build()),
49-
DataTypeOperationStatus.NonDeletable => BadRequest(new ProblemDetailsBuilder()
42+
DataTypeOperationStatus.PropertyEditorNotFound => NotFound(problemDetailsBuilder
43+
.WithTitle("The targeted property editor was not found.")
44+
.Build()),
45+
DataTypeOperationStatus.ParentNotFound => NotFound(problemDetailsBuilder
46+
.WithTitle("The targeted parent for the data type operation was not found.")
47+
.Build()),
48+
DataTypeOperationStatus.NonDeletable => BadRequest(problemDetailsBuilder
5049
.WithTitle("The data type is non-deletable")
5150
.WithDetail("The specified data type is required by the system and cannot be deleted.")
5251
.Build()),
53-
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
52+
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
5453
.WithTitle("Unknown data type operation status.")
5554
.Build()),
56-
};
55+
});
56+
57+
protected IActionResult DataTypeNotFound() => OperationStatusResult(DataTypeOperationStatus.NotFound, DataTypeNotFound);
5758

58-
protected IActionResult DataTypeNotFound() => NotFound(new ProblemDetailsBuilder()
59-
.WithTitle("The data type could not be found")
60-
.Build());
59+
private IActionResult DataTypeNotFound(ProblemDetailsBuilder problemDetailsBuilder)
60+
=> NotFound(problemDetailsBuilder
61+
.WithTitle("The data type could not be found")
62+
.Build());
6163
}

src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/ChildrenDataTypeTreeController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Microsoft.AspNetCore.Mvc;
44
using Umbraco.Cms.Core.Services;
55
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
6-
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
6+
using Umbraco.Cms.Api.Management.ViewModels.Tree;
77

88
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
99

src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using Umbraco.Cms.Core.Services;
77
using Umbraco.Cms.Api.Management.Controllers.Tree;
88
using Umbraco.Cms.Api.Management.Routing;
9-
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
9+
using Umbraco.Cms.Api.Management.ViewModels.Tree;
1010
using Umbraco.Cms.Web.Common.Authorization;
1111
using Umbraco.Extensions;
1212

src/Umbraco.Cms.Api.Management/Controllers/Dictionary/AllDictionaryController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public AllDictionaryController(IDictionaryItemService dictionaryItemService, IUm
2525
[HttpGet]
2626
[MapToApiVersion("1.0")]
2727
[ProducesResponseType(typeof(PagedViewModel<DictionaryOverviewResponseModel>), StatusCodes.Status200OK)]
28-
public async Task<ActionResult<PagedViewModel<DictionaryOverviewResponseModel>>> All(int skip = 0, int take = 100)
28+
public async Task<ActionResult<PagedViewModel<DictionaryOverviewResponseModel>>> All(string? filter = null, int skip = 0, int take = 100)
2929
{
3030
// unfortunately we can't paginate here...we'll have to get all and paginate in memory
31-
IDictionaryItem[] items = (await _dictionaryItemService.GetDescendantsAsync(Constants.System.RootKey)).ToArray();
31+
IDictionaryItem[] items = (await _dictionaryItemService.GetDescendantsAsync(Constants.System.RootKey, filter)).ToArray();
3232
var model = new PagedViewModel<DictionaryOverviewResponseModel>
3333
{
3434
Total = items.Length,

src/Umbraco.Cms.Api.Management/Controllers/Dictionary/ByKeyDictionaryController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public async Task<IActionResult> ByKey(Guid id)
2929
IDictionaryItem? dictionary = await _dictionaryItemService.GetAsync(id);
3030
if (dictionary == null)
3131
{
32-
return DictionaryNotFound();
32+
return DictionaryItemNotFound();
3333
}
3434

3535
return Ok(await _dictionaryPresentationFactory.CreateDictionaryItemViewModelAsync(dictionary));

0 commit comments

Comments
 (0)