/**
* The Content Management API (CMA) is used to manage the content of your Contentstack account. This includes creating, updating, deleting, and fetching content of your account.
* @namespace Contentstack
*/
import packages from '../package.json'
import clonedeep from 'lodash/cloneDeep'
import getUserAgent from './core/Util.js'
import contentstackClient from './contentstackClient.js'
import httpClient from './core/contentstackHTTPClient.js'
/**
* Create client instance
* @name client
* @memberof Contentstack
*
* @example
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client()
*
* @param {object} params - Client initialization parameters
* @param {Object=} param.proxy -
* @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'
* const client = contentstack.client({ endpoint: 'https://api.contentstack.io:{port}/{version}' })
*
* @prop {string=} params.host - API host (default: api.contentstack.io)
* @example //Set the `host` to 'api.contentstack.io'
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ host: 'api.contentstack.io' })
*
* @prop {object=} params.headers - Optional additional headers
* @example //Set the `headers` to { 'headerkey': 'value'}
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ headers: { 'headerkey': 'value'} })
*
* @prop {string=} params.authtoken - Optional Authtoken is a read-write token used to make authorized CMA requests, but it is a user-specific token.
* @example //Set the `authtoken`
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ authtoken: 'value' })
*
* @prop {string=} params.authorization - Optional authorization token is a read-write token used to make authorized CMA requests, but it is a user-specific token.
* @example //Set the `authorization`
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ authorization: 'Bearer <token_value>' })
*
* @prop {number=} params.timeout - Optional number of milliseconds before the request times out. Default is 30000ms
* @example //Set the `timeout` to 50000ms
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ timeout: 50000 })
*
* @prop {number=} params.maxRequests - Optional maximum number of requests SDK should send concurrently. Default is 5 concurrent request.
* @example //Set the `maxRequests` to 5
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ maxRequests: 5 })
*
* @prop {boolean=} params.retryOnError - Optional boolean for retry on failure. Default is true
* @example //Set the `retryOnError` to false
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ retryOnError: false })
*
* @prop {number=} params.retryLimit - Optional number of retries before failure. Default is 5
* @example //Set the `retryLimit` to 2
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ retryLimit: 2 })
*
* @prop {number=} params.retryDelay - The number of milliseconds to use for operation retries. Default is 300ms
* @example //Set the `retryDelay` to 500ms
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ retryDelay: 500 })
*
* @prop {Function=} params.retryCondition - A function to determine if the error can be retried. Default retry is on status 429.
* @example //Set the `retryCondition` on error status 429
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ retryCondition: (error) => {
* if (error.response && error.response.status === 429) {
* return true
* }
* return false
* }
* })
*
* @prop {number=} params.retryDelayOptions.base - The base number of milliseconds to use in the exponential backoff for operation retries.
* @example Set base retry delay for all services to 300 ms
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({retryDelayOptions: {base: 300}})
*
* @prop {Function=} params.retryDelayOptions.customBackoff - A custom function that accepts a retry count and error and returns the amount of time to delay in milliseconds. (if you want not to retry for specific condition return -1)
* @example Set a custom backoff function to provide delay of 500 ms on retryCount < 3 and -1 for retryCount >= 3values on retries
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({retryDelayOptions: {customBackoff: function(retryCount, err) {
* if (retryCount < 3) {
* return 500
* } else {
* return -1 //returning -1 will hold next retry for request
* }
* }}}
* )
*
* @prop {number=} params.maxContentLength - Optional maximum content length in bytes (default: 1073741824 i.e. 1 GB)
* @example //Set the `maxContentLength` to 1024 ** 3
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ maxContentLength: 1024 ** 3 })
*
* @prop {number=} params.maxBodyLength - Optional maximum body length in bytes (default: 10 MB)
* @example //Set the `maxBodyLength` to 1024 ** 2 * 10 // 10 MB
* import * as contentstack from '@contentstack/management'
* const client = contentstack.client({ maxBodyLength: 1024 ** 2 * 10 })
*
* @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}`)
} })
*
* @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
*/
export function client (params = {}) {
const defaultParameter = {
defaultHostName: 'api.contentstack.io'
}
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
}
params = {
...defaultParameter,
...clonedeep(params)
}
params.headers = {
...params.headers,
...requiredHeaders
}
const http = httpClient(params)
return contentstackClient({
http: http
})
}