diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..4f1fbbc3 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,69 @@ +#!/usr/bin/env sh +# Pre-commit hook to run Snyk and Talisman scans, completing both before deciding to commit + +# Function to check if a command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Check if Snyk is installed +if ! command_exists snyk; then + echo "Error: Snyk is not installed. Please install it and try again." + exit 1 +fi + +# Check if Talisman is installed +if ! command_exists talisman; then + echo "Error: Talisman is not installed. Please install it and try again." + 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 + +# Run Snyk vulnerability scan +echo "Running Snyk vulnerability scan..." +snyk test --all-projects > snyk_output.log 2>&1 +snyk_exit_code=$? + +if [ $snyk_exit_code -eq 0 ]; then + echo "Snyk scan passed: No vulnerabilities found." +elif [ $snyk_exit_code -eq 1 ]; then + echo "Snyk found vulnerabilities. See snyk_output.log for details." + snyk_failed=true +else + echo "Snyk scan failed with error (exit code $snyk_exit_code). See snyk_output.log for details." + snyk_failed=true +fi + +# Run Talisman secret scan (continues even if Snyk failed) +echo "Running Talisman secret scan..." +talisman --githook pre-commit > talisman_output.log 2>&1 +talisman_exit_code=$? + +if [ $talisman_exit_code -eq 0 ]; then + echo "Talisman scan passed: No secrets found." +else + echo "Talisman scan failed (exit code $talisman_exit_code). See talisman_output.log for details." + talisman_failed=true +fi + +# Evaluate results after both scans +if [ "$snyk_failed" = true ] || [ "$talisman_failed" = true ]; then + echo "Commit aborted due to issues found in one or both scans." + [ "$snyk_failed" = true ] && echo "- Snyk issues: Check snyk_output.log" + [ "$talisman_failed" = true ] && echo "- Talisman issues: Check talisman_output.log" + exit 1 +fi + +# If both scans pass, allow the commit +echo "All scans passed. Proceeding with commit.cd ." +rm -f snyk_output.log talisman_output.log +exit 0 \ No newline at end of file diff --git a/.talismanrc b/.talismanrc index 1c2ffd0b..41223457 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,8 +1,9 @@ -threshold: medium fileignoreconfig: - filename: .github/workflows/secrets-scan.yml ignore_detectors: - filecontent - filename: package-lock.json checksum: 9d0340f9359927d477fe8ab4650642c068c592be63fb817651d866849e0dbbc2 +- filename: .husky/pre-commit + checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193 version: "" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cc607393..adabd7d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [v1.21.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.21.0) (2025-05-05) + - Enhancement + - Region support added + ## [v1.20.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.20.3) (2025-04-21) - Fix - Handle the sanity tests when ENVs are not provided diff --git a/lib/contentstack.js b/lib/contentstack.js index cf716495..18ded7fd 100644 --- a/lib/contentstack.js +++ b/lib/contentstack.js @@ -7,6 +7,14 @@ import clonedeep from 'lodash/cloneDeep' 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' +} /** * Create client instance @@ -161,8 +169,22 @@ import httpClient from './core/contentstackHTTPClient.js' * @returns Contentstack.Client */ 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'] + } + const defaultParameter = { - defaultHostName: 'api.contentstack.io' + defaultHostName: defaultHostName } const sdkAgent = `contentstack-management-javascript/${packages.version}` diff --git a/lib/core/contentstackHTTPClient.js b/lib/core/contentstackHTTPClient.js index 67cf14ba..c1e12770 100644 --- a/lib/core/contentstackHTTPClient.js +++ b/lib/core/contentstackHTTPClient.js @@ -53,6 +53,9 @@ export default function contentstackHttpClient (options) { let port = config.port || 443 const version = config.version || 'v3' + if (config.region) { + config.host = config.defaultHostName // set region on priority + } if (isHost(config.host)) { const parsed = config.host.split(':') if (parsed.length === 2) { diff --git a/package-lock.json b/package-lock.json index 5b5b6f65..50fa7f36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,35 +1,36 @@ { "name": "@contentstack/management", - "version": "1.20.3", + "version": "1.21.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/management", - "version": "1.20.3", + "version": "1.21.0", "license": "MIT", "dependencies": { "assert": "^2.1.0", - "axios": "^1.8.4", + "axios": "^1.9.0", "buffer": "^6.0.3", "form-data": "^4.0.2", + "husky": "^9.1.7", "lodash": "^4.17.21", "qs": "^6.14.0", "stream-browserify": "^3.0.0" }, "devDependencies": { - "@babel/cli": "^7.26.4", - "@babel/core": "^7.26.9", - "@babel/eslint-parser": "^7.26.8", - "@babel/plugin-transform-runtime": "^7.26.9", + "@babel/cli": "^7.27.0", + "@babel/core": "^7.26.10", + "@babel/eslint-parser": "^7.27.0", + "@babel/plugin-transform-runtime": "^7.26.10", "@babel/preset-env": "^7.26.9", "@babel/register": "^7.25.9", - "@babel/runtime": "^7.26.9", + "@babel/runtime": "^7.27.0", "@slack/bolt": "^4.2.1", "@types/chai": "^4.3.20", "@types/jest": "^28.1.8", "@types/lodash": "^4.17.16", - "@types/mocha": "^7.0.2", + "@types/mocha": "^8.2.3", "axios-mock-adapter": "^1.22.0", "babel-loader": "^8.4.1", "babel-plugin-add-module-exports": "^1.0.4", @@ -39,7 +40,7 @@ "chai": "^4.5.0", "clean-webpack-plugin": "^4.0.0", "docdash": "^1.2.0", - "dotenv": "^16.4.7", + "dotenv": "^16.5.0", "eslint": "^8.57.1", "eslint-config-standard": "^13.0.1", "eslint-plugin-import": "^2.31.0", @@ -81,7 +82,9 @@ } }, "node_modules/@babel/cli": { - "version": "7.26.4", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.27.0.tgz", + "integrity": "sha512-bZfxn8DRxwiVzDO5CEeV+7IqXeCkzI4yYnrQbpwjT76CUyossQc6RYE7n+xfm0/2k40lPaCpW0FhxYs7EBAetw==", "dev": true, "license": "MIT", "dependencies": { @@ -130,20 +133,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.9", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", + "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -159,10 +164,11 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.8.tgz", - "integrity": "sha512-3tBctaHRW6xSub26z7n8uyOTwwUsCdvIug/oxBH9n6yCO5hMj2vwDJAo7RbBMKrM7P+W2j61zLKviJQFGOYKMg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.0.tgz", + "integrity": "sha512-dtnzmSjXfgL/HDgMcmsLSzyGbEosi4DrGWoCNfuI+W4IkVJw6izpTe7LtOdwAXnkDqw5yweboYCTkM2rQizCng==", "dev": true, + "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -181,17 +187,20 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/@babel/generator": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -418,23 +427,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1356,14 +1369,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.26.9", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz", + "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.26.5", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -1586,18 +1601,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "dev": true, @@ -1630,7 +1633,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -1641,28 +1646,32 @@ } }, "node_modules/@babel/template": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1671,7 +1680,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dev": true, "license": "MIT", "dependencies": { @@ -2629,6 +2640,7 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, + "license": "MIT", "dependencies": { "eslint-scope": "5.1.1" } @@ -2638,6 +2650,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -2651,6 +2664,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3072,7 +3086,9 @@ "license": "MIT" }, "node_modules/@types/mocha": { - "version": "7.0.2", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true, "license": "MIT" }, @@ -3653,6 +3669,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "is-nan": "^1.3.2", @@ -3695,9 +3712,9 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -3963,12 +3980,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.6", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2", - "core-js-compat": "^3.38.0" + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4169,7 +4188,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/big.js": { "version": "5.2.2", @@ -4307,6 +4327,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -5023,7 +5044,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.7", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -6472,8 +6495,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6554,6 +6575,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.5.2", "dev": true, @@ -6582,7 +6618,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.2", @@ -7005,6 +7042,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -10688,6 +10726,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -11579,6 +11618,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "license": "MIT", "dependencies": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" @@ -11588,6 +11628,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -12447,6 +12488,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -12458,7 +12500,8 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", diff --git a/package.json b/package.json index 8134643c..51587221 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/management", - "version": "1.20.3", + "version": "1.21.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", @@ -43,7 +43,8 @@ "pretest": "rimraf coverage && npm run lint", "precommit": "npm run lint", "prepush": "npm run test:unit", - "generate:docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --readme README.md --verbose" + "generate:docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --readme README.md --verbose", + "husky-check": "npx husky && chmod +x .husky/pre-commit" }, "engines": { "node": ">=8.0.0" @@ -52,9 +53,10 @@ "license": "MIT", "dependencies": { "assert": "^2.1.0", - "axios": "^1.8.4", + "axios": "^1.9.0", "buffer": "^6.0.3", "form-data": "^4.0.2", + "husky": "^9.1.7", "lodash": "^4.17.21", "qs": "^6.14.0", "stream-browserify": "^3.0.0" @@ -65,18 +67,18 @@ "management api" ], "devDependencies": { - "@babel/cli": "^7.26.4", - "@babel/core": "^7.26.9", - "@babel/eslint-parser": "^7.26.8", - "@babel/plugin-transform-runtime": "^7.26.9", + "@babel/cli": "^7.27.0", + "@babel/core": "^7.26.10", + "@babel/eslint-parser": "^7.27.0", + "@babel/plugin-transform-runtime": "^7.26.10", "@babel/preset-env": "^7.26.9", "@babel/register": "^7.25.9", - "@babel/runtime": "^7.26.9", + "@babel/runtime": "^7.27.0", "@slack/bolt": "^4.2.1", "@types/chai": "^4.3.20", "@types/jest": "^28.1.8", "@types/lodash": "^4.17.16", - "@types/mocha": "^7.0.2", + "@types/mocha": "^8.2.3", "axios-mock-adapter": "^1.22.0", "babel-loader": "^8.4.1", "babel-plugin-add-module-exports": "^1.0.4", @@ -86,7 +88,7 @@ "chai": "^4.5.0", "clean-webpack-plugin": "^4.0.0", "docdash": "^1.2.0", - "dotenv": "^16.4.7", + "dotenv": "^16.5.0", "eslint": "^8.57.1", "eslint-config-standard": "^13.0.1", "eslint-plugin-import": "^2.31.0", diff --git a/test/sanity-check/api/user-test.js b/test/sanity-check/api/user-test.js index 838828cf..015307fa 100644 --- a/test/sanity-check/api/user-test.js +++ b/test/sanity-check/api/user-test.js @@ -4,6 +4,7 @@ import { contentstackClient } from '../../sanity-check/utility/ContentstackClien import { jsonWrite } from '../../sanity-check/utility/fileOperations/readwrite' import axios from 'axios' import dotenv from 'dotenv' +import * as contentstack from '../../../lib/contentstack.js' dotenv.config() var authtoken = '' @@ -74,4 +75,63 @@ describe('Contentstack User Session api Test', () => { }) .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 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 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 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() + } + }) })