Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3bf7d64
Added taxonomy localization support
sunil-lakshman Oct 17, 2025
39a6013
fixed lint errors
sunil-lakshman Oct 17, 2025
498a94e
Merge branch 'development' into enh/dx-3637
sunil-lakshman Nov 5, 2025
9bf6bd3
Merge pull request #442 from contentstack/enh/dx-3637
sunil-lakshman Nov 6, 2025
94a0449
Fix: Fixed the JSDoc strings
cs-raj Nov 25, 2025
3360cce
Fixed the other modules jsdoc
cs-raj Nov 25, 2025
922f08b
Fixed JSDoc String
cs-raj Nov 25, 2025
06c111c
Fixed linting issue
cs-raj Nov 25, 2025
2d4c809
Fixed error throwing
cs-raj Nov 25, 2025
8b14dd3
Fixed Unit test
cs-raj Nov 25, 2025
77230e8
Fixed failing test
cs-raj Nov 25, 2025
40ec3d4
Reverted Region Changes
cs-raj Nov 26, 2025
dd4f539
Skipped Failing test as not re-producable in workflow
cs-raj Nov 26, 2025
7f8a1fb
Testing in workflow
cs-raj Nov 26, 2025
7f39776
Skipped test cases
cs-raj Dec 1, 2025
2d56877
Removed Console Logs
cs-raj Dec 1, 2025
90a0cdd
Removed console logs
cs-raj Dec 1, 2025
65ded8c
Merge pull request #453 from contentstack/fix/DR-47
cs-raj Dec 1, 2025
0622874
Update OAuth and User tests to store authtoken after successful login
harshithad0703 Dec 4, 2025
e56277e
Merge pull request #456 from contentstack/fix/sanity-test-user-login
AniketDev7 Dec 4, 2025
f143b44
Fix assertion in user info test to check for undefined uid
harshithad0703 Dec 4, 2025
8230047
Fix assertion in user info test to ensure uid is defined
harshithad0703 Dec 4, 2025
debf41e
Merge pull request #457 from contentstack/fix/sanity-test-user-login
AniketDev7 Dec 4, 2025
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
12 changes: 3 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
# Changelog

## [v1.25.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.25.2) (2025-10-28)
- Fix
- Fixed HTTP client region endpoint initialization to default to 'na' region when region parameter is not provided
- Test
- Added comprehensive test coverage for region endpoint functionality
- Added 48 test cases for getRegionEndpoint function covering all supported regions, aliases, and service endpoints
- Added 14 test cases for region configuration in client initialization
- Added 13 test cases for HTTP client region integration
- All 626 tests passing with no regressions
## [v1.26.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.26.0) (2025-10-20)
- Enhancement
- Added taxonomy localization support

