Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8b7cf4a
Merge pull request #35 from contentstack/master
harshithad0703 Jan 12, 2026
eda03ed
update: added skill files
cs-raj Apr 10, 2026
d5bd06d
Fixed build error
cs-raj Apr 10, 2026
5bbd9ba
Merge pull request #36 from contentstack/update/DX-5385
cs-raj Apr 10, 2026
1c3e6ad
feat: upgrade to .NET 10 and bump version to 1.0.0-beta.1
OMpawar-21 Jun 30, 2026
e092611
Update CHANGELOG with new version entries
OMpawar-21 Jun 30, 2026
95255f5
feat: migrate internal model DTOs from [JsonProperty] to [JsonPropert…
OMpawar-21 Jul 1, 2026
81e34f0
Merge pull request #39 from contentstack/enhc/DX-9373
OMpawar-21 Jul 1, 2026
70374c2
Merge branch 'enhc/beta' into enhc/DX-9374
OMpawar-21 Jul 1, 2026
8440549
Merge pull request #40 from contentstack/enhc/DX-9374
OMpawar-21 Jul 1, 2026
2861812
feat: migrate HTTP layer from Newtonsoft.Json to System.Text.Json
OMpawar-21 Jul 2, 2026
468ac25
refactor: migrate from Newtonsoft.Json to System.Text.Json for serial…
reeshika-h Jul 3, 2026
9f14ccd
refactor: update serializer settings to use JsonSerializerOptions in …
reeshika-h Jul 3, 2026
216d181
Merge pull request #42 from contentstack/enh/DX-9375-OauthService-mig…
OMpawar-21 Jul 3, 2026
4593fc1
Merge pull request #41 from contentstack/enhc/DX-9374
OMpawar-21 Jul 3, 2026
2489a3a
Merge pull request #43 from contentstack/enh/DX-9377-client-migration
OMpawar-21 Jul 3, 2026
ff75cc2
refactor: remove Newtonsoft.Json package and migrate template attribu…
OMpawar-21 Jul 7, 2026
07011bd
Merge pull request #44 from contentstack/enhc/DX-9378
OMpawar-21 Jul 7, 2026
d046cb4
refactor: migrate modular block converter template to System.Text.Json
OMpawar-21 Jul 7, 2026
e1e689c
refactor: migrate from Newtonsoft.Json to System.Text.Json in ModelGe…
reeshika-h Jul 7, 2026
525b5c3
Merge pull request #45 from contentstack/enhc/DX-9382
OMpawar-21 Jul 8, 2026
5aa4aba
Merge pull request #46 from contentstack/enh/DX-9381-converter-migration
OMpawar-21 Jul 8, 2026
95c5626
test: expand unit test coverage for ModelGenerator and previously-unt…
OMpawar-21 Jul 8, 2026
13615b2
Update CHANGELOG.md
OMpawar-21 Jul 8, 2026
421e64c
Update README.md
OMpawar-21 Jul 8, 2026
ba51a9d
Merge pull request #47 from contentstack/enhc/DX-9463
OMpawar-21 Jul 9, 2026
df874ef
feat: Update the Read me and version bump for Major Release
OMpawar-21 Jul 10, 2026
9a09e91
Merge pull request #48 from contentstack/enhc/DX-9498-model-gen
OMpawar-21 Jul 10, 2026
ce4b101
Merge branch 'master' into enhc/beta
OMpawar-21 Jul 10, 2026
ee3826b
Update check-branch.yml
OMpawar-21 Jul 13, 2026
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
5 changes: 5 additions & 0 deletions .cursor/rules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Cursor (optional)

**Cursor** users: start at **[AGENTS.md](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`**.

This folder only points contributors to **AGENTS.md** so editor-specific config does not duplicate the canonical docs.
18 changes: 8 additions & 10 deletions .github/workflows/check-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ jobs:
check_branch:
runs-on: ubuntu-latest
steps:
- name: Comment PR
if: github.base_ref == 'master' && github.head_ref != 'staging'
uses: thollander/actions-comment-pull-request@v2
with:
message: |
We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the staging branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch.
- name: Check branch
if: github.base_ref == 'master' && github.head_ref != 'staging'
# PRs into master are no longer blocked here based on their source branch.
# Direct merges into master (i.e. without going through PR review) are expected
# to be prevented by GitHub branch protection rules on master, not by this CI check.
- name: Branch check (informational only)
run: |
echo "ERROR: We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the staging branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch."
exit 1
echo "This workflow no longer restricts which branch a PR into master can come from."
echo "Base branch : ${{ github.base_ref }}"
echo "Head branch : ${{ github.head_ref }}"
echo "Direct pushes/merges to master should be prevented via branch protection rules, not this workflow."
19 changes: 11 additions & 8 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ on:
release:
types: [created]
jobs:
publish-nuget:
publish-nuget:
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v1
- name: Setup .NET Core @ Latest
uses: actions/setup-dotnet@v3
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.x'
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY }}
- name: Build solution and generate NuGet package
Expand All @@ -24,14 +26,15 @@ jobs:
cd out
dotnet nuget push "contentstack.model.generator.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate --no-symbols true --source https://api.nuget.org/v3/index.json

publish-git:
publish-git:
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v1
- name: Setup .NET Core @ Latest
uses: actions/setup-dotnet@v3
uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.x'
source-url: https://nuget.pkg.github.com/Contentstack/index.json
env:
NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ packages/
*/mono_crash*
.vscode
.dccache
.sonarqube/
.sonarqube/
*/TestResults/
TestResults/
test-report_*.html
51 changes: 51 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Contentstack Model Generator – Agent guide

**Universal entry point** for contributors and AI agents. Detailed conventions live in **`skills/*/SKILL.md`**.

## What this repo is

| Field | Detail |
| --- | --- |
| **Name:** | [contentstack/contentstack-model-generator](https://github.com/contentstack/contentstack-model-generator) |
| **Purpose:** | A **.NET global tool** (`contentstack.model.generator`) that connects to the Content Management API (CMA), fetches content types and global fields from a stack, and **emits C# model classes** (and helpers) under a `Models` output folder. |
| **Out of scope (if any):** | This package is a **CLI code generator**, not a runtime Contentstack SDK for apps. Product install and CLI flags are documented in [README.md](README.md). |

## Tech stack (at a glance)

| Area | Details |
| --- | --- |
| **Language** | C# — tool targets **.NET 7** (`net7.0`); test project targets **.NET 9** (`net9.0`). |
| **Build** | .NET SDK — solution [contentstack.model.generator/contentstack.model.generator.sln](contentstack.model.generator/contentstack.model.generator.sln); main project [contentstack.model.generator/contentstack.model.generator.csproj](contentstack.model.generator/contentstack.model.generator.csproj) (`PackAsTool`, `PackOnBuild`). |
| **Tests** | xUnit — project [contentstack.model.generator.tests/contentstack.model.generator.tests.csproj](contentstack.model.generator.tests/contentstack.model.generator.tests.csproj); Moq; coverlet.collector. |
| **Lint / coverage** | Built-in .NET analyzers; coverlet for coverage in tests. No repo-wide `dotnet format` / StyleCop config in-tree at time of writing. |
| **Tool dependencies** | [contentstack.model.generator.csproj](contentstack.model.generator/contentstack.model.generator.csproj): McMaster.Extensions.CommandLineUtils, Newtonsoft.Json; HTTP via [HTTPRequestHandler.cs](contentstack.model.generator/CMA/HTTPRequestHandler.cs) (`HttpClient`). |
| **Consumer projects (generated `Models/`)** | Emitted C# references **Contentstack.Core**, **Contentstack.Utils**, **Newtonsoft.Json**, and **Markdig** (e.g. generated `ContentstackStringExtension`). Those NuGet packages must be added to the **application that uses the generated code**, not to the generator tool project. |

## Commands (quick reference)

| Command type | Command |
| --- | --- |
| **Restore** | `dotnet restore contentstack.model.generator/contentstack.model.generator.sln` |
| **Build** | `dotnet build contentstack.model.generator/contentstack.model.generator.sln` |
| **Test** | `dotnet test contentstack.model.generator/contentstack.model.generator.sln` |
| **Pack (tool NuGet)** | From [contentstack.model.generator/](contentstack.model.generator/): CI uses `dotnet pack -c Release -o out` ([nuget-publish.yml](.github/workflows/nuget-publish.yml)), producing `.nupkg` under `contentstack.model.generator/out/`. Local builds also use **`PackOnBuild`** and **`PackageOutputPath`** (`./nupkg`), so packages may appear under `contentstack.model.generator/nupkg/` unless you override with `-o`. |
| **Install globally (users)** | See [README.md](README.md) (`dotnet tool install -g contentstack.model.generator`). |

**CI / automation:** [.github/workflows/](.github/workflows/) — e.g. branch check ([check-branch.yml](.github/workflows/check-branch.yml)), SCA ([sca-scan.yml](.github/workflows/sca-scan.yml)), CodeQL ([codeql-analysis.yml](.github/workflows/codeql-analysis.yml)), NuGet publish on release ([nuget-publish.yml](.github/workflows/nuget-publish.yml)). **No workflow currently runs `dotnet test`** — run tests locally before opening a PR (see [skills/dev-workflow/SKILL.md](skills/dev-workflow/SKILL.md)).

## Where the documentation lives: skills

| Skill | Path | What it covers |
| --- | --- | --- |
| **Dev workflow** | [skills/dev-workflow/SKILL.md](skills/dev-workflow/SKILL.md) | Branches, CI, build/test/pack commands, solution paths. |
| **Testing** | [skills/testing/SKILL.md](skills/testing/SKILL.md) | Test layout, xUnit/Moq/coverlet, test file map, secrets/credentials. |
| **Code review** | [skills/code-review/SKILL.md](skills/code-review/SKILL.md) | PR checklist, branch policy, security scans. |
| **C# / .NET** | [skills/csharp-dotnet/SKILL.md](skills/csharp-dotnet/SKILL.md) | TFMs, namespaces, project layout conventions. |
| **Framework (libraries)** | [skills/framework/SKILL.md](skills/framework/SKILL.md) | McMaster CLI, Newtonsoft.Json, HTTP client, CMA `Config` / base URL—third-party and platform glue. |
| **Product (CLI + CMA + codegen)** | [skills/contentstack-model-generator/SKILL.md](skills/contentstack-model-generator/SKILL.md) | End-to-end runtime flow, layers, extension points. |

Quick links to each **SKILL.md**: [skills/README.md](skills/README.md).

## Using Cursor (optional)

If you use **Cursor**, [.cursor/rules/README.md](.cursor/rules/README.md) points to **[AGENTS.md](AGENTS.md)** so editor-specific config does not duplicate the canonical docs.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
### Version: 1.0.0
#### Date: July-13-2026

##### Breaking Changes:
- Removed the `Newtonsoft.Json` dependency entirely. Both the tool's internals and the models/converters it generates now use `System.Text.Json`.
- Generated model files now use `[JsonPropertyName]` instead of `[JsonProperty]`, and reference `System.Text.Json` / `System.Text.Json.Nodes` / `System.Text.Json.Serialization` instead of `Newtonsoft.Json`.
- Generated embedded-object and modular-block converters now inherit `System.Text.Json.Serialization.JsonConverter<T>` (`Read`/`Write`) instead of Newtonsoft's `JsonConverter<T>` (`ReadJson`/`WriteJson`). Regenerating models against an existing project will change these attributes and converters - update consuming code accordingly.
- Requires **.NET 10.0** or later (previously .NET 7.0).
- `ContentstackException` no longer supports legacy `BinaryFormatter`-based serialization (removed the obsolete `SerializationInfo`/`StreamingContext` constructor and `GetObjectData` override).

##### Enhancements:
- Upgraded target framework from net7.0 to net10.0.
- Updated CI/CD pipeline to use .NET 10 SDK (actions/setup-dotnet@v4).
- Updated Microsoft.AspNetCore.Mvc.Testing from 9.0.9 to 10.0.0.
- Migrated internal model DTOs (Field, MetaData, Contenttype, StackResponse, ContentStackError, OAuth token response) from `[JsonProperty]` to `[JsonPropertyName]`.
- Migrated OAuthService token exchange/refresh deserialization to `System.Text.Json`.
- Migrated the HTTP layer (IResponse, ContentstackResponse, HTTPRequestHandler, ContentstackHttpRequest) from Newtonsoft `JObject` to `System.Text.Json.Nodes.JsonObject`.
- Migrated ContentstackClient's serializer settings, response deserialization, and error parsing to `System.Text.Json` (`JsonSerializerOptions`, `JsonNode`).
- Migrated the code-generation templates (using statements, field attributes, link class, embedded-object converter, modular-block converter, and helper class) to emit `System.Text.Json`-based generated code.
- Fixed reference-field type resolution (`GetDatatypeForContentType`) to use `System.Text.Json.JsonElement` instead of the removed Newtonsoft `JArray`/`JObject` types.

##### Bug fix:
- Fixed GetHeader method visibility (private → internal) to allow test access.
- Fixed a template bug where the generated `embeddedItems` property's nullable annotation was emitted as literal text (`{nullableString()}`) instead of being applied, for content types with RTE-embedded references.

### Version: 0.5.1
#### Date: Jan-12-2026

Expand Down
84 changes: 65 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
# Contentstack model generator
This utility is use to generate models based on ContentTypes in Stack.

## Requirements
**As of v1.0.0**, this tool targets **.NET 10.0** and requires the **.NET 10.0 SDK or later**. Versions prior to v1.0.0 targeted .NET 7.0.

### Compatibility
Since v1.0.0, generated model files use `System.Text.Json` instead of `Newtonsoft.Json`. Because generated code references `Contentstack.Core.Models` and `Contentstack.Utils.Interfaces` / `ContentstackHelper` directly, your consuming project must reference System.Text.Json-based SDK versions for the generated code to compile:

| Package | Minimum Version |
|---|---|
| `contentstack.csharp` (Delivery SDK) | `3.0.0` |
| `contentstack.management.csharp` (Management SDK) | `1.0.0` |
| `contentstack.utils` | `2.0.0` |

Generating models into a project still referencing pre-3.0.0 / pre-1.0.0 / pre-2.0.0 (Newtonsoft-based) SDK versions will produce code that fails to compile.

## Installation
To install Contenstack model generator run following command:
```
Expand All @@ -27,11 +41,11 @@ The Contentstack Model Generator supports two authentication methods:
| `-A` | `--authtoken` | The Authtoken for the Content Management API (required for traditional auth) |
| `-b` | `--branch` | The branch header in the API request to fetch or manage modules located within specific branches. |
| `-e` | `--endpoint` | The Contentstack Host for the Content Management API |
| `-n` | `--namespace` | The namespace the classes should be created in |
| `-n` | `--namespace` | The namespace the classes should be created in (Default Value: ContentstackModels) |
| `-N` | `--is-nullable` | The features that protect against throwing a System.NullReferenceException can be disruptive when turned on. |
| `-f` | `--force` | Automatically overwrite files that already exist |
| `-m` | `--modular-block-prefix` | The Modular block Class Prefix. |
| `-g` | `--group-prefix` | The Group Class Prefix. |
| `-m` | `--modular-block-prefix` | The Modular block Class Prefix. (Default Value: MB) |
| `-g` | `--group-prefix` | The Group Class Prefix. (Default Value: Group) |
| `-p` | `--path` | Path to the file or directory to create files in. |

### OAuth 2.0 Options
Expand Down Expand Up @@ -106,40 +120,72 @@ Here's what you'll see when running an OAuth command:

$ contentstack.model.generator --oauth -a <api_key> --client-id myclient123 --redirect-uri http://localhost:8184

Contentstack Model Generator v0.5.0
=====================================

OAuth Authentication Required
=============================

Please open the following URL in your browser to authorize the application:

https://app.contentstack.com/#!/apps/6400aa06db64de001a31c8a9/authorize?response_type=code&client_id=myclient123&redirect_uri=http%3A%2F%2Flocalhost%3A8184&code_challenge=...
https://app.contentstack.com/#!/apps/6400aa06db64de001a31c8a9/authorize?response_type=code&client_id=myclient123&redirect_uri=http%3A%2F%2Flocalhost%3A8184&code_challenge=...&code_challenge_method=S256

After authorization, you will be redirected to a local URL.
Please copy the 'code' parameter from the redirect URL and paste it here:

Authorization code: [User pastes the code here]
Authorization code: [paste the code here]

Exchanging authorization code for access token...
OAuth authentication successful!
Access token expires at: 2024-01-15 14:30:00 UTC
Access token expires at: 2026-01-15 14:30:00 UTC
Fetching stack details for the provided API key.
No path specified. Generating files in the current working directory: /Users/you/project.
Fetching content types from My Contentstack Stack stack.
Found 5 content types.
Total content types fetched: 5.
Fetching global fields from stack: My Contentstack Stack.
Found 2 global fields.
Total global fields fetched: 2.
Generating files from content types.
Files created successfully.
Opening output directory: /Users/you/project.

Logging out from OAuth...
OAuth logout successful!
```

Fetching stack information...
Stack: My Contentstack Stack
API Key: api_key
## Generated Code

Fetching content types...
Found 5 content types:
Generating files from content type
**As of v1.0.0**, generated model files use **System.Text.Json** instead of Newtonsoft.Json:

Files successfully created!
Opening <file_path>/Models
- Properties are decorated with `[JsonPropertyName("...")]` instead of `[JsonProperty(propertyName: "...")]`.
- Generated files reference `System.Text.Json`, `System.Text.Json.Nodes`, and `System.Text.Json.Serialization` instead of `Newtonsoft.Json`.
- Generated converters (for embedded objects and modular blocks) inherit `System.Text.Json.Serialization.JsonConverter<T>` and implement `Read`/`Write` instead of Newtonsoft's `JsonConverter<T>` with `ReadJson`/`WriteJson`.

Logging out from OAuth...
OAuth logout successful!
A generated model file looks like this:

```csharp
using System;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Contentstack.Core.Models;
using Contentstack.Utils.Interfaces;

namespace ContentstackModels.Models
{
public partial class BlogPost : IEmbeddedObject
{
public const string ContentType = "blog_post";
[JsonPropertyName("uid")]
public string Uid { get; set; }
[JsonPropertyName("_content_type_uid")]
public string ContentTypeUid { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
}
}
```

**Breaking change:** if you regenerate models for an existing project using v1.0.0 or later, the attributes and converter base classes in the output will change from the Newtonsoft-based shape to the System.Text.Json-based shape shown above. Update your consuming code and Contentstack .NET SDK versions accordingly before regenerating.

### MIT License

Copyright (c) 2012-2026 Contentstack
Expand Down
Loading
Loading