From fc0bc0ccd8335b0f7877a12c15c108c9ec21b91b Mon Sep 17 00:00:00 2001 From: Rahul Chavan Date: Thu, 18 Jun 2026 12:21:02 +0530 Subject: [PATCH 1/9] fix: field not found issue for custom field and field modifier --- __test__/uiLocation.test.ts | 24 +++++++++++++++--- src/uiLocation.ts | 49 +++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/__test__/uiLocation.test.ts b/__test__/uiLocation.test.ts index 1c743a50..f51be413 100644 --- a/__test__/uiLocation.test.ts +++ b/__test__/uiLocation.test.ts @@ -2,7 +2,6 @@ import { AxiosRequestConfig, AxiosResponse } from "axios"; import postRobot from "post-robot"; -import UiLocation from "../src/uiLocation"; import { IAppConfigInitData, IAssetSidebarInitData, @@ -14,8 +13,9 @@ import { LocationType, Region, } from "../src/types"; -import { RequestOption } from "../src/types/common.types"; import { RequestConfig } from "../src/types/api.type"; +import { RequestOption } from "../src/types/common.types"; +import UiLocation from "../src/uiLocation"; jest.mock("post-robot"); jest.mock("wolfy87-eventemitter"); @@ -310,7 +310,13 @@ describe("UI Location", () => { const config = await uiLocation.getConfig(); expect(config).toEqual({}); expect(postRobotSendToParentMock).toHaveBeenLastCalledWith( - "getConfig", {"context": {"extensionUID": "extension_uid", "installationUID": "installation_uid"}} + "getConfig", + { + context: { + extensionUID: "extension_uid", + installationUID: "installation_uid", + }, + } ); }); }); @@ -458,6 +464,9 @@ describe("UI Location", () => { const uiLocation = new UiLocation({ ...initData, type: "FIELD_MODIFIER_LOCATION", + schema: { + $uid: "", + }, } as IFieldModifierLocationInitData); expect(uiLocation.location.FieldModifierLocation).toBeDefined(); expect(uiLocation.location.FieldModifierLocation).toHaveProperty( @@ -478,6 +487,9 @@ describe("UI Location", () => { const uiLocation = new UiLocation({ ...initData, type: "FULL_PAGE_LOCATION", + schema: { + $uid: "", + }, } as IFullPageLocationInitData); expect(uiLocation.location.FullPage).toBeDefined(); expect(uiLocation.location.FullPage).toHaveProperty("stack"); @@ -487,6 +499,9 @@ describe("UI Location", () => { const uiLocation = new UiLocation({ ...initData, type: "FIELD", + schema: { + $uid: "", + }, } as IFieldInitData); expect(uiLocation.location.CustomField).toBeDefined(); expect(uiLocation.location.CustomField).toHaveProperty("field"); @@ -502,6 +517,9 @@ describe("UI Location", () => { const uiLocation = new UiLocation({ ...initData, type: "", + schema: { + $uid: "", + }, } as any); expect(uiLocation.location.CustomField).toBeDefined(); expect(uiLocation.location.CustomField).toHaveProperty("field"); diff --git a/src/uiLocation.ts b/src/uiLocation.ts index 7d1b9dec..b84d68f7 100755 --- a/src/uiLocation.ts +++ b/src/uiLocation.ts @@ -2,10 +2,9 @@ import { AxiosRequestConfig, AxiosResponse } from "axios"; import postRobot from "post-robot"; import EventEmitter from "wolfy87-eventemitter"; +import { AppConfig } from "./appConfig"; import AssetSidebarWidget from "./AssetSidebarWidget"; import ContentTypeSidebarWidget from "./ContentTypeSidebarWidget"; -import { IRTEPluginInitializer } from "./RTE/types"; -import { AppConfig } from "./appConfig"; import Entry from "./entry"; import EventRegistry from "./EventRegistry"; import Field from "./field"; @@ -14,6 +13,7 @@ import FieldModifierLocationField from "./fieldModifierLocation/field"; import FieldModifierLocationFrame from "./fieldModifierLocation/frame"; import Metadata from "./metadata"; import Modal from "./modal"; +import { IRTEPluginInitializer } from "./RTE/types"; import Stack from "./stack"; import Store from "./store"; import { @@ -22,20 +22,20 @@ import { IDashboardWidget, IFieldModifierLocation, IFullPageLocation, + IGlobalFullPageLocation, IRTEInitData, ISidebarWidget, InitializationData, LocationType, Manifest, - IGlobalFullPageLocation, RegionType, } from "./types"; +import { ContentstackEndpoints } from "./types/api.type"; import { GenericObjectType } from "./types/common.types"; import { User } from "./types/user.types"; +import { dispatchAdapter, dispatchApiRequest } from "./utils/adapter"; import { formatAppRegion, onData, onError } from "./utils/utils"; import Window from "./window"; -import { dispatchApiRequest, dispatchAdapter } from "./utils/adapter"; -import { ContentstackEndpoints } from "./types/api.type"; const emitter = new EventEmitter(); @@ -263,6 +263,11 @@ class UiLocation { case LocationType.FIELD_MODIFIER_LOCATION: { initializationData.self = true; + // Fix for FIELD_NOT_FOUND issue introduced in v2.4.0 + // Schema field UIDs contain the complete field path, including parent paths + // Custom Field and Field Modifier UIDs currently contain only the field UID + // As a result, schema field lookup fails for nested fields because the full path is required + // MKT-18455 this.location.FieldModifierLocation = { entry: new FieldModifierLocationEntry( initializationData, @@ -273,7 +278,10 @@ class UiLocation { currentBranch: initializationData.currentBranch, }), field: new FieldModifierLocationField( - initializationData, + { + ...initializationData, + uid: initializationData.schema.$uid, + }, postRobot, emitter ), @@ -309,8 +317,20 @@ class UiLocation { case LocationType.FIELD: default: { initializationData.self = true; + // Fix for FIELD_NOT_FOUND issue introduced in v2.4.0 + // Schema field UIDs contain the complete field path, including parent paths + // Custom Field and Field Modifier UIDs currently contain only the field UID + // As a result, schema field lookup fails for nested fields because the full path is required + // MKT-18455 this.location.CustomField = { - field: new Field(initializationData, postRobot, emitter), + field: new Field( + { + ...initializationData, + uid: initializationData.schema.$uid, + }, + postRobot, + emitter + ), fieldConfig: initializationData.field_config, entry: new Entry(initializationData, postRobot, emitter), stack: new Stack(initializationData.stack, postRobot, { @@ -400,9 +420,7 @@ class UiLocation { ]); } if (event.data.name === "onError") { - emitter.emitEvent("onError", [ - event.data.data, - ]); + emitter.emitEvent("onError", [event.data.data]); } }); } catch (err) { @@ -436,7 +454,12 @@ class UiLocation { return Promise.resolve(this.config); } return this.postRobot - .sendToParent("getConfig", {context:{installationUID:this.installationUID, extensionUID:this.locationUID}}) + .sendToParent("getConfig", { + context: { + installationUID: this.installationUID, + extensionUID: this.locationUID, + }, + }) .then(onData) .catch(onError); }; @@ -490,7 +513,7 @@ class UiLocation { api = (url: string, option?: RequestInit): Promise => dispatchApiRequest(url, option) as Promise; - + /** * Method used to create an adapter for management sdk. */ @@ -524,4 +547,4 @@ class UiLocation { } } -export default UiLocation; \ No newline at end of file +export default UiLocation; From 153a54c884843176e74b2984e110c0044a4a9dd2 Mon Sep 17 00:00:00 2001 From: Rahul Chavan Date: Thu, 18 Jun 2026 16:57:42 +0530 Subject: [PATCH 2/9] Release 2.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6aecd069..13c2068e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/app-sdk", - "version": "2.4.0", + "version": "2.4.1", "types": "dist/src/index.d.ts", "description": "The Contentstack App SDK allows you to customize your Contentstack applications.", "main": "dist/index.js", From fede20053c17f346c94581cfee9b5bda50a66ddb Mon Sep 17 00:00:00 2001 From: Rahul Chavan Date: Thu, 18 Jun 2026 16:59:16 +0530 Subject: [PATCH 3/9] updated package-lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88ce9830..02820f62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/app-sdk", - "version": "2.4.0", + "version": "2.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/app-sdk", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "dependencies": { "axios": "^1.7.9", From 57c97b845368a90688c10b4f4300b783c07ddff6 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Fri, 19 Jun 2026 12:49:44 +0530 Subject: [PATCH 4/9] issues-jira.yml --- .github/workflows/issues-jira.yml | 121 +++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 17 deletions(-) diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml index 7bf04694..5f65d0b6 100644 --- a/.github/workflows/issues-jira.yml +++ b/.github/workflows/issues-jira.yml @@ -2,30 +2,117 @@ name: Create Jira Ticket for Github Issue on: issues: - types: [opened] + types: [opened, reopened] jobs: issue-jira: runs-on: ubuntu-latest steps: + - name: Create Jira Issue + id: create_jira + uses: actions/github-script@v9 + with: + script: | + const baseUrl = process.env.JIRA_BASE_URL; + const userEmail = process.env.JIRA_USER_EMAIL; + const jiraToken = process.env.JIRA_API_TOKEN; + const jiraProject = process.env.JIRA_PROJECT; + const jiraIssueType = process.env.JIRA_ISSUE_TYPE; + const jiraFields = JSON.parse(process.env.ISSUES_JIRA_FIELDS); + + let requestBody = JSON.stringify({ + fields: { + ...jiraFields, + "project": { + "key": jiraProject + }, + "issuetype": { + "name": jiraIssueType + }, + "summary": "Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }}", + "description": { + "version": 1, + "type": "doc", + "content": [ + { + "type": "paragraph", + "content": [ + { + "type": "text", + "text": "Github Issue", + "marks": [ + { + "type": "strong" + } + ] + }, + { + "type": "text", + "text": ": " + }, + { + "type": "text", + "text": "${{ github.event.issue.html_url }}", + "marks": [ + { + "type": "link", + "attrs": { + "href": "${{ github.event.issue.html_url }}" + } + } + ] + } + ] + }, + { + "type": "paragraph", + "content": [ + { + "type": "text", + "text": "Description", + "marks": [ + { + "type": "strong" + } + ] + }, + { + "type": "text", + "text": ":" + } + ] + }, + { + "type": "codeBlock", + "content": [ + { + "type": "text", + "text": `${{ github.event.issue.body }}` + } + ] + } + ] + } + } + }); - - name: Login to Jira - uses: atlassian/gajira-login@master + const response = await fetch(`${baseUrl}/rest/api/3/issue`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Basic ${btoa(userEmail + ":" + jiraToken)}` + }, + body: requestBody + }); + if (!response.ok) { + throw new Error(`JIRA API error! Status: ${response.status}`); + } + const data = await response.json(); + console.log('Jira Issue Created:', data.key); env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - - name: Create Jira Issue - id: create_jira - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} - description: | - *GitHub Issue:* ${{ github.event.issue.html_url }} - - *Description:* - ${{ github.event.issue.body }} - fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file + JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }} + JIRA_ISSUE_TYPE: ${{ secrets.JIRA_ISSUE_TYPE }} + ISSUES_JIRA_FIELDS: "${{ secrets.ISSUES_JIRA_FIELDS }}" From bbf7533ca48d09dd4f1c89c9dcfd086aab3e5ddb Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Tue, 30 Jun 2026 20:09:11 +0530 Subject: [PATCH 5/9] Delete issues-jira.yml --- .github/workflows/issues-jira.yml | 118 ------------------------------ 1 file changed, 118 deletions(-) delete mode 100644 .github/workflows/issues-jira.yml diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml deleted file mode 100644 index 5f65d0b6..00000000 --- a/.github/workflows/issues-jira.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: Create Jira Ticket for Github Issue - -on: - issues: - types: [opened, reopened] - -jobs: - issue-jira: - runs-on: ubuntu-latest - steps: - - name: Create Jira Issue - id: create_jira - uses: actions/github-script@v9 - with: - script: | - const baseUrl = process.env.JIRA_BASE_URL; - const userEmail = process.env.JIRA_USER_EMAIL; - const jiraToken = process.env.JIRA_API_TOKEN; - const jiraProject = process.env.JIRA_PROJECT; - const jiraIssueType = process.env.JIRA_ISSUE_TYPE; - const jiraFields = JSON.parse(process.env.ISSUES_JIRA_FIELDS); - - let requestBody = JSON.stringify({ - fields: { - ...jiraFields, - "project": { - "key": jiraProject - }, - "issuetype": { - "name": jiraIssueType - }, - "summary": "Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }}", - "description": { - "version": 1, - "type": "doc", - "content": [ - { - "type": "paragraph", - "content": [ - { - "type": "text", - "text": "Github Issue", - "marks": [ - { - "type": "strong" - } - ] - }, - { - "type": "text", - "text": ": " - }, - { - "type": "text", - "text": "${{ github.event.issue.html_url }}", - "marks": [ - { - "type": "link", - "attrs": { - "href": "${{ github.event.issue.html_url }}" - } - } - ] - } - ] - }, - { - "type": "paragraph", - "content": [ - { - "type": "text", - "text": "Description", - "marks": [ - { - "type": "strong" - } - ] - }, - { - "type": "text", - "text": ":" - } - ] - }, - { - "type": "codeBlock", - "content": [ - { - "type": "text", - "text": `${{ github.event.issue.body }}` - } - ] - } - ] - } - } - }); - - const response = await fetch(`${baseUrl}/rest/api/3/issue`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Basic ${btoa(userEmail + ":" + jiraToken)}` - }, - body: requestBody - }); - if (!response.ok) { - throw new Error(`JIRA API error! Status: ${response.status}`); - } - const data = await response.json(); - console.log('Jira Issue Created:', data.key); - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }} - JIRA_ISSUE_TYPE: ${{ secrets.JIRA_ISSUE_TYPE }} - ISSUES_JIRA_FIELDS: "${{ secrets.ISSUES_JIRA_FIELDS }}" From ab951bad397a86898078ac92d68ab4386079e59e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Sun, 2 Aug 2026 16:49:14 +0530 Subject: [PATCH 6/9] sca-scan.yml --- .github/workflows/sca-scan.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index 2307d489..79b65575 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -5,6 +5,9 @@ on: jobs: security-sca: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - uses: actions/checkout@master - name: Run Snyk to check for vulnerabilities From e65559296f1cbb43d3dab4a9069e94238665f85a Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Tue, 8 Sep 2026 17:51:54 +0530 Subject: [PATCH 7/9] Updated codeowners --- .github/CODEOWNERS | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bf64ecec..cbec7e77 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1,4 @@ * @contentstack/marketplace-pr-reviewers -.github/workflows/sca-scan.yml @contentstack/security-admin - +.github/workflows/ @contentstack/security-admin **/.snyk @contentstack/security-admin - -.github/workflows/policy-scan.yml @contentstack/security-admin - -.github/workflows/issues-jira.yml @contentstack/security-admin \ No newline at end of file +**/CODEOWNERS @contentstack/security-admin \ No newline at end of file From c41dd6fa60640dfccc25ae9d5f3e4386457cc10e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Thu, 10 Sep 2026 08:21:32 +0530 Subject: [PATCH 8/9] Updated codeowners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cbec7e77..ac7dad02 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ -* @contentstack/marketplace-pr-reviewers +* @contentstack/developer-ecosystem-pr-reviewers .github/workflows/ @contentstack/security-admin **/.snyk @contentstack/security-admin **/CODEOWNERS @contentstack/security-admin \ No newline at end of file From 39944afb5deb99f9dffa2b3eb32cc59a33ea79d8 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Tue, 6 Oct 2026 17:42:41 +0530 Subject: [PATCH 9/9] Updated codeowners --- .github/CODEOWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ac7dad02..d9f2fb34 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,5 @@ * @contentstack/developer-ecosystem-pr-reviewers .github/workflows/ @contentstack/security-admin **/.snyk @contentstack/security-admin -**/CODEOWNERS @contentstack/security-admin \ No newline at end of file +**/CODEOWNERS @contentstack/security-admin +**/.gitguardian.yaml @contentstack/security-admin \ No newline at end of file