## [v1.25.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.25.1) (2025-10-06)
- Fix
Expand Down
15 changes: 12 additions & 3 deletions lib/contentstack.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import httpClient from './core/contentstackHTTPClient.js'
* const client = contentstack.client()
*
* @param {object} params - Client initialization parameters
* @param {Object=} param.proxy -
* @param {Object=} params.proxy - Proxy configuration object for HTTP requests
* @param {string=} params.region - Region for API endpoint (NA, EU, AU, AZURE_NA, AZURE_EU, GCP_NA, GCP_EU)
* @param {string=} params.feature - Feature identifier for user agent
* @param {string=} params.refreshToken - Refresh token for OAuth authentication
* @prop {string=} params.endpoint - API endpoint that a service will talk to
* @example //Set the `endpoint` to 'https://api.contentstack.io:{port}/{version}'
* import * as contentstack from '@contentstack/management'
Expand All @@ -39,7 +42,7 @@ import httpClient from './core/contentstackHTTPClient.js'
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ authtoken: 'value' })
*
* @prop {string=} params.early_access - Optional early_access is a token used for early access of new features in CMA requests.
* @prop {Array<string>=} params.early_access - Optional array of early access tokens used for early access of new features in CMA requests.
* @example //Set the `early_access`
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ early_access: ['ea1', 'ea2'] })
Expand Down Expand Up @@ -158,7 +161,13 @@ import httpClient from './core/contentstackHTTPClient.js'
*
* @prop {string=} params.application - Application name and version e.g myApp/version
* @prop {string=} params.integration - Integration name and version e.g react/version
* @returns Contentstack.Client
* @prop {string=} params.region - API region. Valid values: 'na', 'eu', 'au', 'azure_na', 'azure_eu', 'gcp_na', 'gcp_eu' (default: 'na')
* @example //Set the `region` to 'eu'
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ region: 'eu' })
*
* @prop {string=} params.feature - Feature identifier for user agent header
* @returns {ContentstackClient} Instance of ContentstackClient
*/
export function client (params = {}) {
let defaultHostName = getRegionEndpoint('na')
Expand Down
33 changes: 18 additions & 15 deletions lib/contentstackClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default function contentstackClient ({ http }) {
* @prop {string} parameters.password - password for user to login
* @prop {string} parameters.tfa_token - tfa token for user to login (2FA token)
* @prop {string} parameters.mfaSecret - TOTP secret key for generating 2FA token
* @returns {Promise}
* @param {Object=} params - Optional request parameters
* @returns {Promise<Object>} Promise for login response
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
Expand Down Expand Up @@ -59,7 +60,8 @@ export default function contentstackClient ({ http }) {
* The information returned includes details of the stacks owned by and shared with the specified user account.
* @memberof ContentstackClient
* @func getUser
* @returns {Promise}
* @param {Object=} params - Optional request parameters
* @returns {Promise<Object>} Promise for User instance
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
Expand All @@ -78,10 +80,11 @@ export default function contentstackClient ({ http }) {
* @description Get Stack instance. A stack is a space that stores the content of a project.
* @memberof ContentstackClient
* @func stack
* @param {String} api_key - Stack API Key
* @param {String} management_token - Management token for Stack.
* @param {String} branch_name - Branch name or alias to access specific branch. Default is master.
* @returns {Stack} Instance of Stack
* @param {Object=} params - Stack initialization parameters
* @prop {String} params.api_key - Stack API Key
* @prop {String} params.management_token - Management token for Stack.
* @prop {String} params.branch_uid - Branch UID or alias to access specific branch. Default is master.
* @returns {Stack} Instance of Stack.
*
* @example
* import * as contentstack from '@contentstack/management'
Expand Down Expand Up @@ -121,7 +124,7 @@ export default function contentstackClient ({ http }) {
* @description Organization is the top-level entity in the hierarchy of Contentstack, consisting of stacks and stack resources, and users.
* @memberof ContentstackClient
* @func organization
* @param {String} uid - Organization UID.
* @param {String=} uid - Organization UID. If not provided, returns organization instance for querying all organizations.
* @returns {Organization} Instance of Organization.
*
* @example
Expand Down Expand Up @@ -152,7 +155,7 @@ export default function contentstackClient ({ http }) {
* @memberof ContentstackClient
* @param {String} authtoken - Authtoken to logout from.
* @func logout
* @returns {Object} Response object.
* @returns {Promise<Object>} Promise for response object.
*
* @example
* import * as contentstack from '@contentstack/management'
Expand Down Expand Up @@ -195,13 +198,13 @@ export default function contentstackClient ({ http }) {
* @memberof ContentstackClient
* @func oauth
* @param {Object} parameters - oauth parameters
* @prop {string} parameters.appId - appId of the application
* @prop {string} parameters.clientId - clientId of the application
* @prop {string} parameters.clientId - clientId of the application
* @prop {string} parameters.responseType - responseType
* @prop {string} parameters.scope - scope
* @prop {string} parameters.clientSecret - clientSecret of the application
* @returns {OAuthHandler} Instance of OAuthHandler
* @prop {string=} parameters.appId - appId of the application (default: '6400aa06db64de001a31c8a9')
* @prop {string=} parameters.clientId - clientId of the application (default: 'Ie0FEfTzlfAHL4xM')
* @prop {string=} parameters.redirectUri - redirect URI for OAuth callback (default: 'http://localhost:8184')
* @prop {string=} parameters.responseType - responseType (default: 'code')
* @prop {string=} parameters.scope - scope
* @prop {string=} parameters.clientSecret - clientSecret of the application
* @returns {OAuthHandler} Instance of OAuthHandler.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
Expand Down
7 changes: 7 additions & 0 deletions lib/contentstackCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
* @namespace ContentstackCollection
*/
export default class ContentstackCollection {
/**
* Creates a ContentstackCollection instance.
* @param {Object} response - HTTP response object.
* @param {Object} http - HTTP client instance.
* @param {Object=} stackHeaders - Stack headers to include in data.
* @param {Function=} wrapperCollection - Collection wrapper function to transform items.
*/
constructor (response, http, stackHeaders = null, wrapperCollection) {
const data = response.data || {}
if (stackHeaders) {
Expand Down
25 changes: 25 additions & 0 deletions lib/core/concurrency-queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,31 @@ const defaultConfig = {
delayMs: null // Delay in milliseconds before making each request
}

/**
* Creates a concurrency queue manager for Axios requests with retry logic and rate limiting.
* @param {Object} options - Configuration options.
* @param {Object} options.axios - Axios instance to manage.
* @param {Object=} options.config - Queue configuration options.
* @param {number=} options.config.maxRequests - Maximum concurrent requests, defaults to 5.
* @param {number=} options.config.retryLimit - Maximum retry attempts for errors, defaults to 5.
* @param {number=} options.config.retryDelay - Delay between retries in milliseconds, defaults to 300.
* @param {boolean=} options.config.retryOnError - Enable retry on error, defaults to true.
* @param {boolean=} options.config.retryOnNetworkFailure - Enable retry on network failures, defaults to true.
* @param {boolean=} options.config.retryOnDnsFailure - Enable retry on DNS failures, defaults to true.
* @param {boolean=} options.config.retryOnSocketFailure - Enable retry on socket failures, defaults to true.
* @param {boolean=} options.config.retryOnHttpServerError - Enable retry on HTTP 5xx errors, defaults to true.
* @param {number=} options.config.maxNetworkRetries - Maximum network retry attempts, defaults to 3.
* @param {number=} options.config.networkRetryDelay - Base delay for network retries in milliseconds, defaults to 100.
* @param {string=} options.config.networkBackoffStrategy - Backoff strategy ('exponential' or 'fixed'), defaults to 'exponential'.
* @param {number=} options.config.delayMs - Delay before each request in milliseconds.
* @param {Function=} options.config.retryCondition - Custom function to determine if error can be retried.
* @param {Function=} options.config.logHandler - Log handler function.
* @param {Function=} options.config.refreshToken - Token refresh function.
* @param {string=} options.config.authtoken - Auth token.
* @param {string=} options.config.authorization - Authorization token.
* @returns {Object} ConcurrencyQueue instance with request/response interceptors attached to Axios.
* @throws {Error} If axios instance is not provided or configuration is invalid.
*/
export function ConcurrencyQueue ({ axios, config }) {
if (!axios) {
throw Error('Axios instance is not present')
Expand Down
11 changes: 10 additions & 1 deletion lib/core/contentstackError.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

/**
* Formats and throws an error from an HTTP error response.
* @param {Object} errorResponse - Error response object from HTTP request.
* @param {Object} errorResponse.config - Request configuration object.
* @param {Object} errorResponse.response - HTTP response object.
* @param {number} errorResponse.response.status - HTTP status code.
* @param {string} errorResponse.response.statusText - HTTP status text.
* @param {Object} errorResponse.response.data - Response data containing error details.
* @throws {Error} Formatted error object with request and response details.
*/
export default function error (errorResponse) {
const config = errorResponse.config
const response = errorResponse.response
Expand Down
63 changes: 37 additions & 26 deletions lib/core/oauthHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import errorFormatter from './contentstackError'
/**
* @description OAuthHandler class to handle OAuth authorization and token management
* @class OAuthHandler
* @param {any} axiosInstance
* @param {any} appId
* @param {any} clientId
* @param {any} redirectUri
* @param {any} responseType='code'
* @param {any} clientSecret
* @param {any} scope=[]
* @returns {OAuthHandler} OAuthHandler instance
* @param {Object} axiosInstance - Axios HTTP client instance.
* @param {string=} appId - Application ID, defaults to '6400aa06db64de001a31c8a9'.
* @param {string=} clientId - Client ID, defaults to 'Ie0FEfTzlfAHL4xM'.
* @param {string=} redirectUri - Redirect URI for OAuth callback, defaults to 'http://localhost:8184'.
* @param {string=} clientSecret - Client secret. If provided, PKCE will be skipped.
* @param {string=} responseType - Response type, defaults to 'code'.
* @param {Array<string>=} scope - OAuth scope array, defaults to [].
* @returns {OAuthHandler} OAuthHandler instance.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand Down Expand Up @@ -80,7 +80,8 @@ export default class OAuthHandler {
* @description Authorize the user by redirecting to the OAuth provider's authorization page
* @memberof OAuthHandler
* @func authorize
* @returns {any} Authorization URL
* @async
* @returns {Promise<string>} Promise that resolves to authorization URL
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand Down Expand Up @@ -114,8 +115,9 @@ export default class OAuthHandler {
* @description Exchange the authorization code for an access token
* @memberof OAuthHandler
* @func exchangeCodeForToken
* @param {any} code - Authorization code received from the OAuth provider
* @returns {any} Token data
* @async
* @param {string} code - Authorization code received from the OAuth provider
* @returns {Promise<Object>} Promise that resolves to token data object
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand Down Expand Up @@ -155,9 +157,10 @@ export default class OAuthHandler {
* @description Refreshes the access token using the provided refresh token or the one stored in the axios instance.
* @memberof OAuthHandler
* @func refreshAccessToken
* @async
* @param {string|null} [providedRefreshToken=null] - The refresh token to use for refreshing the access token. If not provided, the stored refresh token will be used.
* @returns {Promise<Object>} - A promise that resolves to the response data containing the new access token, refresh token, and expiry time.
* @throws {Error} - Throws an error if no refresh token is available or if the token refresh request fails.
* @returns {Promise<Object>} A promise that resolves to the response data containing the new access token, refresh token, and expiry time.
* @throws {Error} Throws an error if no refresh token is available or if the token refresh request fails.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand Down Expand Up @@ -196,8 +199,9 @@ export default class OAuthHandler {
* @description Logs out the user by revoking the OAuth app authorization
* @memberof OAuthHandler
* @func logout
* @returns {Promise<string>} - A promise that resolves to a success message if the logout was successful.
* @throws {Error} - Throws an error if the logout request fails.
* @async
* @returns {Promise<string>} A promise that resolves to a success message if the logout was successful.
* @throws {Error} Throws an error if the logout request fails.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -219,7 +223,7 @@ export default class OAuthHandler {
* @description Get the current access token
* @memberof OAuthHandler
* @func getAccessToken
* @returns {any}
* @returns {string|undefined} Current access token or undefined if not set.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand Down Expand Up @@ -294,7 +298,8 @@ export default class OAuthHandler {
* @description Set the access token in the axios instance
* @memberof OAuthHandler
* @func setAccessToken
* @param {*} token
* @param {string} token - Access token to set.
* @throws {Error} Throws an error if token is not provided.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -312,7 +317,8 @@ export default class OAuthHandler {
* @description Set the refresh token in the axios instance
* @memberof OAuthHandler
* @func setRefreshToken
* @param {*} token
* @param {string} token - Refresh token to set.
* @throws {Error} Throws an error if token is not provided.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -330,7 +336,8 @@ export default class OAuthHandler {
* @description Set the organization UID in the axios instance
* @memberof OAuthHandler
* @func setOrganizationUID
* @param {*} organizationUID
* @param {string} organizationUID - Organization UID to set.
* @throws {Error} Throws an error if organizationUID is not provided.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -348,7 +355,8 @@ export default class OAuthHandler {
* @description Set the user UID in the axios instance
* @memberof OAuthHandler
* @func setUserUID
* @param {*} userUID
* @param {string} userUID - User UID to set.
* @throws {Error} Throws an error if userUID is not provided.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -366,7 +374,8 @@ export default class OAuthHandler {
* @description Set the token expiry time in the axios instance
* @memberof OAuthHandler
* @func setTokenExpiryTime
* @param {*} expiryTime
* @param {number} expiryTime - Token expiry time (timestamp in milliseconds).
* @throws {Error} Throws an error if expiryTime is not provided.
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -386,8 +395,8 @@ export default class OAuthHandler {
* @func handleRedirect
* @async
* @param {string} url - The URL to handle after the OAuth authorization
* @returns {Promise<void>} - A promise that resolves if the redirect URL is successfully handled
* @throws {Error} - Throws an error if the authorization code is not found in the redirect URL
* @returns {Promise<void>} A promise that resolves if the redirect URL is successfully handled
* @throws {Error} Throws an error if the authorization code is not found in the redirect URL
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client();
Expand All @@ -413,7 +422,8 @@ export default class OAuthHandler {
* @description Get the OAuth app authorization for the current user
* @memberof OAuthHandler
* @func getOauthAppAuthorization
* @returns {any}
* @async
* @returns {Promise<string>} Promise that resolves to authorization UID
*/
async getOauthAppAuthorization () {
const headers = {
Expand Down Expand Up @@ -448,8 +458,9 @@ export default class OAuthHandler {
* @description Revoke the OAuth app authorization for the current user
* @memberof OAuthHandler
* @func revokeOauthAppAuthorization
* @param {any} authorizationId
* @returns {any}
* @async
* @param {string} authorizationId - Authorization ID to revoke
* @returns {Promise<Object>} Promise that resolves to response data
*/
async revokeOauthAppAuthorization (authorizationId) {
if (authorizationId?.length > 1) {
Expand Down
Loading
Loading