Skip to content
Open
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### Version: 2.0.0-beta.1
#### Date: April-27-2026
- **Breaking:** Replaced **Newtonsoft.Json** with **System.Text.Json** across the package. The `Newtonsoft.Json` package reference is removed; add `System.Text.Json` (or rely on the BCL on supported runtimes) as needed in consuming projects.
- **Breaking:** Variant metadata APIs that previously took `JObject` / `JArray` now use `System.Text.Json.Nodes.JsonObject` and `JsonArray` (`GetVariantAliases`, `GetVariantMetadataTags`, and obsolete `GetDataCsvariantsAttribute` overloads).
- JSON serialization uses the same model attributes with `System.Text.Json.Serialization` (`JsonPropertyName`, `JsonConverter`), including custom converters for RTE/GQL-shaped JSON and **path-mapped** embedded models (`PathMappedJsonConverter<T>`).
- RTE JSON deserialization tolerates **trailing commas** when using the documented test/helper patterns (`AllowTrailingCommas`); attribute dictionaries may surface **`JsonElement`** values instead of boxed strings—use helpers or unwrap explicitly if you access `Node.attrs` directly.
- Internal: `LangVersion` set to **latest** for multi-target builds; utilities normalize attribute values where the HTML pipeline expects strings.

### Version: 1.2.0
#### Date: March-31-2026
- Added `GetVariantMetadataTags(JObject, string)` and `GetVariantMetadataTags(JArray, string)` as the canonical API for building the `data-csvariants` payload (same behavior as the previous helpers).
Expand Down
3 changes: 1 addition & 2 deletions Contentstack.Utils.Tests/Contentstack.Utils.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>

<IsPackable>false</IsPackable>
<ReleaseVersion>$(Version)</ReleaseVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="coverlet.collector" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
7 changes: 4 additions & 3 deletions Contentstack.Utils.Tests/DefaultRenderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Contentstack.Utils.Tests.Helpers;
using Contentstack.Utils.Tests.Constants;
using System;
using Contentstack.Utils;

namespace Contentstack.Utils.Tests
{
Expand Down Expand Up @@ -178,9 +179,9 @@ public void testLinkhDocument()

string result = defaultRender.RenderNode("a", nodeLink, (nodes) => { return text; });

string url = nodeLink.attrs.ContainsKey("url") ? (string)nodeLink.attrs["url"] : "";
string target = nodeLink.attrs.ContainsKey("target") ? (string)nodeLink.attrs["target"] : "";
string title = nodeLink.attrs.ContainsKey("title") ? (string)nodeLink.attrs["title"] : "";
string url = nodeLink.attrs.ContainsKey("url") ? JsonAttrValue.AsString(nodeLink.attrs["url"]) : "";
string target = nodeLink.attrs.ContainsKey("target") ? JsonAttrValue.AsString(nodeLink.attrs["target"]) : "";
string title = nodeLink.attrs.ContainsKey("title") ? JsonAttrValue.AsString(nodeLink.attrs["title"]) : "";

Assert.Equal($"<a href=\"{url}\" target=\"{target}\" title=\"{title}\" >Text To set Link</a>", result);
}
Expand Down
28 changes: 16 additions & 12 deletions Contentstack.Utils.Tests/Helpers/NodeParser.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
using Contentstack.Utils.Interfaces;
using System.Text.Json;
using Contentstack.Utils.Interfaces;
using Contentstack.Utils.Models;
using Contentstack.Utils.Tests.Constants;
using Contentstack.Utils.Tests.Mocks;
using Newtonsoft.Json;

