diff --git a/CHANGELOG.md b/CHANGELOG.md index a1f1fc4..32571e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,27 +1,30 @@ # Changelog -## [v1.4.1](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.4.1) (2024-12-24) +## [v1.4.2](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.4.2) (2026-01-12) + - Enhancement: Improved error messages + +## [v1.4.1](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.4.1) (2026-01-05) - Fix: Security issues -## [v1.4.0](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.4.0) (2024-08-25) +## [v1.4.0](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.4.0) (2025-08-25) - Enhancement: Retry logic to make use of x-ratelimit-remaining header -## [v1.3.0](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.3.0) (2024-08-11) +## [v1.3.0](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.3.0) (2025-08-11) - Enh: Add search function to query apps by names -## [v1.2.9](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.9) (2024-08-04) +## [v1.2.9](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.9) (2025-08-04) - Fix: Fixed the Linting issues - Updated all the dependency to the latest version - Added Pre-commit hook to run the snyk and talismand scans -## [v1.2.8](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.8) (2024-05-26) +## [v1.2.8](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.8) (2025-05-26) - Fix: Added params support to getInstalledApps method for enhanced flexibility -## [v1.2.7](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.7) (2024-05-15) +## [v1.2.7](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.7) (2025-05-15) - Fixed base URL path logic in contentstackClient to handle when region and host not provided -## [v1.2.6](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.6) (2024-03-03) +## [v1.2.6](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.6) (2025-03-03) - Update sanity tests ## [v1.2.5](https://github.com/contentstack/contentstack-marketplace-sdk/tree/v1.2.5) (2025-01-17) diff --git a/lib/assets/regions.json b/lib/assets/regions.json new file mode 100644 index 0000000..4729f56 --- /dev/null +++ b/lib/assets/regions.json @@ -0,0 +1,229 @@ +{ + "regions": [ + { + "id": "na", + "name": "AWS North America", + "cloudProvider": "AWS", + "location": "North America", + "alias": [ + "na", + "us", + "aws-na", + "aws_na", + "NA", + "US", + "AWS-NA", + "AWS_NA" + ], + "isDefault": true, + "endpoints": { + "application": "https://app.contentstack.com", + "contentDelivery": "https://cdn.contentstack.io", + "contentManagement": "https://api.contentstack.io", + "auth": "https://auth-api.contentstack.com", + "graphqlDelivery": "https://graphql.contentstack.com", + "preview": "https://rest-preview.contentstack.com", + "graphqlPreview": "https://graphql-preview.contentstack.com", + "images": "https://images.contentstack.io", + "assets": "https://assets.contentstack.io", + "automate": "https://automations-api.contentstack.com", + "launch": "https://launch-api.contentstack.com", + "developerHub": "https://developerhub-api.contentstack.com", + "brandKit": "https://brand-kits-api.contentstack.com", + "genAI": "https://ai.contentstack.com/brand-kits", + "personalizeManagement": "https://personalize-api.contentstack.com", + "personalizeEdge": "https://personalize-edge.contentstack.com" + } + }, + { + "id": "eu", + "name": "AWS Europe", + "cloudProvider": "AWS", + "location": "Europe", + "alias": [ + "eu", + "aws-eu", + "aws_eu", + "EU", + "AWS-EU", + "AWS_EU" + ], + "isDefault": false, + "endpoints": { + "application": "https://eu-app.contentstack.com", + "contentDelivery": "https://eu-cdn.contentstack.com", + "contentManagement": "https://eu-api.contentstack.com", + "auth": "https://eu-auth-api.contentstack.com", + "graphqlDelivery": "https://eu-graphql.contentstack.com", + "preview": "https://eu-rest-preview.contentstack.com", + "graphqlPreview": "https://eu-graphql-preview.contentstack.com", + "images": "https://eu-images.contentstack.com", + "assets": "https://eu-assets.contentstack.com", + "automate": "https://eu-prod-automations-api.contentstack.com", + "launch": "https://eu-launch-api.contentstack.com", + "developerHub": "https://eu-developerhub-api.contentstack.com", + "brandKit": "https://eu-brand-kits-api.contentstack.com", + "genAI": "https://eu-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://eu-personalize-api.contentstack.com", + "personalizeEdge": "https://eu-personalize-edge.contentstack.com" + } + }, + { + "id": "au", + "name": "AWS Australia", + "cloudProvider": "AWS", + "location": "Australia", + "alias": [ + "au", + "aws-au", + "aws_au", + "AU", + "AWS-AU", + "AWS_AU" + ], + "isDefault": false, + "endpoints": { + "application": "https://au-app.contentstack.com", + "contentDelivery": "https://au-cdn.contentstack.com", + "contentManagement": "https://au-api.contentstack.com", + "auth": "https://au-auth-api.contentstack.com", + "graphqlDelivery": "https://au-graphql.contentstack.com", + "preview": "https://au-rest-preview.contentstack.com", + "graphqlPreview": "https://au-graphql-preview.contentstack.com", + "images": "https://au-images.contentstack.com", + "assets": "https://au-assets.contentstack.com", + "automate": "https://au-prod-automations-api.contentstack.com", + "launch": "https://au-launch-api.contentstack.com", + "developerHub": "https://au-developerhub-api.contentstack.com", + "brandKit": "https://au-brand-kits-api.contentstack.com", + "genAI": "https://au-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://au-personalize-api.contentstack.com", + "personalizeEdge": "https://au-personalize-edge.contentstack.com" + } + }, + { + "id": "azure-na", + "name": "Azure North America", + "cloudProvider": "Azure", + "location": "North America", + "alias": [ + "azure-na", + "azure_na", + "AZURE-NA", + "AZURE_NA" + ], + "isDefault": false, + "endpoints": { + "application": "https://azure-na-app.contentstack.com", + "contentDelivery": "https://azure-na-cdn.contentstack.com", + "contentManagement": "https://azure-na-api.contentstack.com", + "auth": "https://azure-na-auth-api.contentstack.com", + "graphqlDelivery": "https://azure-na-graphql.contentstack.com", + "preview": "https://azure-na-rest-preview.contentstack.com", + "graphqlPreview": "https://azure-na-graphql-preview.contentstack.com", + "images": "https://azure-na-images.contentstack.com", + "assets": "https://azure-na-assets.contentstack.com", + "automate": "https://azure-na-automations-api.contentstack.com", + "launch": "https://azure-na-launch-api.contentstack.com", + "developerHub": "https://azure-na-developerhub-api.contentstack.com", + "brandKit": "https://azure-na-brand-kits-api.contentstack.com", + "genAI": "https://azure-na-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://azure-na-personalize-api.contentstack.com", + "personalizeEdge": "https://azure-na-personalize-edge.contentstack.com" + } + }, + { + "id": "azure-eu", + "name": "Azure Europe", + "cloudProvider": "Azure", + "location": "Europe", + "alias": [ + "azure-eu", + "azure_eu", + "AZURE-EU", + "AZURE_EU" + ], + "isDefault": false, + "endpoints": { + "application": "https://azure-eu-app.contentstack.com", + "contentDelivery": "https://azure-eu-cdn.contentstack.com", + "contentManagement": "https://azure-eu-api.contentstack.com", + "auth": "https://azure-eu-auth-api.contentstack.com", + "graphqlDelivery": "https://azure-eu-graphql.contentstack.com", + "preview": "https://azure-eu-rest-preview.contentstack.com", + "graphqlPreview": "https://azure-eu-graphql-preview.contentstack.com", + "images": "https://azure-eu-images.contentstack.com", + "assets": "https://azure-eu-assets.contentstack.com", + "automate": "https://azure-eu-automations-api.contentstack.com", + "launch": "https://azure-eu-launch-api.contentstack.com", + "developerHub": "https://azure-eu-developerhub-api.contentstack.com", + "brandKit": "https://azure-eu-brand-kits-api.contentstack.com", + "genAI": "https://azure-eu-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://azure-eu-personalize-api.contentstack.com", + "personalizeEdge": "https://azure-eu-personalize-edge.contentstack.com" + } + }, + { + "id": "gcp-na", + "name": "GCP North America", + "cloudProvider": "GCP", + "location": "North America", + "alias": [ + "gcp-na", + "gcp_na", + "GCP-NA", + "GCP_NA" + ], + "isDefault": false, + "endpoints": { + "application": "https://gcp-na-app.contentstack.com", + "contentDelivery": "https://gcp-na-cdn.contentstack.com", + "contentManagement": "https://gcp-na-api.contentstack.com", + "auth": "https://gcp-na-auth-api.contentstack.com", + "graphqlDelivery": "https://gcp-na-graphql.contentstack.com", + "preview": "https://gcp-na-rest-preview.contentstack.com", + "graphqlPreview": "https://gcp-na-graphql-preview.contentstack.com", + "images": "https://gcp-na-images.contentstack.com", + "assets": "https://gcp-na-assets.contentstack.com", + "automate": "https://gcp-na-automations-api.contentstack.com", + "launch": "https://gcp-na-launch-api.contentstack.com", + "developerHub": "https://gcp-na-developerhub-api.contentstack.com", + "brandKit": "https://gcp-na-brand-kits-api.contentstack.com", + "genAI": "https://gcp-na-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://gcp-na-personalize-api.contentstack.com", + "personalizeEdge": "https://gcp-na-personalize-edge.contentstack.com" + } + }, + { + "id": "gcp-eu", + "name": "GCP Europe", + "cloudProvider": "GCP", + "location": "Europe", + "alias": [ + "gcp-eu", + "gcp_eu", + "GCP-EU", + "GCP_EU" + ], + "isDefault": false, + "endpoints": { + "application": "https://gcp-eu-app.contentstack.com", + "contentDelivery": "https://gcp-eu-cdn.contentstack.com", + "contentManagement": "https://gcp-eu-api.contentstack.com", + "auth": "https://gcp-eu-auth-api.contentstack.com", + "graphqlDelivery": "https://gcp-eu-graphql.contentstack.com", + "preview": "https://gcp-eu-rest-preview.contentstack.com", + "graphqlPreview": "https://gcp-eu-graphql-preview.contentstack.com", + "images": "https://gcp-eu-images.contentstack.com", + "assets": "https://gcp-eu-assets.contentstack.com", + "automate": "https://gcp-eu-automations-api.contentstack.com", + "launch": "https://gcp-eu-launch-api.contentstack.com", + "developerHub": "https://gcp-eu-developerhub-api.contentstack.com", + "brandKit": "https://gcp-eu-brand-kits-api.contentstack.com", + "genAI": "https://gcp-eu-ai.contentstack.com/brand-kits", + "personalizeManagement": "https://gcp-eu-personalize-api.contentstack.com", + "personalizeEdge": "https://gcp-eu-personalize-edge.contentstack.com" + } + } + ] +} diff --git a/lib/contentstack.js b/lib/contentstack.js index b33a11e..e1800a0 100644 --- a/lib/contentstack.js +++ b/lib/contentstack.js @@ -4,7 +4,7 @@ */ import packages from '../package.json' import clonedeep from 'lodash/cloneDeep' -import getUserAgent from './core/Util.js' +import getUserAgent, { getRegionEndpoint } from './core/Util.js' import contentstackClient from './contentstackClient.js' import httpClient from './core/contentstackHTTPClient.js' import Region from './core/region.js' @@ -111,14 +111,8 @@ import Region from './core/region.js' * @prop {function=} params.logHandler - A log handler function to process given log messages & errors. * @example //Set the `logHandler` * import * as contentstack from '@contentstack/management' - * const client = contentstack.client({ logHandler: (level, data) => { - if (level === 'error' && data) { - const title = [data.name, data.message].filter((a) => a).join(' - ') - console.error(`[error] ${title}`) - return - } - console.log(`[${level}] ${data}`) - } }) + * import { logHandler } from '@contentstack/management/core/messageHandler' + * const client = contentstack.client({ logHandler: logHandler }) * * @prop {function=} params.refreshToken - Optional function used to refresh token. * @example // OAuth example @@ -157,8 +151,9 @@ import Region from './core/region.js' * @returns Contentstack.Client */ function client (params = {}) { + const devHubHost = params.region ? getRegionEndpoint(params.region.toLowerCase(), 'developerHub') : getRegionEndpoint("na", 'developerHub') const defaultParameter = { - defaultHostName: 'developerhub-api.contentstack.com' + defaultHostName: devHubHost } const sdkAgent = `contentstack-marketplace-sdk/${packages.version}` diff --git a/lib/contentstackClient.js b/lib/contentstackClient.js index 7947011..ffab11e 100644 --- a/lib/contentstackClient.js +++ b/lib/contentstackClient.js @@ -5,6 +5,7 @@ import error from './core/contentstackError' import { Marketplace } from './marketplace/index.js' import { Region } from './contentstack.js' +import { MESSAGES } from './core/messageHandler.js' export default function contentstackClient ({ http }) { /** @@ -20,8 +21,8 @@ export default function contentstackClient ({ http }) { * import * as contentstack from '@contentstack/management' * const client = contentstack.client() * - * client.login({ email: , password: }) - * .then(() => console.log('Logged in successfully')) + * client.login({ email: , password: }) + * .then(() => console.log(MESSAGES.LOGIN_SUCCESS)) * * client.marketplace() */ @@ -59,8 +60,8 @@ export default function contentstackClient ({ http }) { * import * as contentstack from '@contentstack/management' * const client = contentstack.client() * - * client.organization().findAll() - * .then((organization) => console.log(organization)) + * client.organization().findAll() + * .then((organization) => console.log(MESSAGES.ORGANIZATION_LOADED)) * * @example * import * as contentstack from '@contentstack/management' @@ -84,14 +85,14 @@ export default function contentstackClient ({ http }) { * @example * import * as contentstack from '@contentstack/management' * const client = contentstack.client() - * client.logout() - * .then((response) => console.log(response)) + * client.logout() + * .then((response) => console.log(MESSAGES.API_RESPONSE_SUCCESS)) * * @example * import * as contentstack from '@contentstack/management' * const client = contentstack.client() - * client.logout('AUTHTOKEN') - * .then((response) => console.log(response)) + * client.logout('AUTHTOKEN') + * .then((response) => console.log(MESSAGES.API_RESPONSE_SUCCESS)) * */ function logout (authtoken) { http.defaults.versioningStrategy = 'path' diff --git a/lib/core/Util.js b/lib/core/Util.js index 0aa3c27..69afa00 100644 --- a/lib/core/Util.js +++ b/lib/core/Util.js @@ -1,4 +1,7 @@ import { platform, release } from 'os' +import regionHostMap from '../assets/regions.json' + + const HOST_REGEX = /^(?!\w+:\/\/)([\w-:]+\.)+([\w-:]+)(?::(\d+))?(?!:)$/ export function isHost (host) { @@ -100,3 +103,14 @@ export default function getUserAgent (sdk, application, integration, feature) { return `${headerParts.filter((item) => item !== '').join('; ')};` } + +export const getRegionEndpoint = (region, service = 'developerHub') => { + const regionData = regionHostMap.regions.find(r => + r.id === region || + r.alias.some(alias => alias === region) + ) + if (!regionData) { + throw new Error(`Invalid region '${region}' provided. Allowed regions are: ${regionHostMap.regions.map(r => r.id).join(', ')}`) + } + return regionData.endpoints[service]?.replace(/^https?:\/\//, '') +} diff --git a/lib/core/contentstackHTTPClient.js b/lib/core/contentstackHTTPClient.js index 28e50f1..f9f9a19 100644 --- a/lib/core/contentstackHTTPClient.js +++ b/lib/core/contentstackHTTPClient.js @@ -3,20 +3,13 @@ import clonedeep from 'lodash/cloneDeep' import Qs from 'qs' import { ConcurrencyQueue } from './concurrency-queue' import { isHost } from './Util' -import Region from './region' +import { httpLogHandler } from './messageHandler.js' export default function contentstackHttpClient (options) { const defaultConfig = { insecure: false, retryOnError: true, - logHandler: (level, data) => { - if (level === 'error' && data) { - const title = [data.name, data.message].filter((a) => a).join(' - ') - console.error(`[error] ${title}`) - return - } - console.log(`[${level}] ${data}`) - }, + logHandler: httpLogHandler, retryCondition: (error) => { if (error.response && error.response.status === 429) { return true @@ -61,11 +54,9 @@ export default function contentstackHttpClient (options) { if (config.basePath) { config.basePath = `/${config.basePath.split('/').filter(Boolean).join('/')}` } - if (config.region && config.region !== Region.NA) { - baseUrlPath = `${protocol}://${config.region}-${hostname}:${port}${config.basePath}` - } else { - baseUrlPath = `${protocol}://${hostname}:${port}${config.basePath}` - } + + baseUrlPath = `${protocol}://${hostname}:${port}${config.basePath}` + const baseURL = config.endpoint || baseUrlPath const axiosOptions = { // Axios diff --git a/lib/core/messageHandler.js b/lib/core/messageHandler.js new file mode 100644 index 0000000..92940ba --- /dev/null +++ b/lib/core/messageHandler.js @@ -0,0 +1,136 @@ +/** + * Centralized message handler for all console logs and error messages + * @namespace MessageHandler + */ + +/** + * Success messages catalog + */ +export const MESSAGES = { + // Authentication + LOGIN_SUCCESS: 'Login successful.', + + // Organization - Includes org UID, name, metadata + ORGANIZATION_LOADED: 'Organization details loaded successfully.', + + // API Responses + API_RESPONSE_SUCCESS: 'API response received successfully.', + API_RESPONSE_APP_OPERATION: 'API response received for app operation.', + + // Marketplace + MARKETPLACE_API_RESPONSE: 'Marketplace API response received.', + MARKETPLACE_ROLES_LOADED: 'Marketplace roles loaded successfully.', + + // Apps - Includes UID, name, description, config + APP_LOADED: 'App details loaded successfully.', + APP_COLLECTION_LOADED: 'App collection loaded successfully.', + APP_REQUEST_RESPONSE: 'App request response received successfully.', + + // Installations - Includes installation UID, app UID, status, config + INSTALLATION_LOADED: 'App installation details loaded successfully.', + INSTALLATIONS_LOADED: 'App installation details loaded successfully.', + INSTALLATION_RESPONSE: 'Installation response received.', + INSTALLATION_COLLECTION_LOADED: 'Installation collection loaded successfully.', + INSTALLATION_WEBHOOK_LOADED: 'Installation webhook details loaded successfully.', + + // Authorization - Includes redirect URIs, auth codes (no tokens for security) + AUTHORIZATION_RESPONSE: 'Authorization response received.', + + // OAuth - WARNING: May contain sensitive values (client_secret) + OAUTH_CONFIG_LOADED: 'OAuth configuration loaded successfully.', + OAUTH_SCOPES_LOADED: 'OAuth scopes loaded successfully.', + + // Slack + SLACK_MESSAGE_SENT: 'Slack message sent successfully.' +} + +/** + * Error messages catalog + * All errors include: status, statusText, errorMessage, errorCode, errors object, request details + */ +export const ERROR_MESSAGES = { + // General Request Errors + REQUEST_FAILED: (title) => `Request failed: ${title}. Review the error details and try again.`, + HTTP_REQUEST_FAILED: (title) => `HTTP request failed: ${title}. Verify your request and try again.`, + + // App Request Errors - Operations: create, update, fetch, delete, install + APP_REQUEST_PROCESS_FAILED: 'App request process failed. Check the response details and try again.', + APP_REQUEST_ERROR: 'App request failed. Check the error details and try again.', + APP_REQUEST_REVIEW: 'App request failed. Review the error details and try again.', + APP_REQUEST_FAILED: 'Failed to process app request. Check the response details and try again.', + APP_OPERATION_ERROR: 'App operation error. Review the error details and try again.', + APP_REQUEST_RESPONSE_RECEIVED: 'App request response received.', + + // Authorization Errors - Common causes: invalid client_id, unauthorized redirect_uri, expired codes + AUTHORIZATION_FAILED: 'Failed to process authorization request. Check the response details and try again.', + AUTHORIZATION_ERROR: 'Authorization failed. Check the error details and try again.', + AUTHORIZATION_REVIEW: 'Authorization failed. Review the error details and try again.', + AUTHORIZATION_RESPONSE_RECEIVED: 'Authorization response received.', + + // Deployment Errors - Common causes: build failures, config issues, timeouts + DEPLOYMENT_FAILED: 'Deployment failed. Check the response details for errors and try again.', + DEPLOYMENT_ERROR: 'Deployment error occurred. Review the error details and try again.', + + // Hosting Errors - Common causes: invalid config, timeouts, deployment failures + HOSTING_REQUEST_FAILED: 'Hosting request failed. Check the response details and try again.', + HOSTING_ERROR: 'Hosting error occurred. Review the error details and try again.', + HOSTING_REQUEST_ERROR: 'Hosting request error. Review the error details and try again.', + + // OAuth Errors - Common causes: invalid credentials, expired tokens, scope errors + OAUTH_REQUEST_FAILED: 'OAuth request failed. Check the response details and try again.', + OAUTH_ERROR: 'OAuth error occurred. Review the error details and try again.', + + // Installation Errors - Operations: fetch, update, uninstall, config + INSTALLATION_REQUEST_FAILED: 'Installation request failed. Check the response details and try again.', + INSTALLATION_ERROR: 'Installation error occurred. Review the error details and try again.', + INSTALLATION_WEBHOOK_FAILED: 'Installation webhook request failed. Check the response details and try again.', + INSTALLATION_WEBHOOK_ERROR: 'Installation webhook error occurred. Review the error details and try again.', + + // Entity Errors - Operations: create, read, update, delete + ENTITY_REQUEST_FAILED: 'Entity request failed. Check the response details and try again.', + ENTITY_ERROR: 'Entity error occurred. Review the error details and try again.', + + // Marketplace Errors + MARKETPLACE_REQUEST_FAILED: 'Marketplace request failed. Review the error details and try again.', + + // Generic Errors + GENERIC_ERROR: 'An error occurred. Check the details and try again.' +} + +/** + * Log level constants + */ +export const LOG_LEVELS = { + ERROR: 'error', + INFO: 'info', + WARN: 'warn' +} + +/** + * Log handler for general operations + * @param {string} level - Log level (error, info, warn) + * @param {*} data - Data to log + */ +export const logHandler = (level, data) => { + if (level === LOG_LEVELS.ERROR && data) { + const title = [data.name, data.message].filter((a) => a).join(' - ') + console.error(`${ERROR_MESSAGES.REQUEST_FAILED(title)}`) + return + } + console.log(`${level}: ${data}. Check the details for troubleshooting.`) +} + +/** + * Log handler for HTTP client operations + * @param {string} level - Log level (error, info, warn) + * @param {*} data - Data to log + */ +export const httpLogHandler = (level, data) => { + if (level === LOG_LEVELS.ERROR && data) { + const title = [data.name, data.message].filter((a) => a).join(' - ') + console.error(`${ERROR_MESSAGES.HTTP_REQUEST_FAILED(title)}`) + return + } + console.log(`${level}: ${data}. Check the HTTP client logs for more information.`) +} + diff --git a/lib/entity.js b/lib/entity.js index 5714116..2bc163a 100644 --- a/lib/entity.js +++ b/lib/entity.js @@ -1,6 +1,7 @@ import error from './core/contentstackError' import cloneDeep from 'lodash/cloneDeep' import ContentstackCollection from './contentstackCollection' +import { ERROR_MESSAGES } from './core/messageHandler.js' export const create = ({ http, params }) => { return async function (data, param) { diff --git a/lib/marketplace/app/hosting/deployment.js b/lib/marketplace/app/hosting/deployment.js index 005ca97..debfb1c 100644 --- a/lib/marketplace/app/hosting/deployment.js +++ b/lib/marketplace/app/hosting/deployment.js @@ -1,6 +1,7 @@ import cloneDeep from 'lodash/cloneDeep' import ContentstackCollection from '../../../contentstackCollection' import error from '../../../core/contentstackError' +import { ERROR_MESSAGES } from '../../../core/messageHandler.js' /** * diff --git a/lib/marketplace/app/hosting/index.js b/lib/marketplace/app/hosting/index.js index 2713c02..1530287 100644 --- a/lib/marketplace/app/hosting/index.js +++ b/lib/marketplace/app/hosting/index.js @@ -1,6 +1,7 @@ import cloneDeep from 'lodash/cloneDeep' import error from '../../../core/contentstackError' import { Deployment } from './deployment' +import { ERROR_MESSAGES } from '../../../core/messageHandler.js' /** * diff --git a/lib/marketplace/app/index.js b/lib/marketplace/app/index.js index ca0f483..fd68044 100644 --- a/lib/marketplace/app/index.js +++ b/lib/marketplace/app/index.js @@ -6,6 +6,7 @@ import { Hosting } from './hosting' import { Installation, InstallationCollection } from '../installation' import { Oauth } from './oauth' import ContentstackCollection from '../../contentstackCollection' +import { MESSAGES, ERROR_MESSAGES } from '../../core/messageHandler.js' /** * @@ -46,8 +47,8 @@ export function App (http, data) { * } * const app = client.marketplace('organization_uid').app('manifest_uid') * app = Object.assign(app, updateApp) - * app.update() - * .then((app) => console.log(app)) + * app.update() + * .then((app) => console.log('App details loaded successfully.')) * */ this.update = update(http, undefined, this.params) @@ -62,8 +63,8 @@ export function App (http, data) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').fetch() - * .then((app) => console.log(app)) + * client.marketplace('organization_uid').app('manifest_uid').fetch() + * .then((app) => console.log('App details loaded successfully.')) * */ this.fetch = fetch(http, 'data', this.params) @@ -78,8 +79,8 @@ export function App (http, data) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').delete() - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').app('manifest_uid').delete() + * .then((response) => console.log('App request response received.')) */ this.delete = deleteEntity(http, false, this.params) @@ -125,7 +126,7 @@ export function App (http, data) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * client.marketplace('organization_uid').app('manifest_uid').install({ targetUid: 'STACK_API_KEY', targetType: 'stack' }) - * .then((installation) => console.log(installation)) + * .then((installation) => console.log('App installation details loaded successfully.')) */ this.install = async ({ targetUid, targetType }) => { try { @@ -156,7 +157,7 @@ export function App (http, data) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * client.marketplace('organization_uid').app('manifest_uid').reinstall({ targetUid: 'STACK_API_KEY', targetType: 'stack' }) - * .then((reinstallation) => console.log(installation)) + * .then((reinstallation) => console.log('App installation details loaded successfully.')) */ this.reinstall = async ({ targetUid, targetType }) => { try { @@ -186,8 +187,8 @@ export function App (http, data) { * @example * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) - * client.marketplace('organization_uid').app('manifest_uid').install({ targetUid: 'STACK_API_KEY', targetType: 'stack' }) - * .then((installation) => console.log(installation)) + * client.marketplace('organization_uid').app('manifest_uid').upgrade({ targetUid: 'STACK_API_KEY', targetType: 'stack' }) + * .then((installation) => console.log('App installation details loaded successfully.')) */ this.upgrade = async ({ targetUid, targetType }) => { try { @@ -216,7 +217,7 @@ export function App (http, data) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').app('app_uid').getRequests() - * .then((response) => console.log(response)) + * .then((response) => console.log('API response received for app operation.')) * */ this.getRequests = async () => { @@ -252,7 +253,7 @@ export function App (http, data) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').app('app_uid').authorize({ responseType, clientId, redirectUri, scope, state }) - * .then((response) => console.log(response)) + * .then((response) => console.log('API response received for app operation.')) * */ this.authorize = async ({ responseType, clientId, redirectUri, scope, state }) => { @@ -305,7 +306,7 @@ export function App (http, data) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').app('app_uid').listInstallations() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('App collection loaded successfully.')) * */ this.listInstallations = async () => { @@ -350,7 +351,7 @@ export function App (http, data) { * } * * client.marketplace('organization_uid').app().create(app) - * .then((app) => console.log(app)) + * .then((app) => console.log('App details loaded successfully.')) * */ this.create = create({ http, params: this.params }) diff --git a/lib/marketplace/app/oauth/index.js b/lib/marketplace/app/oauth/index.js index d3fb690..f337aca 100644 --- a/lib/marketplace/app/oauth/index.js +++ b/lib/marketplace/app/oauth/index.js @@ -1,5 +1,6 @@ import error from '../../../core/contentstackError' import cloneDeep from 'lodash/cloneDeep' +import { MESSAGES } from '../../../core/messageHandler.js' /** * @@ -27,8 +28,8 @@ export function Oauth (http, data, params) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').oauth().fetch() - * .then((oAuthConfig) => console.log(oAuthConfig)) + * client.marketplace('organization_uid').app('manifest_uid').oauth().fetch() + * .then((oAuthConfig) => console.log(MESSAGES.OAUTH_CONFIG_LOADED)) */ this.fetch = async (param = {}) => { try { @@ -70,8 +71,8 @@ export function Oauth (http, data, params) { * scopes: ['scope1', 'scope2'] * } * } - * client.marketplace('organization_uid').app('manifest_uid').oauth().update({ config }) - * .then((oAuthConfig) => console.log(oAuthConfig)) + * client.marketplace('organization_uid').app('manifest_uid').oauth().update({ config }) + * .then((oAuthConfig) => console.log(MESSAGES.OAUTH_CONFIG_LOADED)) */ this.update = async ({ config, param = {} }) => { try { @@ -103,8 +104,8 @@ export function Oauth (http, data, params) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').oauth().getScopes() - * .then((scopes) => console.log(scopes)) + * client.marketplace('organization_uid').app('manifest_uid').oauth().getScopes() + * .then((scopes) => console.log(MESSAGES.OAUTH_SCOPES_LOADED)) */ this.getScopes = async () => { try { diff --git a/lib/marketplace/apprequest/index.js b/lib/marketplace/apprequest/index.js index b9167b5..01da4a9 100644 --- a/lib/marketplace/apprequest/index.js +++ b/lib/marketplace/apprequest/index.js @@ -1,5 +1,6 @@ import cloneDeep from 'lodash/cloneDeep' import error from '../../core/contentstackError' +import { MESSAGES, ERROR_MESSAGES } from '../../core/messageHandler.js' /** * @@ -26,8 +27,8 @@ export function AppRequest (http, data, param) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').appRequests().delete('request_uid`) - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').appRequests().delete('request_uid`) + * .then((response) => console.log(MESSAGES.APP_REQUEST_RESPONSE)) * */ this.delete = async (requestUid) => { @@ -58,8 +59,8 @@ export function AppRequest (http, data, param) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').appRequests().create({ appUid: 'app_uid', targetUid: 'target_uid' }) - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').appRequests().create({ appUid: 'app_uid', targetUid: 'target_uid' }) + * .then((response) => console.log(MESSAGES.APP_REQUEST_RESPONSE)) * */ this.create = async ({ appUid, targetUid }) => { @@ -89,8 +90,8 @@ export function AppRequest (http, data, param) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').appRequests().findAll() - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').appRequests().findAll() + * .then((response) => console.log(MESSAGES.AUTHORIZATION_RESPONSE)) * */ this.findAll = async (param = {}) => { diff --git a/lib/marketplace/authorization/index.js b/lib/marketplace/authorization/index.js index 7a0ab7f..8f69e13 100644 --- a/lib/marketplace/authorization/index.js +++ b/lib/marketplace/authorization/index.js @@ -1,5 +1,6 @@ import cloneDeep from 'lodash/cloneDeep' import error from '../../core/contentstackError' +import { MESSAGES } from '../../core/messageHandler.js' /** * @@ -26,8 +27,8 @@ export function Authorization (http, data, params) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').authorization().findAll() - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').app('manifest_uid').authorization().findAll() + * .then((response) => console.log(MESSAGES.AUTHORIZATION_RESPONSE)) */ this.findAll = async (param = {}) => { try { @@ -58,8 +59,8 @@ export function Authorization (http, data, params) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').authorization().revokeAll() - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').app('manifest_uid').authorization().revokeAll() + * .then((response) => console.log(MESSAGES.AUTHORIZATION_RESPONSE)) */ this.revokeAll = async () => { try { @@ -87,8 +88,8 @@ export function Authorization (http, data, params) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * - * client.marketplace('organization_uid').app('manifest_uid').authorization().revoke('authorization_uid') - * .then((response) => console.log(response)) + * client.marketplace('organization_uid').app('manifest_uid').authorization().revoke('authorization_uid') + * .then((response) => console.log(MESSAGES.AUTHORIZATION_RESPONSE)) */ this.revoke = async (authorizationUid) => { try { diff --git a/lib/marketplace/index.js b/lib/marketplace/index.js index b8c4528..b0a3aa7 100644 --- a/lib/marketplace/index.js +++ b/lib/marketplace/index.js @@ -4,6 +4,7 @@ import { Installation } from './installation' import error from '../core/contentstackError' import { fetchAll } from '../entity' import { AppRequest } from './apprequest' +import { MESSAGES, ERROR_MESSAGES } from '../core/messageHandler.js' /** * @@ -46,13 +47,13 @@ export function Marketplace (http, data) { * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * client.organization('organization_uid').app('manifest_uid').installation().findAll() - * .then((installations) => console.log(installations)) + * .then((installations) => console.log('App installation details loaded successfully.')) * * @example * import * as contentstack from '@contentstack/marketplace' * const client = contentstack.client({ authtoken: 'TOKEN'}) * client.marketplace('organization_uid').installation('installation_uid').fetch() - * .then((installation) => console.log(installation)) + * .then((installation) => console.log('App installation details loaded successfully.')) */ this.installation = (installationUid = null) => { return new Installation(http, installationUid ? { data: { installation_uid: installationUid } } : { data: {} }, this.params) @@ -84,7 +85,7 @@ export function Marketplace (http, data) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').findAllApps() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('App collection loaded successfully.')) * */ this.urlPath = '/manifests' @@ -140,7 +141,7 @@ export function Marketplace (http, data) { * const client = contentstack.client() * * client.marketplace('organization_uid').findAllAuthorizedApps({ skip: 10 }) - * .then((roles) => console.log(roles)) + * .then((roles) => console.log('Marketplace roles loaded successfully.')) * */ this.findAllAuthorizedApps = async (param = {}) => { diff --git a/lib/marketplace/installation/index.js b/lib/marketplace/installation/index.js index fffb4a2..c3d0dae 100644 --- a/lib/marketplace/installation/index.js +++ b/lib/marketplace/installation/index.js @@ -2,6 +2,7 @@ import cloneDeep from 'lodash/cloneDeep' import error from '../../core/contentstackError' import { deleteEntity, fetch, fetchAll, update } from '../../entity' import { WebHooks } from './webhooks' +import { MESSAGES, ERROR_MESSAGES } from '../../core/messageHandler.js' /** * @@ -32,7 +33,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').fetch() - * .then((installation) => console.log(installation)) + * .then((installation) => console.log('App installation details loaded successfully.')) * */ this.fetch = fetch(http, 'data', this.params) @@ -56,7 +57,7 @@ export function Installation (http, data, params = {}) { * const installation = client.marketplace('organization_uid').installation('installation_uid') * installation = Object.assign(installation, updateInstallation) * installation.update() - * .then((installation) => console.log(installation)) + * .then((installation) => console.log('App installation details loaded successfully.')) */ this.update = update(http, 'data', this.params) @@ -71,7 +72,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').uninstall() - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.uninstall = deleteEntity(http, false, this.params) @@ -87,7 +88,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').configuration() - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.configuration = async (param = {}) => { try { @@ -120,7 +121,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').setConfiguration({}) - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.setConfiguration = async (config) => { try { @@ -150,7 +151,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').getConfigLocation() - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.getConfigLocation = async () => { try { @@ -180,7 +181,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').serverConfig() - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.serverConfig = async (param = {}) => { try { @@ -213,7 +214,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').setServerConfig({}) - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.setServerConfig = async (config) => { try { @@ -242,7 +243,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').installationData() - * .then((response) => console.log(response)) + * .then((response) => console.log('Installation response received.')) */ this.installationData = async () => { try { @@ -288,7 +289,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation().fetchAll() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('Installation collection loaded successfully.')) * */ this.fetchAll = fetchAll(http, InstallationCollection, params) @@ -304,7 +305,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation().getInstalledApps() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('Installation collection loaded successfully.')) * */ this.getInstalledApps = async (param = {}) => { @@ -337,7 +338,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation().getInstalledUsers() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('Installation collection loaded successfully.')) * */ this.getInstalledUsers = async () => { @@ -367,7 +368,7 @@ export function Installation (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation().getInstalledStacks() - * .then((collection) => console.log(collection)) + * .then((collection) => console.log('Installation collection loaded successfully.')) * */ this.getInstalledStacks = async () => { diff --git a/lib/marketplace/installation/webhooks/index.js b/lib/marketplace/installation/webhooks/index.js index 48a0582..cac9e91 100644 --- a/lib/marketplace/installation/webhooks/index.js +++ b/lib/marketplace/installation/webhooks/index.js @@ -1,5 +1,6 @@ import cloneDeep from 'lodash/cloneDeep' import error from '../../../core/contentstackError' +import { MESSAGES, ERROR_MESSAGES } from '../../../core/messageHandler.js' /** * @@ -28,7 +29,7 @@ export function WebHooks (http, data, params = {}) { * const client = contentstack.client({ authtoken: 'TOKEN'}) * * client.marketplace('organization_uid').installation('installation_uid').webhooks('webhook_uid').listExecutionLogs() - * .then((installation) => console.log(installation)) + * .then((installation) => console.log('Installation webhook details loaded successfully.')) * */ this.listExecutionLogs = async () => { diff --git a/package-lock.json b/package-lock.json index 8ac510e..22e74d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { "name": "@contentstack/marketplace-sdk", - "version": "1.4.1", + "version": "1.4.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/marketplace-sdk", - "version": "1.4.1", + "version": "1.4.2", + "hasInstallScript": true, "license": "MIT", "dependencies": { "axios": "^1.13.2" @@ -116,7 +117,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -3237,6 +3237,7 @@ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -3248,6 +3249,7 @@ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -3300,6 +3302,7 @@ "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3333,7 +3336,8 @@ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", @@ -3411,7 +3415,6 @@ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -3467,14 +3470,16 @@ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/retry": { "version": "0.12.0", @@ -3489,6 +3494,7 @@ "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -3499,6 +3505,7 @@ "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/http-errors": "*", "@types/node": "*" @@ -3779,7 +3786,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3830,7 +3836,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4170,7 +4175,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -4804,7 +4808,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -6012,7 +6015,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6150,7 +6152,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -6208,7 +6209,6 @@ "integrity": "sha512-2abNmzAH/JpxI4gEOwd6K8wZIodK3BmHbTxz4s79OIYwwIt2gkpEXlAouJXu4H1c9ySTnRso0tsuthSOZbUMlA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "eslint-plugin-es": "^1.4.1", "eslint-utils": "^1.4.2", @@ -6230,7 +6230,6 @@ "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", "dev": true, "license": "ISC", - "peer": true, "engines": { "node": ">=6" } @@ -6255,7 +6254,6 @@ } ], "license": "MIT", - "peer": true, "peerDependencies": { "eslint": ">=5.0.0" } @@ -8509,7 +8507,6 @@ "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^28.1.3", "@jest/types": "^28.1.3", @@ -10396,7 +10393,6 @@ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -13264,7 +13260,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -13680,7 +13675,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -14080,7 +14074,6 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14312,7 +14305,6 @@ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -14455,7 +14447,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", diff --git a/package.json b/package.json index 321a1fd..de08f20 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/marketplace-sdk", - "version": "1.4.1", + "version": "1.4.2", "description": "The Contentstack Marketplace SDK is used to manage the content of your Contentstack marketplace apps", "main": "./dist/node/contentstack-marketplace.js", "browser": "./dist/web/contentstack-marketplace.js", @@ -40,7 +40,9 @@ "pretest": "rimraf coverage && npm run lint", "precommit": "npm run lint", "prepush": "npm run test:unit", - "husky-check": "npx husky && chmod +x .husky/pre-commit" + "husky-check": "npx husky && chmod +x .husky/pre-commit", + "postinstall": "curl -s --max-time 30 --fail https://artifacts.contentstack.com/regions.json -o lib/assets/regions.json || echo 'Warning: Failed to download regions.json, using existing file if available'", + "postupdate": "curl -s --max-time 30 --fail https://artifacts.contentstack.com/regions.json -o lib/assets/regions.json || echo 'Warning: Failed to download regions.json, using existing file if available'" }, "repository": { "type": "git", diff --git a/test/unit/ContentstackHTTPClient-test.js b/test/unit/ContentstackHTTPClient-test.js index c7e76e1..4008664 100644 --- a/test/unit/ContentstackHTTPClient-test.js +++ b/test/unit/ContentstackHTTPClient-test.js @@ -164,7 +164,7 @@ describe('Contentstack HTTP Client', () => { host: 'contentstack.com:443' }) expect(axiosInstance.defaults.region).to.be.equal('azure-eu') - expect(axiosInstance.defaults.baseURL).to.be.equal('https://azure-eu-contentstack.com:443') + expect(axiosInstance.defaults.baseURL).to.be.equal('https://contentstack.com:443') done() }) @@ -176,7 +176,7 @@ describe('Contentstack HTTP Client', () => { host: 'contentstack.com:443' }) expect(axiosInstance.defaults.region).to.be.equal('gcp-na') - expect(axiosInstance.defaults.baseURL).to.be.equal('https://gcp-na-contentstack.com:443') + expect(axiosInstance.defaults.baseURL).to.be.equal('https://contentstack.com:443') done() }) }) diff --git a/test/unit/Util-test.js b/test/unit/Util-test.js index d41bfe3..d928588 100644 --- a/test/unit/Util-test.js +++ b/test/unit/Util-test.js @@ -1,4 +1,4 @@ -import getUserAgent, { __RewireAPI__ as getUserAgentRewireApi, isHost } from '../../lib/core/Util.js' +import getUserAgent, { __RewireAPI__ as getUserAgentRewireApi, isHost, getRegionEndpoint } from '../../lib/core/Util.js' import { expect } from 'chai' import { describe, it } from 'mocha' const headerRegEx = /(app|sdk|platform|integration|os) \S+(\/\d+.\d+.\d+(-[\w\d-]+)?)?;/igm @@ -126,3 +126,92 @@ describe('Get User Agent', () => { done() }) }) + +describe('Get Region Endpoint', () => { + it('should return default NA region developerHub endpoint', done => { + const endpoint = getRegionEndpoint('na') + expect(endpoint).to.be.equal('developerhub-api.contentstack.com', 'NA region developerHub endpoint should match') + done() + }) + + it('should return NA region developerHub endpoint using alias', done => { + const endpoint = getRegionEndpoint('us') + expect(endpoint).to.be.equal('developerhub-api.contentstack.com', 'US alias should return NA developerHub endpoint') + done() + }) + + it('should return EU region developerHub endpoint', done => { + const endpoint = getRegionEndpoint('eu') + expect(endpoint).to.be.equal('eu-developerhub-api.contentstack.com', 'EU region developerHub endpoint should match') + done() + }) + + it('should return Azure NA region developerHub endpoint', done => { + const endpoint = getRegionEndpoint('azure-na') + expect(endpoint).to.be.equal('azure-na-developerhub-api.contentstack.com', 'Azure NA region developerHub endpoint should match') + done() + }) + + it('should return Azure NA region developerHub endpoint using alias', done => { + const endpoint = getRegionEndpoint('azure_na') + expect(endpoint).to.be.equal('azure-na-developerhub-api.contentstack.com', 'Azure NA alias should return developerHub endpoint') + done() + }) + + it('should return GCP NA region developerHub endpoint', done => { + const endpoint = getRegionEndpoint('gcp-na') + expect(endpoint).to.be.equal('gcp-na-developerhub-api.contentstack.com', 'GCP NA region developerHub endpoint should match') + done() + }) + + it('should return GCP EU region developerHub endpoint', done => { + const endpoint = getRegionEndpoint('gcp-eu') + expect(endpoint).to.be.equal('gcp-eu-developerhub-api.contentstack.com', 'GCP EU region developerHub endpoint should match') + done() + }) + + it('should return AU region contentManagement endpoint', done => { + const endpoint = getRegionEndpoint('au', 'contentManagement') + expect(endpoint).to.be.equal('au-api.contentstack.com', 'AU region contentManagement endpoint should match') + done() + }) + + it('should return NA region auth endpoint', done => { + const endpoint = getRegionEndpoint('na', 'auth') + expect(endpoint).to.be.equal('auth-api.contentstack.com', 'NA region auth endpoint should match') + done() + }) + + it('should return EU region contentDelivery endpoint', done => { + const endpoint = getRegionEndpoint('eu', 'contentDelivery') + expect(endpoint).to.be.equal('eu-cdn.contentstack.com', 'EU region contentDelivery endpoint should match') + done() + }) + + it('should throw error for invalid region', done => { + try { + getRegionEndpoint('invalid-region') + done(new Error('Should have thrown an error for invalid region')) + } catch (error) { + expect(error.message).to.include('Invalid region') + expect(error.message).to.include('invalid-region') + done() + } + }) + + it('should return Azure EU region application endpoint', done => { + const endpoint = getRegionEndpoint('azure-eu', 'application') + expect(endpoint).to.be.equal('azure-eu-app.contentstack.com', 'Azure EU region application endpoint should match') + done() + }) + + it('should return all regions developerHub endpoints', done => { + const regions = ['na', 'eu', 'au', 'azure-na', 'azure-eu', 'gcp-na', 'gcp-eu'] + regions.forEach(region => { + const endpoint = getRegionEndpoint(region, 'developerHub') + expect(endpoint).to.be.a('string') + expect(endpoint).to.include('contentstack.com') + }) + done() + }) +}) diff --git a/test/unit/contentstack-test.js b/test/unit/contentstack-test.js index 0e738fd..6c7072b 100644 --- a/test/unit/contentstack-test.js +++ b/test/unit/contentstack-test.js @@ -55,6 +55,66 @@ describe('Contentstack HTTP Client', () => { done() }) + it('Contentstack Http Client Default Host with NA region', done => { + createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) + const createHttpClientStub = sinon.stub() + createClientRewireApi.__Rewire__('httpClient', createHttpClientStub) + createClientRewireApi.__Rewire__('contentstackClient', sinon.stub().returns({})) + client({ region: 'na' }) + expect(createHttpClientStub.args[0][0].defaultHostName).to.be.equal('developerhub-api.contentstack.com', 'NA region host name not match') + createClientRewireApi.__ResetDependency__('httpClient') + createClientRewireApi.__ResetDependency__('contentstackClient') + done() + }) + + it('Contentstack Http Client Default Host with EU region', done => { + createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) + const createHttpClientStub = sinon.stub() + createClientRewireApi.__Rewire__('httpClient', createHttpClientStub) + createClientRewireApi.__Rewire__('contentstackClient', sinon.stub().returns({})) + client({ region: 'eu' }) + expect(createHttpClientStub.args[0][0].defaultHostName).to.be.equal('eu-developerhub-api.contentstack.com', 'EU region host name not match') + createClientRewireApi.__ResetDependency__('httpClient') + createClientRewireApi.__ResetDependency__('contentstackClient') + done() + }) + + it('Contentstack Http Client Default Host with Azure NA region', done => { + createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) + const createHttpClientStub = sinon.stub() + createClientRewireApi.__Rewire__('httpClient', createHttpClientStub) + createClientRewireApi.__Rewire__('contentstackClient', sinon.stub().returns({})) + client({ region: 'azure-na' }) + expect(createHttpClientStub.args[0][0].defaultHostName).to.be.equal('azure-na-developerhub-api.contentstack.com', 'Azure NA region host name not match') + createClientRewireApi.__ResetDependency__('httpClient') + createClientRewireApi.__ResetDependency__('contentstackClient') + done() + }) + + it('Contentstack Http Client Default Host with GCP EU region', done => { + createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) + const createHttpClientStub = sinon.stub() + createClientRewireApi.__Rewire__('httpClient', createHttpClientStub) + createClientRewireApi.__Rewire__('contentstackClient', sinon.stub().returns({})) + client({ region: 'gcp-eu' }) + expect(createHttpClientStub.args[0][0].defaultHostName).to.be.equal('gcp-eu-developerhub-api.contentstack.com', 'GCP EU region host name not match') + createClientRewireApi.__ResetDependency__('httpClient') + createClientRewireApi.__ResetDependency__('contentstackClient') + done() + }) + + it('Contentstack Http Client Default Host with uppercase region', done => { + createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) + const createHttpClientStub = sinon.stub() + createClientRewireApi.__Rewire__('httpClient', createHttpClientStub) + createClientRewireApi.__Rewire__('contentstackClient', sinon.stub().returns({})) + client({ region: 'EU' }) + expect(createHttpClientStub.args[0][0].defaultHostName).to.be.equal('eu-developerhub-api.contentstack.com', 'Uppercase EU region should be handled') + createClientRewireApi.__ResetDependency__('httpClient') + createClientRewireApi.__ResetDependency__('contentstackClient') + done() + }) + it('Contentstack Http Client Default Host Custom', done => { createClientRewireApi.__Rewire__('client', { create: sinon.stub() }) const createHttpClientStub = sinon.stub()