Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Extract version from tag
id: get_version
uses: battila7/get-version-action@v2
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

| Packages | Version | Downloads | Compatibility | Documentation |
| ------------------------- | :-----------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------: | :-------------------------: |
| Kontent.Ai.ModelGenerator | [![NuGet](https://img.shields.io/nuget/vpre/Kontent.Ai.ModelGenerator.svg)](https://www.nuget.org/packages/Kontent.Ai.ModelGenerator) | [![NuGet](https://img.shields.io/nuget/dt/Kontent.Ai.ModelGenerator.svg)](https://www.nuget.org/packages/Kontent.Ai.ModelGenerator) | [`net6.0`](https://dotnet.microsoft.com/download/dotnet/6.0) | [📖 Docs](./docs/README.md) |
| Kontent.Ai.ModelGenerator | [![NuGet](https://img.shields.io/nuget/vpre/Kontent.Ai.ModelGenerator.svg)](https://www.nuget.org/packages/Kontent.Ai.ModelGenerator) | [![NuGet](https://img.shields.io/nuget/dt/Kontent.Ai.ModelGenerator.svg)](https://www.nuget.org/packages/Kontent.Ai.ModelGenerator) | [`net8.0`](https://dotnet.microsoft.com/download/dotnet/8.0) | [📖 Docs](./docs/README.md) |

This utility generates strongly-typed (POCO) models based on [content types](https://kontent.ai/learn/tutorials/manage-kontent/content-modeling/create-and-delete-content-types) in a Kontent.ai project. You can choose one of the following:
This utility generates strongly-typed (POCO) models based on [content types](https://kontent.ai/learn/tutorials/manage-kontent/content-modeling/create-and-delete-content-types) in a Kontent.ai project environment. You can choose one of the following:

- [Generate models compatible with the Kontent.ai Delivery SDK for .NET](#how-to-use-for-delivery-sdk)
- [Generate models compatible with the Kontent.ai Management SDK for .NET](#how-to-use-for-management-sdk).
Expand All @@ -27,29 +27,29 @@ The recommended way of obtaining this tool is installing it as a [.NET Tool](htt
#### Global Tool

- `dotnet tool install -g Kontent.Ai.ModelGenerator`
- `KontentModelGenerator --projectid "<projectid>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`
- `KontentModelGenerator --environmentid "<environmentId>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`

#### Local Tool

- `dotnet new tool-manifest` to initialize the tools manifest (if you haven't done that already)
- `dotnet tool install Kontent.Ai.ModelGenerator` (to install the latest version
- `dotnet tool run KontentModelGenerator --projectid "<projectid>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`
- `dotnet tool run KontentModelGenerator --environmentId "<environmentId>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`

### Standalone apps for Windows 🗔, Linux 🐧, macOS 🍎

[Self-contained apps](https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained) are an ideal choice for machines without any version of .NET installed.

Latest release: [Download](https://github.com/kontent-ai/model-generator-net/releases/latest)

- `KontentModelGenerator --projectid "<projectid>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`
- `KontentModelGenerator --environmentId "<environmentId>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel "<structured_model>"] [--filenamesuffix "<suffix>"]`

To learn how to generate executables for your favorite target platform, follow the steps in the [docs](./docs/build-and-run.md).

### Delivery API parameters

| Short key | Long key | Required | Default value | Description |
| --------- | :--------------------------------------: | :------: | :---------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID |
| `-i` | `--environmentId` | True | `null` | A GUID that can be found in [Kontent.ai](https://app.kontent.ai) -> Environment settings -> Environment ID |
| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) |
| `-o` | `--outputdir` | False | `\.` | An output folder path |
| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. |
Expand Down Expand Up @@ -108,7 +108,7 @@ namespace KontentAiModels
### Customizing models - Extended delivery models
Provides support to customize generated models based on content linked/subpages element constraints. This feature uses [Management SDK](https://github.com/kontent-ai/management-sdk-net) thus you'll need to provide api key as well.

`KontentModelGenerator --projectid "<projectid>" -e true -k "<apikey>"`
`KontentModelGenerator --environmentId "<environmentId>" -e true -k "<apikey>"`

#### Extended delivery models example output
Model is generated using structured model option ModularContent.
Expand Down Expand Up @@ -162,16 +162,16 @@ public partial class Home
### Usage

```sh
KontentModelGenerator.exe --projectid "<projectid>" --managementapi true --apikey "<apikey>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--filenamesuffix "<suffix>"]
KontentModelGenerator.exe --environmentId "<environmentId>" --managementapi true --apikey "<apikey>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--filenamesuffix "<suffix>"]
```

### Management API parameters

| Short key | Long key | Required | Default value | Description |
| --------- | :----------------: | :------: | :---------------: | :------------------------------------------------------------------------------------------------------------------------------------: |
| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID |
| `-p` | `--environmentId` | True | `null` | A GUID that can be found in [Kontent.ai](https://app.kontent.ai) -> Environment settings -> Environment ID |
| `-m` | `--managementapi` | True | `false` | Indicates that models should be generated for [Content Management SDK](https://github.com/kontent-ai/management-sdk-net) |
| `-k` | `--apikey` | True | `null` | A api key that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Management API |
| `-k` | `--apikey` | True | `null` | An api key that can be found in [Kontent.ai](https://app.kontent.ai) -> Project settings -> API keys -> Management API keys |
| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) |
| `-o` | `--outputdir` | False | `\.` | An output folder path |
| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) |
Expand Down
11 changes: 4 additions & 7 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
# Kontent.ai Model Generator .NET docs

Welcome to the Kontent.ai Model Generateor .NET docs!
Welcome to the Kontent.ai Model Generator .NET docs!

## Table of Contents

* [**Release & version management**](https://github.com/kontent-ai/kontent-ai.github.io/blob/main/docs/articles/Release-%26-version-management-of-.NET-projects.md)
* [**Release & version management**](https://kontent-ai.github.io/ci-and-automation/net-guidelines/Kontent.ai-best-practices-for-.csproj-files#version-management)
* [**Building and running the generator for your target platform**](./build-and-run.md)

***

## Blog

* [Kontent blog](https://kontent.ai/blog)
* [Kontent.ai blog](https://kontent.ai/blog)

## Documentation

* [Kontent.ai Learn portal](https://kontent.ai/learn)
* [Kontent.ai API reference](https://kontent.ai/learn/reference)
* [Kontent.ai API reference](https://kontent.ai/learn/docs/apis/overview)

## Product roadmap

* [Kontent Roadmap](https://kontent.ai/roadmap)
2 changes: 1 addition & 1 deletion docs/build-and-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
* Run `dotnet publish -c release -r <RID>` to publish the app

```sh
dotnet run --projectid "<projectid>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel <True|False>] [--filenamesuffix "<suffix>"]
dotnet run --environmentid "<environmentid>" [--namespace "<custom-namespace>"] [--outputdir "<output-directory>"] [--withtypeprovider <True|False>] [--structuredmodel <True|False>] [--filenamesuffix "<suffix>"]
```
33 changes: 12 additions & 21 deletions src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,22 @@

namespace Kontent.Ai.ModelGenerator.Core;

public abstract class CodeGeneratorBase
public abstract class CodeGeneratorBase(
IOptions<CodeGeneratorOptions> options,
IOutputProvider outputProvider,
IClassCodeGeneratorFactory classCodeGeneratorFactory,
IClassDefinitionFactory classDefinitionFactory,
IUserMessageLogger logger)
{
protected readonly IUserMessageLogger Logger;
protected readonly IClassCodeGeneratorFactory ClassCodeGeneratorFactory;
protected readonly IClassDefinitionFactory ClassDefinitionFactory;
protected readonly CodeGeneratorOptions Options;
protected readonly IOutputProvider OutputProvider;
protected readonly IUserMessageLogger Logger = logger;
protected readonly IClassCodeGeneratorFactory ClassCodeGeneratorFactory = classCodeGeneratorFactory;
protected readonly IClassDefinitionFactory ClassDefinitionFactory = classDefinitionFactory;
protected readonly CodeGeneratorOptions Options = options.Value;
protected readonly IOutputProvider OutputProvider = outputProvider;

protected string FilenameSuffix => string.IsNullOrEmpty(Options.FileNameSuffix) ? "" : $".{Options.FileNameSuffix}";
private string NoContentTypeAvailableMessage =>
$@"No content type available for the project ({Options.GetProjectId()}). Please make sure you have the Delivery API enabled at https://app.kontent.ai/.";

protected CodeGeneratorBase(
IOptions<CodeGeneratorOptions> options,
IOutputProvider outputProvider,
IClassCodeGeneratorFactory classCodeGeneratorFactory,
IClassDefinitionFactory classDefinitionFactory,
IUserMessageLogger logger)
{
ClassCodeGeneratorFactory = classCodeGeneratorFactory;
ClassDefinitionFactory = classDefinitionFactory;
Options = options.Value;
OutputProvider = outputProvider;
Logger = logger;
}
$@"No content type available for the environment ({Options.GetEnvironmentId()}). Check the environment and project settings at https://app.kontent.ai/.";

public async Task<int> RunAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,13 @@ public ClassCodeGenerator CreateClassCodeGenerator(
IUserMessageLogger logger,
bool customPartial = false)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
ArgumentNullException.ThrowIfNull(options);

if (classDefinition == null)
{
throw new ArgumentNullException(nameof(classDefinition));
}
ArgumentNullException.ThrowIfNull(classDefinition);

if (classFilename == null)
{
throw new ArgumentNullException(nameof(classFilename));
}
ArgumentNullException.ThrowIfNull(classFilename);

if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
ArgumentNullException.ThrowIfNull(logger);

if (customPartial)
{
Expand Down
13 changes: 4 additions & 9 deletions src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@

namespace Kontent.Ai.ModelGenerator.Core.Common;

public class ClassDefinition
public class ClassDefinition(string codeName)
{
public List<Property> Properties { get; } = new List<Property>();
public List<Property> Properties { get; } = [];

public List<string> PropertyCodenameConstants { get; } = new List<string>();
public List<string> PropertyCodenameConstants { get; } = [];

public string ClassName => TextHelpers.GetValidPascalCaseIdentifierName(Codename);

public string Codename { get; }

public ClassDefinition(string codeName)
{
Codename = codeName;
}
public string Codename { get; } = codeName;

public void AddProperty(Property property)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ public class ClassDefinitionFactory : IClassDefinitionFactory
{
public ClassDefinition CreateClassDefinition(string codename)
{
if (string.IsNullOrWhiteSpace(codename))
{
throw new ArgumentException("Class codeName must be a non null and not white space string.", nameof(codename));
}
ArgumentException.ThrowIfNullOrWhiteSpace(codename, nameof(codename));

return new ClassDefinition(codename);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

namespace Kontent.Ai.ModelGenerator.Core.Common;

public class InvalidIdentifierException : Exception
public class InvalidIdentifierException(string message) : Exception(message)
{
public InvalidIdentifierException(string message) : base(message)
{
}
}
15 changes: 4 additions & 11 deletions src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Kontent.Ai.ModelGenerator.Core.Common;

public class Property
public class Property(string codename, string typeName, string id = null)
{
private const string RichTextElementType = "rich_text";
private const string DateTimeElementType = "date_time";
Expand All @@ -21,14 +21,14 @@ public class Property

public string Identifier => TextHelpers.GetValidPascalCaseIdentifierName(Codename);

public string Codename { get; }
public string Codename { get; } = codename;

public string Id { get; }
public string Id { get; } = id;

/// <summary>
/// Returns return type of the property in a string format (e.g.: "string").
/// </summary>
public string TypeName { get; }
public string TypeName { get; } = typeName;

private static readonly IImmutableDictionary<string, string> DeliverElementTypesDictionary = new Dictionary<string, string>
{
Expand Down Expand Up @@ -79,13 +79,6 @@ public class Property
{ ElementMetadataType.Custom, nameof(CustomElement) }
}.ToImmutableDictionary();

public Property(string codename, string typeName, string id = null)
{
Codename = codename;
TypeName = typeName;
Id = id;
}

public static bool IsDateTimeElementType(string elementType) => elementType == DateTimeElementType;

public static bool IsRichTextElementType(string elementType) => elementType == RichTextElementType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public static DesiredModelsType GetDesiredModelsType(this CodeGeneratorOptions o
return options.ExtendedDeliveryModels() ? DesiredModelsType.ExtendedDelivery : DesiredModelsType.Delivery;
}

public static string GetProjectId(this CodeGeneratorOptions options) =>
public static string GetEnvironmentId(this CodeGeneratorOptions options) =>
options.ManagementApi || options.ExtendedDeliveryModels
? options.ManagementOptions.ProjectId
: options.DeliveryOptions.ProjectId;
? options.ManagementOptions.EnvironmentId
: options.DeliveryOptions.EnvironmentId;

public static bool IsStructuredModelModularContent(this CodeGeneratorOptions options) =>
options.StructuredModelFlags.HasFlag(StructuredModelFlags.ModularContent);
Expand Down
Loading