Compare commits

...
Author SHA1 Message Date
Laura Neto 09acba310f Merge branch 'v18/feature/delivery-api-document-type-schema-generation-clean' into v18/task/delivery-api-openapi-sample-content 2026-05-06 11:16:44 +02:00
Laura Neto 93a13648b7 Qualify properties model schema IDs by item type
Document, element, and media types share the same alias namespace
across content/media (a doc-type and a media-type can use the same
alias), so a "{Schema}PropertiesModel" naming scheme could collide.

Properties model schemas now follow the same Content/Element/Media
suffix as their parent *Model schema:

- Document type: ArticlePageContentPropertiesModel
- Element type:  TestElementElementPropertiesModel
- Media type:    VideoMediaPropertiesModel

Composition references look up each composition's own IsElement so
that a doc-type composing an element-type (allowed in the UI) still
references the correct ElementPropertiesModel schema.
2026-05-06 11:15:46 +02:00
Laura Neto 417eae32a7 Preserve casing of content type aliases in OpenAPI schema IDs
Replaces the legacy ModelsBuilder-style ToCleanString tokenizer with
ToFirstUpperInvariant. The tokenizer split aliases on case boundaries
and mangled capital-letter runs (e.g. "xMLSitemap" -> "XMlsitemap"),
making the typed schema names harder to read for OpenAPI consumers.
Since content type aliases are already valid identifiers, only the
first character needs uppercasing.