namespace Contentstack.Utils.Tests.Helpers
{
public class NodeParser
{
public static Node parse(string jsonNode)
private static readonly JsonSerializerOptions SerializerSettings = new JsonSerializerOptions
{
JsonSerializerSettings SerializerSettings = new JsonSerializerSettings();
JsonSerializer Serializer = JsonSerializer.Create(SerializerSettings);
AllowTrailingCommas = true,
};

return JsonConvert.DeserializeObject<Node>(jsonNode, SerializerSettings);
public static Node parse(string jsonNode)
{
return JsonSerializer.Deserialize<Node>(jsonNode, SerializerSettings);
}
}

public class GQLParser
{
public static GQLModel<T> parse<T>(string jsonNode, string embedConnection = null) where T: IEmbeddedObject
private static readonly JsonSerializerOptions SerializerSettings = new JsonSerializerOptions
{
AllowTrailingCommas = true,
};

public static GQLModel<T> parse<T>(string jsonNode, string embedConnection = null) where T : IEmbeddedObject
{
var data = JsonToHtmlConstants.KGQLModel(jsonNode, embedConnection);
JsonSerializerSettings SerializerSettings = new JsonSerializerSettings();
JsonSerializer Serializer = JsonSerializer.Create(SerializerSettings);
return JsonConvert.DeserializeObject<GQLModel<T>>(data, SerializerSettings);
return JsonSerializer.Deserialize<GQLModel<T>>(data, SerializerSettings);
}
}

}

5 changes: 3 additions & 2 deletions Contentstack.Utils.Tests/Mocks/CustomRenderOptionMock.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Contentstack.Utils;
using Contentstack.Utils.Interfaces;
using Contentstack.Utils.Models;
using HtmlAgilityPack;
Expand All @@ -17,9 +18,9 @@ public override string RenderNode(string nodeType, Node node, NodeChildrenCallBa
case "a":
if (node.attrs.ContainsKey("target"))
{
return $"<a href=\"{(string)node.attrs["url"]}\" target=\"{(string)node.attrs["target"]}\">{callBack(node.children)}</a>";
return $"<a href=\"{JsonAttrValue.AsString(node.attrs["url"])}\" target=\"{JsonAttrValue.AsString(node.attrs["target"])}\">{callBack(node.children)}</a>";
}
return $"<a href=\"{(string)node.attrs["url"]}\">{callBack(node.children)}</a>";
return $"<a href=\"{JsonAttrValue.AsString(node.attrs["url"])}\">{callBack(node.children)}</a>";
}
return base.RenderNode(nodeType, node, callBack);
}
Expand Down
26 changes: 12 additions & 14 deletions Contentstack.Utils.Tests/Mocks/GQLModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,71 @@
using Contentstack.Utils.Converters;
using Contentstack.Utils.Interfaces;
using Contentstack.Utils.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Contentstack.Utils.Tests.Mocks
{
public class GQLModel<T> where T: IEmbeddedObject
public class GQLModel<T> where T : IEmbeddedObject
{
[Newtonsoft.Json.JsonConverter(typeof(RTEJsonConverter))]
public JsonRTENodes<T> multiplerte { get; set; }
public JsonRTENode<T> singlerte { get; set; }
}

[Newtonsoft.Json.JsonConverter(typeof(RTEJsonConverter))]
[JsonConverter(typeof(PathMappedJsonConverter<EntryModel>))]
public class EntryModel : IEmbeddedEntry
{
[JsonProperty("system.uid")]
[JsonPropertyName("system.uid")]
public string Uid
{
get;
set;
}
[JsonProperty("system.content_type_uid")]
[JsonPropertyName("system.content_type_uid")]
public string ContentTypeUid
{
get;
set;
}
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title
{
get;
set;
}
}

[Newtonsoft.Json.JsonConverter(typeof(RTEJsonConverter))]
[JsonConverter(typeof(PathMappedJsonConverter<AssetModel>))]
public class AssetModel : IEmbeddedAsset
{
[JsonProperty("system.uid")]
[JsonPropertyName("system.uid")]
public string Uid
{
get;
set;
}
[JsonProperty("system.content_type_uid")]
[JsonPropertyName("system.content_type_uid")]
public string ContentTypeUid
{
get;
set;
}
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title
{
get;
set;
}
[JsonProperty("filename")]
[JsonPropertyName("filename")]
public string FileName
{
get;
set;
}
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url
{
get;
set;
}
}
}

Loading
Loading