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
29 changes: 0 additions & 29 deletions .github/workflows/secrets-scan.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fileignoreconfig:
ignore_detectors:
- filecontent
- filename: package-lock.json
checksum: f5a5aba11ae3778465d1c001151fefa136629e136a7037fbb70fc7c738cb9d36
checksum: fb18e620409c9476503edb301ef7b1360681e7d03d8c9b93c2e7a6453c744631
- filename: src/entry-editable.ts
checksum: 3ba7af9ed1c1adef2e2bd5610099716562bebb8ba750d4b41ddda99fc9eaf115
- filename: .husky/pre-commit
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.5.0](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.4.5) (2025-10-27)
- fix: handle null and undefined values in getTag function
- fix: refernce variant cslp generation fix

## [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
12 changes: 11 additions & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
* @contentstack/security-admin
* @contentstack/devex-pr-reviewers

.github/workflows/sca-scan.yml @contentstack/security-admin

.github/workflows/codeql-anaylsis.yml @contentstack/security-admin

**/.snyk @contentstack/security-admin

.github/workflows/policy-scan.yml @contentstack/security-admin

.github/workflows/issues-jira.yml @contentstack/security-admin
249 changes: 249 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 Expand Up @@ -268,6 +372,151 @@ describe('Entry editable test', () => {

done()
})

it('Reference fields should not inherit parent variants when they have no applied_variants', done => {
const entryWithReferenceAndVariants = {
"title": "home",
"url": "/data/all_test/first",
"single_line": "ssd",
"tags": ["hi"],
"locale": "en-us",
"uid": "blt827e0ad3608248be",
"created_by": "bltf0d59057590e9b09",
"updated_by": "bltf0d59057590e9b09",
"created_at": "2025-08-25T09:43:49.935Z",
"updated_at": "2025-10-09T11:45:19.967Z",
"ACL": [] as any[],
"_version": 40,
"_in_progress": false,
"json_rte": "<p>hisdassf</p>",
"select": "1",
"group": {
"single_line": ""
},
"non_single_line_textbox": "",
"reference": [
{
"title": "base variant",
"single_line": "bases",
"tags": [] as any[],
"locale": "en-us",
"uid": "blt07a6c7258ddba844",
"created_by": "bltf0d59057590e9b09",
"updated_by": "bltf0d59057590e9b09",
"created_at": "2025-10-01T03:10:10.701Z",
"updated_at": "2025-10-09T11:44:44.981Z",
"_content_type_uid": "all_test_3",
"ACL": [] as any[],
"_version": 3,
"_in_progress": false,
"multi_line_reference": "hii\n"
// Note: This reference object has NO _applied_variants
}
],
"taxonomies": [] as any[],
"multi_line": "woek",
"_applied_variants": {
"single_line": "csfff653e89df54e8c",
"tags": "csfff653e89df54e8c",
"multi_line": "csfff653e89df54e8c"
}
}

addTags(entryWithReferenceAndVariants, 'all_test', false)

// Parent entry fields with variants should get v2 prefix
expect((entryWithReferenceAndVariants as any)['$']['single_line']).toEqual('data-cslp=v2:all_test.blt827e0ad3608248be_csfff653e89df54e8c.en-us.single_line')
expect((entryWithReferenceAndVariants as any)['$']['tags']).toEqual('data-cslp=v2:all_test.blt827e0ad3608248be_csfff653e89df54e8c.en-us.tags')
expect((entryWithReferenceAndVariants as any)['$']['multi_line']).toEqual('data-cslp=v2:all_test.blt827e0ad3608248be_csfff653e89df54e8c.en-us.multi_line')

// Reference fields should NOT get v2 prefix since they have no _applied_variants
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['title']).toEqual('data-cslp=all_test_3.blt07a6c7258ddba844.en-us.title')
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['single_line']).toEqual('data-cslp=all_test_3.blt07a6c7258ddba844.en-us.single_line')
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['tags']).toEqual('data-cslp=all_test_3.blt07a6c7258ddba844.en-us.tags')
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['multi_line_reference']).toEqual('data-cslp=all_test_3.blt07a6c7258ddba844.en-us.multi_line_reference')

done()
})

it('Reference fields with their own applied_variants should use their variants', done => {
const entryWithReferenceHavingVariants = {
"title": "home",
"locale": "en-us",
"uid": "blt827e0ad3608248be",
"ACL": [] as any[],
"_version": 40,
"_in_progress": false,
"single_line": "parent field",
"reference": [
{
"title": "base variant",
"single_line": "reference field",
"locale": "en-us",
"uid": "blt07a6c7258ddba844",
"_content_type_uid": "all_test_3",
"ACL": [] as any[],
"_version": 3,
"_in_progress": false,
"_applied_variants": {
"single_line": "ref_variant_123"
}
}
],
"_applied_variants": {
"single_line": "parent_variant_456"
}
}

addTags(entryWithReferenceHavingVariants, 'all_test', false)

// Parent entry field should get parent variant
expect((entryWithReferenceHavingVariants as any)['$']['single_line']).toEqual('data-cslp=v2:all_test.blt827e0ad3608248be_parent_variant_456.en-us.single_line')

// Reference field should get its own variant, not parent variant
expect((entryWithReferenceHavingVariants as any)['reference'][0]['$']['title']).toEqual('data-cslp=all_test_3.blt07a6c7258ddba844.en-us.title')
expect((entryWithReferenceHavingVariants as any)['reference'][0]['$']['single_line']).toEqual('data-cslp=v2:all_test_3.blt07a6c7258ddba844_ref_variant_123.en-us.single_line')

done()
})

it('Reference fields should work correctly with tagsAsObject=true', done => {
const entryWithReferenceAndVariants = {
"title": "home",
"single_line": "ssd",
"locale": "en-us",
"uid": "blt827e0ad3608248be",
"ACL": [] as any[],
"_version": 40,
"_in_progress": false,
"reference": [
{
"title": "base variant",
"single_line": "bases",
"locale": "en-us",
"uid": "blt07a6c7258ddba844",
"_content_type_uid": "all_test_3",
"ACL": [] as any[],
"_version": 3,
"_in_progress": false
// No _applied_variants
}
],
"_applied_variants": {
"single_line": "csfff653e89df54e8c"
}
}

addTags(entryWithReferenceAndVariants, 'all_test', true)

// Parent entry field with variant should get v2 prefix as object
expect((entryWithReferenceAndVariants as any)['$']['single_line']).toEqual({'data-cslp': 'v2:all_test.blt827e0ad3608248be_csfff653e89df54e8c.en-us.single_line'})

// Reference fields should NOT get v2 prefix as objects
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['title']).toEqual({'data-cslp': 'all_test_3.blt07a6c7258ddba844.en-us.title'})
expect((entryWithReferenceAndVariants as any)['reference'][0]['$']['single_line']).toEqual({'data-cslp': 'all_test_3.blt07a6c7258ddba844.en-us.single_line'})

done()
})
})

})
Loading
Loading