From 8b72afac1275b59f403faf3ff5817fc67cf4a68f Mon Sep 17 00:00:00 2001 From: Netraj Patel Date: Tue, 1 Jul 2025 18:02:29 +0530 Subject: [PATCH 1/5] Added AWS-AU support --- .talismanrc | 27 +--- lib/contentstack.js | 105 ++++++------- package-lock.json | 4 +- package.json | 2 +- test/sanity-check/api/user-test.js | 219 ++++++++++++++------------- test/unit/Util-test.js | 229 +++++++++++++++-------------- 6 files changed, 286 insertions(+), 300 deletions(-) diff --git a/.talismanrc b/.talismanrc index 61cb65f1..5d535773 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,27 +1,4 @@ fileignoreconfig: -- filename: .github/workflows/secrets-scan.yml - ignore_detectors: - - filecontent -- filename: package-lock.json - checksum: 9d0340f9359927d477fe8ab4650642c068c592be63fb817651d866849e0dbbc2 -- filename: .husky/pre-commit - checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193 + - filename: test/sanity-check/api/user-test.js + checksum: c82c76ef1a4d175044b9a30a82ed20f004320ec297ea37f27fdbd5c3fec9ff34 version: "" -fileignoreconfig: -- filename: test/unit/globalField-test.js - checksum: 25185e3400a12e10a043dc47502d8f30b7e1c4f2b6b4d3b8b55cdc19850c48bf -version: "1.0" -fileignoreconfig: -- filename: lib/stack/index.js - checksum: 6aab5edf85efb17951418b4dc4402889cd24c8d786c671185074aeb4d50f0242 -- filename: test/sanity-check/api/stack-test.js - checksum: 198d5cf7ead33b079249dc3ecdee61a9c57453e93f1073ed0341400983e5aa53 -version: "1.0" -fileignoreconfig: -- filename: test/sanity-check/api/previewToken-test.js - checksum: 9a42e079b7c71f76932896a0d2390d86ac626678ab20d36821dcf962820a886c -- filename: lib/stack/deliveryToken/index.js - checksum: 51ae00f07f4cc75c1cd832b311c2e2482f04a8467a0139da6013ceb88fbdda2f -- filename: lib/stack/deliveryToken/previewToken/index.js - checksum: b506f33bffdd20dfc701f964370707f5d7b28a2c05c70665f0edb7b3c53c165b -version: "1.0" diff --git a/lib/contentstack.js b/lib/contentstack.js index 18ded7fd..6bffe573 100644 --- a/lib/contentstack.js +++ b/lib/contentstack.js @@ -8,12 +8,13 @@ import getUserAgent from './core/Util.js' import contentstackClient from './contentstackClient.js' import httpClient from './core/contentstackHTTPClient.js' const regionHostMap = { - NA: 'api.contentstack.io', - EU: 'eu-api.contentstack.com', - AZURE_NA: 'azure-na-api.contentstack.com', - AZURE_EU: 'azure-eu-api.contentstack.com', - GCP_NA: 'gcp-na-api.contentstack.com', - GCP_EU: 'gcp-eu-api.contentstack.com' + NA: 'api.contentstack.io', + EU: 'eu-api.contentstack.com', + AU: 'au-api.contentstack.com', + AZURE_NA: 'azure-na-api.contentstack.com', + AZURE_EU: 'azure-eu-api.contentstack.com', + GCP_NA: 'gcp-na-api.contentstack.com', + GCP_EU: 'gcp-eu-api.contentstack.com' } /** @@ -168,56 +169,56 @@ const regionHostMap = { * @prop {string=} params.integration - Integration name and version e.g react/version * @returns Contentstack.Client */ -export function client (params = {}) { - let defaultHostName +export function client(params = {}) { + let defaultHostName - if (params.region) { - const region = params.region.toUpperCase() - if (!regionHostMap[region]) { - throw new Error(`Invalid region '${params.region}' provided. Allowed regions are: ${Object.keys(regionHostMap).join(', ')}`) + if (params.region) { + const region = params.region.toUpperCase() + if (!regionHostMap[region]) { + throw new Error(`Invalid region '${params.region}' provided. Allowed regions are: ${Object.keys(regionHostMap).join(', ')}`) + } + defaultHostName = regionHostMap[region] + } else if (params.host) { + defaultHostName = params.host + } else { + defaultHostName = regionHostMap['NA'] } - defaultHostName = regionHostMap[region] - } else if (params.host) { - defaultHostName = params.host - } else { - defaultHostName = regionHostMap['NA'] - } - const defaultParameter = { - defaultHostName: defaultHostName - } + const defaultParameter = { + defaultHostName: defaultHostName + } - const sdkAgent = `contentstack-management-javascript/${packages.version}` - const userAgentHeader = getUserAgent(sdkAgent, - params.application, - params.integration, - params.feature - ) - const requiredHeaders = { - 'X-User-Agent': sdkAgent, - 'User-Agent': userAgentHeader - } + const sdkAgent = `contentstack-management-javascript/${packages.version}` + const userAgentHeader = getUserAgent(sdkAgent, + params.application, + params.integration, + params.feature + ) + const requiredHeaders = { + 'X-User-Agent': sdkAgent, + 'User-Agent': userAgentHeader + } - if (params.authtoken) { - requiredHeaders.authtoken = params.authtoken - } - if (params.authorization) { - requiredHeaders.authorization = params.authorization - } - if (params.early_access) { - requiredHeaders.early_access = params.early_access.join(',') - } - params = { - ...defaultParameter, - ...clonedeep(params) - } + if (params.authtoken) { + requiredHeaders.authtoken = params.authtoken + } + if (params.authorization) { + requiredHeaders.authorization = params.authorization + } + if (params.early_access) { + requiredHeaders.early_access = params.early_access.join(',') + } + params = { + ...defaultParameter, + ...clonedeep(params) + } - params.headers = { - ...params.headers, - ...requiredHeaders - } - const http = httpClient(params) - return contentstackClient({ - http: http - }) + params.headers = { + ...params.headers, + ...requiredHeaders + } + const http = httpClient(params) + return contentstackClient({ + http: http + }) } diff --git a/package-lock.json b/package-lock.json index a1c14318..76926083 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.22.0", "license": "MIT", "dependencies": { "assert": "^2.1.0", diff --git a/package.json b/package.json index 376be90e..106a4501 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.22.0", "description": "The Content Management API is used to manage the content of your Contentstack account", "main": "./dist/node/contentstack-management.js", "browser": "./dist/web/contentstack-management.js", diff --git a/test/sanity-check/api/user-test.js b/test/sanity-check/api/user-test.js index 015307fa..f16c8f08 100644 --- a/test/sanity-check/api/user-test.js +++ b/test/sanity-check/api/user-test.js @@ -11,127 +11,134 @@ var authtoken = '' var loggedinUserID = '' var client = contentstackClient() describe('Contentstack User Session api Test', () => { - it('should check user login with wrong credentials', done => { - contentstackClient().login({ email: process.env.EMAIL, password: process.env.PASSWORD }) - .then((response) => { - done() - }).catch((error) => { - const jsonMessage = JSON.parse(error.message) - const payload = JSON.parse(jsonMessage.request.data) - expect(jsonMessage.status).to.be.equal(422, 'Status code does not match') - expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') - expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') - expect(payload.user.email).to.be.equal(process.env.EMAIL, 'Email id does not match') - expect(payload.user.password).to.be.equal('contentstack', 'Password does not match') - done() - }) - }) + it('should check user login with wrong credentials', done => { + contentstackClient().login({ email: process.env.EMAIL, password: process.env.PASSWORD }) + .then((response) => { + done() + }).catch((error) => { + const jsonMessage = JSON.parse(error.message) + const payload = JSON.parse(jsonMessage.request.data) + expect(jsonMessage.status).to.be.equal(422, 'Status code does not match') + expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') + expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') + expect(payload.user.email).to.be.equal(process.env.EMAIL, 'Email id does not match') + expect(payload.user.password).to.be.equal('contentstack', 'Password does not match') + done() + }) + }) - it('should Login user', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() + it('should Login user', done => { + client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { + jsonWrite(response.user, 'loggedinuser.json') + expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') + done() + }) + .catch(done) }) - .catch(done) - }) - it('should logout user', done => { - client.logout() - .then((response) => { - expect(axios.defaults.headers.common.authtoken).to.be.equal(undefined) - expect(response.notice).to.be.equal('You\'ve logged out successfully.') - done() - }) - .catch(done) - }) + it('should logout user', done => { + client.logout() + .then((response) => { + expect(axios.defaults.headers.common.authtoken).to.be.equal(undefined) + expect(response.notice).to.be.equal('You\'ve logged out successfully.') + done() + }) + .catch(done) + }) + + it('should login with credentials', done => { + client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { + loggedinUserID = response.user.uid + jsonWrite(response.user, 'loggedinuser.json') + expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') + done() + }) + .catch(done) + }) - it('should login with credentials', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - loggedinUserID = response.user.uid - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() + it('should get Current user info test', done => { + client.getUser().then((user) => { + authtoken = user.authtoken + expect(user.uid).to.be.equal(loggedinUserID) + done() + }) + .catch(done) }) - .catch(done) - }) - it('should get Current user info test', done => { - client.getUser().then((user) => { - authtoken = user.authtoken - expect(user.uid).to.be.equal(loggedinUserID) - done() + it('should get user info from authtoken', done => { + contentstackClient(authtoken) + .getUser() + .then((user) => { + expect(user.uid).to.be.equal(loggedinUserID) + expect(true).to.be.equal(true) + done() + }) + .catch(done) }) - .catch(done) - }) - it('should get user info from authtoken', done => { - contentstackClient(authtoken) - .getUser() - .then((user) => { - expect(user.uid).to.be.equal(loggedinUserID) - expect(true).to.be.equal(true) + it('should get host for NA region by default', done => { + const client = contentstack.client() + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly by default') done() - }) - .catch(done) - }) + }) - it('should get host for NA region by default', done => { - const client = contentstack.client() - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly by default') - done() - }) + it('should get host for NA region', done => { + const client = contentstack.client({ region: 'NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly') + done() + }) - it('should get host for NA region', done => { - const client = contentstack.client({ region: 'NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly') - done() - }) + it('should get host for NA region on priority', done => { + const client = contentstack.client({ region: 'NA', host: 'dev11-api.csnonprod.com' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly with priority') + done() + }) - it('should get host for NA region on priority', done => { - const client = contentstack.client({ region: 'NA', host: 'dev11-api.csnonprod.com' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly with priority') - done() - }) + it('should get custom host', done => { + const client = contentstack.client({ host: 'dev11-api.csnonprod.com' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('dev11-api.csnonprod.com', 'custom host set correctly') + done() + }) - it('should get custom host', done => { - const client = contentstack.client({ host: 'dev11-api.csnonprod.com' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('dev11-api.csnonprod.com', 'custom host set correctly') - done() - }) + it('should get host for EU region', done => { + const client = contentstack.client({ region: 'EU' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('eu-api.contentstack.com', 'region EU set correctly') + done() + }) - it('should get host for EU region', done => { - const client = contentstack.client({ region: 'EU' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('eu-api.contentstack.com', 'region EU set correctly') - done() - }) + it('should get host for AU region', done => { + const client = contentstack.client({ region: 'AU' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('au-api.contentstack.com', 'region AU set correctly') + done() + }) - it('should get host for AZURE_NA region', done => { - const client = contentstack.client({ region: 'AZURE_NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('azure-na-api.contentstack.com', 'region AZURE_NA set correctly') - done() - }) + it('should get host for AZURE_NA region', done => { + const client = contentstack.client({ region: 'AZURE_NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('azure-na-api.contentstack.com', 'region AZURE_NA set correctly') + done() + }) - it('should get host for GCP_NA region', done => { - const client = contentstack.client({ region: 'GCP_NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('gcp-na-api.contentstack.com', 'region GCP_NA set correctly') - done() - }) + it('should get host for GCP_NA region', done => { + const client = contentstack.client({ region: 'GCP_NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('gcp-na-api.contentstack.com', 'region GCP_NA set correctly') + done() + }) - it('should throw error for invalid region', done => { - try { - contentstack.client({ region: 'DUMMYREGION' }) - done(new Error('Expected error was not thrown for invalid region')) - } catch (error) { - expect(error.message).to.include('Invalid region', 'Error message should indicate invalid region') - done() - } - }) + it('should throw error for invalid region', done => { + try { + contentstack.client({ region: 'DUMMYREGION' }) + done(new Error('Expected error was not thrown for invalid region')) + } catch (error) { + expect(error.message).to.include('Invalid region', 'Error message should indicate invalid region') + done() + } + }) }) diff --git a/test/unit/Util-test.js b/test/unit/Util-test.js index 0e125976..e380ee14 100644 --- a/test/unit/Util-test.js +++ b/test/unit/Util-test.js @@ -4,126 +4,127 @@ import { describe, it } from 'mocha' const headerRegEx = /(app|sdk|platform|integration|os) \S+(\/\d+.\d+.\d+(-[\w\d-]+)?)?;/igm describe('Get User Agent', () => { - it('Node user agent', done => { - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(userAgent.match(headerRegEx).length).to.be.equal(5) - expect(userAgent.indexOf('platform node.js/')).to.not.equal(-1) - done() - }) - - it('Browser user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false + it('Node user agent', done => { + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(userAgent.match(headerRegEx).length).to.be.equal(5) + expect(userAgent.indexOf('platform node.js/')).to.not.equal(-1) + done() }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => false) - global.window = { - navigator: { - platform: 'MacIntel' - } - } - const macUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(macUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(macUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(macUserAgent.indexOf('os macOS;')).to.not.equal(-1) - - global.window.navigator.platform = 'Windows' - const windowsUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(windowsUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(windowsUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(windowsUserAgent.indexOf('os Windows;')).to.not.equal(-1) - - global.window.navigator = { userAgent: 'Android' } - const androidUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(androidUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(androidUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(androidUserAgent.indexOf('os Android;')).to.not.equal(-1) - - global.window.navigator = { platform: 'Linux' } - const linuxUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(linuxUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(linuxUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(linuxUserAgent.indexOf('os Linux;')).to.not.equal(-1) - done() - - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) - - it('Fail User agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false + + it('Browser user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false + }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => false) + global.window = { + navigator: { + platform: 'MacIntel' + } + } + const macUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(macUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(macUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(macUserAgent.indexOf('os macOS;')).to.not.equal(-1) + + global.window.navigator.platform = 'Windows' + const windowsUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(windowsUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(windowsUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(windowsUserAgent.indexOf('os Windows;')).to.not.equal(-1) + + global.window.navigator = { userAgent: 'Android' } + const androidUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(androidUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(androidUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(androidUserAgent.indexOf('os Android;')).to.not.equal(-1) + + global.window.navigator = { platform: 'Linux' } + const linuxUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(linuxUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(linuxUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(linuxUserAgent.indexOf('os Linux;')).to.not.equal(-1) + done() + + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => false) - global.window = {} - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + it('Fail User agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false + }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => false) + global.window = {} + + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + + expect(userAgent.match(headerRegEx).length).to.be.equal(3) + expect(userAgent.indexOf('platform browser')).to.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() - expect(userAgent.match(headerRegEx).length).to.be.equal(3) - expect(userAgent.indexOf('platform browser')).to.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) + it('ReactNative user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false + }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => true) + global.window = { + navigator: { + product: 'ReactNative' + } + } + + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + + expect(userAgent.match(headerRegEx).length).to.be.equal(4) + expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() + + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) - it('ReactNative user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false + it('ReactNative ios user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false + }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => true) + global.window = { + navigator: { + product: 'ReactNative', + platform: 'iPhone' + } + } + + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1', 'SampleFeature/0.1') + + expect(userAgent.match(headerRegEx).length).to.be.equal(5) + expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() + global.window = {} + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => true) - global.window = { - navigator: { - product: 'ReactNative' - } - } - - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - - expect(userAgent.match(headerRegEx).length).to.be.equal(4) - expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() - - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) - - it('ReactNative ios user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false + + it('Contentstack host test', done => { + expect(isHost('contentstack.io')).to.be.equal(true, 'contentstack.io should be host') + expect(isHost('contentstack.io:334')).to.be.equal(true, 'contentstack.io:334 should be host') + expect(isHost('http://contentstack.io')).to.be.equal(false, 'http://contentstack.io should not host') + expect(isHost('contentstack.io:2Sdrd')).to.be.equal(true, 'contentstack.io:2Sdrd should be host') + expect(isHost('contentstack.io:wedsfa2')).to.be.equal(true, 'contentstack.io:wedsfa2 should be host') + expect(isHost('eu-api.contentstack.com')).to.be.equal(true, 'eu-api.contentstack.com should be host') + expect(isHost('au-api.contentstack.com')).to.be.equal(true, 'au-api.contentstack.com should be host') + expect(isHost('contentstack.io/path')).to.be.equal(false, 'contentstack.io/path should not host') + done() }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => true) - global.window = { - navigator: { - product: 'ReactNative', - platform: 'iPhone' - } - } - - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1', 'SampleFeature/0.1') - - expect(userAgent.match(headerRegEx).length).to.be.equal(5) - expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() - global.window = {} - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) - - it('Contentstack host test', done => { - expect(isHost('contentstack.io')).to.be.equal(true, 'contentstack.io should be host') - expect(isHost('contentstack.io:334')).to.be.equal(true, 'contentstack.io:334 should be host') - expect(isHost('http://contentstack.io')).to.be.equal(false, 'http://contentstack.io should not host') - expect(isHost('contentstack.io:2Sdrd')).to.be.equal(true, 'contentstack.io:2Sdrd should be host') - expect(isHost('contentstack.io:wedsfa2')).to.be.equal(true, 'contentstack.io:wedsfa2 should be host') - expect(isHost('eu-api.contentstack.com')).to.be.equal(true, 'eu-api.contentstack.com should be host') - expect(isHost('contentstack.io/path')).to.be.equal(false, 'contentstack.io/path should not host') - done() - }) }) From 72da0d0ffea8feca69476e630f02776a1cd38f4d Mon Sep 17 00:00:00 2001 From: Netraj Patel Date: Tue, 1 Jul 2025 18:42:48 +0530 Subject: [PATCH 2/5] Fixed linting and added to pre-commit hook --- .husky/pre-commit | 31 ++-- .talismanrc | 4 +- lib/contentstack.js | 106 ++++++------- test/sanity-check/api/user-test.js | 226 ++++++++++++++-------------- test/unit/Util-test.js | 230 ++++++++++++++--------------- 5 files changed, 306 insertions(+), 291 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 4f1fbbc3..ede0c885 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,11 +1,30 @@ #!/usr/bin/env sh -# Pre-commit hook to run Snyk and Talisman scans, completing both before deciding to commit +# Pre-commit hook to run lint, Snyk and Talisman scans, completing all before deciding to commit # Function to check if a command exists command_exists() { command -v "$1" >/dev/null 2>&1 } +# Allow bypassing the hook with an environment variable +if [ "$SKIP_HOOK" = "1" ]; then + echo "Skipping lint, Snyk and Talisman scans (SKIP_HOOK=1)." + exit 0 +fi + +# Run ESLint check first +echo "Running ESLint check..." +npm run lint +lint_exit_code=$? + +if [ $lint_exit_code -ne 0 ]; then + echo "ESLint check failed. Please fix the linting issues and try again." + echo "You can run 'npm run format' to auto-fix most issues." + exit 1 +fi + +echo "ESLint check passed." + # Check if Snyk is installed if ! command_exists snyk; then echo "Error: Snyk is not installed. Please install it and try again." @@ -18,12 +37,6 @@ if ! command_exists talisman; then exit 1 fi -# Allow bypassing the hook with an environment variable -if [ "$SKIP_HOOK" = "1" ]; then - echo "Skipping Snyk and Talisman scans (SKIP_HOOK=1)." - exit 0 -fi - # Initialize variables to track scan results snyk_failed=false talisman_failed=false @@ -63,7 +76,7 @@ if [ "$snyk_failed" = true ] || [ "$talisman_failed" = true ]; then exit 1 fi -# If both scans pass, allow the commit -echo "All scans passed. Proceeding with commit.cd ." +# If all checks pass, allow the commit +echo "All checks passed (ESLint, Snyk, Talisman). Proceeding with commit." rm -f snyk_output.log talisman_output.log exit 0 \ No newline at end of file diff --git a/.talismanrc b/.talismanrc index 5d535773..df7a3fac 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,6 @@ fileignoreconfig: + - filename: .husky/pre-commit + checksum: 52a664f536cf5d1be0bea19cb6031ca6e8107b45b6314fe7d47b7fad7d800632 - filename: test/sanity-check/api/user-test.js - checksum: c82c76ef1a4d175044b9a30a82ed20f004320ec297ea37f27fdbd5c3fec9ff34 + checksum: 6bb8251aad584e09f4d963a913bd0007e5f6e089357a44c3fb1529e3fda5509d version: "" diff --git a/lib/contentstack.js b/lib/contentstack.js index 6bffe573..02088318 100644 --- a/lib/contentstack.js +++ b/lib/contentstack.js @@ -8,13 +8,13 @@ import getUserAgent from './core/Util.js' import contentstackClient from './contentstackClient.js' import httpClient from './core/contentstackHTTPClient.js' const regionHostMap = { - NA: 'api.contentstack.io', - EU: 'eu-api.contentstack.com', - AU: 'au-api.contentstack.com', - AZURE_NA: 'azure-na-api.contentstack.com', - AZURE_EU: 'azure-eu-api.contentstack.com', - GCP_NA: 'gcp-na-api.contentstack.com', - GCP_EU: 'gcp-eu-api.contentstack.com' + NA: 'api.contentstack.io', + EU: 'eu-api.contentstack.com', + AU: 'au-api.contentstack.com', + AZURE_NA: 'azure-na-api.contentstack.com', + AZURE_EU: 'azure-eu-api.contentstack.com', + GCP_NA: 'gcp-na-api.contentstack.com', + GCP_EU: 'gcp-eu-api.contentstack.com' } /** @@ -169,56 +169,56 @@ const regionHostMap = { * @prop {string=} params.integration - Integration name and version e.g react/version * @returns Contentstack.Client */ -export function client(params = {}) { - let defaultHostName +export function client (params = {}) { + let defaultHostName - if (params.region) { - const region = params.region.toUpperCase() - if (!regionHostMap[region]) { - throw new Error(`Invalid region '${params.region}' provided. Allowed regions are: ${Object.keys(regionHostMap).join(', ')}`) - } - defaultHostName = regionHostMap[region] - } else if (params.host) { - defaultHostName = params.host - } else { - defaultHostName = regionHostMap['NA'] + if (params.region) { + const region = params.region.toUpperCase() + if (!regionHostMap[region]) { + throw new Error(`Invalid region '${params.region}' provided. Allowed regions are: ${Object.keys(regionHostMap).join(', ')}`) } + defaultHostName = regionHostMap[region] + } else if (params.host) { + defaultHostName = params.host + } else { + defaultHostName = regionHostMap['NA'] + } - const defaultParameter = { - defaultHostName: defaultHostName - } + const defaultParameter = { + defaultHostName: defaultHostName + } - const sdkAgent = `contentstack-management-javascript/${packages.version}` - const userAgentHeader = getUserAgent(sdkAgent, - params.application, - params.integration, - params.feature - ) - const requiredHeaders = { - 'X-User-Agent': sdkAgent, - 'User-Agent': userAgentHeader - } + const sdkAgent = `contentstack-management-javascript/${packages.version}` + const userAgentHeader = getUserAgent(sdkAgent, + params.application, + params.integration, + params.feature + ) + const requiredHeaders = { + 'X-User-Agent': sdkAgent, + 'User-Agent': userAgentHeader + } - if (params.authtoken) { - requiredHeaders.authtoken = params.authtoken - } - if (params.authorization) { - requiredHeaders.authorization = params.authorization - } - if (params.early_access) { - requiredHeaders.early_access = params.early_access.join(',') - } - params = { - ...defaultParameter, - ...clonedeep(params) - } + if (params.authtoken) { + requiredHeaders.authtoken = params.authtoken + } + if (params.authorization) { + requiredHeaders.authorization = params.authorization + } + if (params.early_access) { + requiredHeaders.early_access = params.early_access.join(',') + } + params = { + ...defaultParameter, + ...clonedeep(params) + } - params.headers = { - ...params.headers, - ...requiredHeaders - } - const http = httpClient(params) - return contentstackClient({ - http: http - }) + params.headers = { + ...params.headers, + ...requiredHeaders + } + const http = httpClient(params) + return contentstackClient({ + http: http + }) } diff --git a/test/sanity-check/api/user-test.js b/test/sanity-check/api/user-test.js index f16c8f08..8010834d 100644 --- a/test/sanity-check/api/user-test.js +++ b/test/sanity-check/api/user-test.js @@ -11,134 +11,134 @@ var authtoken = '' var loggedinUserID = '' var client = contentstackClient() describe('Contentstack User Session api Test', () => { - it('should check user login with wrong credentials', done => { - contentstackClient().login({ email: process.env.EMAIL, password: process.env.PASSWORD }) - .then((response) => { - done() - }).catch((error) => { - const jsonMessage = JSON.parse(error.message) - const payload = JSON.parse(jsonMessage.request.data) - expect(jsonMessage.status).to.be.equal(422, 'Status code does not match') - expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') - expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') - expect(payload.user.email).to.be.equal(process.env.EMAIL, 'Email id does not match') - expect(payload.user.password).to.be.equal('contentstack', 'Password does not match') - done() - }) - }) - - it('should Login user', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() - }) - .catch(done) - }) + it('should check user login with wrong credentials', done => { + contentstackClient().login({ email: process.env.EMAIL, password: process.env.PASSWORD }) + .then((response) => { + done() + }).catch((error) => { + const jsonMessage = JSON.parse(error.message) + const payload = JSON.parse(jsonMessage.request.data) + expect(jsonMessage.status).to.be.equal(422, 'Status code does not match') + expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') + expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') + expect(payload.user.email).to.be.equal(process.env.EMAIL, 'Email id does not match') + expect(payload.user.password).to.be.equal('contentstack', 'Password does not match') + done() + }) + }) - it('should logout user', done => { - client.logout() - .then((response) => { - expect(axios.defaults.headers.common.authtoken).to.be.equal(undefined) - expect(response.notice).to.be.equal('You\'ve logged out successfully.') - done() - }) - .catch(done) + it('should Login user', done => { + client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { + jsonWrite(response.user, 'loggedinuser.json') + expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') + done() }) + .catch(done) + }) - it('should login with credentials', done => { - client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { - loggedinUserID = response.user.uid - jsonWrite(response.user, 'loggedinuser.json') - expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') - done() - }) - .catch(done) - }) + it('should logout user', done => { + client.logout() + .then((response) => { + expect(axios.defaults.headers.common.authtoken).to.be.equal(undefined) + expect(response.notice).to.be.equal('You\'ve logged out successfully.') + done() + }) + .catch(done) + }) - it('should get Current user info test', done => { - client.getUser().then((user) => { - authtoken = user.authtoken - expect(user.uid).to.be.equal(loggedinUserID) - done() - }) - .catch(done) + it('should login with credentials', done => { + client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { + loggedinUserID = response.user.uid + jsonWrite(response.user, 'loggedinuser.json') + expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') + done() }) + .catch(done) + }) - it('should get user info from authtoken', done => { - contentstackClient(authtoken) - .getUser() - .then((user) => { - expect(user.uid).to.be.equal(loggedinUserID) - expect(true).to.be.equal(true) - done() - }) - .catch(done) + it('should get Current user info test', done => { + client.getUser().then((user) => { + authtoken = user.authtoken + expect(user.uid).to.be.equal(loggedinUserID) + done() }) + .catch(done) + }) - it('should get host for NA region by default', done => { - const client = contentstack.client() - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly by default') + it('should get user info from authtoken', done => { + contentstackClient(authtoken) + .getUser() + .then((user) => { + expect(user.uid).to.be.equal(loggedinUserID) + expect(true).to.be.equal(true) done() - }) + }) + .catch(done) + }) - it('should get host for NA region', done => { - const client = contentstack.client({ region: 'NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly') - done() - }) + it('should get host for NA region by default', done => { + const client = contentstack.client() + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly by default') + done() + }) - it('should get host for NA region on priority', done => { - const client = contentstack.client({ region: 'NA', host: 'dev11-api.csnonprod.com' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly with priority') - done() - }) + it('should get host for NA region', done => { + const client = contentstack.client({ region: 'NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly') + done() + }) - it('should get custom host', done => { - const client = contentstack.client({ host: 'dev11-api.csnonprod.com' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('dev11-api.csnonprod.com', 'custom host set correctly') - done() - }) + it('should get host for NA region on priority', done => { + const client = contentstack.client({ region: 'NA', host: 'dev11-api.csnonprod.com' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('api.contentstack.io', 'region NA set correctly with priority') + done() + }) - it('should get host for EU region', done => { - const client = contentstack.client({ region: 'EU' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('eu-api.contentstack.com', 'region EU set correctly') - done() - }) + it('should get custom host', done => { + const client = contentstack.client({ host: 'dev11-api.csnonprod.com' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('dev11-api.csnonprod.com', 'custom host set correctly') + done() + }) - it('should get host for AU region', done => { - const client = contentstack.client({ region: 'AU' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('au-api.contentstack.com', 'region AU set correctly') - done() - }) + it('should get host for EU region', done => { + const client = contentstack.client({ region: 'EU' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('eu-api.contentstack.com', 'region EU set correctly') + done() + }) - it('should get host for AZURE_NA region', done => { - const client = contentstack.client({ region: 'AZURE_NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('azure-na-api.contentstack.com', 'region AZURE_NA set correctly') - done() - }) + it('should get host for AU region', done => { + const client = contentstack.client({ region: 'AU' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('au-api.contentstack.com', 'region AU set correctly') + done() + }) - it('should get host for GCP_NA region', done => { - const client = contentstack.client({ region: 'GCP_NA' }) - const baseUrl = client.axiosInstance.defaults.baseURL - expect(baseUrl).to.include('gcp-na-api.contentstack.com', 'region GCP_NA set correctly') - done() - }) + it('should get host for AZURE_NA region', done => { + const client = contentstack.client({ region: 'AZURE_NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('azure-na-api.contentstack.com', 'region AZURE_NA set correctly') + done() + }) - it('should throw error for invalid region', done => { - try { - contentstack.client({ region: 'DUMMYREGION' }) - done(new Error('Expected error was not thrown for invalid region')) - } catch (error) { - expect(error.message).to.include('Invalid region', 'Error message should indicate invalid region') - done() - } - }) + it('should get host for GCP_NA region', done => { + const client = contentstack.client({ region: 'GCP_NA' }) + const baseUrl = client.axiosInstance.defaults.baseURL + expect(baseUrl).to.include('gcp-na-api.contentstack.com', 'region GCP_NA set correctly') + done() + }) + + it('should throw error for invalid region', done => { + try { + contentstack.client({ region: 'DUMMYREGION' }) + done(new Error('Expected error was not thrown for invalid region')) + } catch (error) { + expect(error.message).to.include('Invalid region', 'Error message should indicate invalid region') + done() + } + }) }) diff --git a/test/unit/Util-test.js b/test/unit/Util-test.js index e380ee14..b7845fff 100644 --- a/test/unit/Util-test.js +++ b/test/unit/Util-test.js @@ -4,127 +4,127 @@ import { describe, it } from 'mocha' const headerRegEx = /(app|sdk|platform|integration|os) \S+(\/\d+.\d+.\d+(-[\w\d-]+)?)?;/igm describe('Get User Agent', () => { - it('Node user agent', done => { - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(userAgent.match(headerRegEx).length).to.be.equal(5) - expect(userAgent.indexOf('platform node.js/')).to.not.equal(-1) - done() + it('Node user agent', done => { + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(userAgent.match(headerRegEx).length).to.be.equal(5) + expect(userAgent.indexOf('platform node.js/')).to.not.equal(-1) + done() + }) + + it('Browser user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false }) - - it('Browser user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false - }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => false) - global.window = { - navigator: { - platform: 'MacIntel' - } - } - const macUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(macUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(macUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(macUserAgent.indexOf('os macOS;')).to.not.equal(-1) - - global.window.navigator.platform = 'Windows' - const windowsUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(windowsUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(windowsUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(windowsUserAgent.indexOf('os Windows;')).to.not.equal(-1) - - global.window.navigator = { userAgent: 'Android' } - const androidUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(androidUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(androidUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(androidUserAgent.indexOf('os Android;')).to.not.equal(-1) - - global.window.navigator = { platform: 'Linux' } - const linuxUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - expect(linuxUserAgent.match(headerRegEx).length).to.be.equal(5) - expect(linuxUserAgent.indexOf('platform browser')).to.not.equal(-1) - expect(linuxUserAgent.indexOf('os Linux;')).to.not.equal(-1) - done() - - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') + getUserAgentRewireApi.__Rewire__('isReactNative', () => false) + global.window = { + navigator: { + platform: 'MacIntel' + } + } + const macUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(macUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(macUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(macUserAgent.indexOf('os macOS;')).to.not.equal(-1) + + global.window.navigator.platform = 'Windows' + const windowsUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(windowsUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(windowsUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(windowsUserAgent.indexOf('os Windows;')).to.not.equal(-1) + + global.window.navigator = { userAgent: 'Android' } + const androidUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(androidUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(androidUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(androidUserAgent.indexOf('os Android;')).to.not.equal(-1) + + global.window.navigator = { platform: 'Linux' } + const linuxUserAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + expect(linuxUserAgent.match(headerRegEx).length).to.be.equal(5) + expect(linuxUserAgent.indexOf('platform browser')).to.not.equal(-1) + expect(linuxUserAgent.indexOf('os Linux;')).to.not.equal(-1) + done() + + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) + + it('Fail User agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => false) + global.window = {} - it('Fail User agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false - }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => false) - global.window = {} - - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - - expect(userAgent.match(headerRegEx).length).to.be.equal(3) - expect(userAgent.indexOf('platform browser')).to.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) + expect(userAgent.match(headerRegEx).length).to.be.equal(3) + expect(userAgent.indexOf('platform browser')).to.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() - it('ReactNative user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false - }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => true) - global.window = { - navigator: { - product: 'ReactNative' - } - } - - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') - - expect(userAgent.match(headerRegEx).length).to.be.equal(4) - expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() - - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') - }) + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) - it('ReactNative ios user agent', done => { - getUserAgentRewireApi.__Rewire__('isNode', () => { - return false - }) - getUserAgentRewireApi.__Rewire__('isReactNative', () => true) - global.window = { - navigator: { - product: 'ReactNative', - platform: 'iPhone' - } - } - - const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1', 'SampleFeature/0.1') - - expect(userAgent.match(headerRegEx).length).to.be.equal(5) - expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) - expect(userAgent.indexOf('os macOS;')).to.equal(-1) - done() - global.window = {} - getUserAgentRewireApi.__ResetDependency__('isNode') - getUserAgentRewireApi.__ResetDependency__('isReactNative') - getUserAgentRewireApi.__ResetDependency__('window') + it('ReactNative user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false }) - - it('Contentstack host test', done => { - expect(isHost('contentstack.io')).to.be.equal(true, 'contentstack.io should be host') - expect(isHost('contentstack.io:334')).to.be.equal(true, 'contentstack.io:334 should be host') - expect(isHost('http://contentstack.io')).to.be.equal(false, 'http://contentstack.io should not host') - expect(isHost('contentstack.io:2Sdrd')).to.be.equal(true, 'contentstack.io:2Sdrd should be host') - expect(isHost('contentstack.io:wedsfa2')).to.be.equal(true, 'contentstack.io:wedsfa2 should be host') - expect(isHost('eu-api.contentstack.com')).to.be.equal(true, 'eu-api.contentstack.com should be host') - expect(isHost('au-api.contentstack.com')).to.be.equal(true, 'au-api.contentstack.com should be host') - expect(isHost('contentstack.io/path')).to.be.equal(false, 'contentstack.io/path should not host') - done() + getUserAgentRewireApi.__Rewire__('isReactNative', () => true) + global.window = { + navigator: { + product: 'ReactNative' + } + } + + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1') + + expect(userAgent.match(headerRegEx).length).to.be.equal(4) + expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() + + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) + + it('ReactNative ios user agent', done => { + getUserAgentRewireApi.__Rewire__('isNode', () => { + return false }) + getUserAgentRewireApi.__Rewire__('isReactNative', () => true) + global.window = { + navigator: { + product: 'ReactNative', + platform: 'iPhone' + } + } + + const userAgent = getUserAgent('contentstack-sdk/1.0.0', 'SampleApplication/0.1', 'SampleIntegration/0,1', 'SampleFeature/0.1') + + expect(userAgent.match(headerRegEx).length).to.be.equal(5) + expect(userAgent.indexOf('platform ReactNative')).to.not.equal(-1) + expect(userAgent.indexOf('os macOS;')).to.equal(-1) + done() + global.window = {} + getUserAgentRewireApi.__ResetDependency__('isNode') + getUserAgentRewireApi.__ResetDependency__('isReactNative') + getUserAgentRewireApi.__ResetDependency__('window') + }) + + it('Contentstack host test', done => { + expect(isHost('contentstack.io')).to.be.equal(true, 'contentstack.io should be host') + expect(isHost('contentstack.io:334')).to.be.equal(true, 'contentstack.io:334 should be host') + expect(isHost('http://contentstack.io')).to.be.equal(false, 'http://contentstack.io should not host') + expect(isHost('contentstack.io:2Sdrd')).to.be.equal(true, 'contentstack.io:2Sdrd should be host') + expect(isHost('contentstack.io:wedsfa2')).to.be.equal(true, 'contentstack.io:wedsfa2 should be host') + expect(isHost('eu-api.contentstack.com')).to.be.equal(true, 'eu-api.contentstack.com should be host') + expect(isHost('au-api.contentstack.com')).to.be.equal(true, 'au-api.contentstack.com should be host') + expect(isHost('contentstack.io/path')).to.be.equal(false, 'contentstack.io/path should not host') + done() + }) }) From 2745dbea9b487fe00d6bbcffbe14b05b74ea19e0 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:11:05 +0530 Subject: [PATCH 3/5] Fixed branch header conflits issue --- .gitignore | 3 ++- CHANGELOG.md | 3 +++ lib/stack/index.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 52bba02c..b16a4a66 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,5 @@ tsconfig.json .next .dccache dist -jsdocs \ No newline at end of file +jsdocs +.early.coverage \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8abd625d..8605e14f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # Changelog +## [v1.21.8](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.8) (2025-07-07) + - Fix + - Fixed branch header conflits ## [v1.21.7](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.7) (2025-06-30) - Fix - Fixed Request-URI Too Large error diff --git a/lib/stack/index.js b/lib/stack/index.js index c954e81c..f4a4984c 100644 --- a/lib/stack/index.js +++ b/lib/stack/index.js @@ -168,8 +168,8 @@ export function Stack (http, data) { this.globalField = (uidOrOptions = null, option = {}) => { let globalFieldUid = null let apiVersion = '3.0' - let branch = 'main' const stackHeaders = { ...this.stackHeaders } + let branch = stackHeaders.branch || http.defaults.headers.branch || 'main' if (typeof uidOrOptions === 'object' && uidOrOptions !== null) { option = uidOrOptions } else { diff --git a/package-lock.json b/package-lock.json index a1c14318..67054cc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.21.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.21.8", "license": "MIT", "dependencies": { "assert": "^2.1.0", diff --git a/package.json b/package.json index 376be90e..e05e986a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.21.7", + "version": "1.21.8", "description": "The Content Management API is used to manage the content of your Contentstack account", "main": "./dist/node/contentstack-management.js", "browser": "./dist/web/contentstack-management.js", From 2ae487c08c83ca295bcbd0540945430d0d130ad8 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:27:45 +0530 Subject: [PATCH 4/5] Fixed term move issue --- lib/entity.js | 3 +-- test/sanity-check/api/terms-test.js | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/entity.js b/lib/entity.js index cf8ac93b..dc5742b7 100644 --- a/lib/entity.js +++ b/lib/entity.js @@ -313,7 +313,6 @@ export const move = (http, type, force = false, params = {}) => { try { let updateData = {} const json = cloneDeep(this) - delete json.parent_uid if (type) { updateData[type] = json } else { @@ -328,7 +327,7 @@ export const move = (http, type, force = false, params = {}) => { if (force === true) { headers.params.force = true } - const response = await http.put(`${this.urlPath}/move`, updateData, headers) + const response = await http.put(`${this.urlPath}/move`, param, headers) if (response.data) { return new this.constructor(http, parseData(response, this.stackHeaders, this.content_type_uid, this.taxonomy_uid, http)) } else { diff --git a/test/sanity-check/api/terms-test.js b/test/sanity-check/api/terms-test.js index 871f870e..771ed9a0 100644 --- a/test/sanity-check/api/terms-test.js +++ b/test/sanity-check/api/terms-test.js @@ -135,13 +135,14 @@ describe('Terms API Test', () => { }) it('should move the term to parent uid passed', done => { - makeTerms(taxonomy.uid, childTerm2.term.uid).fetch() + const term = { + parent_uid: 'term_test_child1', + order: 1 + } + makeTerms(taxonomy.uid, childTerm2.term.uid).move({ term, force: true }) .then(async (term) => { - term.parent_uid = null - const moveTerm = await term.move({ force: true }) - expect(moveTerm.parent_uid).to.be.equal(null) + expect(term.parent_uid).to.not.equal(null) done() - return moveTerm }) .catch(done) }) From 74125a616a872dae1810bf9f2320942d1f6dae4a Mon Sep 17 00:00:00 2001 From: "harshitha.d" Date: Thu, 3 Jul 2025 12:27:07 +0530 Subject: [PATCH 5/5] Update changelog for v1.22.0 --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8605e14f..5cfd4f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog -## [v1.21.8](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.8) (2025-07-07) +## [v1.22.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.22.0) (2025-07-07) + - Enhancement + - AWS-AU Region support added - Fix - Fixed branch header conflits ## [v1.21.7](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.7) (2025-06-30)