Also adds an "xMLSitemap" sample type to the integration tests to
cover the casing-preservation behavior.
2026-05-06 10:48:10 +02:00
Laura Neto c45813bebd Drop additionalProperties: false from typed schemas
JSON Schema 2020-12 (mandated by OpenAPI 3.1) does not let additionalProperties look through allOf, so a strict validator rejects every inherited field on the composed *ResponseModel/*Model/*PropertiesModel schemas. Most code generators silently ignore it, but the document is technically invalid and the constraint would be a lie anyway since Umbraco can grow new properties in non-major releases.

Removed from all four schema construction sites (response, content type, properties, and the interface-based fallback) and regenerated the affected snapshots.
2026-05-06 10:22:22 +02:00
Laura Neto 074d2ea9f0 Updated expected contracts following code adjustments 2026-05-06 09:49:04 +02:00
Andy Butland c45a79bcd7 Allows nulls at property reference sites without mutating any shared component schema.
Avoid unnecessary re-get of the JsonTypeInfo for the default case.
2026-05-06 08:04:35 +02:00
Laura Neto c6140ed807 Merge remote-tracking branch 'origin/v18/dev' into v18/feature/delivery-api-document-type-schema-generation-clean 2026-05-05 16:42:32 +02:00
Laura Neto 1eb0ec9755 Merge branch 'v18/dev' into v18/feature/delivery-api-document-type-schema-generation-clean
# Conflicts:
#	tests/Umbraco.Tests.Integration/Umbraco.Api.Delivery/OpenApi/ExpectedContracts/default.json
2026-05-05 16:41:33 +02:00
Laura Neto 61ce9e70e9 Merge remote-tracking branch 'origin/v18/dev' into v18/feature/delivery-api-document-type-schema-generation-clean 2026-05-04 23:10:54 +02:00
Laura Neto ecce15c39b Drop default JsonDerivedType registrations from Delivery API interfaces
Removes the [JsonDerivedType] attributes from IApiContent,
IApiContentResponse, and IApiElement. Without them System.Text.Json
configures no polymorphism by default, so wire payloads stop carrying
$type fields and the OpenAPI spec stops emitting a discriminator on
the generic schemas - matching v17 Delivery API behaviour. Consumers
that need polymorphic serialization can still register derived types
via ContentJsonTypeResolverBase.

Snapshots regenerated.
2026-05-04 23:10:02 +02:00
Laura Neto 085fcda2ba Stop registering media derived types in the JSON resolver
ContentJsonTypeResolverBase.GetDerivedTypes goes back to returning
empty. Previously it registered ApiMediaWithCrops and
ApiMediaWithCropsResponse as derived types of their interfaces, which
made every consumer of the resolver (the Delivery API and webhooks)
emit a $type discriminator on media payloads, even when the typed
schema feature was disabled.

The Delivery API still needs a base schema for the typed media
schemas to extend via allOf. Since the concrete media classes are
internal to Umbraco.Infrastructure and cannot be referenced from
[JsonDerivedType] in Core, ContentTypeSchemaTransformer now builds
that base from the interface's own properties when the interface has
no [JsonDerivedType] entries. Content/element interfaces are
unaffected and keep using their declared concrete derived types.

Snapshots regenerated.
2026-05-04 20:54:40 +02:00
Laura Neto e0abfcb4b0 Honour Delivery API allow/deny list in typed OpenAPI schemas
ContentTypeSchemaTransformer now filters DocumentTypes through
DeliveryApiSettings.IsAllowedContentType so document types blocked
by AllowedContentTypeAliases / DisallowedContentTypeAliases no longer
leak into the polymorphic union or discriminator mapping.
2026-05-04 18:42:34 +02:00
Laura NetoandGitHub 5bd22410a6 Merge branch 'v18/dev' into v18/feature/delivery-api-document-type-schema-generation 2026-05-04 15:20:30 +02:00
Laura Neto 16f6e3a4b2 Add Delivery API client test projects 2026-05-04 15:06:00 +02:00
Laura NetoandGitHub 308369452d Merge branch 'v18/dev' into v18/feature/delivery-api-document-type-schema-generation 2026-05-04 11:42:38 +02:00
Laura Neto f97db75db0 Delivery API: Generate typed OpenAPI schemas per content type 2026-05-01 10:48:27 +02:00
103 changed files with 27194 additions and 51 deletions
+2 -1
View File
@@ -80,7 +80,8 @@ tools/docfx/
/src/Umbraco.Web.UI/wwwroot/[Mm]edia/
/src/Umbraco.Web.UI/App_Code/
/src/Umbraco.Web.UI/App_Plugins/
/src/Umbraco.Web.UI/[Uu]mbraco/[Dd]ata/
/src/Umbraco.Web.UI/[Uu]mbraco/[Dd]ata/*
!/src/Umbraco.Web.UI/[Uu]mbraco/[Dd]ata/Umbraco.Sample.sqlite.db
/src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ogs/
/src/Umbraco.Web.UI/[Uu]mbraco/[Mm]odels/
/src/Umbraco.Web.UI/Views/
@@ -1,7 +1,9 @@
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Common.Configuration;
using Umbraco.Cms.Api.Common.OpenApi;
using Umbraco.Cms.Api.Delivery.OpenApi.Transformers;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Api.Delivery.Configuration;
@@ -10,6 +12,17 @@ namespace Umbraco.Cms.Api.Delivery.Configuration;
/// </summary>
internal class ConfigureUmbracoDeliveryApiOpenApiOptions : ConfigureUmbracoOpenApiOptionsBase
{
private readonly DeliveryApiSettings _deliveryApiSettings;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigureUmbracoDeliveryApiOpenApiOptions"/> class.
/// </summary>
/// <param name="deliveryApiSettings">The Delivery API settings.</param>
public ConfigureUmbracoDeliveryApiOpenApiOptions(IOptions<DeliveryApiSettings> deliveryApiSettings)
{
_deliveryApiSettings = deliveryApiSettings.Value;
}
/// <inheritdoc />
protected override string ApiName => DeliveryApiConfiguration.ApiName;
@@ -38,5 +51,12 @@ internal class ConfigureUmbracoDeliveryApiOpenApiOptions : ConfigureUmbracoOpenA
options.AddOperationTransformer<MimeTypesTransformer>();
options.AddOperationTransformer<ContentApiTransformer>();
options.AddOperationTransformer<MediaApiTransformer>();
if (_deliveryApiSettings.OpenApi.GenerateContentTypeSchemas)
{
options
.AddSchemaTransformer<ContentTypeSchemaTransformer>()
.AddDocumentTransformer<ContentTypeSchemaTransformer>();
}
}
}
@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi;
namespace Umbraco.Cms.Api.Delivery.OpenApi.Extensions;
/// <summary>
/// Provides extension methods for <see cref="OpenApiSchemaTransformerContext"/>.
/// </summary>
internal static class OpenApiSchemaTransformerContextExtensions
{
/// <summary>
/// Gets the OpenAPI document from the context, throwing if it is null.
/// </summary>
/// <param name="context">The schema transformer context.</param>
/// <returns>The OpenAPI document.</returns>
/// <exception cref="InvalidOperationException">Thrown when the document is null.</exception>
public static OpenApiDocument GetRequiredDocument(this OpenApiSchemaTransformerContext context)
=> context.Document ?? throw new InvalidOperationException("OpenAPI document context is required for schema registration.");
}
@@ -0,0 +1,691 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi;
using Umbraco.Cms.Api.Common.Configuration;
using Umbraco.Cms.Api.Delivery.OpenApi.Extensions;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.DeliveryApi;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Delivery.OpenApi.Transformers;
/// <summary>
/// Transforms the OpenAPI document to add schemas for the instance's document types.
/// </summary>
/// <remarks>
/// <para>
/// This transformer implements both <see cref="IOpenApiSchemaTransformer"/> and <see cref="IOpenApiDocumentTransformer"/>
/// to handle schema generation in two phases:
/// </para>
/// <para>
/// <b>Phase 1 - Schema Transformation:</b> When the schema transformer encounters types like
/// <see cref="IApiContentResponse"/> or <see cref="IApiMediaWithCrops"/>, it generates content-type-specific
/// schemas (e.g., "ArticleContentResponseModel") and registers them as components in the OpenAPI document.
/// </para>
/// <para>
/// <b>Circular Reference Handling:</b> Content type schemas can reference each other (e.g., a "Page"
/// might have a property of type "Article", which might reference "Page" again). To prevent infinite recursion
/// during schema generation, we use a placeholder pattern:
/// <list type="bullet">
/// <item>When generating a schema, we track its ID in <c>_handledSchemas</c></item>
/// <item>If we encounter the same schema ID again (circular reference), we return a temporary placeholder
/// schema with metadata marking it for later replacement</item>
/// <item>The placeholder contains a <c>x-recursive-ref</c> metadata key with the target schema ID</item>
/// </list>
/// </para>
/// <para>
/// <b>Phase 2 - Document Transformation:</b> After all schemas are generated, the document transformer
/// resolves inline schemas into proper <c>$ref</c> references. This handles two cases:
/// <list type="bullet">
/// <item>Circular reference placeholders (marked with <c>x-recursive-ref</c>) created during Phase 1</item>
/// <item>Componentized schemas (marked with <c>x-schema-id</c>) that the framework did not automatically
/// resolve to <c>$ref</c> — this can happen for schemas reached through properties or composition
/// rather than as direct API response types</item>
/// </list>
/// This is done by <see cref="ResolveSchemaReferences(OpenApiDocument, IOpenApiSchema)"/> which recursively walks
/// through all schemas and substitutes matching entries with <see cref="OpenApiSchemaReference"/> instances.
/// </para>
/// </remarks>
public sealed class ContentTypeSchemaTransformer : IOpenApiSchemaTransformer, IOpenApiDocumentTransformer
{
// Metadata keys
private const string RecursiveRefMetadataKey = "x-recursive-ref";
private const string SchemaIdMetadataKey = "x-schema-id";
// Schema ID suffixes
private const string ResponseModelSuffix = "ResponseModel";
private const string ModelSuffix = "Model";
private const string ContentSuffix = "Content";
private const string ElementSuffix = "Element";
private const string MediaSuffix = "Media";
private const string MediaWithCropsSuffix = "MediaWithCrops";
private const string PropertiesModelSuffix = "PropertiesModel";
private readonly IContentTypeSchemaService _contentTypeSchemaService;
private readonly IOptionsMonitor<DeliveryApiSettings> _deliveryApiSettings;
private readonly ILogger<ContentTypeSchemaTransformer> _logger;
private readonly IJsonTypeInfoResolver _jsonTypeInfoResolver;
/// <summary>
/// Tracks schema IDs that have been or are being generated to detect circular references.
/// When a schema ID is encountered a second time, a placeholder is returned instead of recursing infinitely.
/// </summary>
private readonly HashSet<string> _handledSchemas = [];
private readonly JsonSerializerOptions _serializerOptions;
/// <summary>
/// Initializes a new instance of the <see cref="ContentTypeSchemaTransformer"/> class.
/// </summary>
/// <param name="contentTypeSchemaService">The content type info service.</param>
/// <param name="jsonOptionsMonitor">The JSON options monitor.</param>
/// <param name="deliveryApiSettings">The Delivery API settings, used to honour the allow/deny content type list.</param>
/// <param name="logger">The logger.</param>
public ContentTypeSchemaTransformer(
IContentTypeSchemaService contentTypeSchemaService,
IOptionsMonitor<JsonOptions> jsonOptionsMonitor,
IOptionsMonitor<DeliveryApiSettings> deliveryApiSettings,
ILogger<ContentTypeSchemaTransformer> logger)
{
_contentTypeSchemaService = contentTypeSchemaService;
_deliveryApiSettings = deliveryApiSettings;
_logger = logger;
_serializerOptions = jsonOptionsMonitor
.Get(Constants.JsonOptionsNames.DeliveryApi)
.SerializerOptions;
_jsonTypeInfoResolver = _serializerOptions.TypeInfoResolver
?? throw new InvalidOperationException("The JSON serializer options must have a TypeInfoResolver configured.");
}
private IReadOnlyCollection<ContentTypeSchemaInfo> DocumentTypes
=> field ??= FilterAllowedDocumentTypes(_contentTypeSchemaService.GetDocumentTypes());
private IReadOnlyCollection<ContentTypeSchemaInfo> MediaTypes
=> field ??= _contentTypeSchemaService.GetMediaTypes();
/// <inheritdoc />
public Task TransformAsync(
OpenApiDocument document,
OpenApiDocumentTransformerContext context,
CancellationToken cancellationToken)
{
if (document.Components?.Schemas is not { Count: > 0 })
{
return Task.CompletedTask;
}
foreach (IOpenApiSchema componentsSchema in document.Components.Schemas.Values)
{
ResolveSchemaReferences(document, componentsSchema);
}
return Task.CompletedTask;
}
/// <inheritdoc />
public async Task TransformAsync(
OpenApiSchema schema,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
switch (context.JsonTypeInfo.Type)
{
case var type when type == typeof(IApiContentResponse):
await ApplyPolymorphicContentType(
schema,
context,
PublishedItemType.Content,
DocumentTypes.Where(c => !c.IsElement),
async (contentType, derivedTypeSchemas) =>
{
var schemaIdPrefix = $"{contentType.SchemaId}{ContentSuffix}";
return await CreateContentTypeResponseSchema(
schemaIdPrefix,
derivedTypeSchemas,
context);
},
cancellationToken);
await CreateSchema(GetJsonTypeInfo(typeof(IApiContent)), context, cancellationToken);
return;
case var type when type == typeof(IApiContent):
await ApplyPolymorphicContentType(
schema,
context,
PublishedItemType.Content,
DocumentTypes.Where(c => !c.IsElement),
async (contentType, derivedTypeSchemas) =>
{
var schemaId = $"{contentType.SchemaId}{ContentSuffix}{ModelSuffix}";
return await CreateContentTypeSchema(
schemaId,
PublishedItemType.Content,
contentType,
derivedTypeSchemas,
context,
cancellationToken);
},
cancellationToken);
await CreateSchema(GetJsonTypeInfo(typeof(IApiElement)), context, cancellationToken);
return;
case var type when type == typeof(IApiElement):
await ApplyPolymorphicContentType(
schema,
context,
PublishedItemType.Content,
DocumentTypes.Where(c => c.IsElement),
async (contentType, derivedTypeSchemas) =>
{
var schemaId = $"{contentType.SchemaId}{ElementSuffix}{ModelSuffix}";
return await CreateContentTypeSchema(
schemaId,
PublishedItemType.Content,
contentType,
derivedTypeSchemas,
context,
cancellationToken);
},
cancellationToken);
return;
case var type when type == typeof(IApiMediaWithCropsResponse):
await ApplyPolymorphicContentType(
schema,
context,
PublishedItemType.Media,
MediaTypes,
async (contentType, derivedTypeSchemas) =>
{
var schemaId = $"{contentType.SchemaId}{MediaWithCropsSuffix}";
return await CreateContentTypeResponseSchema(
schemaId,
derivedTypeSchemas,
context);
},
cancellationToken);
await CreateSchema(GetJsonTypeInfo(typeof(IApiMediaWithCrops)), context, cancellationToken);
return;
case var type when type == typeof(IApiMediaWithCrops):
await ApplyPolymorphicContentType(
schema,
context,
PublishedItemType.Media,
MediaTypes,
async (contentType, derivedTypeSchemas) =>
{
var schemaId = $"{contentType.SchemaId}{MediaWithCropsSuffix}{ModelSuffix}";
return await CreateContentTypeSchema(
schemaId,
PublishedItemType.Media,
contentType,
derivedTypeSchemas,
context,
cancellationToken);
},
cancellationToken);
return;
default:
// HACK: Some types with circular references (e.g. ApiBlockGridItem) get left
// inlined by the framework, breaking $ref resolution. Register them explicitly.
if (GetSchemaId(context.JsonTypeInfo) is not { } schemaId || !_handledSchemas.Add(schemaId))
{
return;
}
OpenApiDocument document = context.GetRequiredDocument();
document.AddComponent(schemaId, schema);
return;
}
}
private async Task ApplyPolymorphicContentType(
OpenApiSchema schema,
OpenApiSchemaTransformerContext context,
PublishedItemType itemType,
IEnumerable<ContentTypeSchemaInfo> contentTypes,
Func<ContentTypeSchemaInfo, List<IOpenApiSchema>, Task<OpenApiSchema>> contentTypeSchemaFactory,
CancellationToken cancellationToken)
{
List<IOpenApiSchema> derivedTypeSchemas = await ResolveDerivedTypeSchemas(
schema,
context,
cancellationToken);
OpenApiDocument document = context.GetRequiredDocument();
var typePropertyName = GetTypePropertyName(itemType);
schema.Discriminator = new OpenApiDiscriminator
{
PropertyName = typePropertyName,
Mapping = new Dictionary<string, OpenApiSchemaReference>(),
};
schema.OneOf ??= new List<IOpenApiSchema>();
foreach (ContentTypeSchemaInfo contentType in contentTypes)
{
OpenApiSchema contentTypeSchema = await contentTypeSchemaFactory(contentType, derivedTypeSchemas);
var schemaId = (string)contentTypeSchema.Metadata![SchemaIdMetadataKey];
schema.Discriminator.Mapping[contentType.Alias] = new OpenApiSchemaReference(schemaId, document);
schema.OneOf.Add(contentTypeSchema);
}
// Remove all schema properties that are now handled by the derived types
schema.AnyOf = null;
schema.Properties = null;
schema.Required = new HashSet<string> { typePropertyName };
}
/// <summary>
/// Creates and adds a schema to the OpenAPI document if it does not already exist.
/// </summary>
/// <remarks>A placeholder schema is added first to avoid recursion issues when generating schemas that reference themselves.</remarks>
private async Task<IOpenApiSchema> CreateSchema(
JsonTypeInfo jsonTypeInfo,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
if (jsonTypeInfo.Type.IsArray || jsonTypeInfo.Kind == JsonTypeInfoKind.Enumerable)
{
Type elementType = jsonTypeInfo.ElementType ?? jsonTypeInfo.Type.GetElementType() ?? typeof(object);
JsonTypeInfo elementJsonTypeInfo = GetJsonTypeInfo(elementType);
IOpenApiSchema itemSchema = await CreateSchema(elementJsonTypeInfo, context, cancellationToken);
return new OpenApiSchema
{
Type = JsonSchemaType.Array,
Items = itemSchema,
};
}
var schemaId = GetSchemaId(jsonTypeInfo);
// If this is one of the types we handle, and we already started generating it, return a placeholder
// to avoid circular reference issues.
// In the document transformer, these placeholders will be replaced with the actual schemas.
if (schemaId is not null && !_handledSchemas.Add(schemaId))
{
return GetPlaceholderSchema(schemaId);
}
OpenApiSchema schema;
try
{
schema = await context.GetOrCreateSchemaAsync(
jsonTypeInfo.Type,
cancellationToken: cancellationToken);
}
catch (Exception ex)
{
// Log the error but continue with a fallback schema to avoid failing the entire document generation.
// The fallback schema includes a description indicating the failure, making it visible to API consumers.
_logger.LogError(ex, "Failed to create OpenAPI schema for type {TypeName}", jsonTypeInfo.Type.FullName);
schema = new OpenApiSchema
{
Description = $"[Schema generation failed for type '{jsonTypeInfo.Type.FullName}'. See server logs for details.]",
};
}
if (schemaId is null)
{
return schema;
}
OpenApiDocument document = context.GetRequiredDocument();
document.AddComponent(schemaId, schema);
return new OpenApiSchemaReference(schemaId, document);
}
/// <summary>
/// Allows null at a property reference site without mutating any shared component schema.
/// Inline schemas have <c>null</c> OR-ed into their <c>type</c> flags; schema references and
/// recursive-ref placeholders are wrapped in a <c>oneOf</c> with an explicit null branch so the
/// shared component is left unchanged.
/// </summary>
private static IOpenApiSchema AsNullable(IOpenApiSchema schema)
{
if (schema is OpenApiSchema inline
&& inline.Metadata?.ContainsKey(RecursiveRefMetadataKey) is not true)
{
inline.Type |= JsonSchemaType.Null;
return inline;
}
return new OpenApiSchema
{
OneOf =
[
schema,
new OpenApiSchema { Type = JsonSchemaType.Null },
],
};
}
private static Task<OpenApiSchema> CreateContentTypeResponseSchema(
string schemaIdPrefix,
List<IOpenApiSchema> derivedTypeSchemas,
OpenApiSchemaTransformerContext context)
{
var schemaId = $"{schemaIdPrefix}{ResponseModelSuffix}";
OpenApiDocument document = context.GetRequiredDocument();
var schema = new OpenApiSchema
{
Type = JsonSchemaType.Object,
AllOf = [..derivedTypeSchemas, new OpenApiSchemaReference($"{schemaIdPrefix}{ModelSuffix}", document)],
Metadata = new Dictionary<string, object> { [SchemaIdMetadataKey] = schemaId },
};
document.AddComponent(schemaId, schema);
return Task.FromResult(schema);
}
private async Task<OpenApiSchema> CreateContentTypeSchema(
string schemaId,
PublishedItemType itemType,
ContentTypeSchemaInfo contentType,
List<IOpenApiSchema> derivedTypeSchemas,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
var typePropertyName = GetTypePropertyName(itemType);
var schema = new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties = new Dictionary<string, IOpenApiSchema>
{
[typePropertyName] = new OpenApiSchema { Const = contentType.Alias },
["properties"] = await CreatePropertiesSchema(contentType, itemType, context, cancellationToken),
},
Required = new HashSet<string> { typePropertyName },
AllOf = derivedTypeSchemas.Count > 0 ? derivedTypeSchemas : null,
Metadata = new Dictionary<string, object> { [SchemaIdMetadataKey] = schemaId, },
};
OpenApiDocument document = context.GetRequiredDocument();
document.AddComponent(schemaId, schema);
return schema;
}
private async Task<OpenApiSchemaReference> CreatePropertiesSchema(
ContentTypeSchemaInfo contentType,
PublishedItemType itemType,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
var schemaId = GetPropertiesModelSchemaId(contentType, itemType);
var propertiesSchema = new OpenApiSchema
{
Type = JsonSchemaType.Object,
AllOf =
[
..contentType.CompositionSchemaIds.Select(compositionSchemaId
=> GetPlaceholderSchema(GetCompositionPropertiesModelSchemaId(compositionSchemaId, itemType)))
],
Properties = await CreateContentTypeProperties(contentType, context, cancellationToken),
Metadata = new Dictionary<string, object> { [SchemaIdMetadataKey] = schemaId },
};
OpenApiDocument document = context.GetRequiredDocument();
document.AddComponent(schemaId, propertiesSchema);
return new OpenApiSchemaReference(schemaId, document);
}
private static string GetPropertiesModelSchemaId(ContentTypeSchemaInfo contentType, PublishedItemType itemType) =>
$"{contentType.SchemaId}{GetItemTypeSuffix(itemType, contentType.IsElement)}{PropertiesModelSuffix}";
private string GetCompositionPropertiesModelSchemaId(string compositionSchemaId, PublishedItemType itemType)
{
// Look up the composition's own IsElement so its reference points at the right
// generated schema (element-type compositions live under the Element suffix).
IReadOnlyCollection<ContentTypeSchemaInfo> candidates = itemType == PublishedItemType.Media ? MediaTypes : DocumentTypes;
ContentTypeSchemaInfo? composition = candidates.FirstOrDefault(c => c.SchemaId == compositionSchemaId);
var suffix = GetItemTypeSuffix(itemType, composition?.IsElement ?? false);
return $"{compositionSchemaId}{suffix}{PropertiesModelSuffix}";
}
private static string GetItemTypeSuffix(PublishedItemType itemType, bool isElement) =>
itemType switch
{
PublishedItemType.Media => MediaSuffix,
PublishedItemType.Content => isElement ? ElementSuffix : ContentSuffix,
_ => throw new NotSupportedException($"Unsupported PublishedItemType: {itemType}"),
};
private async Task<Dictionary<string, IOpenApiSchema>> CreateContentTypeProperties(
ContentTypeSchemaInfo contentType,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
var properties = new Dictionary<string, IOpenApiSchema>();
foreach (ContentTypePropertySchemaInfo propertyInfo in contentType.Properties.Where(p => !p.Inherited))
{
IOpenApiSchema schema = await CreateSchema(
GetJsonTypeInfo(propertyInfo.DeliveryApiClrType),
context,
cancellationToken);
// Properties may be null (e.g. property added after content was last published).
// Nullability is applied at the reference site, never on a shared component schema.
properties[propertyInfo.Alias] = AsNullable(schema);
}
return properties;
}
private JsonTypeInfo GetJsonTypeInfo(Type type)
{
JsonTypeInfo? jsonTypeInfo = _jsonTypeInfoResolver.GetTypeInfo(type, _serializerOptions);
return jsonTypeInfo ?? throw new InvalidOperationException("Could not get JsonTypeInfo for type " + type.FullName);
}
private string GetTypePropertyName(PublishedItemType itemType)
{
var propertyName = itemType switch
{
PublishedItemType.Content => nameof(IApiElement.ContentType),
PublishedItemType.Media => nameof(IApiMedia.MediaType),
_ => throw new NotSupportedException($"Unsupported PublishedItemType: {itemType}"),
};
return _serializerOptions.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName;
}
private static string? GetSchemaId(JsonTypeInfo type)
=> ConfigureUmbracoOpenApiOptionsBase.CreateSchemaReferenceId(type);
/// <summary>
/// Creates a temporary placeholder schema to break circular reference chains during schema generation.
/// </summary>
/// <remarks>
/// The placeholder contains metadata with the target schema ID. During the document transformation phase,
/// <see cref="ResolveSchemaReferences(OpenApiDocument, IOpenApiSchema)"/> will replace these placeholders with actual schema references.
/// </remarks>
/// <param name="schemaId">The ID of the schema this placeholder represents.</param>
/// <returns>A placeholder schema with metadata indicating the target schema reference.</returns>
private static OpenApiSchema GetPlaceholderSchema(string schemaId)
=> new()
{
Metadata = new Dictionary<string, object>
{
[RecursiveRefMetadataKey] = schemaId,
},
};
/// <summary>
/// Recursively resolves inline schemas into proper <c>$ref</c> references.
/// </summary>
/// <remarks>
/// This method is called during the document transformation phase (after all schemas have been generated).
/// It walks through all schema properties, allOf, oneOf, and anyOf collections, resolving two types of
/// inline schemas:
/// <list type="bullet">
/// <item>Circular reference placeholders created by <see cref="GetPlaceholderSchema"/> (marked with <c>x-recursive-ref</c>)</item>
/// <item>Componentized schemas that should be references (marked with <c>x-schema-id</c>)</item>
/// </list>
/// Each match is replaced with an <see cref="OpenApiSchemaReference"/> pointing to the actual schema in the document's components.
/// </remarks>
/// <param name="document">The OpenAPI document containing the registered schema components.</param>
/// <param name="schema">The schema to process (will be modified in place).</param>
private static void ResolveSchemaReferences(OpenApiDocument document, IOpenApiSchema schema)
{
// Replace in allOf, oneOf, anyOf
ResolveSchemaReferences(document, schema.AllOf);
ResolveSchemaReferences(document, schema.OneOf);
ResolveSchemaReferences(document, schema.AnyOf);
// Process array items
if (schema is OpenApiSchema { Items: OpenApiSchema itemsSchema } parentSchema)
{
parentSchema.Items = GetActualSchemaOrReference(document, itemsSchema, out var itemsReplaced);
if (!itemsReplaced)
{
ResolveSchemaReferences(document, itemsSchema);
}
}
if (schema.Properties is not { Count: > 0 })
{
return;
}
// Process properties
foreach (var propertyKey in schema.Properties.Keys)
{
IOpenApiSchema propertySchema = schema.Properties[propertyKey];
if (propertySchema is not OpenApiSchema innerSchema)
{
continue;
}
schema.Properties[propertyKey] = GetActualSchemaOrReference(document, innerSchema, out var replaced);
if (replaced)
{
continue;
}
// Recursive call to handle the property schema
ResolveSchemaReferences(document, innerSchema);
}
}
private static void ResolveSchemaReferences(OpenApiDocument document, IList<IOpenApiSchema>? schemas)
{
if (schemas is null || schemas.Count == 0)
{
return;
}
for (var i = 0; i < schemas.Count; i++)
{
IOpenApiSchema allOfSchema = schemas[i];
schemas[i] = GetActualSchemaOrReference(document, allOfSchema, out var replaced);
if (!replaced)
{
ResolveSchemaReferences(document, schemas[i]);
}
}
}
[return: NotNullIfNotNull(nameof(schema))]
private static IOpenApiSchema? GetActualSchemaOrReference(
OpenApiDocument document,
IOpenApiSchema? schema,
out bool replaced)
{
if (schema is not OpenApiSchema openApiSchema)
{
replaced = false;
return schema;
}
// Check if this is a placeholder schema (circular reference)
if (openApiSchema.Metadata?.TryGetValue(RecursiveRefMetadataKey, out var recursiveRefIdObj) == true
&& recursiveRefIdObj is string recursiveRefId)
{
replaced = true;
return new OpenApiSchemaReference(recursiveRefId, document);
}
// Check if this is a componentized schema that should be a $ref
// Only resolve if the component actually exists — the framework also sets x-schema-id on
// schemas that may not end up as components.
if (openApiSchema.Metadata?.TryGetValue(SchemaIdMetadataKey, out var schemaIdObj) == true
&& schemaIdObj is string schemaId
&& !string.IsNullOrEmpty(schemaId)
&& document.Components?.Schemas?.ContainsKey(schemaId) == true)
{
replaced = true;
return new OpenApiSchemaReference(schemaId, document);
}
replaced = false;
return schema;
}
private IReadOnlyCollection<ContentTypeSchemaInfo> FilterAllowedDocumentTypes(IReadOnlyCollection<ContentTypeSchemaInfo> documentTypes)
{
DeliveryApiSettings settings = _deliveryApiSettings.CurrentValue;
return documentTypes
.Where(c => settings.IsAllowedContentType(c.Alias))
.ToList();
}
/// <summary>
/// Returns the schemas to use as the <c>allOf</c> bases for each typed content type
/// schema in a polymorphic union. Prefers concrete derived types declared on the
/// interface via <c>[JsonDerivedType]</c>; when none are advertised, falls back to a
/// schema built from the interface's own properties.
/// </summary>
/// <remarks>
/// The fallback exists for media interfaces, whose concrete classes are internal in
/// Umbraco.Infrastructure and therefore cannot be referenced via <c>[JsonDerivedType]</c>
/// from Umbraco.Core.
/// </remarks>
private async Task<List<IOpenApiSchema>> ResolveDerivedTypeSchemas(
OpenApiSchema interfaceSchema,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
List<IOpenApiSchema> derivedTypeSchemas = [];
foreach (JsonDerivedType derivedType in context.JsonTypeInfo.PolymorphismOptions?.DerivedTypes ?? [])
{
IOpenApiSchema derivedTypeSchema = await CreateSchema(
GetJsonTypeInfo(derivedType.DerivedType),
context,
cancellationToken);
derivedTypeSchemas.Add(derivedTypeSchema);
}
if (derivedTypeSchemas.Count == 0)
{
derivedTypeSchemas.Add(CreateBaseSchemaFromInterface(interfaceSchema, context));
}
return derivedTypeSchemas;
}
private static IOpenApiSchema CreateBaseSchemaFromInterface(
OpenApiSchema interfaceSchema,
OpenApiSchemaTransformerContext context)
{
// Append a "Base" marker so this schema stays distinct from the polymorphic union
// schema for the same interface (e.g. IApiMediaWithCropsResponseBaseModel vs.
// IApiMediaWithCropsResponseModel).
var baseSchemaId = $"{context.JsonTypeInfo.Type.Name}Base{ModelSuffix}";
OpenApiDocument document = context.GetRequiredDocument();
var baseSchema = new OpenApiSchema
{
Type = interfaceSchema.Type,
Properties = interfaceSchema.Properties,
Required = interfaceSchema.Required,
Metadata = new Dictionary<string, object> { [SchemaIdMetadataKey] = baseSchemaId },
};
document.AddComponent(baseSchemaId, baseSchema);
return new OpenApiSchemaReference(baseSchemaId, document);
}
}
@@ -83,6 +83,11 @@ public class DeliveryApiSettings
/// </summary>
public OutputCacheSettings OutputCache { get; set; } = new ();
/// <summary>
/// Gets or sets the settings for the Delivery API OpenAPI document.
/// </summary>
public OpenApiSettings OpenApi { get; set; } = new ();
/// <summary>
/// Gets a value indicating if any member authorization type is enabled for the Delivery API.
/// </summary>
@@ -254,4 +259,27 @@ public class DeliveryApiSettings
/// <value>The client secret.</value>
public string ClientSecret { get; set; } = string.Empty;
}
/// <summary>
/// Typed configuration options for the OpenAPI document of the Delivery API.
/// </summary>
public class OpenApiSettings
{
private const bool StaticGenerateContentTypeSchemas = false;
/// <summary>
/// Gets or sets a value indicating whether the Delivery API OpenAPI document should include
/// schemas for the instance's content types (document types, element types, and media types).
/// </summary>
/// <value>
/// <c>true</c> to generate content-type-specific schemas in the OpenAPI document;
/// <c>false</c> to use only the base interface schemas.
/// </value>
/// <remarks>
/// When enabled, the OpenAPI document will contain content-type-specific schemas with their
/// specific properties. When disabled (default), only the base interface schemas will be used.
/// </remarks>
[DefaultValue(StaticGenerateContentTypeSchemas)]
public bool GenerateContentTypeSchemas { get; set; } = StaticGenerateContentTypeSchemas;
}
}
@@ -1,7 +1,6 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Strings;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Services;
@@ -12,7 +11,6 @@ internal sealed class ContentTypeSchemaService : IContentTypeSchemaService
private readonly IContentTypeService _contentTypeService;
private readonly IMediaTypeService _mediaTypeService;
private readonly IPublishedContentTypeCache _publishedContentTypeCache;
private readonly IShortStringHelper _shortStringHelper;
/// <summary>
/// Initializes a new instance of the <see cref="ContentTypeSchemaService"/> class.
@@ -20,13 +18,11 @@ internal sealed class ContentTypeSchemaService : IContentTypeSchemaService
public ContentTypeSchemaService(
IContentTypeService contentTypeService,
IMediaTypeService mediaTypeService,
IPublishedContentTypeCache publishedContentTypeCache,
IShortStringHelper shortStringHelper)
IPublishedContentTypeCache publishedContentTypeCache)
{
_contentTypeService = contentTypeService;
_mediaTypeService = mediaTypeService;
_publishedContentTypeCache = publishedContentTypeCache;
_shortStringHelper = shortStringHelper;
}
/// <inheritdoc/>
@@ -81,7 +77,9 @@ internal sealed class ContentTypeSchemaService : IContentTypeSchemaService
return result;
}
// Currently uses the same transformation as ModelsBuilder (UmbracoServices.GetClrName)
private string GetContentTypeSchemaId(string contentTypeAlias) =>
contentTypeAlias.ToCleanString(_shortStringHelper, CleanStringType.ConvertCase | CleanStringType.PascalCase);
// Aliases are already valid identifiers, so only the first char needs uppercasing.
// Deliberately avoids ModelsBuilder's GetClrName, which re-tokenises by case boundaries
// and mangles capital-letter runs (e.g. "xMLSitemap" -> "XMlsitemap" instead of "XMLSitemap").
private static string GetContentTypeSchemaId(string contentTypeAlias) =>
contentTypeAlias.ToFirstUpperInvariant();
}
@@ -1,4 +1,4 @@
using System.Text.Json;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
namespace Umbraco.Cms.Infrastructure.Serialization;
@@ -10,12 +10,12 @@ namespace Umbraco.Cms.Infrastructure.Serialization;
public abstract class ContentJsonTypeResolverBase : DefaultJsonTypeInfoResolver
{
/// <summary>
/// Gets the <see cref="System.Text.Json.Serialization.JsonTypeInfo"/> for the specified <see cref="System.Type"/>,
/// Gets the <see cref="JsonTypeInfo"/> for the specified <see cref="System.Type"/>,
/// configuring polymorphic serialization options for derived types if applicable.
/// </summary>
/// <param name="type">The type to get the <see cref="System.Text.Json.Serialization.JsonTypeInfo"/> for.</param>
/// <param name="type">The type to get the <see cref="JsonTypeInfo"/> for.</param>
/// <param name="options">The <see cref="System.Text.Json.JsonSerializerOptions"/> to use when getting the type info.</param>
/// <returns>The <see cref="System.Text.Json.Serialization.JsonTypeInfo"/> for the specified type, with polymorphism options configured if derived types are present.</returns>
/// <returns>The <see cref="JsonTypeInfo"/> for the specified type, with polymorphism options configured if derived types are present.</returns>
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
@@ -30,7 +30,7 @@ public abstract class ContentJsonTypeResolverBase : DefaultJsonTypeInfoResolver
}
/// <summary>
/// Returns the concrete types that are derived from the type described by the specified <see cref="System.Text.Json.Serialization.JsonTypeInfo" />.
/// Returns the concrete types that are derived from the type described by the specified <see cref="JsonTypeInfo" />.
/// </summary>
/// <param name="jsonTypeInfo">The JSON type information representing the base type for which to resolve derived types.</param>
/// <returns>
+2 -1
View File
@@ -1,5 +1,6 @@
wwwroot/
umbraco/[Dd]ata/
umbraco/[Dd]ata/*
!umbraco/[Dd]ata/Umbraco.Sample.sqlite.db
umbraco/[Ll]ogs/
umbraco/[Mm]odels/
App_Plugins/
+2 -2
View File
@@ -7,9 +7,9 @@ WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
#if UseDeliveryApi
//#if UseDeliveryApi
.AddDeliveryApi()
#endif
//#endif
.AddComposers()
.Build();
@@ -0,0 +1,51 @@
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Tests the default OpenAPI contract with <see cref="DeliveryApiSettings.OpenApiSettings.GenerateContentTypeSchemas"/> disabled.
/// This produces generic schemas without type-specific response models.
/// </summary>
[TestFixture]
internal sealed class OpenApiContractTestDefault : OpenApiContractTestBase
{
private const string ExpectedContractFileName = "default.json";
public override void Setup()
{
// Disable content type schema generation
InMemoryConfiguration[$"{Constants.Configuration.ConfigDeliveryApi}:OpenApi:GenerateContentTypeSchemas"] = "false";
base.Setup();
}
[Test]
public async Task OpenApiDocument_IsValid()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateOpenApiSpecAsync(openApiSpec);
}
[Test]
public async Task OpenApiContract_MatchesExpected()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateContractAsync(openApiSpec, ExpectedContractFileName);
}
[Test]
public async Task OpenApiContract_HasExpectedSchemas()
{
var openApiSpec = await FetchOpenApiSpecAsync();
var openApiDocument = ParseOpenApiSpec(openApiSpec);
// Verify built-in media type schemas are NOT present when disabled
AssertSchemaDoesNotExist(openApiDocument, "ImageMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "FileMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "FolderMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "ImagePropertiesModel");
AssertSchemaDoesNotExist(openApiDocument, "FilePropertiesModel");
AssertSchemaDoesNotExist(openApiDocument, "FolderPropertiesModel");
}
}
@@ -0,0 +1,66 @@
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Tests the OpenAPI contract with <see cref="DeliveryApiSettings.OpenApiSettings.GenerateContentTypeSchemas"/> disabled
/// but with sample content types defined. This verifies that type-specific schemas are NOT generated even when types exist.
/// </summary>
[TestFixture]
internal sealed class OpenApiContractTestGenericSchemasWithSampleTypes : OpenApiContractTestBase
{
private const string ExpectedContractFileName = "generic-schemas-with-sample-types.json";
public override void Setup()
{
// Disable content type schema generation
InMemoryConfiguration[$"{Constants.Configuration.ConfigDeliveryApi}:OpenApi:GenerateContentTypeSchemas"] = "false";
base.Setup();
}
[SetUp]
public async Task SetupSampleTypesAsync() => await CreateSampleContentTypesAsync();
[Test]
public async Task OpenApiDocument_IsValid()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateOpenApiSpecAsync(openApiSpec);
}
[Test]
public async Task OpenApiContract_MatchesExpected()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateContractAsync(openApiSpec, ExpectedContractFileName);
}
[Test]
public async Task OpenApiContract_HasExpectedSchemas()
{
var openApiSpec = await FetchOpenApiSpecAsync();
var openApiDocument = ParseOpenApiSpec(openApiSpec);
// Verify sample document type schemas are NOT present when disabled
AssertSchemaDoesNotExist(openApiDocument, "ArticlePageContentResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "ArticlePagePropertiesModel");
AssertSchemaDoesNotExist(openApiDocument, "LandingPageContentResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "LandingPagePropertiesModel");
// Verify element type schemas are NOT present when disabled
AssertSchemaDoesNotExist(openApiDocument, "TestElementElementModel");
AssertSchemaDoesNotExist(openApiDocument, "TestElementPropertiesModel");
// Verify built-in media type schemas are also NOT present when disabled
AssertSchemaDoesNotExist(openApiDocument, "ImageMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "FileMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "ImagePropertiesModel");
AssertSchemaDoesNotExist(openApiDocument, "FilePropertiesModel");
// Verify sample media type schemas are NOT present when disabled
AssertSchemaDoesNotExist(openApiDocument, "VideoMediaWithCropsResponseModel");
AssertSchemaDoesNotExist(openApiDocument, "VideoPropertiesModel");
}
}
@@ -0,0 +1,53 @@
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Tests the OpenAPI contract with <see cref="DeliveryApiSettings.OpenApiSettings.GenerateContentTypeSchemas"/> enabled.
/// This produces typed schemas including Umbraco's built-in media types (File, Folder, Image, etc.).
/// </summary>
[TestFixture]
internal sealed class OpenApiContractTestTypedSchemasEmptyProject : OpenApiContractTestBase
{
private const string ExpectedContractFileName = "typed-schemas-empty-project.json";
public override void Setup()
{
// Enable content type schema generation
InMemoryConfiguration[$"{Constants.Configuration.ConfigDeliveryApi}:OpenApi:GenerateContentTypeSchemas"] = "true";
base.Setup();
}
[Test]
public async Task OpenApiDocument_IsValid()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateOpenApiSpecAsync(openApiSpec);
}
[Test]
public async Task OpenApiContract_MatchesExpected()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateContractAsync(openApiSpec, ExpectedContractFileName);
}
[Test]
public async Task OpenApiContract_HasExpectedSchemas()
{
var openApiSpec = await FetchOpenApiSpecAsync();
var openApiDocument = ParseOpenApiSpec(openApiSpec);
// Verify built-in media types are present in the schema
AssertSchemaExists(openApiDocument, "ImageMediaWithCropsResponseModel");
AssertSchemaExists(openApiDocument, "FileMediaWithCropsResponseModel");
AssertSchemaExists(openApiDocument, "FolderMediaWithCropsResponseModel");
// Verify the properties models for built-in media types
AssertSchemaExists(openApiDocument, "ImageMediaPropertiesModel");
AssertSchemaExists(openApiDocument, "FileMediaPropertiesModel");
AssertSchemaExists(openApiDocument, "FolderMediaPropertiesModel");
}
}
@@ -0,0 +1,120 @@
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Tests the OpenAPI contract with <see cref="DeliveryApiSettings.OpenApiSettings.GenerateContentTypeSchemas"/> enabled
/// and sample content types defined. This shows how document/element types appear in the generated schema.
/// </summary>
[TestFixture]
internal sealed class OpenApiContractTestTypedSchemasWithSampleTypes : OpenApiContractTestBase
{
private const string ExpectedContractFileName = "typed-schemas-with-sample-types.json";
public override void Setup()
{
// Enable content type schema generation
InMemoryConfiguration[$"{Constants.Configuration.ConfigDeliveryApi}:OpenApi:GenerateContentTypeSchemas"] = "true";
base.Setup();
}
[SetUp]
public async Task SetupSampleTypesAsync() => await CreateSampleContentTypesAsync();
[Test]
public async Task OpenApiDocument_IsValid()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateOpenApiSpecAsync(openApiSpec);
}
[Test]
public async Task OpenApiContract_MatchesExpected()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateContractAsync(openApiSpec, ExpectedContractFileName);
}
[Test]
public async Task OpenApiContract_HasExpectedSchemas()
{
var openApiSpec = await FetchOpenApiSpecAsync();
var openApiDocument = ParseOpenApiSpec(openApiSpec);
// Verify sample document type schemas are present
AssertSchemaExists(openApiDocument, "ArticlePageContentResponseModel");
AssertSchemaExists(openApiDocument, "ArticlePageContentPropertiesModel");
AssertSchemaExists(openApiDocument, "LandingPageContentResponseModel");
AssertSchemaExists(openApiDocument, "LandingPageContentPropertiesModel");
AssertSchemaExists(openApiDocument, "XMLSitemapContentResponseModel");
AssertSchemaExists(openApiDocument, "XMLSitemapContentPropertiesModel");
// Verify element type schemas are present (via block list on landing page)
AssertSchemaExists(openApiDocument, "TestElementElementModel");
AssertSchemaExists(openApiDocument, "TestElementElementPropertiesModel");
// Verify the SEO composition schema is present and referenced from the composing type's properties model
AssertSchemaExists(openApiDocument, "SeoMetadataContentPropertiesModel");
AssertSchemaComposesFrom(openApiDocument, "ArticlePageContentPropertiesModel", "SeoMetadataContentPropertiesModel");
// Verify built-in media types are also present
AssertSchemaExists(openApiDocument, "ImageMediaWithCropsResponseModel");
AssertSchemaExists(openApiDocument, "FileMediaWithCropsResponseModel");
// Verify sample media type schemas are present
AssertSchemaExists(openApiDocument, "VideoMediaWithCropsResponseModel");
AssertSchemaExists(openApiDocument, "VideoMediaPropertiesModel");
// Verify the polymorphic interface schemas wire each derived type into oneOf + discriminator mapping
AssertSchemaIsPolymorphicUnion(
openApiDocument,
"IApiContentResponseModel",
"contentType",
new Dictionary<string, string>
{
["articlePage"] = "ArticlePageContentResponseModel",
["landingPage"] = "LandingPageContentResponseModel",
["seoMetadata"] = "SeoMetadataContentResponseModel",
["xMLSitemap"] = "XMLSitemapContentResponseModel",
});
AssertSchemaIsPolymorphicUnion(
openApiDocument,
"IApiContentModel",
"contentType",
new Dictionary<string, string>
{
["articlePage"] = "ArticlePageContentModel",
["landingPage"] = "LandingPageContentModel",
["seoMetadata"] = "SeoMetadataContentModel",
["xMLSitemap"] = "XMLSitemapContentModel",
});
AssertSchemaIsPolymorphicUnion(
openApiDocument,
"IApiMediaWithCropsResponseModel",
"mediaType",
new Dictionary<string, string>
{
["Folder"] = "FolderMediaWithCropsResponseModel",
["Image"] = "ImageMediaWithCropsResponseModel",
["File"] = "FileMediaWithCropsResponseModel",
["video"] = "VideoMediaWithCropsResponseModel",
});
AssertSchemaIsPolymorphicUnion(
openApiDocument,
"IApiMediaWithCropsModel",
"mediaType",
new Dictionary<string, string>
{
["Folder"] = "FolderMediaWithCropsModel",
["Image"] = "ImageMediaWithCropsModel",
["File"] = "FileMediaWithCropsModel",
["video"] = "VideoMediaWithCropsModel",
});
}
}
@@ -1,26 +0,0 @@
using NUnit.Framework;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Tests the Delivery API OpenAPI contract for correctness and consistency.
/// </summary>
[TestFixture]
internal sealed class OpenApiContractTest : OpenApiTestBase
{
private const string ExpectedContractFileName = "default.json";
[Test]
public async Task OpenApiDocument_IsValid()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateOpenApiSpecAsync(openApiSpec);
}
[Test]
public async Task OpenApiContract_MatchesExpected()
{
var openApiSpec = await FetchOpenApiSpecAsync();
await ValidateContractAsync(openApiSpec, ExpectedContractFileName);
}
}
@@ -0,0 +1,304 @@
using System.Text.Json.Nodes;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Tests.Common.Builders;
using Umbraco.Cms.Tests.Common.Builders.Extensions;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Api.Delivery.OpenApi;
/// <summary>
/// Base class for OpenAPI contract tests with shared test logic.
/// </summary>
internal abstract class OpenApiContractTestBase : OpenApiTestBase
{
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
private PropertyEditorCollection PropertyEditorCollection => GetRequiredService<PropertyEditorCollection>();
private IConfigurationEditorJsonSerializer ConfigurationEditorJsonSerializer => GetRequiredService<IConfigurationEditorJsonSerializer>();
/// <summary>
/// Asserts that the specified schema exists in the OpenAPI document.
/// </summary>
protected static void AssertSchemaExists(JsonNode openApiDocument, string schemaName)
{
var schemas = openApiDocument["components"]?["schemas"];
Assert.That(schemas, Is.Not.Null, "OpenAPI document has no schemas defined.");
Assert.That(schemas![schemaName], Is.Not.Null, $"Schema '{schemaName}' was not found in the OpenAPI document.");
}
/// <summary>
/// Asserts that the specified schema does NOT exist in the OpenAPI document.
/// </summary>
protected static void AssertSchemaDoesNotExist(JsonNode openApiDocument, string schemaName)
{
var schemas = openApiDocument["components"]?["schemas"];
Assert.That(schemas?[schemaName], Is.Null, $"Schema '{schemaName}' should not exist in the OpenAPI document when content type schemas are disabled.");
}
/// <summary>
/// Asserts that the specified schema contains an <c>allOf</c> entry referencing the expected composition schema.
/// </summary>
protected static void AssertSchemaComposesFrom(JsonNode openApiDocument, string schemaName, string expectedCompositionSchemaName)
{
var schemas = openApiDocument["components"]?["schemas"];
Assert.That(schemas?[schemaName], Is.Not.Null, $"Schema '{schemaName}' was not found in the OpenAPI document.");
var allOf = schemas![schemaName]!["allOf"]?.AsArray();
Assert.That(allOf, Is.Not.Null, $"Schema '{schemaName}' has no 'allOf' entries.");
var expectedRef = $"#/components/schemas/{expectedCompositionSchemaName}";
var hasReference = allOf!.Any(entry => entry?["$ref"]?.GetValue<string>() == expectedRef);
Assert.That(hasReference, Is.True, $"Schema '{schemaName}' does not compose from '{expectedCompositionSchemaName}'.");
}
/// <summary>
/// Asserts that the specified schema is a polymorphic union: it has a <c>oneOf</c> covering the expected derived
/// schemas and a discriminator on <paramref name="discriminatorPropertyName"/> mapping each alias to its schema.
/// </summary>
/// <param name="openApiDocument">The parsed OpenAPI document.</param>
/// <param name="schemaName">The name of the polymorphic union schema (e.g. "IApiContentResponseModel").</param>
/// <param name="discriminatorPropertyName">The discriminator property name (e.g. "contentType" or "mediaType").</param>
/// <param name="expectedDiscriminatorMapping">The expected discriminator mapping from alias to derived schema name.</param>
protected static void AssertSchemaIsPolymorphicUnion(
JsonNode openApiDocument,
string schemaName,
string discriminatorPropertyName,
IReadOnlyDictionary<string, string> expectedDiscriminatorMapping)
{
var schemas = openApiDocument["components"]?["schemas"];
Assert.That(schemas?[schemaName], Is.Not.Null, $"Schema '{schemaName}' was not found in the OpenAPI document.");
var schema = schemas![schemaName]!;
var oneOf = schema["oneOf"]?.AsArray();
Assert.That(oneOf, Is.Not.Null, $"Schema '{schemaName}' has no 'oneOf' entries.");
var oneOfRefs = oneOf!
.Select(entry => entry?["$ref"]?.GetValue<string>())
.Where(value => value is not null)
.ToHashSet();
foreach (var expectedSchemaName in expectedDiscriminatorMapping.Values)
{
var expectedRef = $"#/components/schemas/{expectedSchemaName}";
Assert.That(oneOfRefs, Contains.Item(expectedRef), $"Schema '{schemaName}' 'oneOf' is missing reference to '{expectedSchemaName}'.");
}
var discriminator = schema["discriminator"];
Assert.That(discriminator, Is.Not.Null, $"Schema '{schemaName}' has no 'discriminator'.");
Assert.That(
discriminator!["propertyName"]?.GetValue<string>(),
Is.EqualTo(discriminatorPropertyName),
$"Schema '{schemaName}' has wrong discriminator property name.");
var mapping = discriminator["mapping"];
Assert.That(mapping, Is.Not.Null, $"Schema '{schemaName}' discriminator has no 'mapping'.");
foreach ((var alias, var expectedSchemaName) in expectedDiscriminatorMapping)
{
var expectedRef = $"#/components/schemas/{expectedSchemaName}";
Assert.That(
mapping![alias]?.GetValue<string>(),
Is.EqualTo(expectedRef),
$"Schema '{schemaName}' discriminator mapping for alias '{alias}' is incorrect.");
}
}
/// <summary>
/// Creates sample content types for testing schema generation.
/// Includes document types, element types, and media types with various property types.
/// </summary>
protected async Task CreateSampleContentTypesAsync()
{
// Fetch built-in data types (WithDataTypeId requires the integer ID, not just the GUID)
var textDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.TextstringGuid);
var richTextDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.RichtextEditorGuid);
var dateDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.DatePickerWithTimeGuid);
var contentPickerDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.ContentPickerGuid);
var mediaPickerDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.MediaPicker3Guid);
var uploadVideoDataType = await DataTypeService.GetAsync(Constants.DataTypes.Guids.UploadVideoGuid);
// Create an element type (for use in block editors)
var testElement = new ContentTypeBuilder()
.WithAlias("testElement")
.WithName("Test Element")
.WithIsElement(true)
.AddPropertyGroup()
.WithName("Content")
.WithAlias("content")
.AddPropertyType()
.WithAlias("title")
.WithName("Title")
.WithDataTypeId(textDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("subtitle")
.WithName("Subtitle")
.WithDataTypeId(textDataType!.Id)
.Done()
.Done()
.Build();
await ContentTypeService.CreateAsync(testElement, Constants.Security.SuperUserKey);
// Create a block list data type that allows the test element
var blockListDataType = await CreateBlockListDataTypeAsync(testElement);
// Create a composition type that exposes shared SEO metadata properties
var seoMetadataComposition = new ContentTypeBuilder()
.WithAlias("seoMetadata")
.WithName("SEO Metadata")
.AddPropertyGroup()
.WithName("SEO")
.WithAlias("seo")
.AddPropertyType()
.WithAlias("metaDescription")
.WithName("Meta Description")
.WithDataTypeId(textDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("metaKeywords")
.WithName("Meta Keywords")
.WithDataTypeId(textDataType!.Id)
.Done()
.Done()
.Build();
await ContentTypeService.CreateAsync(seoMetadataComposition, Constants.Security.SuperUserKey);
// Create a document type for articles (with content picker for circular reference, and the SEO composition applied)
var articlePage = new ContentTypeBuilder()
.WithAlias("articlePage")
.WithName("Article Page")
.AddPropertyGroup()
.WithName("Content")
.WithAlias("content")
.AddPropertyType()
.WithAlias("headline")
.WithName("Headline")
.WithDataTypeId(textDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("bodyText")
.WithName("Body Text")
.WithDataTypeId(richTextDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("publishDate")
.WithName("Publish Date")
.WithDataTypeId(dateDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("relatedArticles")
.WithName("Related Articles")
.WithDataTypeId(contentPickerDataType!.Id)
.Done()
.Done()
.Build();
articlePage.AddContentType(seoMetadataComposition);
await ContentTypeService.CreateAsync(articlePage, Constants.Security.SuperUserKey);
// Create a document type for landing pages (with block list for element type testing)
var landingPage = new ContentTypeBuilder()
.WithAlias("landingPage")
.WithName("Landing Page")
.AddPropertyGroup()
.WithName("Content")
.WithAlias("content")
.AddPropertyType()
.WithAlias("pageTitle")
.WithName("Page Title")
.WithDataTypeId(textDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("introduction")
.WithName("Introduction")
.WithDataTypeId(richTextDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("contentBlocks")
.WithName("Content Blocks")
.WithDataTypeId(blockListDataType.Id)
.Done()
.Done()
.Build();
await ContentTypeService.CreateAsync(landingPage, Constants.Security.SuperUserKey);
// Create a document type with a capital-letter run in its alias to verify that
// the schema ID preserves the original casing (e.g. "xMLSitemap" -> "XMLSitemap"
// rather than the mangled "XMlsitemap" produced by the legacy ToCleanString tokenizer).
var xmlSitemapPage = new ContentTypeBuilder()
.WithAlias("xMLSitemap")
.WithName("XML Sitemap")
.AddPropertyGroup()
.WithName("Content")
.WithAlias("content")
.AddPropertyType()
.WithAlias("changeFrequency")
.WithName("Change Frequency")
.WithDataTypeId(textDataType!.Id)
.Done()
.Done()
.Build();
await ContentTypeService.CreateAsync(xmlSitemapPage, Constants.Security.SuperUserKey);
// Create a custom media type for videos (with media picker for circular reference)
var videoMedia = new MediaTypeBuilder()
.WithAlias("video")
.WithName("Video")
.AddPropertyGroup()
.WithName("Media")
.WithAlias("media")
.AddPropertyType()
.WithAlias("videoTitle")
.WithName("Video Title")
.WithDataTypeId(textDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("videoFile")
.WithName("Video File")
.WithDataTypeId(uploadVideoDataType!.Id)
.Done()
.AddPropertyType()
.WithAlias("thumbnailImage")
.WithName("Thumbnail Image")
.WithDataTypeId(mediaPickerDataType!.Id)
.Done()
.Done()
.Build();
await MediaTypeService.CreateAsync(videoMedia, Constants.Security.SuperUserKey);
}
/// <summary>
/// Creates a block list data type configured with the specified element type.
/// </summary>
private async Task<IDataType> CreateBlockListDataTypeAsync(IContentType elementType)
{
var blockListEditor = PropertyEditorCollection[Constants.PropertyEditors.Aliases.BlockList];
var dataType = new DataType(blockListEditor, ConfigurationEditorJsonSerializer)
{
ConfigurationData = new Dictionary<string, object>
{
{
"blocks", new BlockListConfiguration.BlockConfiguration[]
{
new() { ContentElementTypeKey = elementType.Key },
}
},
},
Name = "Content Blocks",
DatabaseType = ValueStorageType.Ntext,
ParentId = Constants.System.Root,
CreateDate = DateTime.UtcNow,
};
await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
return dataType;
}
}
@@ -0,0 +1,620 @@
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Api.Delivery.OpenApi.Transformers;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.DeliveryApi;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Delivery.OpenApi;
[TestFixture]
public class ContentTypeSchemaTransformerTests
{
private Mock<IContentTypeSchemaService> _contentTypeSchemaServiceMock = null!;
private Mock<IOptionsMonitor<JsonOptions>> _jsonOptionsMonitorMock = null!;
private Mock<IOptionsMonitor<DeliveryApiSettings>> _deliveryApiSettingsMonitorMock = null!;
private Mock<ILogger<ContentTypeSchemaTransformer>> _loggerMock = null!;
private JsonSerializerOptions _jsonSerializerOptions = null!;
private IServiceProvider _services = null!;
[SetUp]
public void SetUp()
{
_contentTypeSchemaServiceMock = new Mock<IContentTypeSchemaService>(MockBehavior.Strict);
_loggerMock = new Mock<ILogger<ContentTypeSchemaTransformer>>();
_jsonOptionsMonitorMock = new Mock<IOptionsMonitor<JsonOptions>>(MockBehavior.Strict);
_deliveryApiSettingsMonitorMock = new Mock<IOptionsMonitor<DeliveryApiSettings>>();
_deliveryApiSettingsMonitorMock.Setup(x => x.CurrentValue).Returns(new DeliveryApiSettings());
_jsonSerializerOptions = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var jsonOptions = new JsonOptions
{
SerializerOptions =
{
TypeInfoResolver = _jsonSerializerOptions.TypeInfoResolver,
PropertyNamingPolicy = _jsonSerializerOptions.PropertyNamingPolicy,
},
};
_jsonOptionsMonitorMock
.Setup(x => x.Get(Constants.JsonOptionsNames.DeliveryApi))
.Returns(jsonOptions);
_services = new ServiceCollection().BuildServiceProvider();
}
[Test]
public void Constructor_Throws_When_TypeInfoResolver_Is_Null()
{
// Arrange
var jsonOptions = new JsonOptions { SerializerOptions = { TypeInfoResolver = null } };
_jsonOptionsMonitorMock
.Setup(x => x.Get(Constants.JsonOptionsNames.DeliveryApi))
.Returns(jsonOptions);
// Act & Assert
Assert.Throws<InvalidOperationException>(() => CreateTransformer());
}
[Test]
public async Task DocumentTransformAsync_Does_Not_Throw_When_Components_Is_Null()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument { Components = null };
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
Assert.IsNull(document.Components);
}
[Test]
public async Task DocumentTransformAsync_Does_Not_Throw_When_Schemas_Is_Null()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents { Schemas = null },
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
Assert.IsNull(document.Components.Schemas);
}
[Test]
public async Task DocumentTransformAsync_Does_Not_Throw_When_Schemas_Is_Empty()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
Schemas = new Dictionary<string, IOpenApiSchema>(),
},
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
Assert.AreEqual(0, document.Components.Schemas.Count);
}
[Test]
public async Task DocumentTransformAsync_Preserves_Schemas_Without_Placeholders()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
Schemas = new Dictionary<string, IOpenApiSchema>
{
["TestSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties = new Dictionary<string, IOpenApiSchema>
{
["TestProperty"] = new OpenApiSchema { Type = JsonSchemaType.String },
},
},
},
},
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
Assert.AreEqual(1, document.Components.Schemas.Count);
Assert.That(document.Components.Schemas.ContainsKey("TestSchema"));
var schema = document.Components.Schemas["TestSchema"] as OpenApiSchema;
Assert.IsNotNull(schema);
Assert.AreEqual(JsonSchemaType.Object, schema.Type);
Assert.IsNotNull(schema.Properties);
Assert.AreEqual(1, schema.Properties.Count);
Assert.That(schema.Properties.ContainsKey("TestProperty"));
var propertySchema = schema.Properties["TestProperty"] as OpenApiSchema;
Assert.IsNotNull(propertySchema);
Assert.AreEqual(JsonSchemaType.String, propertySchema.Type);
}
[Test]
public async Task DocumentTransformAsync_Replaces_Placeholder_Schema_In_Properties_With_Reference()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
Schemas = new Dictionary<string, IOpenApiSchema>
{
["ParentSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties = new Dictionary<string, IOpenApiSchema>
{
["ChildProperty"] = new OpenApiSchema
{
Metadata = new Dictionary<string, object>
{
["x-recursive-ref"] = "ChildSchema",
},
},
},
},
["ChildSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
},
},
},
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
var parentSchema = document.Components.Schemas["ParentSchema"] as OpenApiSchema;
Assert.IsNotNull(parentSchema?.Properties);
var childProperty = parentSchema.Properties["ChildProperty"];
Assert.IsInstanceOf<OpenApiSchemaReference>(childProperty);
Assert.That(((OpenApiSchemaReference)childProperty).Reference.Id, Is.EqualTo("ChildSchema"));
}
[Test]
public async Task DocumentTransformAsync_Replaces_Placeholder_Schema_In_AllOf_With_Reference()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
Schemas = new Dictionary<string, IOpenApiSchema>
{
["ComposedSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
AllOf = new List<IOpenApiSchema>
{
new OpenApiSchema
{
Metadata = new Dictionary<string, object>
{
["x-recursive-ref"] = "BaseSchema",
},
},
},
},
["BaseSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
},
},
},
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
var composedSchema = document.Components.Schemas["ComposedSchema"] as OpenApiSchema;
Assert.IsNotNull(composedSchema);
Assert.IsNotNull(composedSchema.AllOf);
Assert.AreEqual(1, composedSchema.AllOf.Count);
Assert.IsInstanceOf<OpenApiSchemaReference>(composedSchema.AllOf[0]);
var baseReference = (OpenApiSchemaReference)composedSchema.AllOf[0];
Assert.That(baseReference.Reference?.Id, Is.EqualTo("BaseSchema"));
}
[Test]
public async Task DocumentTransformAsync_Replaces_Placeholder_Schema_In_Array_Items_With_Reference()
{
// Arrange
var transformer = CreateTransformer();
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
Schemas = new Dictionary<string, IOpenApiSchema>
{
["ArraySchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties = new Dictionary<string, IOpenApiSchema>
{
["Items"] = new OpenApiSchema
{
Type = JsonSchemaType.Array,
Items = new OpenApiSchema
{
Metadata = new Dictionary<string, object>
{
["x-recursive-ref"] = "ItemSchema",
},
},
},
},
},
["ItemSchema"] = new OpenApiSchema
{
Type = JsonSchemaType.Object,
},
},
},
};
// Act
await transformer.TransformAsync(document, null!, CancellationToken.None);
// Assert
var arraySchema = document.Components.Schemas["ArraySchema"] as OpenApiSchema;
Assert.IsNotNull(arraySchema);
Assert.IsNotNull(arraySchema.Properties);
var itemsProperty = arraySchema.Properties["Items"] as OpenApiSchema;
Assert.IsNotNull(itemsProperty);
Assert.IsNotNull(itemsProperty.Items);
Assert.IsInstanceOf<OpenApiSchemaReference>(itemsProperty.Items);
var itemReference = (OpenApiSchemaReference)itemsProperty.Items;
Assert.That(itemReference.Reference?.Id, Is.EqualTo("ItemSchema"));
}
[Test]
public async Task SchemaTransformAsync_Does_Nothing_For_NonMatching_Types()
{
// Arrange
var transformer = CreateTransformer();
var schema = new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties = new Dictionary<string, IOpenApiSchema>
{
["Name"] = new OpenApiSchema { Type = JsonSchemaType.String },
},
};
var jsonTypeInfo = _jsonSerializerOptions.GetTypeInfo(typeof(object));
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - Schema should remain unchanged (no discriminator added)
Assert.IsNull(schema.Discriminator);
Assert.IsNull(schema.OneOf);
}
[Test]
public async Task SchemaTransformAsync_Adds_ElementTypes_For_IApiElement()
{
// Arrange
var documentTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("article", "Article", isElement: false),
CreateContentTypeSchemaInfo("textBlock", "TextBlock", isElement: true),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetDocumentTypes())
.Returns(documentTypes);
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
var jsonTypeInfo = CreatePolymorphicJsonTypeInfo<IApiElement>();
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - Only element types should be included
_contentTypeSchemaServiceMock.Verify(x => x.GetDocumentTypes(), Times.Once);
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsNotNull(schema.OneOf);
Assert.AreEqual("contentType", schema.Discriminator.PropertyName);
Assert.AreEqual(1, schema.OneOf.Count);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("textBlock"));
Assert.IsFalse(schema.Discriminator.Mapping.ContainsKey("article"));
}
[Test]
public async Task SchemaTransformAsync_Adds_NonElementTypes_For_IApiContent()
{
// Arrange
var documentTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("article", "Article", isElement: false),
CreateContentTypeSchemaInfo("textBlock", "TextBlock", isElement: true),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetDocumentTypes())
.Returns(documentTypes);
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
var jsonTypeInfo = CreatePolymorphicJsonTypeInfo<IApiContent>();
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - Only non-element types should be included
_contentTypeSchemaServiceMock.Verify(x => x.GetDocumentTypes(), Times.Once);
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsNotNull(schema.OneOf);
Assert.AreEqual("contentType", schema.Discriminator.PropertyName);
Assert.AreEqual(1, schema.OneOf.Count);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("article"));
Assert.IsFalse(schema.Discriminator.Mapping.ContainsKey("textBlock"));
}
[Test]
public async Task SchemaTransformAsync_Adds_NonElementTypes_For_IApiContentResponse()
{
// Arrange
var documentTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("article", "Article", isElement: false),
CreateContentTypeSchemaInfo("textBlock", "TextBlock", isElement: true),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetDocumentTypes())
.Returns(documentTypes);
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
var jsonTypeInfo = CreatePolymorphicJsonTypeInfo<IApiContentResponse>();
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - Only non-element types should be included for IApiContentResponse
_contentTypeSchemaServiceMock.Verify(x => x.GetDocumentTypes(), Times.Once);
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsNotNull(schema.OneOf);
Assert.AreEqual("contentType", schema.Discriminator.PropertyName);
Assert.AreEqual(1, schema.OneOf.Count);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("article"));
Assert.IsFalse(schema.Discriminator.Mapping.ContainsKey("textBlock"));
}
[Test]
public async Task SchemaTransformAsync_Adds_MediaTypes_For_IApiMediaWithCropsResponse()
{
// Arrange
var mediaTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("image", "Image", isElement: false),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetMediaTypes())
.Returns(mediaTypes);
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
var jsonTypeInfo = CreatePolymorphicJsonTypeInfo<IApiMediaWithCropsResponse>();
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert
_contentTypeSchemaServiceMock.Verify(x => x.GetMediaTypes(), Times.Once);
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsNotNull(schema.OneOf);
Assert.AreEqual("mediaType", schema.Discriminator.PropertyName);
Assert.AreEqual(1, schema.OneOf.Count);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("image"));
}
[Test]
public async Task SchemaTransformAsync_Adds_MediaTypes_For_IApiMediaWithCrops()
{
// Arrange
var mediaTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("image", "Image", isElement: false),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetMediaTypes())
.Returns(mediaTypes);
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
var jsonTypeInfo = CreatePolymorphicJsonTypeInfo<IApiMediaWithCrops>();
var context = CreateSchemaContext(jsonTypeInfo);
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert
_contentTypeSchemaServiceMock.Verify(x => x.GetMediaTypes(), Times.Once);
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsNotNull(schema.OneOf);
Assert.AreEqual("mediaType", schema.Discriminator.PropertyName);
Assert.AreEqual(1, schema.OneOf.Count);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("image"));
}
[Test]
public async Task SchemaTransformAsync_Excludes_DocumentTypes_On_Deny_List()
{
// Arrange
var documentTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("publicArticle", "PublicArticle", isElement: false),
CreateContentTypeSchemaInfo("hiddenArticle", "HiddenArticle", isElement: false),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetDocumentTypes())
.Returns(documentTypes);
_deliveryApiSettingsMonitorMock
.Setup(x => x.CurrentValue)
.Returns(new DeliveryApiSettings
{
DisallowedContentTypeAliases = new HashSet<string> { "hiddenArticle" },
});
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
OpenApiSchemaTransformerContext context = CreateSchemaContext(CreatePolymorphicJsonTypeInfo<IApiContentResponse>());
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - the disallowed alias is filtered out before being emitted to the polymorphic union
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("publicArticle"));
Assert.IsFalse(schema.Discriminator.Mapping.ContainsKey("hiddenArticle"));
Assert.AreEqual(1, schema.OneOf?.Count);
}
[Test]
public async Task SchemaTransformAsync_Excludes_DocumentTypes_Not_On_Allow_List()
{
// Arrange
var documentTypes = new List<ContentTypeSchemaInfo>
{
CreateContentTypeSchemaInfo("articleA", "ArticleA", isElement: false),
CreateContentTypeSchemaInfo("articleB", "ArticleB", isElement: false),
CreateContentTypeSchemaInfo("articleC", "ArticleC", isElement: false),
};
_contentTypeSchemaServiceMock
.Setup(x => x.GetDocumentTypes())
.Returns(documentTypes);
_deliveryApiSettingsMonitorMock
.Setup(x => x.CurrentValue)
.Returns(new DeliveryApiSettings
{
AllowedContentTypeAliases = new HashSet<string> { "articleA", "articleC" },
});
var transformer = CreateTransformer();
var schema = new OpenApiSchema();
OpenApiSchemaTransformerContext context = CreateSchemaContext(CreatePolymorphicJsonTypeInfo<IApiContentResponse>());
// Act
await transformer.TransformAsync(schema, context, CancellationToken.None);
// Assert - only the explicitly allowed aliases are emitted
Assert.IsNotNull(schema.Discriminator);
Assert.IsNotNull(schema.Discriminator.Mapping);
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("articleA"));
Assert.IsFalse(schema.Discriminator.Mapping.ContainsKey("articleB"));
Assert.IsTrue(schema.Discriminator.Mapping.ContainsKey("articleC"));
Assert.AreEqual(2, schema.OneOf?.Count);
}
private ContentTypeSchemaTransformer CreateTransformer() =>
new(
_contentTypeSchemaServiceMock.Object,
_jsonOptionsMonitorMock.Object,
_deliveryApiSettingsMonitorMock.Object,
_loggerMock.Object);
private OpenApiSchemaTransformerContext CreateSchemaContext(JsonTypeInfo jsonTypeInfo) =>
new()
{
JsonTypeInfo = jsonTypeInfo,
JsonPropertyInfo = null,
ParameterDescription = null,
DocumentName = "test",
ApplicationServices = _services,
Document = new OpenApiDocument(),
};
private static JsonTypeInfo<T> CreatePolymorphicJsonTypeInfo<T>() =>
JsonTypeInfo.CreateJsonTypeInfo<T>(
new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver() });
private static ContentTypeSchemaInfo CreateContentTypeSchemaInfo(
string alias,
string schemaId,
bool isElement,
List<ContentTypePropertySchemaInfo>? properties = null) =>
new()
{
Alias = alias,
SchemaId = schemaId,
CompositionSchemaIds = [],
Properties = properties ?? [],
IsElement = isElement,
};
}
@@ -4,8 +4,6 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Tests.UnitTests.Umbraco.Core.ShortStringHelper;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Services;
@@ -27,8 +25,7 @@ public class ContentTypeSchemaServiceTests
_sut = new ContentTypeSchemaService(
_contentTypeServiceMock.Object,
_mediaTypeServiceMock.Object,
_publishedContentTypeCacheMock.Object,
new DefaultShortStringHelper(new DefaultShortStringHelperConfig()));
_publishedContentTypeCacheMock.Object);
}
[Test]
@@ -54,7 +51,7 @@ public class ContentTypeSchemaServiceTests
// Assert
Assert.That(result, Has.Count.EqualTo(1));
Assert.That(result.First().Alias, Is.EqualTo("cachedType"));
Assert.That(result.First().SchemaId, Is.EqualTo("Cachedtype"));
Assert.That(result.First().SchemaId, Is.EqualTo("CachedType"));
}
[Test]
@@ -106,8 +103,8 @@ public class ContentTypeSchemaServiceTests
// Assert
var schema = result.First();
Assert.That(schema.SchemaId, Is.EqualTo("Articlepage"));
Assert.That(schema.CompositionSchemaIds, Is.EquivalentTo(new[] { "Basepage", "Seocomposition" }));
Assert.That(schema.SchemaId, Is.EqualTo("ArticlePage"));
Assert.That(schema.CompositionSchemaIds, Is.EquivalentTo(new[] { "BasePage", "SeoComposition" }));
}
[Test]
@@ -176,6 +173,6 @@ public class ContentTypeSchemaServiceTests
// Assert
Assert.That(result, Has.Count.EqualTo(1));
Assert.That(result.First().Alias, Is.EqualTo("cachedType"));
Assert.That(result.First().SchemaId, Is.EqualTo("Cachedtype"));
Assert.That(result.First().SchemaId, Is.EqualTo("CachedType"));
}
}
+4
View File
@@ -0,0 +1,4 @@
node_modules/
dist/
**/api/*.gen.ts
**/api/umbraco-delivery.ts
+42
View File
@@ -0,0 +1,42 @@
# Delivery API client smoke tests
Reviewer-only branch (`v18/task/delivery-api-openapi-sample-content`). Houses a pre-seeded SQLite DB and four console projects that consume the Delivery API OpenAPI document with different generators (`orval`, `hey-api`, `kiota`, `nswag`). Not for merge.
## One-time setup
The DB ships in `src/Umbraco.Web.UI/umbraco/Data/Umbraco.Sample.sqlite.db`. To use it, point the web app at that file and enable the Delivery API.
After your first `dotnet build`, the project's auto-copy target writes `src/Umbraco.Web.UI/appsettings.json` from the template. Edit the generated file:
1. **Connection string** — change `umbracoDbDSN` to point at the committed sample DB:
```jsonc
"ConnectionStrings": {
"umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.Sample.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
"umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
}
```
2. **Delivery API + content type schemas** — add (or merge into) the `Umbraco:CMS` section:
```jsonc
"DeliveryApi": {
"Enabled": true,
"PublicAccess": true,
"Media": { "Enabled": true },
"OpenApi": { "GenerateContentTypeSchemas": true }
}
```
Then run `dotnet run --project src/Umbraco.Web.UI`. The web app should boot at `https://localhost:44339`, with the seeded `testPage` available at `/`.
## Running the clients
| Project | Command | Status |
| --- | --- | --- |
| `orval/` | `npm install && npm start` | Works — full property typing |
| `hey-api/` | `npm install && npm start` | Works — full property typing |
| `kiota/` | `dotnet run` | Compiles + runs, but property bags collapse to `AdditionalData`. See project README. |
| `nswag/` | `dotnet run` | **Build fails** with ~17 errors (Anonymous, MultinodeTreepicker, MediaPicker). Documented failure of NSwag against OpenAPI 3.1 polymorphic shapes. |
Each project's own README has the per-client details and caveats.
+25
View File
@@ -0,0 +1,25 @@
# @hey-api/openapi-ts client smoke test
Verifies that the Delivery API OpenAPI document produces a valid client when consumed by [@hey-api/openapi-ts](https://heyapi.dev) with the `@hey-api/client-fetch` runtime.
## Prerequisites
- Node.js 22 or later
- The committed SQLite DB and `appsettings.json` ship with this branch and already have `Umbraco:CMS:DeliveryApi:Enabled = true`, `Umbraco:CMS:DeliveryApi:OpenApi:GenerateContentTypeSchemas = true`, and a few sample content types and items.
- Run the web app: `dotnet run --project src/Umbraco.Web.UI`. It should be reachable at `https://localhost:44339`.
## Run
```bash
npm install
npm start
```
`npm start` regenerates the client from the live OpenAPI document, builds, and executes `app.ts`. The script lists the seeded content items and uses TypeScript discriminated unions on `contentType` to access type-specific properties.
## What this proves
- The generated TypeScript types compile (`tsc --build`).
- The polymorphic `IApiContentResponseModel` narrows correctly on the `contentType` discriminator.
- Composition properties (e.g. `metaDescription` from `seoMetadata`) appear on the composing type's properties model.
- A real HTTP request returns data shaped according to the spec.
@@ -0,0 +1,280 @@
// This file is auto-generated by @hey-api/openapi-ts
import { createSseClient } from '../core/serverSentEvents.gen.js';
import type { HttpMethod } from '../core/types.gen.js';
import { getValidRequestBody } from '../core/utils.gen.js';
import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen.js';
import {
buildUrl,
createConfig,
createInterceptors,
getParseAs,
mergeConfigs,
mergeHeaders,
setAuthParams,
} from './utils.gen.js';
type ReqInit = Omit<RequestInit, 'body' | 'headers'> & {
body?: any;
headers: ReturnType<typeof mergeHeaders>;
};
export const createClient = (config: Config = {}): Client => {
let _config = mergeConfigs(createConfig(), config);
const getConfig = (): Config => ({ ..._config });
const setConfig = (config: Config): Config => {
_config = mergeConfigs(_config, config);
return getConfig();
};
const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();
const beforeRequest = async <
TData = unknown,
TResponseStyle extends 'data' | 'fields' = 'fields',
ThrowOnError extends boolean = boolean,
Url extends string = string,
>(
options: RequestOptions<TData, TResponseStyle, ThrowOnError, Url>,
) => {
const opts = {
..._config,
...options,
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
await setAuthParams({
...opts,
security: opts.security,
});
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
// remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
const resolvedOpts = opts as typeof opts &
ResolvedRequestOptions<TResponseStyle, ThrowOnError, Url>;
const url = buildUrl(resolvedOpts);
return { opts: resolvedOpts, url };
};
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
const responseStyle = options.responseStyle ?? _config.responseStyle;
let request: Request | undefined;
let response: Response | undefined;
try {
const { opts, url } = await beforeRequest(options);
const requestInit: ReqInit = {
redirect: 'follow',
...opts,
body: getValidRequestBody(opts),
};
request = new Request(url, requestInit);
for (const fn of interceptors.request.fns) {
if (fn) {
request = await fn(request, opts);
}
}
// fetch must be assigned here, otherwise it would throw the error:
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
const _fetch = opts.fetch!;
response = await _fetch(request);
for (const fn of interceptors.response.fns) {
if (fn) {
response = await fn(response, request, opts);
}
}
const result = {
request,
response,
};
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
let emptyData: any;
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
break;
case 'formData':
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
case 'json':
default:
emptyData = {};
break;
}
return opts.responseStyle === 'data'
? emptyData
: {
data: emptyData,
...result,
};
}
let data: any;
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
case 'json': {
// Some servers return 200 with no Content-Length and empty body.
// response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
case 'stream':
return opts.responseStyle === 'data'
? response.body
: {
data: response.body,
...result,
};
}
if (parseAs === 'json') {
if (opts.responseValidator) {
await opts.responseValidator(data);
}
if (opts.responseTransformer) {
data = await opts.responseTransformer(data);
}
}
return opts.responseStyle === 'data'
? data
: {
data,
...result,
};
}
const textError = await response.text();
let jsonError: unknown;
try {
jsonError = JSON.parse(textError);
} catch {
// noop
}
throw jsonError ?? textError;
} catch (error) {
let finalError = error;
for (const fn of interceptors.error.fns) {
if (fn) {
finalError = await fn(finalError, response, request, options as ResolvedRequestOptions);
}
}
finalError = finalError || {};
if (throwOnError) {
throw finalError;
}
// TODO: we probably want to return error and improve types
return responseStyle === 'data'
? undefined
: {
error: finalError,
request,
response,
};
}
};
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
request({ ...options, method });
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
const { opts, url } = await beforeRequest(options);
return createSseClient({
...opts,
body: opts.body as BodyInit | null | undefined,
method,
onRequest: async (url, init) => {
let request = new Request(url, init);
for (const fn of interceptors.request.fns) {
if (fn) {
request = await fn(request, opts);
}
}
return request;
},
serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,
url,
});
};
const _buildUrl: Client['buildUrl'] = (options) => buildUrl({ ..._config, ...options });
return {
buildUrl: _buildUrl,
connect: makeMethodFn('CONNECT'),
delete: makeMethodFn('DELETE'),
get: makeMethodFn('GET'),
getConfig,
head: makeMethodFn('HEAD'),
interceptors,
options: makeMethodFn('OPTIONS'),
patch: makeMethodFn('PATCH'),
post: makeMethodFn('POST'),
put: makeMethodFn('PUT'),
request,
setConfig,
sse: {
connect: makeSseFn('CONNECT'),
delete: makeSseFn('DELETE'),
get: makeSseFn('GET'),
head: makeSseFn('HEAD'),
options: makeSseFn('OPTIONS'),
patch: makeSseFn('PATCH'),
post: makeSseFn('POST'),
put: makeSseFn('PUT'),
trace: makeSseFn('TRACE'),
},
trace: makeMethodFn('TRACE'),
} as Client;
};
+25
View File
@@ -0,0 +1,25 @@
// This file is auto-generated by @hey-api/openapi-ts
export type { Auth } from '../core/auth.gen.js';
export type { QuerySerializerOptions } from '../core/bodySerializer.gen.js';
export {
formDataBodySerializer,
jsonBodySerializer,
urlSearchParamsBodySerializer,
} from '../core/bodySerializer.gen.js';
export { buildClientParams } from '../core/params.gen.js';
export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen.js';
export { createClient } from './client.gen.js';
export type {
Client,
ClientOptions,
Config,
CreateClientConfig,
Options,
RequestOptions,
RequestResult,
ResolvedRequestOptions,
ResponseStyle,
TDataShape,
} from './types.gen.js';
export { createConfig, mergeHeaders } from './utils.gen.js';
@@ -0,0 +1,217 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { Auth } from '../core/auth.gen.js';
import type {
ServerSentEventsOptions,
ServerSentEventsResult,
} from '../core/serverSentEvents.gen.js';
import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen.js';
import type { Middleware } from './utils.gen.js';
export type ResponseStyle = 'data' | 'fields';
export interface Config<T extends ClientOptions = ClientOptions>
extends Omit<RequestInit, 'body' | 'headers' | 'method'>, CoreConfig {
/**
* Base URL for all requests made by this client.
*/
baseUrl?: T['baseUrl'];
/**
* Fetch API implementation. You can use this option to provide a custom
* fetch instance.
*
* @default globalThis.fetch
*/
fetch?: typeof fetch;
/**
* Please don't use the Fetch client for Next.js applications. The `next`
* options won't have any effect.
*
* Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
*/
next?: never;
/**
* Return the response data parsed in a specified format. By default, `auto`
* will infer the appropriate method from the `Content-Type` response header.
* You can override this behavior with any of the {@link Body} methods.
* Select `stream` if you don't want to parse response data at all.
*
* @default 'auto'
*/
parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
/**
* Should we return only data or multiple fields (data, error, response, etc.)?
*
* @default 'fields'
*/
responseStyle?: ResponseStyle;
/**
* Throw an error instead of returning it in the response?
*
* @default false
*/
throwOnError?: T['throwOnError'];
}
export interface RequestOptions<
TData = unknown,
TResponseStyle extends ResponseStyle = 'fields',
ThrowOnError extends boolean = boolean,
Url extends string = string,
>
extends
Config<{
responseStyle: TResponseStyle;
throwOnError: ThrowOnError;
}>,
Pick<
ServerSentEventsOptions<TData>,
| 'onRequest'
| 'onSseError'
| 'onSseEvent'
| 'sseDefaultRetryDelay'
| 'sseMaxRetryAttempts'
| 'sseMaxRetryDelay'
> {
/**
* Any body that you want to add to your request.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
*/
body?: unknown;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
/**
* Security mechanism(s) to use for the request.
*/
security?: ReadonlyArray<Auth>;
url: Url;
}
export interface ResolvedRequestOptions<
TResponseStyle extends ResponseStyle = 'fields',
ThrowOnError extends boolean = boolean,
Url extends string = string,
> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
headers: Headers;
serializedBody?: string;
}
export type RequestResult<
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = boolean,
TResponseStyle extends ResponseStyle = 'fields',
> = ThrowOnError extends true
? Promise<
TResponseStyle extends 'data'
? TData extends Record<string, unknown>
? TData[keyof TData]
: TData
: {
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
request: Request;
response: Response;
}
>
: Promise<
TResponseStyle extends 'data'
? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined
: (
| {
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
error: undefined;
}
| {
data: undefined;
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
}
) & {
/** request may be undefined, because error may be from building the request object itself */
request?: Request;
/** response may be undefined, because error may be from building the request object itself or from a network error */
response?: Response;
}
>;
export interface ClientOptions {
baseUrl?: string;
responseStyle?: ResponseStyle;
throwOnError?: boolean;
}
type MethodFn = <
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = false,
TResponseStyle extends ResponseStyle = 'fields',
>(
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>,
) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
type SseFn = <
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = false,
TResponseStyle extends ResponseStyle = 'fields',
>(
options: Omit<RequestOptions<never, TResponseStyle, ThrowOnError>, 'method'>,
) => Promise<ServerSentEventsResult<TData, TError>>;
type RequestFn = <
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = false,
TResponseStyle extends ResponseStyle = 'fields',
>(
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> &
Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>,
) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
type BuildUrlFn = <
TData extends {
body?: unknown;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
url: string;
},
>(
options: TData & Options<TData>,
) => string;
export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
};
/**
* The `createClientConfig()` function will be called on client initialization
* and the returned object will become the client's initial configuration.
*
* You may want to initialize your client this way instead of calling
* `setConfig()`. This is useful for example if you're using Next.js
* to ensure your client always has the correct values.
*/
export type CreateClientConfig<T extends ClientOptions = ClientOptions> = (
override?: Config<ClientOptions & T>,
) => Config<Required<ClientOptions> & T>;
export interface TDataShape {
body?: unknown;
headers?: unknown;
path?: unknown;
query?: unknown;
url: string;
}
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
export type Options<
TData extends TDataShape = TDataShape,
ThrowOnError extends boolean = boolean,
TResponse = unknown,
TResponseStyle extends ResponseStyle = 'fields',
> = OmitKeys<
RequestOptions<TResponse, TResponseStyle, ThrowOnError>,
'body' | 'path' | 'query' | 'url'
> &
([TData] extends [never] ? unknown : Omit<TData, 'url'>);
@@ -0,0 +1,318 @@
// This file is auto-generated by @hey-api/openapi-ts
import { getAuthToken } from '../core/auth.gen.js';
import type { QuerySerializerOptions } from '../core/bodySerializer.gen.js';
import { jsonBodySerializer } from '../core/bodySerializer.gen.js';
import {
serializeArrayParam,
serializeObjectParam,
serializePrimitiveParam,
} from '../core/pathSerializer.gen.js';
import { getUrl } from '../core/utils.gen.js';
import type { Client, ClientOptions, Config, RequestOptions } from './types.gen.js';
export const createQuerySerializer = <T = unknown>({
parameters = {},
...args
}: QuerySerializerOptions = {}) => {
const querySerializer = (queryParams: T) => {
const search: string[] = [];
if (queryParams && typeof queryParams === 'object') {
for (const name in queryParams) {
const value = queryParams[name];
if (value === undefined || value === null) {
continue;
}
const options = parameters[name] || args;
if (Array.isArray(value)) {
const serializedArray = serializeArrayParam({
allowReserved: options.allowReserved,
explode: true,
name,
style: 'form',
value,
...options.array,
});
if (serializedArray) search.push(serializedArray);
} else if (typeof value === 'object') {
const serializedObject = serializeObjectParam({
allowReserved: options.allowReserved,
explode: true,
name,
style: 'deepObject',
value: value as Record<string, unknown>,
...options.object,
});
if (serializedObject) search.push(serializedObject);
} else {
const serializedPrimitive = serializePrimitiveParam({
allowReserved: options.allowReserved,
name,
value: value as string,
});
if (serializedPrimitive) search.push(serializedPrimitive);
}
}
}
return search.join('&');
};
return querySerializer;
};
/**
* Infers parseAs value from provided Content-Type header.
*/
export const getParseAs = (contentType: string | null): Exclude<Config['parseAs'], 'auto'> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return 'stream';
}
const cleanContent = contentType.split(';')[0]?.trim();
if (!cleanContent) {
return;
}
if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) {
return 'json';
}
if (cleanContent === 'multipart/form-data') {
return 'formData';
}
if (
['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type))
) {
return 'blob';
}
if (cleanContent.startsWith('text/')) {
return 'text';
}
return;
};
const checkForExistence = (
options: Pick<RequestOptions, 'auth' | 'query'> & {
headers: Headers;
},
name?: string,
): boolean => {
if (!name) {
return false;
}
if (
options.headers.has(name) ||
options.query?.[name] ||
options.headers.get('Cookie')?.includes(`${name}=`)
) {
return true;
}
return false;
};
export const setAuthParams = async ({
security,
...options
}: Pick<Required<RequestOptions>, 'security'> &
Pick<RequestOptions, 'auth' | 'query'> & {
headers: Headers;
}) => {
for (const auth of security) {
if (checkForExistence(options, auth.name)) {
continue;
}
const token = await getAuthToken(auth, options.auth);
if (!token) {
continue;
}
const name = auth.name ?? 'Authorization';
switch (auth.in) {
case 'query':
if (!options.query) {
options.query = {};
}
options.query[name] = token;
break;
case 'cookie':
options.headers.append('Cookie', `${name}=${token}`);
break;
case 'header':
default:
options.headers.set(name, token);
break;
}
}
};
export const buildUrl: Client['buildUrl'] = (options) =>
getUrl({
baseUrl: options.baseUrl as string,
path: options.path,
query: options.query,
querySerializer:
typeof options.querySerializer === 'function'
? options.querySerializer
: createQuerySerializer(options.querySerializer),
url: options.url,
});
export const mergeConfigs = (a: Config, b: Config): Config => {
const config = { ...a, ...b };
if (config.baseUrl?.endsWith('/')) {
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
}
config.headers = mergeHeaders(a.headers, b.headers);
return config;
};
const headersEntries = (headers: Headers): Array<[string, string]> => {
const entries: Array<[string, string]> = [];
headers.forEach((value, key) => {
entries.push([key, value]);
});
return entries;
};
export const mergeHeaders = (
...headers: Array<Required<Config>['headers'] | undefined>
): Headers => {
const mergedHeaders = new Headers();
for (const header of headers) {
if (!header) {
continue;
}
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
for (const [key, value] of iterator) {
if (value === null) {
mergedHeaders.delete(key);
} else if (Array.isArray(value)) {
for (const v of value) {
mergedHeaders.append(key, v as string);
}
} else if (value !== undefined) {
// assume object headers are meant to be JSON stringified, i.e., their
// content value in OpenAPI specification is 'application/json'
mergedHeaders.set(
key,
typeof value === 'object' ? JSON.stringify(value) : (value as string),
);
}
}
}
return mergedHeaders;
};
type ErrInterceptor<Err, Res, Req, Options> = (
error: Err,
/** response may be undefined due to a network error where no response object is produced */
response: Res | undefined,
/** request may be undefined, because error may be from building the request object itself */
request: Req | undefined,
options: Options,
) => Err | Promise<Err>;
type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
type ResInterceptor<Res, Req, Options> = (
response: Res,
request: Req,
options: Options,
) => Res | Promise<Res>;
class Interceptors<Interceptor> {
fns: Array<Interceptor | null> = [];
clear(): void {
this.fns = [];
}
eject(id: number | Interceptor): void {
const index = this.getInterceptorIndex(id);
if (this.fns[index]) {
this.fns[index] = null;
}
}
exists(id: number | Interceptor): boolean {
const index = this.getInterceptorIndex(id);
return Boolean(this.fns[index]);
}
getInterceptorIndex(id: number | Interceptor): number {
if (typeof id === 'number') {
return this.fns[id] ? id : -1;
}
return this.fns.indexOf(id);
}
update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false {
const index = this.getInterceptorIndex(id);
if (this.fns[index]) {
this.fns[index] = fn;
return id;
}
return false;
}
use(fn: Interceptor): number {
this.fns.push(fn);
return this.fns.length - 1;
}
}
export interface Middleware<Req, Res, Err, Options> {
error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
request: Interceptors<ReqInterceptor<Req, Options>>;
response: Interceptors<ResInterceptor<Res, Req, Options>>;
}
export const createInterceptors = <Req, Res, Err, Options>(): Middleware<
Req,
Res,
Err,
Options
> => ({
error: new Interceptors<ErrInterceptor<Err, Res, Req, Options>>(),
request: new Interceptors<ReqInterceptor<Req, Options>>(),
response: new Interceptors<ResInterceptor<Res, Req, Options>>(),
});
const defaultQuerySerializer = createQuerySerializer({
allowReserved: false,
array: {
explode: true,
style: 'form',
},
object: {
explode: true,
style: 'deepObject',
},
});
const defaultHeaders = {
'Content-Type': 'application/json',
};
export const createConfig = <T extends ClientOptions = ClientOptions>(
override: Config<Omit<ClientOptions, keyof T> & T> = {},
): Config<Omit<ClientOptions, keyof T> & T> => ({
...jsonBodySerializer,
headers: defaultHeaders,
parseAs: 'auto',
querySerializer: defaultQuerySerializer,
...override,
});
@@ -0,0 +1,41 @@
// This file is auto-generated by @hey-api/openapi-ts
export type AuthToken = string | undefined;
export interface Auth {
/**
* Which part of the request do we use to send the auth?
*
* @default 'header'
*/
in?: 'header' | 'query' | 'cookie';
/**
* Header or query parameter name.
*
* @default 'Authorization'
*/
name?: string;
scheme?: 'basic' | 'bearer';
type: 'apiKey' | 'http';
}
export const getAuthToken = async (
auth: Auth,
callback: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken,
): Promise<string | undefined> => {
const token = typeof callback === 'function' ? await callback(auth) : callback;
if (!token) {
return;
}
if (auth.scheme === 'bearer') {
return `Bearer ${token}`;
}
if (auth.scheme === 'basic') {
return `Basic ${btoa(token)}`;
}
return token;
};
@@ -0,0 +1,82 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen.js';
export type QuerySerializer = (query: Record<string, unknown>) => string;
export type BodySerializer = (body: unknown) => unknown;
type QuerySerializerOptionsObject = {
allowReserved?: boolean;
array?: Partial<SerializerOptions<ArrayStyle>>;
object?: Partial<SerializerOptions<ObjectStyle>>;
};
export type QuerySerializerOptions = QuerySerializerOptionsObject & {
/**
* Per-parameter serialization overrides. When provided, these settings
* override the global array/object settings for specific parameter names.
*/
parameters?: Record<string, QuerySerializerOptionsObject>;
};
const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => {
if (typeof value === 'string' || value instanceof Blob) {
data.append(key, value);
} else if (value instanceof Date) {
data.append(key, value.toISOString());
} else {
data.append(key, JSON.stringify(value));
}
};
const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => {
if (typeof value === 'string') {
data.append(key, value);
} else {
data.append(key, JSON.stringify(value));
}
};
export const formDataBodySerializer = {
bodySerializer: (body: unknown): FormData => {
const data = new FormData();
Object.entries(body as Record<string, unknown>).forEach(([key, value]) => {
if (value === undefined || value === null) {
return;
}
if (Array.isArray(value)) {
value.forEach((v) => serializeFormDataPair(data, key, v));
} else {
serializeFormDataPair(data, key, value);
}
});
return data;
},
};
export const jsonBodySerializer = {
bodySerializer: (body: unknown): string =>
JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)),
};
export const urlSearchParamsBodySerializer = {
bodySerializer: (body: unknown): string => {
const data = new URLSearchParams();
Object.entries(body as Record<string, unknown>).forEach(([key, value]) => {
if (value === undefined || value === null) {
return;
}
if (Array.isArray(value)) {
value.forEach((v) => serializeUrlSearchParamsPair(data, key, v));
} else {
serializeUrlSearchParamsPair(data, key, value);
}
});
return data.toString();
},
};
@@ -0,0 +1,169 @@
// This file is auto-generated by @hey-api/openapi-ts
type Slot = 'body' | 'headers' | 'path' | 'query';
export type Field =
| {
in: Exclude<Slot, 'body'>;
/**
* Field name. This is the name we want the user to see and use.
*/
key: string;
/**
* Field mapped name. This is the name we want to use in the request.
* If omitted, we use the same value as `key`.
*/
map?: string;
}
| {
in: Extract<Slot, 'body'>;
/**
* Key isn't required for bodies.
*/
key?: string;
map?: string;
}
| {
/**
* Field name. This is the name we want the user to see and use.
*/
key: string;
/**
* Field mapped name. This is the name we want to use in the request.
* If `in` is omitted, `map` aliases `key` to the transport layer.
*/
map: Slot;
};
export interface Fields {
allowExtra?: Partial<Record<Slot, boolean>>;
args?: ReadonlyArray<Field>;
}
export type FieldsConfig = ReadonlyArray<Field | Fields>;
const extraPrefixesMap: Record<string, Slot> = {
$body_: 'body',
$headers_: 'headers',
$path_: 'path',
$query_: 'query',
};
const extraPrefixes = Object.entries(extraPrefixesMap);
type KeyMap = Map<
string,
| {
in: Slot;
map?: string;
}
| {
in?: never;
map: Slot;
}
>;
const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
if (!map) {
map = new Map();
}
for (const config of fields) {
if ('in' in config) {
if (config.key) {
map.set(config.key, {
in: config.in,
map: config.map,
});
}
} else if ('key' in config) {
map.set(config.key, {
map: config.map,
});
} else if (config.args) {
buildKeyMap(config.args, map);
}
}
return map;
};
interface Params {
body: unknown;
headers: Record<string, unknown>;
path: Record<string, unknown>;
query: Record<string, unknown>;
}
const stripEmptySlots = (params: Params) => {
for (const [slot, value] of Object.entries(params)) {
if (value && typeof value === 'object' && !Array.isArray(value) && !Object.keys(value).length) {
delete params[slot as Slot];
}
}
};
export const buildClientParams = (args: ReadonlyArray<unknown>, fields: FieldsConfig) => {
const params: Params = {
body: {},
headers: {},
path: {},
query: {},
};
const map = buildKeyMap(fields);
let config: FieldsConfig[number] | undefined;
for (const [index, arg] of args.entries()) {
if (fields[index]) {
config = fields[index];
}
if (!config) {
continue;
}
if ('in' in config) {
if (config.key) {
const field = map.get(config.key)!;
const name = field.map || config.key;
if (field.in) {
(params[field.in] as Record<string, unknown>)[name] = arg;
}
} else {
params.body = arg;
}
} else {
for (const [key, value] of Object.entries(arg ?? {})) {
const field = map.get(key);
if (field) {
if (field.in) {
const name = field.map || key;
(params[field.in] as Record<string, unknown>)[name] = value;
} else {
params[field.map] = value;
}
} else {
const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix));
if (extra) {
const [prefix, slot] = extra;
(params[slot] as Record<string, unknown>)[key.slice(prefix.length)] = value;
} else if ('allowExtra' in config && config.allowExtra) {
for (const [slot, allowed] of Object.entries(config.allowExtra)) {
if (allowed) {
(params[slot as Slot] as Record<string, unknown>)[key] = value;
break;
}
}
}
}
}
}
}
stripEmptySlots(params);
return params;
};
@@ -0,0 +1,171 @@
// This file is auto-generated by @hey-api/openapi-ts
interface SerializeOptions<T> extends SerializePrimitiveOptions, SerializerOptions<T> {}
interface SerializePrimitiveOptions {
allowReserved?: boolean;
name: string;
}
export interface SerializerOptions<T> {
/**
* @default true
*/
explode: boolean;
style: T;
}
export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
export type ArraySeparatorStyle = ArrayStyle | MatrixStyle;
type MatrixStyle = 'label' | 'matrix' | 'simple';
export type ObjectStyle = 'form' | 'deepObject';
type ObjectSeparatorStyle = ObjectStyle | MatrixStyle;
interface SerializePrimitiveParam extends SerializePrimitiveOptions {
value: string;
}
export const separatorArrayExplode = (style: ArraySeparatorStyle) => {
switch (style) {
case 'label':
return '.';
case 'matrix':
return ';';
case 'simple':
return ',';
default:
return '&';
}
};
export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => {
switch (style) {
case 'form':
return ',';
case 'pipeDelimited':
return '|';
case 'spaceDelimited':
return '%20';
default:
return ',';
}
};
export const separatorObjectExplode = (style: ObjectSeparatorStyle) => {
switch (style) {
case 'label':
return '.';
case 'matrix':
return ';';
case 'simple':
return ',';
default:
return '&';
}
};
export const serializeArrayParam = ({
allowReserved,
explode,
name,
style,
value,
}: SerializeOptions<ArraySeparatorStyle> & {
value: unknown[];
}) => {
if (!explode) {
const joinedValues = (
allowReserved ? value : value.map((v) => encodeURIComponent(v as string))
).join(separatorArrayNoExplode(style));
switch (style) {
case 'label':
return `.${joinedValues}`;
case 'matrix':
return `;${name}=${joinedValues}`;
case 'simple':
return joinedValues;
default:
return `${name}=${joinedValues}`;
}
}
const separator = separatorArrayExplode(style);
const joinedValues = value
.map((v) => {
if (style === 'label' || style === 'simple') {
return allowReserved ? v : encodeURIComponent(v as string);
}
return serializePrimitiveParam({
allowReserved,
name,
value: v as string,
});
})
.join(separator);
return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
};
export const serializePrimitiveParam = ({
allowReserved,
name,
value,
}: SerializePrimitiveParam) => {
if (value === undefined || value === null) {
return '';
}
if (typeof value === 'object') {
throw new Error(
'Deeply-nested arrays/objects arent supported. Provide your own `querySerializer()` to handle these.',
);
}
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
};
export const serializeObjectParam = ({
allowReserved,
explode,
name,
style,
value,
valueOnly,
}: SerializeOptions<ObjectSeparatorStyle> & {
value: Record<string, unknown> | Date;
valueOnly?: boolean;
}) => {
if (value instanceof Date) {
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
}
if (style !== 'deepObject' && !explode) {
let values: string[] = [];
Object.entries(value).forEach(([key, v]) => {
values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)];
});
const joinedValues = values.join(',');
switch (style) {
case 'form':
return `${name}=${joinedValues}`;
case 'label':
return `.${joinedValues}`;
case 'matrix':
return `;${name}=${joinedValues}`;
default:
return joinedValues;
}
}
const separator = separatorObjectExplode(style);
const joinedValues = Object.entries(value)
.map(([key, v]) =>
serializePrimitiveParam({
allowReserved,
name: style === 'deepObject' ? `${name}[${key}]` : key,
value: v as string,
}),
)
.join(separator);
return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
};
@@ -0,0 +1,117 @@
// This file is auto-generated by @hey-api/openapi-ts
/**
* JSON-friendly union that mirrors what Pinia Colada can hash.
*/
export type JsonValue =
| null
| string
| number
| boolean
| JsonValue[]
| { [key: string]: JsonValue };
/**
* Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
*/
export const queryKeyJsonReplacer = (_key: string, value: unknown) => {
if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
return undefined;
}
if (typeof value === 'bigint') {
return value.toString();
}
if (value instanceof Date) {
return value.toISOString();
}
return value;
};
/**
* Safely stringifies a value and parses it back into a JsonValue.
*/
export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => {
try {
const json = JSON.stringify(input, queryKeyJsonReplacer);
if (json === undefined) {
return undefined;
}
return JSON.parse(json) as JsonValue;
} catch {
return undefined;
}
};
/**
* Detects plain objects (including objects with a null prototype).
*/
const isPlainObject = (value: unknown): value is Record<string, unknown> => {
if (value === null || typeof value !== 'object') {
return false;
}
const prototype = Object.getPrototypeOf(value as object);
return prototype === Object.prototype || prototype === null;
};
/**
* Turns URLSearchParams into a sorted JSON object for deterministic keys.
*/
const serializeSearchParams = (params: URLSearchParams): JsonValue => {
const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b));
const result: Record<string, JsonValue> = {};
for (const [key, value] of entries) {
const existing = result[key];
if (existing === undefined) {
result[key] = value;
continue;
}
if (Array.isArray(existing)) {
(existing as string[]).push(value);
} else {
result[key] = [existing, value];
}
}
return result;
};
/**
* Normalizes any accepted value into a JSON-friendly shape for query keys.
*/
export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => {
if (value === null) {
return null;
}
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
return value;
}
if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
return undefined;
}
if (typeof value === 'bigint') {
return value.toString();
}
if (value instanceof Date) {
return value.toISOString();
}
if (Array.isArray(value)) {
return stringifyToJsonValue(value);
}
if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) {
return serializeSearchParams(value);
}
if (isPlainObject(value)) {
return stringifyToJsonValue(value);
}
return undefined;
};
@@ -0,0 +1,242 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { Config } from './types.gen.js';
export type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> &
Pick<Config, 'method' | 'responseTransformer' | 'responseValidator'> & {
/**
* Fetch API implementation. You can use this option to provide a custom
* fetch instance.
*
* @default globalThis.fetch
*/
fetch?: typeof fetch;
/**
* Implementing clients can call request interceptors inside this hook.
*/
onRequest?: (url: string, init: RequestInit) => Promise<Request>;
/**
* Callback invoked when a network or parsing error occurs during streaming.
*
* This option applies only if the endpoint returns a stream of events.
*
* @param error The error that occurred.
*/
onSseError?: (error: unknown) => void;
/**
* Callback invoked when an event is streamed from the server.
*
* This option applies only if the endpoint returns a stream of events.
*
* @param event Event streamed from the server.
* @returns Nothing (void).
*/
onSseEvent?: (event: StreamEvent<TData>) => void;
serializedBody?: RequestInit['body'];
/**
* Default retry delay in milliseconds.
*
* This option applies only if the endpoint returns a stream of events.
*
* @default 3000
*/
sseDefaultRetryDelay?: number;
/**
* Maximum number of retry attempts before giving up.
*/
sseMaxRetryAttempts?: number;
/**
* Maximum retry delay in milliseconds.
*
* Applies only when exponential backoff is used.
*
* This option applies only if the endpoint returns a stream of events.
*
* @default 30000
*/
sseMaxRetryDelay?: number;
/**
* Optional sleep function for retry backoff.
*
* Defaults to using `setTimeout`.
*/
sseSleepFn?: (ms: number) => Promise<void>;
url: string;
};
export interface StreamEvent<TData = unknown> {
data: TData;
event?: string;
id?: string;
retry?: number;
}
export type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
stream: AsyncGenerator<
TData extends Record<string, unknown> ? TData[keyof TData] : TData,
TReturn,
TNext
>;
};
export function createSseClient<TData = unknown>({
onRequest,
onSseError,
onSseEvent,
responseTransformer,
responseValidator,
sseDefaultRetryDelay,
sseMaxRetryAttempts,
sseMaxRetryDelay,
sseSleepFn,
url,
...options
}: ServerSentEventsOptions): ServerSentEventsResult<TData> {
let lastEventId: string | undefined;
const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
const createStream = async function* () {
let retryDelay: number = sseDefaultRetryDelay ?? 3000;
let attempt = 0;
const signal = options.signal ?? new AbortController().signal;
while (true) {
if (signal.aborted) break;
attempt++;
const headers =
options.headers instanceof Headers
? options.headers
: new Headers(options.headers as Record<string, string> | undefined);
if (lastEventId !== undefined) {
headers.set('Last-Event-ID', lastEventId);
}
try {
const requestInit: RequestInit = {
redirect: 'follow',
...options,
body: options.serializedBody,
headers,
signal,
};
let request = new Request(url, requestInit);
if (onRequest) {
request = await onRequest(url, requestInit);
}
// fetch must be assigned here, otherwise it would throw the error:
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
const _fetch = options.fetch ?? globalThis.fetch;
const response = await _fetch(request);
if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
if (!response.body) throw new Error('No body in SSE response');
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
let buffer = '';
const abortHandler = () => {
try {
reader.cancel();
} catch {
// noop
}
};
signal.addEventListener('abort', abortHandler);
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += value;
buffer = buffer.replace(/\r\n?/g, '\n'); // normalize line endings
const chunks = buffer.split('\n\n');
buffer = chunks.pop() ?? '';
for (const chunk of chunks) {
const lines = chunk.split('\n');
const dataLines: Array<string> = [];
let eventName: string | undefined;
for (const line of lines) {
if (line.startsWith('data:')) {
dataLines.push(line.replace(/^data:\s*/, ''));
} else if (line.startsWith('event:')) {
eventName = line.replace(/^event:\s*/, '');
} else if (line.startsWith('id:')) {
lastEventId = line.replace(/^id:\s*/, '');
} else if (line.startsWith('retry:')) {
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10);
if (!Number.isNaN(parsed)) {
retryDelay = parsed;
}
}
}
let data: unknown;
let parsedJson = false;
if (dataLines.length) {
const rawData = dataLines.join('\n');
try {
data = JSON.parse(rawData);
parsedJson = true;
} catch {
data = rawData;
}
}
if (parsedJson) {
if (responseValidator) {
await responseValidator(data);
}
if (responseTransformer) {
data = await responseTransformer(data);
}
}
onSseEvent?.({
data,
event: eventName,
id: lastEventId,
retry: retryDelay,
});
if (dataLines.length) {
yield data as any;
}
}
}
} finally {
signal.removeEventListener('abort', abortHandler);
reader.releaseLock();
}
break; // exit loop on normal completion
} catch (error) {
// connection failed or aborted; retry after delay
onSseError?.(error);
if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) {
break; // stop after firing error
}
// exponential backoff: double retry each attempt, cap at 30s
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
await sleep(backoff);
}
}
};
const stream = createStream();
return { stream };
}
+104
View File
@@ -0,0 +1,104 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { Auth, AuthToken } from './auth.gen.js';
import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen.js';
export type HttpMethod =
| 'connect'
| 'delete'
| 'get'
| 'head'
| 'options'
| 'patch'
| 'post'
| 'put'
| 'trace';
export type Client<
RequestFn = never,
Config = unknown,
MethodFn = never,
BuildUrlFn = never,
SseFn = never,
> = {
/**
* Returns the final request URL.
*/
buildUrl: BuildUrlFn;
getConfig: () => Config;
request: RequestFn;
setConfig: (config: Config) => Config;
} & {
[K in HttpMethod]: MethodFn;
} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } });
export interface Config {
/**
* Auth token or a function returning auth token. The resolved value will be
* added to the request payload as defined by its `security` array.
*/
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
/**
* A function for serializing request body parameter. By default,
* {@link JSON.stringify()} will be used.
*/
bodySerializer?: BodySerializer | null;
/**
* An object containing any HTTP headers that you want to pre-populate your
* `Headers` object with.
*
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
*/
headers?:
| RequestInit['headers']
| Record<
string,
string | number | boolean | (string | number | boolean)[] | null | undefined | unknown
>;
/**
* The request method.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
*/
method?: Uppercase<HttpMethod>;
/**
* A function for serializing request query parameters. By default, arrays
* will be exploded in form style, objects will be exploded in deepObject
* style, and reserved characters are percent-encoded.
*
* This method will have no effect if the native `paramsSerializer()` Axios
* API function is used.
*
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
*/
querySerializer?: QuerySerializer | QuerySerializerOptions;
/**
* A function validating request data. This is useful if you want to ensure
* the request conforms to the desired shape, so it can be safely sent to
* the server.
*/
requestValidator?: (data: unknown) => Promise<unknown>;
/**
* A function transforming response data before it's returned. This is useful
* for post-processing data, e.g., converting ISO strings into Date objects.
*/
responseTransformer?: (data: unknown) => Promise<unknown>;
/**
* A function validating response data. This is useful if you want to ensure
* the response conforms to the desired shape, so it can be safely passed to
* the transformers and returned to the user.
*/
responseValidator?: (data: unknown) => Promise<unknown>;
}
type IsExactlyNeverOrNeverUndefined<T> = [T] extends [never]
? true
: [T] extends [never | undefined]
? [undefined] extends [T]
? false
: true
: false;
export type OmitNever<T extends Record<string, unknown>> = {
[K in keyof T as IsExactlyNeverOrNeverUndefined<T[K]> extends true ? never : K]: T[K];
};
+140
View File
@@ -0,0 +1,140 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { BodySerializer, QuerySerializer } from './bodySerializer.gen.js';
import {
type ArraySeparatorStyle,
serializeArrayParam,
serializeObjectParam,
serializePrimitiveParam,
} from './pathSerializer.gen.js';
export interface PathSerializer {
path: Record<string, unknown>;
url: string;
}
export const PATH_PARAM_RE = /\{[^{}]+\}/g;
export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
let url = _url;
const matches = _url.match(PATH_PARAM_RE);
if (matches) {
for (const match of matches) {
let explode = false;
let name = match.substring(1, match.length - 1);
let style: ArraySeparatorStyle = 'simple';
if (name.endsWith('*')) {
explode = true;
name = name.substring(0, name.length - 1);
}
if (name.startsWith('.')) {
name = name.substring(1);
style = 'label';
} else if (name.startsWith(';')) {
name = name.substring(1);
style = 'matrix';
}
const value = path[name];
if (value === undefined || value === null) {
continue;
}
if (Array.isArray(value)) {
url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
continue;
}
if (typeof value === 'object') {
url = url.replace(
match,
serializeObjectParam({
explode,
name,
style,
value: value as Record<string, unknown>,
valueOnly: true,
}),
);
continue;
}
if (style === 'matrix') {
url = url.replace(
match,
`;${serializePrimitiveParam({
name,
value: value as string,
})}`,
);
continue;
}
const replaceValue = encodeURIComponent(
style === 'label' ? `.${value as string}` : (value as string),
);
url = url.replace(match, replaceValue);
}
}
return url;
};
export const getUrl = ({
baseUrl,
path,
query,
querySerializer,
url: _url,
}: {
baseUrl?: string;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
querySerializer: QuerySerializer;
url: string;
}) => {
const pathUrl = _url.startsWith('/') ? _url : `/${_url}`;
let url = (baseUrl ?? '') + pathUrl;
if (path) {
url = defaultPathSerializer({ path, url });
}
let search = query ? querySerializer(query) : '';
if (search.startsWith('?')) {
search = search.substring(1);
}
if (search) {
url += `?${search}`;
}
return url;
};
export function getValidRequestBody(options: {
body?: unknown;
bodySerializer?: BodySerializer | null;
serializedBody?: unknown;
}) {
const hasBody = options.body !== undefined;
const isSerializedBody = hasBody && options.bodySerializer;
if (isSerializedBody) {
if ('serializedBody' in options) {
const hasSerializedBody =
options.serializedBody !== undefined && options.serializedBody !== '';
return hasSerializedBody ? options.serializedBody : null;
}
// not all clients implement a serializedBody property (i.e., client-axios)
return options.body !== '' ? options.body : null;
}
// plain/text body
if (hasBody) {
return options.body;
}
// no body was provided
return undefined;
}
+4
View File
@@ -0,0 +1,4 @@
// This file is auto-generated by @hey-api/openapi-ts
export { getContent20, getContentItemById20, getContentItemByPath20, getContentItems20, getMedia20, getMediaItemById20, getMediaItemByPath20, getMediaItems20, type Options } from './sdk.gen.js';
export type { ApiBlockGridAreaModel, ApiBlockGridItemModel, ApiBlockGridModel, ApiBlockItemModel, ApiBlockListModel, ApiContentModel, ApiContentResponseModel, ApiElementModel, ApiImageCropperValueModel, ApiLinkModel, ApiMediaWithCropsModel, ApiMediaWithCropsResponseModel, BlockSettingsElementModel, BlockSettingsPropertiesModel, ClientOptions, FileMediaWithCropsModel, FileMediaWithCropsResponseModel, FilePropertiesModel, FolderMediaWithCropsModel, FolderMediaWithCropsResponseModel, FolderPropertiesModel, GetContent20Data, GetContent20Error, GetContent20Errors, GetContent20Response, GetContent20Responses, GetContentItemById20Data, GetContentItemById20Errors, GetContentItemById20Response, GetContentItemById20Responses, GetContentItemByPath20Data, GetContentItemByPath20Errors, GetContentItemByPath20Response, GetContentItemByPath20Responses, GetContentItems20Data, GetContentItems20Errors, GetContentItems20Response, GetContentItems20Responses, GetMedia20Data, GetMedia20Error, GetMedia20Errors, GetMedia20Response, GetMedia20Responses, GetMediaItemById20Data, GetMediaItemById20Errors, GetMediaItemById20Response, GetMediaItemById20Responses, GetMediaItemByPath20Data, GetMediaItemByPath20Errors, GetMediaItemByPath20Response, GetMediaItemByPath20Responses, GetMediaItems20Data, GetMediaItems20Response, GetMediaItems20Responses, IApiContentModel, IApiContentResponseModel, IApiContentRouteModel, IApiContentStartItemModel, IApiElementModel, IApiMediaWithCropsModel, IApiMediaWithCropsResponseModel, ImageCropCoordinatesModel, ImageCropModel, ImageFocalPointModel, ImageMediaWithCropsModel, ImageMediaWithCropsResponseModel, ImagePropertiesModel, LinkTypeModel, PagedIApiContentResponseModel, PagedIApiMediaWithCropsResponseModel, PickedColorModel, ProblemDetails, RichTextModel, TestBlock2ElementModel, TestBlock2PropertiesModel, TestBlockElementModel, TestBlockPropertiesModel, TestComposition2ElementModel, TestComposition2PropertiesModel, TestCompositionElementModel, TestCompositionPropertiesModel, TestPageContentModel, TestPageContentResponseModel, TestPageInvariantContentModel, TestPageInvariantContentResponseModel, TestPageInvariantPropertiesModel, TestPagePropertiesModel, UmbracoMediaArticleMediaWithCropsModel, UmbracoMediaArticleMediaWithCropsResponseModel, UmbracoMediaArticlePropertiesModel, UmbracoMediaAudioMediaWithCropsModel, UmbracoMediaAudioMediaWithCropsResponseModel, UmbracoMediaAudioPropertiesModel, UmbracoMediaVectorGraphicsMediaWithCropsModel, UmbracoMediaVectorGraphicsMediaWithCropsResponseModel, UmbracoMediaVectorGraphicsPropertiesModel, UmbracoMediaVideoMediaWithCropsModel, UmbracoMediaVideoMediaWithCropsResponseModel, UmbracoMediaVideoPropertiesModel } from './types.gen.js';
+144
View File
@@ -0,0 +1,144 @@
import {client} from './api/client.gen';
import {getContentItemByPath20} from './api/sdk.gen';
import type {
ApiBlockItemModel,
IApiContentResponseModel,
TestPageContentResponseModel,
} from './api/types.gen';
client.setConfig({
baseUrl: 'https://localhost:44339',
});
(async () => {
console.log('** Page - Default **');
const {data, error} = await getContentItemByPath20({
path: {path: '/'},
query: {expand: 'properties[$all]'},
});
if (error) {
console.error('Failed to fetch content:', error);
return;
}
if (!data) {
console.error('No content returned.');
return;
}
renderPage(data);
})();
function renderPage(content: IApiContentResponseModel) {
console.log(' Name: ', content.name);
console.log(' Path: ', content.route?.path);
if (content.contentType === 'testPage') {
renderTestPage(content);
}
}
function renderTestPage(content: TestPageContentResponseModel) {
const {properties} = content;
console.log('\n **Common**');
print('textString', properties?.textString);
print('textArea', properties?.textArea);
print('datePickerWithTime', properties?.datePickerWithTime);
print('datePicker', properties?.datePicker);
print('toggle', properties?.toggle);
print('numeric', properties?.numeric);
print('decimal', properties?.decimal);
print('slider', properties?.slider);
print('tags', properties?.tags);
print('email', properties?.email);
print('dateOnly', properties?.dateOnly);
print('timeOnly', properties?.timeOnly);
print('dateTimeUnspecified', properties?.dateTimeUnspecified);
print('dateTimeWithTimeZone', properties?.dateTimeWithTimeZone);
console.log('\n **Pickers**');
print('colorPicker', properties?.colorPicker);
print('contentPicker', '<tested below>');
print('eyeDropperColorPicker', properties?.eyeDropperColorPicker);
print('urlPicker', properties?.urlPicker);
print('multinodeTreepicker', '<tested below>');
print('userPicker', properties?.userPicker);
console.log('\n **Rich content**');
print('richText', properties?.richText);
print('blockGrid', '<tested below>');
print('markdown', properties?.markdown);
console.log('\n **Lists**');
print('blockList', '<tested below>');
print('checkboxList', properties?.checkboxList);
print('dropdown', properties?.dropdown);
print('radiobox', properties?.radiobox);
print('repeatableTextstrings', properties?.repeatableTextstrings);
console.log('\n **Media**');
print('uploadFile', properties?.uploadFile);
print('imageCropper', properties?.imageCropper);
print('mediaPicker', properties?.mediaPicker);
console.log('\n **Content Picker**');
print('name', properties?.contentPicker?.name);
print('route>path', properties?.contentPicker?.route?.path);
console.log('\n **Multinode Treepicker**');
print('name', properties?.multinodeTreepicker?.[0]?.name);
print('route>path', properties?.multinodeTreepicker?.[0]?.route?.path);
console.log('\n **Block List**');
properties?.blockList?.items?.forEach((block, i) => {
console.log(` Block[${i}]:`);
renderBlock(block);
});
console.log('\n **Block Grid**');
properties?.blockGrid?.items?.forEach((block, i) => {
console.log(` Block[${i}]:`);
renderBlock(block);
});
console.log('\n **From compositions**');
print(' sharedToggle', properties?.sharedToggle);
print(' sharedString', properties?.sharedString);
print(' sharedRadiobox', properties?.sharedRadiobox);
print(' sharedRichText', properties?.sharedRichText);
}
function renderBlock(block: ApiBlockItemModel) {
console.log(' Type: ', block.content?.contentType);
switch (block.content?.contentType) {
case 'testBlock': {
console.log(' String: ', block.content.properties?.string);
console.log(' Multinode Treepicker: ', block.content.properties?.multinodeTreepicker?.[0]?.id);
console.log(' Shared string: ', block.content.properties?.sharedString);
const nestedBlock = block.content.properties?.blocks?.items?.[0];
if (nestedBlock) {
console.log(' **Nested block**');
renderBlock(nestedBlock);
}
break;
}
case 'testBlock2': {
console.log(' Shared string (testBlock2): ', block.content.properties?.sharedString);
if (block.settings?.contentType === 'blockSettings') {
console.log(' Anchor id (settings): ', block.settings.properties?.anchorId);
}
break;
}
default:
console.error(' Unknown block type');
break;
}
}
function print(propertyName: string, value: unknown) {
console.log(` ${propertyName} (${typeof value}): ${JSON.stringify(value)}`);
}
@@ -0,0 +1,7 @@
import {defineConfig} from '@hey-api/openapi-ts';
export default defineConfig({
input: 'https://localhost:44339/umbraco/openapi/delivery.json',
output: './api',
plugins: ['@hey-api/client-fetch'],
});
+695
View File
@@ -0,0 +1,695 @@
{
"name": "delivery-api-hey-api",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "delivery-api-hey-api",
"version": "1.0.0",
"devDependencies": {
"@hey-api/openapi-ts": "^0.97.1",
"@types/node": "^22.19.1",
"typescript": "^5.9.3"
},
"engines": {
"node": ">=22"
}
},
"node_modules/@hey-api/codegen-core": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@hey-api/codegen-core/-/codegen-core-0.8.1.tgz",
"integrity": "sha512-Iciv2vUCJTW9lWM/ROvyZLblmcbYJHPuXfzb1SzeDVVn4xEXu2ilLU1pq3fn+09FZ/Y0P7VyvRE47UDU6om8xA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@hey-api/types": "0.1.4",
"ansi-colors": "4.1.3",
"c12": "3.3.4",
"color-support": "1.1.3"
},
"engines": {
"node": ">=22.13.0"
},
"funding": {
"url": "https://github.com/sponsors/hey-api"
}
},
"node_modules/@hey-api/json-schema-ref-parser": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.4.2.tgz",
"integrity": "sha512-ZhCFSKI2ipZHEbgmtUHdyddvRU3wJ4elgCfYUC7T7hZa4EivSrVflTQf2w+v3TuaYxR1Y2V2kq3otqTttrrK8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jsdevtools/ono": "7.1.3",
"@types/json-schema": "7.0.15",
"js-yaml": "4.1.1"
},
"engines": {
"node": ">=22.13.0"
},
"funding": {
"url": "https://github.com/sponsors/hey-api"
}
},
"node_modules/@hey-api/openapi-ts": {
"version": "0.97.1",
"resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.97.1.tgz",
"integrity": "sha512-LksUJeXAqwf6OhcCCr3/B4YjnBs5rqSqjDUKMBvkgp4OhaCQiJrOvntctFxdnugy8jUojP4yi/eJf5xYzcYzCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@hey-api/codegen-core": "0.8.1",
"@hey-api/json-schema-ref-parser": "1.4.2",
"@hey-api/shared": "0.4.3",
"@hey-api/spec-types": "0.2.0",
"@hey-api/types": "0.1.4",
"@lukeed/ms": "2.0.2",
"ansi-colors": "4.1.3",
"color-support": "1.1.3",
"commander": "14.0.3",
"get-tsconfig": "4.14.0"
},
"bin": {
"openapi-ts": "bin/run.js"
},
"engines": {
"node": ">=22.13.0"
},
"funding": {
"url": "https://github.com/sponsors/hey-api"
},
"peerDependencies": {
"typescript": ">=5.5.3 || >=6.0.0 || 6.0.1-rc"
}
},
"node_modules/@hey-api/shared": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@hey-api/shared/-/shared-0.4.3.tgz",
"integrity": "sha512-3tHfZNXgGOt+3P3Kq9cvqmZ9i7e3jtrkip1uDpZTX1+hTNboHhYdjxnT8AbrDuvslTaQHoAOlP4/iCDdzd9Jag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@hey-api/codegen-core": "0.8.1",
"@hey-api/json-schema-ref-parser": "1.4.2",
"@hey-api/spec-types": "0.2.0",
"@hey-api/types": "0.1.4",
"ansi-colors": "4.1.3",
"cross-spawn": "7.0.6",
"open": "11.0.0",
"semver": "7.7.4"
},
"engines": {
"node": ">=22.13.0"
},
"funding": {
"url": "https://github.com/sponsors/hey-api"
}
},
"node_modules/@hey-api/spec-types": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@hey-api/spec-types/-/spec-types-0.2.0.tgz",
"integrity": "sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@hey-api/types": "0.1.4"
},
"funding": {
"url": "https://github.com/sponsors/hey-api"
}
},
"node_modules/@hey-api/types": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@hey-api/types/-/types-0.1.4.tgz",
"integrity": "sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg==",
"dev": true,
"license": "MIT"
},
"node_modules/@jsdevtools/ono": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
"dev": true,
"license": "MIT"
},
"node_modules/@lukeed/ms": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz",
"integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.19.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
"integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0"
},
"node_modules/bundle-name": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
"integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"run-applescript": "^7.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/c12": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/c12/-/c12-3.3.4.tgz",
"integrity": "sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==",
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": "^5.0.0",
"confbox": "^0.2.4",
"defu": "^6.1.6",
"dotenv": "^17.3.1",
"exsolve": "^1.0.8",
"giget": "^3.2.0",
"jiti": "^2.6.1",
"ohash": "^2.0.11",
"pathe": "^2.0.3",
"perfect-debounce": "^2.1.0",
"pkg-types": "^2.3.0",
"rc9": "^3.0.1"
},
"peerDependencies": {
"magicast": "*"
},
"peerDependenciesMeta": {
"magicast": {
"optional": true
}
}
},
"node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"dev": true,
"license": "MIT",
"dependencies": {
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true,
"license": "ISC",
"bin": {
"color-support": "bin.js"
}
},
"node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/confbox": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
"integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
"dev": true,
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/default-browser": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz",
"integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==",
"dev": true,
"license": "MIT",
"dependencies": {
"bundle-name": "^4.1.0",
"default-browser-id": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser-id": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
"integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-lazy-prop": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/defu": {
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
"integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
"dev": true,
"license": "MIT"
},
"node_modules/destr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz",
"integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
"dev": true,
"license": "MIT"
},
"node_modules/dotenv": {
"version": "17.4.2",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
"integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/exsolve": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
"dev": true,
"license": "MIT"
},
"node_modules/get-tsconfig": {
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz",
"integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==",
"dev": true,
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/giget": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/giget/-/giget-3.2.0.tgz",
"integrity": "sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==",
"dev": true,
"license": "MIT",
"bin": {
"giget": "dist/cli.mjs"
}
},
"node_modules/is-docker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
"dev": true,
"license": "MIT",
"bin": {
"is-docker": "cli.js"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-in-ssh": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
"integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-inside-container": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-docker": "^3.0.0"
},
"bin": {
"is-inside-container": "cli.js"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-wsl": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
"integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-inside-container": "^1.0.0"
},
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/jiti": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
"dev": true,
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/js-yaml": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/ohash": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
"integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
"dev": true,
"license": "MIT"
},
"node_modules/open": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz",
"integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==",
"dev": true,
"license": "MIT",
"dependencies": {
"default-browser": "^5.4.0",
"define-lazy-prop": "^3.0.0",
"is-in-ssh": "^1.0.0",
"is-inside-container": "^1.0.0",
"powershell-utils": "^0.1.0",
"wsl-utils": "^0.3.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pathe": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"dev": true,
"license": "MIT"
},
"node_modules/perfect-debounce": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz",
"integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==",
"dev": true,
"license": "MIT"
},
"node_modules/pkg-types": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz",
"integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"confbox": "^0.2.4",
"exsolve": "^1.0.8",
"pathe": "^2.0.3"
}
},
"node_modules/powershell-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
"integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/rc9": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/rc9/-/rc9-3.0.1.tgz",
"integrity": "sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"defu": "^6.1.6",
"destr": "^2.0.5"
}
},
"node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/run-applescript": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
"integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wsl-utils": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz",
"integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-wsl": "^3.1.0",
"powershell-utils": "^0.1.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
}
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"name": "delivery-api-hey-api",
"version": "1.0.0",
"private": true,
"description": "@hey-api/openapi-ts client to verify the Delivery API OpenAPI document.",
"main": "dist/app.js",
"scripts": {
"generate": "NODE_TLS_REJECT_UNAUTHORIZED=0 openapi-ts -f openapi-ts.config.ts",
"build": "npm run generate && tsc --build",
"clean": "tsc --build --clean",
"start": "npm run build && NODE_TLS_REJECT_UNAUTHORIZED=0 node dist/app.js"
},
"devDependencies": {
"@hey-api/openapi-ts": "^0.97.1",
"@types/node": "^22.19.1",
"typescript": "^5.9.3"
},
"engines": {
"node": ">=22"
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": ".",
"resolveJsonModule": true
},
"include": ["app.ts", "api/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"microsoft.openapi.kiota": {
"version": "1.31.1",
"commands": [
"kiota"
]
}
}
}
+3
View File
@@ -0,0 +1,3 @@
Warning: KiotaBuilder No server url found in the OpenAPI document. The base url will need to be set when using the client.
Warning: KiotaBuilder Duplicate operation GET in path default
Warning: KiotaBuilder Duplicate operation GET in path default
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class FileMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class FileMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public FileMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class FolderMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class FolderMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public FolderMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,86 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
/// <summary>
/// Composed type wrapper for classes <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel"/>
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class IApiContentResponseModel : IComposedTypeWrapper, IParsable
{
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel? TestPageContentResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel TestPageContentResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel? TestPageInvariantContentResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel TestPageInvariantContentResponseModel { get; set; }
#endif
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
var mappingValue = parseNode.GetChildNode("contentType")?.GetStringValue();
var result = new global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel();
if("testPage".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.TestPageContentResponseModel = new global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel();
}
else if("testPageInvariant".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.TestPageInvariantContentResponseModel = new global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel();
}
return result;
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
if(TestPageContentResponseModel != null)
{
return TestPageContentResponseModel.GetFieldDeserializers();
}
else if(TestPageInvariantContentResponseModel != null)
{
return TestPageInvariantContentResponseModel.GetFieldDeserializers();
}
return new Dictionary<string, Action<IParseNode>>();
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
if(TestPageContentResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel>(null, TestPageContentResponseModel);
}
else if(TestPageInvariantContentResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel>(null, TestPageInvariantContentResponseModel);
}
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,85 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class IApiContentRouteModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The queryString property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? QueryString { get; set; }
#nullable restore
#else
public string QueryString { get; set; }
#endif
/// <summary>The startItem property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel? StartItem { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel StartItem { get; set; }
#endif
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel"/> and sets the default values.
/// </summary>
public IApiContentRouteModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "path", n => { Path = n.GetStringValue(); } },
{ "queryString", n => { QueryString = n.GetStringValue(); } },
{ "startItem", n => { StartItem = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel>(global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel.CreateFromDiscriminatorValue); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("path", Path);
writer.WriteStringValue("queryString", QueryString);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel>("startItem", StartItem);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,69 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class IApiContentStartItemModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel"/> and sets the default values.
/// </summary>
public IApiContentStartItemModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.IApiContentStartItemModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "id", n => { Id = n.GetGuidValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("path", Path);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,186 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
/// <summary>
/// Composed type wrapper for classes <see cref="global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel"/>, <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel"/>
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class IApiMediaWithCropsResponseModel : IComposedTypeWrapper, IParsable
{
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel? FileMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel FileMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel? FolderMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel FolderMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel? ImageMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel ImageMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel? UmbracoMediaArticleMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel UmbracoMediaArticleMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel? UmbracoMediaAudioMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel UmbracoMediaAudioMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel? UmbracoMediaVectorGraphicsMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel UmbracoMediaVectorGraphicsMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>Composed type representation for type <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel"/></summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel? UmbracoMediaVideoMediaWithCropsResponseModel { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel UmbracoMediaVideoMediaWithCropsResponseModel { get; set; }
#endif
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
var mappingValue = parseNode.GetChildNode("mediaType")?.GetStringValue();
var result = new global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel();
if("File".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.FileMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel();
}
else if("Folder".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.FolderMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel();
}
else if("Image".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.ImageMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel();
}
else if("umbracoMediaArticle".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.UmbracoMediaArticleMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel();
}
else if("umbracoMediaAudio".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.UmbracoMediaAudioMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel();
}
else if("umbracoMediaVectorGraphics".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel();
}
else if("umbracoMediaVideo".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))
{
result.UmbracoMediaVideoMediaWithCropsResponseModel = new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel();
}
return result;
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
if(FileMediaWithCropsResponseModel != null)
{
return FileMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(FolderMediaWithCropsResponseModel != null)
{
return FolderMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(ImageMediaWithCropsResponseModel != null)
{
return ImageMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(UmbracoMediaArticleMediaWithCropsResponseModel != null)
{
return UmbracoMediaArticleMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(UmbracoMediaAudioMediaWithCropsResponseModel != null)
{
return UmbracoMediaAudioMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(UmbracoMediaVectorGraphicsMediaWithCropsResponseModel != null)
{
return UmbracoMediaVectorGraphicsMediaWithCropsResponseModel.GetFieldDeserializers();
}
else if(UmbracoMediaVideoMediaWithCropsResponseModel != null)
{
return UmbracoMediaVideoMediaWithCropsResponseModel.GetFieldDeserializers();
}
return new Dictionary<string, Action<IParseNode>>();
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
if(FileMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.FileMediaWithCropsResponseModel>(null, FileMediaWithCropsResponseModel);
}
else if(FolderMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.FolderMediaWithCropsResponseModel>(null, FolderMediaWithCropsResponseModel);
}
else if(ImageMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel>(null, ImageMediaWithCropsResponseModel);
}
else if(UmbracoMediaArticleMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel>(null, UmbracoMediaArticleMediaWithCropsResponseModel);
}
else if(UmbracoMediaAudioMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel>(null, UmbracoMediaAudioMediaWithCropsResponseModel);
}
else if(UmbracoMediaVectorGraphicsMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel>(null, UmbracoMediaVectorGraphicsMediaWithCropsResponseModel);
}
else if(UmbracoMediaVideoMediaWithCropsResponseModel != null)
{
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel>(null, UmbracoMediaVideoMediaWithCropsResponseModel);
}
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,71 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ImageCropCoordinatesModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The x1 property</summary>
public double? X1 { get; set; }
/// <summary>The x2 property</summary>
public double? X2 { get; set; }
/// <summary>The y1 property</summary>
public double? Y1 { get; set; }
/// <summary>The y2 property</summary>
public double? Y2 { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel"/> and sets the default values.
/// </summary>
public ImageCropCoordinatesModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "x1", n => { X1 = n.GetDoubleValue(); } },
{ "x2", n => { X2 = n.GetDoubleValue(); } },
{ "y1", n => { Y1 = n.GetDoubleValue(); } },
{ "y2", n => { Y2 = n.GetDoubleValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteDoubleValue("x1", X1);
writer.WriteDoubleValue("x2", X2);
writer.WriteDoubleValue("y1", Y1);
writer.WriteDoubleValue("y2", Y2);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,83 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ImageCropModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The alias property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Alias { get; set; }
#nullable restore
#else
public string Alias { get; set; }
#endif
/// <summary>The coordinates property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel? Coordinates { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel Coordinates { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageCropModel"/> and sets the default values.
/// </summary>
public ImageCropModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageCropModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ImageCropModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ImageCropModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "alias", n => { Alias = n.GetStringValue(); } },
{ "coordinates", n => { Coordinates = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("alias", Alias);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageCropCoordinatesModel>("coordinates", Coordinates);
writer.WriteIntValue("height", Height);
writer.WriteIntValue("width", Width);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,63 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ImageFocalPointModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The left property</summary>
public double? Left { get; set; }
/// <summary>The top property</summary>
public double? Top { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel"/> and sets the default values.
/// </summary>
public ImageFocalPointModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "left", n => { Left = n.GetDoubleValue(); } },
{ "top", n => { Top = n.GetDoubleValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteDoubleValue("left", Left);
writer.WriteDoubleValue("top", Top);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ImageMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ImageMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public ImageMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ImageMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,69 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class PagedIApiContentResponseModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The items property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>? Items { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel> Items { get; set; }
#endif
/// <summary>The total property</summary>
public long? Total { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel"/> and sets the default values.
/// </summary>
public PagedIApiContentResponseModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "items", n => { Items = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>(global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "total", n => { Total = n.GetLongValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>("items", Items);
writer.WriteLongValue("total", Total);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,69 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class PagedIApiMediaWithCropsResponseModel : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The items property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>? Items { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel> Items { get; set; }
#endif
/// <summary>The total property</summary>
public long? Total { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel"/> and sets the default values.
/// </summary>
public PagedIApiMediaWithCropsResponseModel()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "items", n => { Items = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>(global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "total", n => { Total = n.GetLongValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>("items", Items);
writer.WriteLongValue("total", Total);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,102 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ProblemDetails : ApiException, IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>The detail property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Detail { get; set; }
#nullable restore
#else
public string Detail { get; set; }
#endif
/// <summary>The instance property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Instance { get; set; }
#nullable restore
#else
public string Instance { get; set; }
#endif
/// <summary>The primary error message.</summary>
public override string Message { get => base.Message; }
/// <summary>The status property</summary>
public int? Status { get; set; }
/// <summary>The title property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Title { get; set; }
#nullable restore
#else
public string Title { get; set; }
#endif
/// <summary>The type property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Type { get; set; }
#nullable restore
#else
public string Type { get; set; }
#endif
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.ProblemDetails"/> and sets the default values.
/// </summary>
public ProblemDetails()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.ProblemDetails"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.ProblemDetails CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.ProblemDetails();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "detail", n => { Detail = n.GetStringValue(); } },
{ "instance", n => { Instance = n.GetStringValue(); } },
{ "status", n => { Status = n.GetIntValue(); } },
{ "title", n => { Title = n.GetStringValue(); } },
{ "type", n => { Type = n.GetStringValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("detail", Detail);
writer.WriteStringValue("instance", Instance);
writer.WriteIntValue("status", Status);
writer.WriteStringValue("title", Title);
writer.WriteStringValue("type", Type);
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,107 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageContentResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The contentType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? ContentType { get; set; }
#nullable restore
#else
public string ContentType { get; set; }
#endif
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The cultures property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures? Cultures { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures Cultures { get; set; }
#endif
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties Properties { get; set; }
#endif
/// <summary>The route property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel? Route { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel Route { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "contentType", n => { ContentType = n.GetStringValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "cultures", n => { Cultures = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures>(global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures.CreateFromDiscriminatorValue); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "route", n => { Route = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel>(global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("contentType", ContentType);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures>("cultures", Cultures);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("name", Name);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties>("properties", Properties);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel>("route", Route);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageContentResponseModel_cultures : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures"/> and sets the default values.
/// </summary>
public TestPageContentResponseModel_cultures()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_cultures();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageContentResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties"/> and sets the default values.
/// </summary>
public TestPageContentResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageContentResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,107 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageInvariantContentResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The contentType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? ContentType { get; set; }
#nullable restore
#else
public string ContentType { get; set; }
#endif
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The cultures property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures? Cultures { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures Cultures { get; set; }
#endif
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties Properties { get; set; }
#endif
/// <summary>The route property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel? Route { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel Route { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "contentType", n => { ContentType = n.GetStringValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "cultures", n => { Cultures = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures>(global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures.CreateFromDiscriminatorValue); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "route", n => { Route = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel>(global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("contentType", ContentType);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures>("cultures", Cultures);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("name", Name);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties>("properties", Properties);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.IApiContentRouteModel>("route", Route);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageInvariantContentResponseModel_cultures : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures"/> and sets the default values.
/// </summary>
public TestPageInvariantContentResponseModel_cultures()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_cultures();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class TestPageInvariantContentResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties"/> and sets the default values.
/// </summary>
public TestPageInvariantContentResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.TestPageInvariantContentResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaArticleMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaArticleMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public UmbracoMediaArticleMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaArticleMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaAudioMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaAudioMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public UmbracoMediaAudioMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaAudioMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaVectorGraphicsMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVectorGraphicsMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,149 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaVideoMediaWithCropsResponseModel : IParsable
#pragma warning restore CS1591
{
/// <summary>The bytes property</summary>
public int? Bytes { get; set; }
/// <summary>The createDate property</summary>
public DateTimeOffset? CreateDate { get; set; }
/// <summary>The crops property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>? Crops { get; set; }
#nullable restore
#else
public List<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel> Crops { get; set; }
#endif
/// <summary>The extension property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Extension { get; set; }
#nullable restore
#else
public string Extension { get; set; }
#endif
/// <summary>The focalPoint property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel? FocalPoint { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel FocalPoint { get; set; }
#endif
/// <summary>The height property</summary>
public int? Height { get; set; }
/// <summary>The id property</summary>
public Guid? Id { get; set; }
/// <summary>The mediaType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? MediaType { get; set; }
#nullable restore
#else
public string MediaType { get; set; }
#endif
/// <summary>The name property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Name { get; set; }
#nullable restore
#else
public string Name { get; set; }
#endif
/// <summary>The path property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Path { get; set; }
#nullable restore
#else
public string Path { get; set; }
#endif
/// <summary>The properties property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties? Properties { get; set; }
#nullable restore
#else
public global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties Properties { get; set; }
#endif
/// <summary>The updateDate property</summary>
public DateTimeOffset? UpdateDate { get; set; }
/// <summary>The url property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? Url { get; set; }
#nullable restore
#else
public string Url { get; set; }
#endif
/// <summary>The width property</summary>
public int? Width { get; set; }
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
{ "bytes", n => { Bytes = n.GetIntValue(); } },
{ "createDate", n => { CreateDate = n.GetDateTimeOffsetValue(); } },
{ "crops", n => { Crops = n.GetCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>(global::UmbracoDeliveryClient.Generated.Models.ImageCropModel.CreateFromDiscriminatorValue)?.AsList(); } },
{ "extension", n => { Extension = n.GetStringValue(); } },
{ "focalPoint", n => { FocalPoint = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>(global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel.CreateFromDiscriminatorValue); } },
{ "height", n => { Height = n.GetIntValue(); } },
{ "id", n => { Id = n.GetGuidValue(); } },
{ "mediaType", n => { MediaType = n.GetStringValue(); } },
{ "name", n => { Name = n.GetStringValue(); } },
{ "path", n => { Path = n.GetStringValue(); } },
{ "properties", n => { Properties = n.GetObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties>(global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties.CreateFromDiscriminatorValue); } },
{ "updateDate", n => { UpdateDate = n.GetDateTimeOffsetValue(); } },
{ "url", n => { Url = n.GetStringValue(); } },
{ "width", n => { Width = n.GetIntValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteIntValue("bytes", Bytes);
writer.WriteDateTimeOffsetValue("createDate", CreateDate);
writer.WriteCollectionOfObjectValues<global::UmbracoDeliveryClient.Generated.Models.ImageCropModel>("crops", Crops);
writer.WriteStringValue("extension", Extension);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.ImageFocalPointModel>("focalPoint", FocalPoint);
writer.WriteIntValue("height", Height);
writer.WriteGuidValue("id", Id);
writer.WriteStringValue("mediaType", MediaType);
writer.WriteStringValue("name", Name);
writer.WriteStringValue("path", Path);
writer.WriteObjectValue<global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties>("properties", Properties);
writer.WriteDateTimeOffsetValue("updateDate", UpdateDate);
writer.WriteStringValue("url", Url);
writer.WriteIntValue("width", Width);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,55 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using System.Collections.Generic;
using System.IO;
using System;
namespace UmbracoDeliveryClient.Generated.Models
{
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class UmbracoMediaVideoMediaWithCropsResponseModel_properties : IAdditionalDataHolder, IParsable
#pragma warning restore CS1591
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData { get; set; }
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties"/> and sets the default values.
/// </summary>
public UmbracoMediaVideoMediaWithCropsResponseModel_properties()
{
AdditionalData = new Dictionary<string, object>();
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties"/></returns>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties CreateFromDiscriminatorValue(IParseNode parseNode)
{
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
return new global::UmbracoDeliveryClient.Generated.Models.UmbracoMediaVideoMediaWithCropsResponseModel_properties();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
{
return new Dictionary<string, Action<IParseNode>>
{
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public virtual void Serialize(ISerializationWriter writer)
{
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
writer.WriteAdditionalData(AdditionalData);
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,41 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ApiRequestBuilder : BaseRequestBuilder
{
/// <summary>The v2 property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.V2RequestBuilder V2
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.V2RequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.ApiRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ApiRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.ApiRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ApiRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api", rawUrl)
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,165 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\content
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ContentRequestBuilder : BaseRequestBuilder
{
/// <summary>The item property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item_EscapedRequestBuilder Item
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item_EscapedRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>The items property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder Items
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ContentRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content{?expand*,fetch*,fields*,filter*,skip*,sort*,take*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ContentRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content{?expand*,fetch*,fields*,filter*,skip*,sort*,take*}", rawUrl)
{
}
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel"/></returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
/// <exception cref="global::UmbracoDeliveryClient.Generated.Models.ProblemDetails">When receiving a 400 status code</exception>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder.ContentRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder.ContentRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>>
{
{ "400", global::UmbracoDeliveryClient.Generated.Models.ProblemDetails.CreateFromDiscriminatorValue },
};
return await RequestAdapter.SendAsync<global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.PagedIApiContentResponseModel.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder.ContentRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder.ContentRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ContentRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Specifies the content items to fetch. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fetch")]
public string? Fetch { get; set; }
#nullable restore
#else
[QueryParameter("fetch")]
public string Fetch { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
/// <summary>Defines how to filter the fetched content items. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("filter")]
public string[]? Filter { get; set; }
#nullable restore
#else
[QueryParameter("filter")]
public string[] Filter { get; set; }
#endif
/// <summary>Specifies the number of found content items to skip. Use this to control pagination of the response.</summary>
[QueryParameter("skip")]
public int? Skip { get; set; }
/// <summary>Defines how to sort the found content items. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("sort")]
public string[]? Sort { get; set; }
#nullable restore
#else
[QueryParameter("sort")]
public string[] Sort { get; set; }
#endif
/// <summary>Specifies the number of found content items to take. Use this to control pagination of the response.</summary>
[QueryParameter("take")]
public int? Take { get; set; }
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ContentRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder.ContentRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,112 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\content\item\{-id}
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemRequestBuilder : BaseRequestBuilder
{
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/item/{%2Did}{?expand*,fields*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/item/{%2Did}{?expand*,fields*}", rawUrl)
{
}
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel"/></returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
return await RequestAdapter.SendAsync<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel.CreateFromDiscriminatorValue, default, cancellationToken).ConfigureAwait(false);
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ItemRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,61 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\content\item
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class Item_EscapedRequestBuilder : BaseRequestBuilder
{
/// <summary>Gets an item from the UmbracoDeliveryClient.Generated.umbraco.delivery.api.v2.content.Item_Escaped.item collection</summary>
/// <param name="position">Unique identifier of the item</param>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder"/></returns>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder this[Guid position]
{
get
{
var urlTplParams = new Dictionary<string, object>(PathParameters);
urlTplParams.Add("%2Did", position);
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder(urlTplParams, RequestAdapter);
}
}
/// <summary>Gets an item from the UmbracoDeliveryClient.Generated.umbraco.delivery.api.v2.content.Item_Escaped.item collection</summary>
/// <param name="position">Unique identifier of the item</param>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder"/></returns>
[Obsolete("This indexer is deprecated and will be removed in the next major version. Use the one with the typed parameter instead.")]
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder this[string position]
{
get
{
var urlTplParams = new Dictionary<string, object>(PathParameters);
if (!string.IsNullOrWhiteSpace(position)) urlTplParams.Add("%2Did", position);
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item.ItemRequestBuilder(urlTplParams, RequestAdapter);
}
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item_EscapedRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public Item_EscapedRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/item", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Item_Escaped.Item_EscapedRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public Item_EscapedRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/item", rawUrl)
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,122 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\content\items
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemsRequestBuilder : BaseRequestBuilder
{
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemsRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/items{?expand*,fields*,id*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/content/items{?expand*,fields*,id*}", rawUrl)
{
}
/// <returns>A List&lt;global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel&gt;</returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<List<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<List<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
var collectionResult = await RequestAdapter.SendCollectionAsync<global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.IApiContentResponseModel.CreateFromDiscriminatorValue, default, cancellationToken).ConfigureAwait(false);
return collectionResult?.AsList();
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ItemsRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("id")]
public Guid?[]? Id { get; set; }
#nullable restore
#else
[QueryParameter("id")]
public Guid?[] Id { get; set; }
#endif
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemsRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,112 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\media\item\{-id}
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemRequestBuilder : BaseRequestBuilder
{
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/item/{%2Did}{?expand*,fields*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/item/{%2Did}{?expand*,fields*}", rawUrl)
{
}
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel"/></returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
return await RequestAdapter.SendAsync<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel.CreateFromDiscriminatorValue, default, cancellationToken).ConfigureAwait(false);
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ItemRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder.ItemRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,61 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\media\item
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class Item_EscapedRequestBuilder : BaseRequestBuilder
{
/// <summary>Gets an item from the UmbracoDeliveryClient.Generated.umbraco.delivery.api.v2.media.Item_Escaped.item collection</summary>
/// <param name="position">Unique identifier of the item</param>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder"/></returns>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder this[Guid position]
{
get
{
var urlTplParams = new Dictionary<string, object>(PathParameters);
urlTplParams.Add("%2Did", position);
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder(urlTplParams, RequestAdapter);
}
}
/// <summary>Gets an item from the UmbracoDeliveryClient.Generated.umbraco.delivery.api.v2.media.Item_Escaped.item collection</summary>
/// <param name="position">Unique identifier of the item</param>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder"/></returns>
[Obsolete("This indexer is deprecated and will be removed in the next major version. Use the one with the typed parameter instead.")]
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder this[string position]
{
get
{
var urlTplParams = new Dictionary<string, object>(PathParameters);
if (!string.IsNullOrWhiteSpace(position)) urlTplParams.Add("%2Did", position);
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item.ItemRequestBuilder(urlTplParams, RequestAdapter);
}
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item_EscapedRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public Item_EscapedRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/item", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item_EscapedRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public Item_EscapedRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/item", rawUrl)
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,122 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\media\items
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemsRequestBuilder : BaseRequestBuilder
{
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemsRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/items{?expand*,fields*,id*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public ItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media/items{?expand*,fields*,id*}", rawUrl)
{
}
/// <returns>A List&lt;global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel&gt;</returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<List<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<List<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
var collectionResult = await RequestAdapter.SendCollectionAsync<global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.IApiMediaWithCropsResponseModel.CreateFromDiscriminatorValue, default, cancellationToken).ConfigureAwait(false);
return collectionResult?.AsList();
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class ItemsRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("id")]
public Guid?[]? Id { get; set; }
#nullable restore
#else
[QueryParameter("id")]
public Guid?[] Id { get; set; }
#endif
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class ItemsRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,165 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System;
using UmbracoDeliveryClient.Generated.Models;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2\media
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class MediaRequestBuilder : BaseRequestBuilder
{
/// <summary>The item property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item_EscapedRequestBuilder Item
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Item_Escaped.Item_EscapedRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>The items property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder Items
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.Items.ItemsRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public MediaRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media{?expand*,fetch*,fields*,filter*,skip*,sort*,take*}", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public MediaRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2/media{?expand*,fetch*,fields*,filter*,skip*,sort*,take*}", rawUrl)
{
}
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel"/></returns>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
/// <exception cref="global::UmbracoDeliveryClient.Generated.Models.ProblemDetails">When receiving a 400 status code</exception>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel?> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder.MediaRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
#nullable restore
#else
public async Task<global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel> GetAsync(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder.MediaRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>>
{
{ "400", global::UmbracoDeliveryClient.Generated.Models.ProblemDetails.CreateFromDiscriminatorValue },
};
return await RequestAdapter.SendAsync<global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel>(requestInfo, global::UmbracoDeliveryClient.Generated.Models.PagedIApiMediaWithCropsResponseModel.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
}
/// <returns>A <see cref="RequestInformation"/></returns>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder.MediaRequestBuilderGetQueryParameters>>? requestConfiguration = default)
{
#nullable restore
#else
public RequestInformation ToGetRequestInformation(Action<RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder.MediaRequestBuilderGetQueryParameters>> requestConfiguration = default)
{
#endif
var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
requestInfo.Configure(requestConfiguration);
requestInfo.Headers.TryAdd("Accept", "application/json");
return requestInfo;
}
/// <summary>
/// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
/// </summary>
/// <returns>A <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder"/></returns>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder WithUrl(string rawUrl)
{
return new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder(rawUrl, RequestAdapter);
}
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
#pragma warning disable CS1591
public partial class MediaRequestBuilderGetQueryParameters
#pragma warning restore CS1591
{
/// <summary>Defines the properties that should be expanded in the response. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("expand")]
public string? Expand { get; set; }
#nullable restore
#else
[QueryParameter("expand")]
public string Expand { get; set; }
#endif
/// <summary>Specifies the media items to fetch. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fetch")]
public string? Fetch { get; set; }
#nullable restore
#else
[QueryParameter("fetch")]
public string Fetch { get; set; }
#endif
/// <summary>Explicitly defines which properties should be included in the response (by default all properties are included). Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("fields")]
public string? Fields { get; set; }
#nullable restore
#else
[QueryParameter("fields")]
public string Fields { get; set; }
#endif
/// <summary>Defines how to filter the fetched media items. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("filter")]
public string[]? Filter { get; set; }
#nullable restore
#else
[QueryParameter("filter")]
public string[] Filter { get; set; }
#endif
/// <summary>Specifies the number of found media items to skip. Use this to control pagination of the response.</summary>
[QueryParameter("skip")]
public int? Skip { get; set; }
/// <summary>Defines how to sort the found media items. Refer to [the documentation](https://docs.umbraco.com/umbraco-cms/reference/content-delivery-api/media-delivery-api#query-parameters) for more details on this.</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
[QueryParameter("sort")]
public string[]? Sort { get; set; }
#nullable restore
#else
[QueryParameter("sort")]
public string[] Sort { get; set; }
#endif
/// <summary>Specifies the number of found media items to take. Use this to control pagination of the response.</summary>
[QueryParameter("take")]
public int? Take { get; set; }
}
/// <summary>
/// Configuration for the request such as headers, query parameters, and middleware options.
/// </summary>
[Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")]
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class MediaRequestBuilderGetRequestConfiguration : RequestConfiguration<global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder.MediaRequestBuilderGetQueryParameters>
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,47 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery\api\v2
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class V2RequestBuilder : BaseRequestBuilder
{
/// <summary>The content property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder Content
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Content.ContentRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>The media property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder Media
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.Media.MediaRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.V2RequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public V2RequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.V2.V2RequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public V2RequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery/api/v2", rawUrl)
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,41 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api;
namespace UmbracoDeliveryClient.Generated.Umbraco.Delivery
{
/// <summary>
/// Builds and executes requests for operations under \umbraco\delivery
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class DeliveryRequestBuilder : BaseRequestBuilder
{
/// <summary>The api property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.ApiRequestBuilder Api
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.Api.ApiRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.DeliveryRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public DeliveryRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.DeliveryRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public DeliveryRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco/delivery", rawUrl)
{
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,41 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco.Delivery;
namespace UmbracoDeliveryClient.Generated.Umbraco
{
/// <summary>
/// Builds and executes requests for operations under \umbraco
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class UmbracoRequestBuilder : BaseRequestBuilder
{
/// <summary>The delivery property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.DeliveryRequestBuilder Delivery
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.Delivery.DeliveryRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.UmbracoRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="pathParameters">Path parameters for the request</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public UmbracoRequestBuilder(Dictionary<string, object> pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco", pathParameters)
{
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.Umbraco.UmbracoRequestBuilder"/> and sets the default values.
/// </summary>
/// <param name="rawUrl">The raw URL to use for the request builder.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public UmbracoRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/umbraco", rawUrl)
{
}
}
}
#pragma warning restore CS0618
+43
View File
@@ -0,0 +1,43 @@
// <auto-generated/>
#pragma warning disable CS0618
using Microsoft.Kiota.Abstractions.Extensions;
using Microsoft.Kiota.Abstractions;
using Microsoft.Kiota.Serialization.Form;
using Microsoft.Kiota.Serialization.Json;
using Microsoft.Kiota.Serialization.Multipart;
using Microsoft.Kiota.Serialization.Text;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using UmbracoDeliveryClient.Generated.Umbraco;
namespace UmbracoDeliveryClient.Generated
{
/// <summary>
/// The main entry point of the SDK, exposes the configuration and the fluent API.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
public partial class UmbracoApi : BaseRequestBuilder
{
/// <summary>The umbraco property</summary>
public global::UmbracoDeliveryClient.Generated.Umbraco.UmbracoRequestBuilder Umbraco
{
get => new global::UmbracoDeliveryClient.Generated.Umbraco.UmbracoRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new <see cref="global::UmbracoDeliveryClient.Generated.UmbracoApi"/> and sets the default values.
/// </summary>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public UmbracoApi(IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}", new Dictionary<string, object>())
{
ApiClientBuilder.RegisterDefaultSerializer<JsonSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<TextSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<FormSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<MultipartSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<JsonParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<TextParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<FormParseNodeFactory>();
}
}
}
#pragma warning restore CS0618
@@ -0,0 +1,36 @@
{
"descriptionHash": "71D88F285143C70064711077E60EA2258EEB6F50A79202E8427348999402C14C3D6EDEE053FA649FC8CDB9282F064F729C01C8564A4329EB0A3791FA425B2E23",
"descriptionLocation": "../spec/delivery.json",
"lockFileVersion": "1.0.0",
"kiotaVersion": "1.31.1",
"clientClassName": "UmbracoApi",
"typeAccessModifier": "Public",
"clientNamespaceName": "UmbracoDeliveryClient.Generated",
"language": "CSharp",
"usesBackingStore": false,
"excludeBackwardCompatible": false,
"includeAdditionalData": true,
"disableSSLValidation": false,
"serializers": [
"Microsoft.Kiota.Serialization.Json.JsonSerializationWriterFactory",
"Microsoft.Kiota.Serialization.Text.TextSerializationWriterFactory",
"Microsoft.Kiota.Serialization.Form.FormSerializationWriterFactory",
"Microsoft.Kiota.Serialization.Multipart.MultipartSerializationWriterFactory"
],
"deserializers": [
"Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory",
"Microsoft.Kiota.Serialization.Text.TextParseNodeFactory",
"Microsoft.Kiota.Serialization.Form.FormParseNodeFactory"
],
"structuredMimeTypes": [
"application/json",
"text/plain;q=0.9",
"application/x-www-form-urlencoded;q=0.2",
"multipart/form-data;q=0.1"
],
"includePatterns": [],
"excludePatterns": [],
"disabledValidationRules": [
"all"
]
}
+78
View File
@@ -0,0 +1,78 @@
using System.Text.Json;
using Microsoft.Kiota.Abstractions.Authentication;
using Microsoft.Kiota.Http.HttpClientLibrary;
using UmbracoDeliveryClient.Generated;
using UmbracoDeliveryClient.Generated.Models;
// Trust the dev cert at https://localhost:44339
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
};
var httpClient = new HttpClient(handler);
var authProvider = new AnonymousAuthenticationProvider();
var requestAdapter = new HttpClientRequestAdapter(authProvider, httpClient: httpClient)
{
BaseUrl = "https://localhost:44339",
};
var client = new UmbracoApi(requestAdapter);
// The OpenAPI spec exposes both /content/item/{id} (Guid) and /content/item/{path} (string)
// at the same kiota-collapsed path. The string indexer is marked [Obsolete]; suppressing
// the warning so we can call the by-path variant.
#pragma warning disable CS0618
IApiContentResponseModel? wrapper = await client
.Umbraco
.Delivery
.Api
.V2
.Content
.Item["/"]
.GetAsync(config => config.QueryParameters.Expand = "properties[$all]");
#pragma warning restore CS0618
if (wrapper is null)
{
Console.WriteLine("No content returned for path '/'");
return;
}
// Kiota generates polymorphic schemas as IComposedTypeWrapper: a single class with
// nullable properties for each variant. CreateFromDiscriminatorValue populates the
// matching one based on the contentType field.
if (wrapper.TestPageContentResponseModel is { } testPage)
{
RenderTestPage(testPage);
}
else if (wrapper.TestPageInvariantContentResponseModel is { } invariant)
{
Console.WriteLine($" Name: {invariant.Name}");
Console.WriteLine($" Path: {invariant.Route?.Path}");
}
else
{
Console.WriteLine("Wrapper had no populated variant. Discriminator value: unknown.");
}
static void RenderTestPage(TestPageContentResponseModel content)
{
Console.WriteLine($" Name: {content.Name}");
Console.WriteLine($" Path: {content.Route?.Path}");
Console.WriteLine($" ContentType: {content.ContentType}");
// Kiota does not emit strongly-typed property fields for the *PropertiesModel
// schemas — they collapse to AdditionalData. Property access is therefore
// untyped (in contrast to orval/hey-api which preserve every field).
if (content.Properties?.AdditionalData is not { Count: > 0 } props)
{
Console.WriteLine("\n Properties: (none)");
return;
}
Console.WriteLine($"\n Properties (untyped; {props.Count} entries):");
foreach (KeyValuePair<string, object> kv in props.OrderBy(p => p.Key))
{
Console.WriteLine($" {kv.Key}: {JsonSerializer.Serialize(kv.Value)}");
}
}
+35
View File
@@ -0,0 +1,35 @@
# Kiota client smoke test
> ⚠️ **This client only partially works.** Kiota compiles and runs, and discriminates polymorphic content types correctly via the composed-type wrapper. However, the per-content-type property bags (e.g. `TestPagePropertiesModel`) lose their typed fields — kiota synthesizes empty `<Owner>_properties` types and only exposes `AdditionalData`. Property access from generated code is therefore untyped, in contrast to orval and hey-api.
Verifies that the Delivery API OpenAPI document produces a valid client when consumed by [Microsoft Kiota](https://learn.microsoft.com/openapi/kiota/overview), Microsoft's modern OpenAPI client generator with first-class OpenAPI 3.1 support.
## Prerequisites
- .NET 10 SDK
- The committed SQLite DB and `appsettings.json` ship with this branch and already have `Umbraco:CMS:DeliveryApi:Enabled = true`, `Umbraco:CMS:DeliveryApi:OpenApi:GenerateContentTypeSchemas = true`, and a few sample content types and items.
- Run the web app: `dotnet run --project src/Umbraco.Web.UI`. It should be reachable at `https://localhost:44339`.
## Run
```bash
dotnet run --project tests/clients/kiota
```
Each build:
1. Re-downloads the spec from the live URL into `spec/delivery.json`.
2. Restores the local kiota tool (`dotnet tool restore`).
3. Runs `dotnet kiota generate` to emit a fluent client into `Client/`.
4. Compiles and runs `Program.cs`.
## Why kiota and not nswag?
NSwag's generator currently breaks on parts of OpenAPI 3.1 (`oneOf` + `discriminator` + `const`), which our typed schemas use. Kiota was designed for 3.1 from the start and is the generator behind Microsoft Graph SDKs. This project is here to confirm a .NET client can be generated and used against the typed Delivery API spec.
## Caveats
- `Program.cs` deliberately bypasses certificate validation against `https://localhost:44339`. Don't reuse this handler in any non-throwaway code.
- The csproj passes `--disable-validation-rules all` to kiota. The Delivery API spec has two routes that share the same kiota-collapsed path signature (`/content/item/{id}` taking a Guid and `/content/item/{path}` taking a string). Without the flag, kiota refuses to generate. With it, kiota emits both as indexers on the same builder — the string overload is marked `[Obsolete]` and `Program.cs` suppresses `CS0618` to call it.
- Kiota generates polymorphic schemas as a `IComposedTypeWrapper` class with nullable properties for each variant rather than as a real interface or base type. Use `wrapper.TestPageContentResponseModel is { } testPage` (or similar) to access the populated variant.
- The properties bag (`TestPageContentResponseModel.Properties`) collapses to `AdditionalData` only — kiota does not emit strongly-typed fields for the per-property aliases. This is in contrast to orval and hey-api, which keep full type fidelity. Unclear whether this is a kiota limitation around `allOf` composition + `additionalProperties: false`, or a quirk of disabling validation. The fluent path + discriminator handling are otherwise solid.
+28
View File
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>UmbracoDeliveryClient</RootNamespace>
<AssemblyName>UmbracoDeliveryKiotaClient</AssemblyName>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Kiota.Bundle" Version="1.22.1" />
</ItemGroup>
<Target Name="DownloadDeliveryApiSpec" BeforeTargets="GenerateKiotaClient;BeforeBuild" Condition="!Exists('$(ProjectDir)spec\delivery.json')">
<MakeDir Directories="$(ProjectDir)spec" />
<Exec Command="curl -sk https://localhost:44339/umbraco/openapi/delivery.json -o &quot;$(ProjectDir)spec/delivery.json&quot;" />
</Target>
<Target Name="GenerateKiotaClient" BeforeTargets="BeforeBuild" DependsOnTargets="DownloadDeliveryApiSpec">
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet kiota generate -l csharp -d spec/delivery.json -c UmbracoApi -n UmbracoDeliveryClient.Generated -o Client --clean-output --clear-cache --disable-validation-rules all" />
</Target>
</Project>
File diff suppressed because it is too large Load Diff
+139
View File
@@ -0,0 +1,139 @@
using System.Text.Json;
using UmbracoDeliveryClient;
// Trust the dev cert at https://localhost:44339
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
};
var httpClient = new HttpClient(handler);
UmbracoApi umbracoApi = new("https://localhost:44339", httpClient);
IApiContentResponseModel page = await umbracoApi.GetContentItemByPath2_0Async("/", expand: "properties[$all]");
RenderPage(page);
void RenderPage(IApiContentResponseModel content)
{
Console.WriteLine($" Name: {content.Name}");
Console.WriteLine($" Path: {content.Route?.Path}");
if (content is TestPageContentResponseModel testPage)
{
RenderTestPage(testPage);
}
}
void RenderTestPage(TestPageContentResponseModel content)
{
TestPagePropertiesModel? properties = content.Properties;
Console.WriteLine("\n **Common**");
Print("textString", properties?.TextString);
Print("textArea", properties?.TextArea);
Print("datePickerWithTime", properties?.DatePickerWithTime);
Print("datePicker", properties?.DatePicker);
Print("toggle", properties?.Toggle);
Print("numeric", properties?.Numeric);
Print("decimal", properties?.Decimal);
Print("slider", properties?.Slider);
Print("tags", properties?.Tags);
Print("email", properties?.Email);
Print("dateOnly", properties?.DateOnly);
Print("timeOnly", properties?.TimeOnly);
Print("dateTimeUnspecified", properties?.DateTimeUnspecified);
Print("dateTimeWithTimeZone", properties?.DateTimeWithTimeZone);
Console.WriteLine("\n **Pickers**");
Print("colorPicker", properties?.ColorPicker);
Print("contentPicker", "<tested below>");
Print("eyeDropperColorPicker", properties?.EyeDropperColorPicker);
Print("urlPicker", properties?.UrlPicker);
Print("multinodeTreepicker", "<tested below>");
Print("userPicker", properties?.UserPicker);
Console.WriteLine("\n **Rich content**");
Print("richText", properties?.RichText);
Print("blockGrid", "<tested below>");
Print("markdown", properties?.Markdown);
Console.WriteLine("\n **Lists**");
Print("blockList", "<tested below>");
Print("checkboxList", properties?.CheckboxList);
Print("dropdown", properties?.Dropdown);
Print("radiobox", properties?.Radiobox);
Print("repeatableTextstrings", properties?.RepeatableTextstrings);
Console.WriteLine("\n **Media**");
Print("uploadFile", properties?.UploadFile);
Print("imageCropper", properties?.ImageCropper);
Print("mediaPicker", properties?.MediaPicker);
Console.WriteLine("\n **Content Picker**");
Print("name", properties?.ContentPicker?.Name);
Print("route>path", properties?.ContentPicker?.Route?.Path);
Console.WriteLine("\n **Multinode Treepicker**");
Print("name", properties?.MultinodeTreepicker?.FirstOrDefault()?.Name);
Print("route>path", properties?.MultinodeTreepicker?.FirstOrDefault()?.Route?.Path);
Console.WriteLine("\n **Block List**");
foreach ((ApiBlockItemModel block, int i) in content.Properties?.BlockList?.Items?.Select((b, i) => (b, i)) ?? [])
{
Console.WriteLine($" Block[{i}]:");
RenderBlock(block);
}
Console.WriteLine("\n **Block Grid**");
foreach ((ApiBlockGridItemModel block, int i) in content.Properties?.BlockGrid?.Items?.Select((b, i) => (b, i)) ?? [])
{
Console.WriteLine($" Block[{i}]:");
RenderBlock(block);
}
Console.WriteLine("\n **From compositions**");
Print(" sharedToggle", properties?.SharedToggle);
Print(" sharedString", properties?.SharedString);
Print(" sharedRadiobox", properties?.SharedRadiobox);
Print(" sharedRichText", properties?.SharedRichText);
}
void RenderBlock(ApiBlockItemModel block)
{
Console.WriteLine($" Type: {block.Content?.GetType().Name}");
switch (block.Content)
{
case TestBlockElementModel testBlock:
{
Console.WriteLine($" String: {testBlock.Properties?.String}");
Console.WriteLine($" Multinode Treepicker: {testBlock.Properties?.MultinodeTreepicker?.FirstOrDefault()?.Id}");
Console.WriteLine($" Shared string: {testBlock.Properties?.SharedString}");
ApiBlockItemModel? nestedBlock = testBlock.Properties?.Blocks?.Items?.FirstOrDefault();
if (nestedBlock is not null)
{
Console.WriteLine(" **Nested block**");
RenderBlock(nestedBlock);
}
break;
}
case TestBlock2ElementModel testBlock2:
{
Console.WriteLine($" Shared string (testBlock2): {testBlock2.Properties?.SharedString}");
if (block.Settings is BlockSettingsElementModel settings)
{
Console.WriteLine($" Anchor id (settings): {settings.Properties?.AnchorId}");
}
break;
}
default:
Console.WriteLine(" Unknown block type");
break;
}
}
void Print(string propertyName, object? value) =>
Console.WriteLine($" {propertyName} ({value?.GetType().Name}): {JsonSerializer.Serialize(value)}");
+31
View File
@@ -0,0 +1,31 @@
# NSwag client smoke test
> ⚠️ **This client does not work today.** NSwag's generator emits broken references (inline `Anonymous`, `Anonymous2`, `MultinodeTreepicker`, `MediaPicker`, `Content` types) when faced with the OpenAPI 3.1 polymorphic shape this spec uses. The project is kept here to document the failure mode; expect compile errors on first build.
Verifies that the Delivery API OpenAPI document produces a valid client when consumed by [NSwag](https://github.com/RicoSuter/NSwag) via the `NSwag.ApiDescription.Client` MSBuild integration.
## Prerequisites
- .NET 10 SDK
- The committed SQLite DB and `appsettings.json` ship with this branch and already have `Umbraco:CMS:DeliveryApi:Enabled = true`, `Umbraco:CMS:DeliveryApi:OpenApi:GenerateContentTypeSchemas = true`, and a few sample content types and items.
- Run the web app: `dotnet run --project src/Umbraco.Web.UI`. It should be reachable at `https://localhost:44339`.
## Run
```bash
dotnet run --project tests/clients/nswag
```
`dotnet build` invokes `NSwag.ApiDescription.Client` which fetches the spec from the live URL and emits `UmbracoApi.g.cs` next to the project file. The generated client is a single file with both the SDK class and the typed models.
## Caveats
- NSwag is currently maintained against OpenAPI 3.0; the document we generate is OpenAPI 3.1.1. Some 3.1-only constructs (`const`, `null` in `type` arrays, `oneOf` + `discriminator` shape) may not generate cleanly. Failures here are expected to be reported as issues against NSwag, not against the OpenAPI generation.
- The `Program.cs` deliberately bypasses certificate validation against `https://localhost:44339`. Don't reuse this handler in any non-throwaway code.
## What this proves (when it works)
- The generated C# types compile.
- The polymorphic `IApiContentResponseModel` resolves to the correct concrete model (`TestPageContentResponseModel`) via pattern matching.
- Composition properties (`SharedToggle`, `SharedString`, `SharedRadiobox`, `SharedRichText`) appear directly on the composing type's properties model.
- A real HTTP request returns data shaped according to the spec.
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>UmbracoDeliveryClient</RootNamespace>
<AssemblyName>UmbracoDeliveryClient</AssemblyName>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NSwag.ApiDescription.Client" Version="14.6.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<OpenApiReference Include="spec\delivery.json" CodeGenerator="NSwagCSharp">
<OutputPath>$(ProjectDir)UmbracoApi.g.cs</OutputPath>
<ClassName>UmbracoApi</ClassName>
<Namespace>UmbracoDeliveryClient</Namespace>
<Options>/JsonLibrary:SystemTextJson /GenerateClientInterfaces:true /GenerateNullableReferenceTypes:true /GenerateOptionalPropertiesAsNullable:true /GenerateOptionalParameters:true</Options>
</OpenApiReference>
</ItemGroup>
<Target Name="DownloadDeliveryApiSpec" BeforeTargets="GenerateNSwagCSharp;BeforeBuild" Condition="!Exists('$(ProjectDir)spec\delivery.json')">
<MakeDir Directories="$(ProjectDir)spec" />
<Exec Command="curl -sk https://localhost:44339/umbraco/openapi/delivery.json -o &quot;$(ProjectDir)spec/delivery.json&quot;" />
</Target>
</Project>
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
# Orval client smoke test
Verifies that the Delivery API OpenAPI document produces a valid client when consumed by [orval](https://orval.dev).
## Prerequisites
- Node.js 22 or later
- The committed SQLite DB and `appsettings.json` ship with this branch and already have `Umbraco:CMS:DeliveryApi:Enabled = true`, `Umbraco:CMS:DeliveryApi:OpenApi:GenerateContentTypeSchemas = true`, and a few sample content types and items.
- Run the web app: `dotnet run --project src/Umbraco.Web.UI`. It should be reachable at `https://localhost:44339`.
## Run
```bash
npm install
npm start
```
`npm start` regenerates the client from the live OpenAPI document, builds, and executes `app.ts`. The script lists the seeded content items and uses TypeScript discriminated unions on `contentType` to access type-specific properties.
## What this proves
- The generated TypeScript types compile (`tsc --build`).
- The polymorphic `IApiContentResponseModel` narrows correctly on the `contentType` discriminator.
- Composition properties (e.g. `metaDescription` from `seoMetadata`) appear on the composing type's properties model.
- A real HTTP request returns data shaped according to the spec.
+127
View File
@@ -0,0 +1,127 @@
import {
getContentItemByPath20,
type ApiBlockItemModel,
type IApiContentResponseModel,
type TestPageContentResponseModel,
} from './api/umbraco-delivery';
(async () => {
console.log('** Page - Default **');
const content = (await getContentItemByPath20('/', {expand: 'properties[$all]'})).data;
renderPage(content);
})();
function renderPage(content: IApiContentResponseModel) {
console.log(' Name: ', content.name);
console.log(' Path: ', content.route?.path);
if (content.contentType === 'testPage') {
renderTestPage(content);
}
}
function renderTestPage(content: TestPageContentResponseModel) {
const {properties} = content;
console.log('\n **Common**');
print('textString', properties?.textString);
print('textArea', properties?.textArea);
print('datePickerWithTime', properties?.datePickerWithTime);
print('datePicker', properties?.datePicker);
print('toggle', properties?.toggle);
print('numeric', properties?.numeric);
print('decimal', properties?.decimal);
print('slider', properties?.slider);
print('tags', properties?.tags);
print('email', properties?.email);
print('dateOnly', properties?.dateOnly);
print('timeOnly', properties?.timeOnly);
print('dateTimeUnspecified', properties?.dateTimeUnspecified);
print('dateTimeWithTimeZone', properties?.dateTimeWithTimeZone);
console.log('\n **Pickers**');
print('colorPicker', properties?.colorPicker);
print('contentPicker', '<tested below>');
print('eyeDropperColorPicker', properties?.eyeDropperColorPicker);
print('urlPicker', properties?.urlPicker);
print('multinodeTreepicker', '<tested below>');
print('userPicker', properties?.userPicker);
console.log('\n **Rich content**');
print('richText', properties?.richText);
print('blockGrid', '<tested below>');
print('markdown', properties?.markdown);
console.log('\n **Lists**');
print('blockList', '<tested below>');
print('checkboxList', properties?.checkboxList);
print('dropdown', properties?.dropdown);
print('radiobox', properties?.radiobox);
print('repeatableTextstrings', properties?.repeatableTextstrings);
console.log('\n **Media**');
print('uploadFile', properties?.uploadFile);
print('imageCropper', properties?.imageCropper);
print('mediaPicker', properties?.mediaPicker);
console.log('\n **Content Picker**');
print('name', properties?.contentPicker?.name);
print('route>path', properties?.contentPicker?.route?.path);
console.log('\n **Multinode Treepicker**');
print('name', properties?.multinodeTreepicker?.[0]?.name);
print('route>path', properties?.multinodeTreepicker?.[0]?.route?.path);
console.log('\n **Block List**');
properties?.blockList?.items?.forEach((block, i) => {
console.log(` Block[${i}]:`);
renderBlock(block);
});
console.log('\n **Block Grid**');
properties?.blockGrid?.items?.forEach((block, i) => {
console.log(` Block[${i}]:`);
renderBlock(block);
});
console.log('\n **From compositions**');
print(' sharedToggle', properties?.sharedToggle);
print(' sharedString', properties?.sharedString);
print(' sharedRadiobox', properties?.sharedRadiobox);
print(' sharedRichText', properties?.sharedRichText);
}
function renderBlock(block: ApiBlockItemModel) {
console.log(' Type: ', block.content?.contentType);
switch (block.content?.contentType) {
case 'testBlock': {
console.log(' String: ', block.content.properties?.string);
console.log(' Multinode Treepicker: ', block.content.properties?.multinodeTreepicker?.[0]?.id);
console.log(' Shared string: ', block.content.properties?.sharedString);
const nestedBlock = block.content.properties?.blocks?.items?.[0];
if (nestedBlock) {
console.log(' **Nested block**');
renderBlock(nestedBlock);
}
break;
}
case 'testBlock2': {
console.log(' Shared string (testBlock2): ', block.content.properties?.sharedString);
if (block.settings?.contentType === 'blockSettings') {
console.log(' Anchor id (settings): ', block.settings.properties?.anchorId);
}
break;
}
default:
console.error(' Unknown block type');
break;
}
}
function print(propertyName: string, value: unknown) {
console.log(` ${propertyName} (${typeof value}): ${JSON.stringify(value)}`);
}
+14
View File
@@ -0,0 +1,14 @@
import {defineConfig} from 'orval';
export default defineConfig({
'umbraco-delivery': {
input: {
target: 'https://localhost:44339/umbraco/openapi/delivery.json',
validation: false,
},
output: {
target: 'api/umbraco-delivery.ts',
baseUrl: 'https://localhost:44339',
},
},
});

Some files were not shown because too many files have changed in this diff Show More