From 8d89ab16247affe809a0e6993ae6c3b94e991798 Mon Sep 17 00:00:00 2001 From: Timothy Date: Sat, 4 Jul 2026 08:02:28 +0200 Subject: [PATCH] fix(api): add nullable context to #96/#98 DTOs; regen OpenAPI + SPA types ChannelResponseModel and BulkChannelRequests DTOs lacked file-scoped #nullable enable, so the OpenAPI generator emitted every string property as a ["null","string"] union (project Nullable default is disable), polluting SPA typegen with needless `| null` unions. ChannelStateResponseModel already complied with this convention (precedent: PlayoutResponseModel). All properties in both files are always populated (never null in practice), so no property needed to become explicitly optional/nullable - just adding #nullable enable was sufficient to clean up the generated schema. Co-Authored-By: Claude Fable 5 --- .../Api/Channels/ChannelResponseModel.cs | 3 +- .../Api/Requests/BulkChannelRequests.cs | 1 + ErsatzTV/wwwroot/openapi/v1.json | 60 ++++--------------- web/src/api/generated/v1.d.ts | 24 ++++---- 4 files changed, 27 insertions(+), 61 deletions(-) diff --git a/ErsatzTV.Core/Api/Channels/ChannelResponseModel.cs b/ErsatzTV.Core/Api/Channels/ChannelResponseModel.cs index 6301e0903..55ceab9d8 100644 --- a/ErsatzTV.Core/Api/Channels/ChannelResponseModel.cs +++ b/ErsatzTV.Core/Api/Channels/ChannelResponseModel.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +#nullable enable +using Newtonsoft.Json; namespace ErsatzTV.Core.Api.Channels; diff --git a/ErsatzTV/Controllers/Api/Requests/BulkChannelRequests.cs b/ErsatzTV/Controllers/Api/Requests/BulkChannelRequests.cs index c9bcc9ca8..4a7a875f5 100644 --- a/ErsatzTV/Controllers/Api/Requests/BulkChannelRequests.cs +++ b/ErsatzTV/Controllers/Api/Requests/BulkChannelRequests.cs @@ -1,3 +1,4 @@ +#nullable enable using ErsatzTV.Application.Channels; namespace ErsatzTV.Controllers.Api.Requests; diff --git a/ErsatzTV/wwwroot/openapi/v1.json b/ErsatzTV/wwwroot/openapi/v1.json index 9de14c959..e1a7159ea 100644 --- a/ErsatzTV/wwwroot/openapi/v1.json +++ b/ErsatzTV/wwwroot/openapi/v1.json @@ -3916,10 +3916,7 @@ "type": "object", "properties": { "channelIds": { - "type": [ - "null", - "array" - ], + "type": "array", "items": { "type": "integer", "format": "int32" @@ -3935,20 +3932,14 @@ "type": "object", "properties": { "channelIds": { - "type": [ - "null", - "array" - ], + "type": "array", "items": { "type": "integer", "format": "int32" } }, "group": { - "type": [ - "null", - "string" - ] + "type": "string" } } }, @@ -3964,10 +3955,7 @@ "format": "int32" }, "number": { - "type": [ - "null", - "string" - ] + "type": "string" } } }, @@ -3978,10 +3966,7 @@ "type": "object", "properties": { "channels": { - "type": [ - "null", - "array" - ], + "type": "array", "items": { "$ref": "#/components/schemas/BulkRenumberChannelRequest" } @@ -4143,50 +4128,29 @@ "format": "int32" }, "number": { - "type": [ - "null", - "string" - ] + "type": "string" }, "sortNumber": { "type": "number", "format": "double" }, "name": { - "type": [ - "null", - "string" - ] + "type": "string" }, "group": { - "type": [ - "null", - "string" - ] + "type": "string" }, "categories": { - "type": [ - "null", - "string" - ] + "type": "string" }, "fFmpegProfile": { - "type": [ - "null", - "string" - ] + "type": "string" }, "language": { - "type": [ - "null", - "string" - ] + "type": "string" }, "streamingMode": { - "type": [ - "null", - "string" - ] + "type": "string" }, "isEnabled": { "type": "boolean" diff --git a/web/src/api/generated/v1.d.ts b/web/src/api/generated/v1.d.ts index 2fb1d37c9..af5bc052f 100644 --- a/web/src/api/generated/v1.d.ts +++ b/web/src/api/generated/v1.d.ts @@ -27,18 +27,18 @@ export interface components { "contentType": string; }; "BulkDeleteChannelsRequest": { - "channelIds": null | Array; + "channelIds": Array; }; "BulkMoveChannelsToGroupRequest": { - "channelIds": null | Array; - "group": null | string; + "channelIds": Array; + "group": string; }; "BulkRenumberChannelRequest": { "id": number; - "number": null | string; + "number": string; }; "BulkRenumberChannelsRequest": { - "channels": null | Array; + "channels": Array; }; "ChannelGuideChannelResponseModel": { "number": string; @@ -69,14 +69,14 @@ export interface components { "ChannelPlayoutSource": "Generated" | "Mirror"; "ChannelResponseModel": { "id": number; - "number": null | string; + "number": string; "sortNumber": number; - "name": null | string; - "group": null | string; - "categories": null | string; - "fFmpegProfile": null | string; - "language": null | string; - "streamingMode": null | string; + "name": string; + "group": string; + "categories": string; + "fFmpegProfile": string; + "language": string; + "streamingMode": string; "isEnabled": boolean; "showInEpg": boolean; };