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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [1.4.5](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.5) (2025-10-23)
- handle null and undefined values in getTag function

## [1.4.4](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.4) (2025-09-24)
-Enhance break and newline handling, update dependencies

## [1.4.3](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.3) (2025-09-22)
- Fix data-cslp generation logic in case of applied_variants

Expand Down
104 changes: 104 additions & 0 deletions __test__/entry-editable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,110 @@ describe('Entry editable test', () => {
done()
})

it('Entry with array containing null values should skip null elements', done => {
const entryWithNullInArray = {
"locale": "en-us",
"uid": "uid",
"items": [
null,
{ "title": "valid item" },
null
]
}

expect(() => addTags(entryWithNullInArray, 'content_type', false)).not.toThrow()
expect((entryWithNullInArray as any)['items'][1]['$']['title']).toEqual('data-cslp=content_type.uid.en-us.items.1.title')

done()
})

it('Entry with array containing undefined values should skip undefined elements', done => {
const entryWithUndefinedInArray = {
"locale": "en-us",
"uid": "uid",
"items": [
undefined,
{ "title": "valid item" },
undefined
]
}

expect(() => addTags(entryWithUndefinedInArray, 'content_type', false)).not.toThrow()
expect((entryWithUndefinedInArray as any)['items'][1]['$']['title']).toEqual('data-cslp=content_type.uid.en-us.items.1.title')

done()
})

it('Entry with array containing mixed null and undefined values should skip both', done => {
const entryWithMixedNullUndefined = {
"locale": "en-us",
"uid": "uid",
"items": [
null,
undefined,
{ "title": "valid item 1" },
null,
{ "title": "valid item 2" },
undefined
]
}

expect(() => addTags(entryWithMixedNullUndefined, 'content_type', true)).not.toThrow()
expect((entryWithMixedNullUndefined as any)['items'][2]['$']['title']).toEqual({'data-cslp': 'content_type.uid.en-us.items.2.title'})
expect((entryWithMixedNullUndefined as any)['items'][4]['$']['title']).toEqual({'data-cslp': 'content_type.uid.en-us.items.4.title'})

done()
})

it('Entry with _embedded_items containing null values should handle gracefully', done => {
const entryWithEmbeddedNull: any = {
"locale": "en-us",
"uid": "uid",
"blocks": [
{
"items": [
{ "heading": "Item heading" }
]
}
],
"_embedded_items": {
"blocks.items.description": [null]
}
}

expect(() => addTags(entryWithEmbeddedNull, 'content_type', false)).not.toThrow()
expect((entryWithEmbeddedNull as any)['blocks'][0]['items'][0]['$']['heading']).toEqual('data-cslp=content_type.uid.en-us.blocks.0.items.0.heading')
expect((entryWithEmbeddedNull as any)['_embedded_items']['blocks.items.description'][0]).toBeNull()

done()
})

it('Entry with nested arrays containing nulls in complex structure should work', done => {
const entryWithComplexNulls: any = {
"locale": "en-us",
"uid": "uid",
"blocks": [
{
"hero": {
"title": "Hero title",
"items": [null, { "name": "Item name" }, undefined]
}
},
null,
{
"content": "Content text"
}
]
}

expect(() => addTags(entryWithComplexNulls, 'content_type', true)).not.toThrow()
expect((entryWithComplexNulls as any)['blocks'][0]['hero']['$']['title']).toEqual({'data-cslp': 'content_type.uid.en-us.blocks.0.hero.title'})
expect((entryWithComplexNulls as any)['blocks'][0]['hero']['items'][1]['$']['name']).toEqual({'data-cslp': 'content_type.uid.en-us.blocks.0.hero.items.1.name'})
expect((entryWithComplexNulls as any)['blocks'][2]['$']['content']).toEqual({'data-cslp': 'content_type.uid.en-us.blocks.2.content'})

done()
})

it('Variant path sorting should work correctly for nested paths', done => {
const entryWithComplexVariants = {
"_version": 10,
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/utils",
"version": "1.4.4",
"version": "1.4.5",
"description": "Contentstack utilities for Javascript",
"main": "dist/index.es.js",
"types": "dist/types/index.d.ts",
Expand Down
3 changes: 3 additions & 0 deletions src/entry-editable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ function getTag(content: object, prefix: string, tagsAsObject: boolean, locale:
case "object":
if (Array.isArray(value)) {
value.forEach((obj, index) => {
if (obj === null || obj === undefined) {
return;
}
const childKey = `${key}__${index}`
const parentKey = `${key}__parent`
metaUID = value && typeof value === 'object' && obj !== null && obj._metadata && obj._metadata.uid ? obj._metadata.uid : '';
Expand Down
Loading