From 8029b41f00380f5c84524ce3bdbab551179189ba Mon Sep 17 00:00:00 2001 From: Nadeem Patwekar Date: Mon, 12 Jan 2026 17:09:24 +0530 Subject: [PATCH] fix: ESM compatibility fixes and improved error handling --- .talismanrc | 4 +- CHANGELOG.md | 9 ++ README.md | 115 +++++++++++++++++++--- package-lock.json | 174 ++++++++++++++++++--------------- package.json | 2 +- src/lib/contentstack-core.ts | 5 +- test/contentstack-core.spec.ts | 83 ++++++++++++++-- tools/postbuild.js | 53 ++++++++++ 8 files changed, 339 insertions(+), 106 deletions(-) diff --git a/.talismanrc b/.talismanrc index df8a173..b7172be 100644 --- a/.talismanrc +++ b/.talismanrc @@ -3,7 +3,7 @@ fileignoreconfig: ignore_detectors: - filecontent - filename: package-lock.json - checksum: af3bffd9f46b71daf5b8dd0b3eace75dfd367e359b11503259dc00a8c7105bf0 + checksum: 59653dc17458f6bddffb6178bfb8f8191ad4715f41a788082a11d3b08e966b4c - filename: .husky/pre-commit checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193 - filename: test/request.spec.ts @@ -14,4 +14,6 @@ fileignoreconfig: checksum: 08ccd6342b3adbeb7b85309a034b4df4b2ad905a0cc2a3778ab483b61ba41b9e - filename: test/retryPolicy/delivery-sdk-handlers.spec.ts checksum: 6d22d7482aa6dccba5554ae497e5b0c3572357a5cead6f4822ee4428edc12207 +- filename: test/contentstack-core.spec.ts + checksum: 2d1e0f63ad8ea37890de2aa6c7e394c83488888f4a40ad7a71eeba2290b95924 version: "" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 90809ba..075d7f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## Change log +### Version: 1.3.8 +#### Date: Jan-15-2026 + - Fix: Add .js extensions to relative imports in ESM build for proper module resolution + - Fix: Change lodash import from named import to default import for ESM compatibility with CommonJS modules + +### Version: 1.3.7 +#### Date: Jan-12-2026 + - Fix: Improve error messages + ### Version: 1.3.6 #### Date: Jan-05-2026 - Fix: Resolve qa dependency snyk issue diff --git a/README.md b/README.md index 74d78d1..34dc0f4 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,129 @@ +# @contentstack/core + [![Contentstack](https://www.contentstack.com/docs/static/images/contentstack.png)](https://www.contentstack.com/) -## TypeScript Core SDK for Contentstack + +TypeScript Core SDK for Contentstack - A foundational library providing core modules and utilities for Contentstack TypeScript SDKs. + +## About Contentstack Contentstack is a headless CMS with an API-first approach. It is a CMS that developers can use to build powerful cross-platform applications in their favorite languages. Build your application frontend, and Contentstack will take care of the rest. [Read More](https://www.contentstack.com/). -### Prerequisite +## Description -You need Node.js version 4.4.7 or later installed to use the Contentstack TS Core SDK. +This package contains core modules and utilities used by the [Contentstack TypeScript Delivery SDK](https://github.com/contentstack/contentstack-javascript/). It provides essential functionality including HTTP client configuration, error handling, request management, parameter serialization, and retry policies. -## Installation +## Features -``` +- **HTTP Client**: Configurable Axios-based HTTP client with support for custom adapters +- **Error Handling**: Comprehensive error classes for API and Contentstack-specific errors +- **Request Management**: Request handling with interceptors and custom error callbacks +- **Parameter Serialization**: Custom parameter serialization for API requests +- **Retry Policies**: Built-in retry logic for handling rate limits and transient errors +- **TypeScript Support**: Full TypeScript definitions included +- **Multiple Build Formats**: Supports CommonJS, ESM, UMD, and TypeScript declarations + +## Important Note + +**This package is an internal dependency** used by Contentstack TypeScript SDKs. End users should **not** install this package directly. Instead, install the appropriate Contentstack SDK (e.g., [Contentstack TypeScript Delivery SDK](https://github.com/contentstack/contentstack-typescript/)), which will automatically include this package as a dependency. + +## For SDK Developers + +If you are developing or maintaining a Contentstack SDK and need to use this core package directly, you can install it as a dependency: + +```bash npm install @contentstack/core ``` -## Use case +Then import the modules: -This package contains some core modules and utilities used by the [Contentstack Typescript Delivery SDK](https://github.com/contentstack/contentstack-javascript/) SDK. +```typescript +import { + httpClient, + ContentstackError, + ApiError, + // ... other exports +} from '@contentstack/core'; +``` ## Development -### Create the build: +### Prerequisites +- Node.js version 4.4.7 or later + +### Setup + +Clone the repository and install dependencies: + +```bash +git clone https://github.com/contentstack/contentstack-js-core.git +cd contentstack-js-core +npm install ``` + +### Build + +Build all output formats (CommonJS, ESM, UMD, and TypeScript declarations): + +```bash npm run build ``` -### Run Scripts: - -Run the unit tests: +Build specific formats: +```bash +npm run build:cjs # CommonJS +npm run build:esm # ES Modules +npm run build:umd # UMD +npm run build:types # TypeScript declarations ``` + +### Testing + +Run unit tests: + +```bash npm run test ``` -Run the lint tests: +Run linting: -``` +```bash npm run lint ``` -Pack the SDK: +### Packaging -``` +Create a package tarball: + +```bash npm run package -``` \ No newline at end of file +``` + +### Clean + +Clean build artifacts: + +```bash +npm run clean +``` + +## License + +This project is licensed under the MIT License. See the [LICENSE.txt](LICENSE.txt) file for details. + +## Repository + +- **GitHub**: [contentstack/contentstack-js-core](https://github.com/contentstack/contentstack-js-core) + +## Related Projects + +- [Contentstack TypeScript Delivery SDK](https://github.com/contentstack/contentstack-javascript/) + +## Support + +For issues and feature requests, please visit the [GitHub Issues](https://github.com/contentstack/contentstack-js-core/issues) page. + +--- + +Copyright (c) 2016-2025 Contentstack. All rights reserved. diff --git a/package-lock.json b/package-lock.json index 93ed127..fbbc247 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/core", - "version": "1.3.6", + "version": "1.3.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/core", - "version": "1.3.6", + "version": "1.3.8", "license": "MIT", "dependencies": { "axios": "^1.12.2", @@ -87,6 +87,7 @@ "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", @@ -955,9 +956,9 @@ } }, "node_modules/@cspell/dict-companies": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.9.tgz", - "integrity": "sha512-y5GdU+LnuMhUE/WYwOYt7GcJdrpmV4KXE1oFb5toEsnGa2KzffUbS6lwPpeRBocQoqZj8jJYFtxoQ+2KVg++/A==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.8.tgz", + "integrity": "sha512-NTP6ITcNvQqpZT86yPZX6kfGhjxD409K8GxFPSHODqKOLxi6eQkUTW9YSXe0o1rzio2Lm7P17laugXjvGnwOjg==", "dev": true, "license": "MIT" }, @@ -976,23 +977,23 @@ "license": "MIT" }, "node_modules/@cspell/dict-csharp": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.8.tgz", - "integrity": "sha512-qmk45pKFHSxckl5mSlbHxmDitSsGMlk/XzFgt7emeTJWLNSTUK//MbYAkBNRtfzB4uD7pAFiKgpKgtJrTMRnrQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.7.tgz", + "integrity": "sha512-H16Hpu8O/1/lgijFt2lOk4/nnldFtQ4t8QHbyqphqZZVE5aS4J/zD/WvduqnLY21aKhZS6jo/xF5PX9jyqPKUA==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-css": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.19.tgz", - "integrity": "sha512-VYHtPnZt/Zd/ATbW3rtexWpBnHUohUrQOHff/2JBhsVgxOrksAxJnLAO43Q1ayLJBJUUwNVo+RU0sx0aaysZfg==", + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.18.tgz", + "integrity": "sha512-EF77RqROHL+4LhMGW5NTeKqfUd/e4OOv6EDFQ/UQQiFyWuqkEKyEz0NDILxOFxWUEVdjT2GQ2cC7t12B6pESwg==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-dart": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.3.2.tgz", - "integrity": "sha512-sUiLW56t9gfZcu8iR/5EUg+KYyRD83Cjl3yjDEA2ApVuJvK1HhX+vn4e4k4YfjpUQMag8XO2AaRhARE09+/rqw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.3.1.tgz", + "integrity": "sha512-xoiGnULEcWdodXI6EwVyqpZmpOoh8RA2Xk9BNdR7DLamV/QMvEYn8KJ7NlRiTSauJKPNkHHQ5EVHRM6sTS7jdg==", "dev": true, "license": "MIT" }, @@ -1004,16 +1005,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-django": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.6.tgz", - "integrity": "sha512-SdbSFDGy9ulETqNz15oWv2+kpWLlk8DJYd573xhIkeRdcXOjskRuxjSZPKfW7O3NxN/KEf3gm3IevVOiNuFS+w==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.5.tgz", + "integrity": "sha512-AvTWu99doU3T8ifoMYOMLW2CXKvyKLukPh1auOPwFGHzueWYvBBN+OxF8wF7XwjTBMMeRleVdLh3aWCDEX/ZWg==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-docker": { - "version": "1.1.17", - "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.17.tgz", - "integrity": "sha512-OcnVTIpHIYYKhztNTyK8ShAnXTfnqs43hVH6p0py0wlcwRIXe5uj4f12n7zPf2CeBI7JAlPjEsV0Rlf4hbz/xQ==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.16.tgz", + "integrity": "sha512-UiVQ5RmCg6j0qGIxrBnai3pIB+aYKL3zaJGvXk1O/ertTKJif9RZikKXCEgqhaCYMweM4fuLqWSVmw3hU164Iw==", "dev": true, "license": "MIT" }, @@ -1032,9 +1033,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.26", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.26.tgz", - "integrity": "sha512-rpjM87n2e3PN3mx9SbzQOIniEWUKewZj0xFA796Pzeu3gJlYsHsSkZZC6Jxdea2992EfrzJZYwJb+mjxa3gWGg==", + "version": "4.4.25", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.25.tgz", + "integrity": "sha512-cEdLVSjwfFHK+QmsGYzh8a4QUqXP6B5UPiFlbkIV+eolD5hWuhBaFtaXM6+/kD47/hV2UDYj4yUdD9xsMnlBBQ==", "dev": true, "license": "MIT" }, @@ -1088,9 +1089,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-golang": { - "version": "6.0.25", - "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.25.tgz", - "integrity": "sha512-Q0mkUj1mFN1P5LZoKBeTLOQehlHMYv62K0Px9FS7qykSvZjBz44bhCezJuepTPCiCFqmwQgT2fc3Ixw+fhO6pQ==", + "version": "6.0.24", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.24.tgz", + "integrity": "sha512-rY7PlC3MsHozmjrZWi0HQPUl0BVCV0+mwK0rnMT7pOIXqOe4tWCYMULDIsEk4F0gbIxb5badd2dkCPDYjLnDgA==", "dev": true, "license": "MIT" }, @@ -1102,16 +1103,16 @@ "license": "MIT" }, "node_modules/@cspell/dict-html": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.14.tgz", - "integrity": "sha512-2bf7n+kS92g+cMKV0wr9o/Oq9n8JzU7CcrB96gIh2GHgnF+0xDOqO2W/1KeFAqOfqosoOVE48t+4dnEMkkoJ2Q==", + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.13.tgz", + "integrity": "sha512-vHzk2xfqQYPvoXtQtywa6ekIonPrUEwe2uftjry3UNRNl89TtzLJVSkiymKJ3WMb+W/DwKXKIb1tKzcIS8ccIg==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-html-symbol-entities": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.5.tgz", - "integrity": "sha512-429alTD4cE0FIwpMucvSN35Ld87HCyuM8mF731KU5Rm4Je2SG6hmVx7nkBsLyrmH3sQukTcr1GaiZsiEg8svPA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.4.tgz", + "integrity": "sha512-afea+0rGPDeOV9gdO06UW183Qg6wRhWVkgCFwiO3bDupAoyXRuvupbb5nUyqSTsLXIKL8u8uXQlJ9pkz07oVXw==", "dev": true, "license": "MIT" }, @@ -1158,9 +1159,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.2.27", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.27.tgz", - "integrity": "sha512-REy2vRQ9BJkjoW8cEr8ewoJAZ0DsTh+TimJ58KgIG1d81caanNgdvKLSgDkPd8OlGxPfLKHe7o2TJuk/l7VqhA==", + "version": "5.2.26", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.26.tgz", + "integrity": "sha512-jtjp/wE/4KRTWjtiosAakDwdvrU4lTF3djOaI0tPDPytxou6QTHSm5A7FzU+MzLqvNfdYHUsCcdvx1FE1T/6pg==", "dev": true, "license": "MIT" }, @@ -1210,9 +1211,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-rust": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.1.0.tgz", - "integrity": "sha512-ysFxxKc3QjPWtPacbwxzz8sDOACHNShlhQpnBsDXAHN3LogmuBsQtfyuU30APqFjCOg9KwGciKYC/hcGxJCbiA==", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.12.tgz", + "integrity": "sha512-z2QiH+q9UlNhobBJArvILRxV8Jz0pKIK7gqu4TgmEYyjiu1TvnGZ1tbYHeu9w3I/wOP6UMDoCBTty5AlYfW0mw==", "dev": true, "license": "MIT" }, @@ -1332,9 +1333,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { @@ -2210,7 +2211,8 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", @@ -2332,6 +2334,7 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -2748,6 +2751,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2831,6 +2835,7 @@ "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", @@ -3227,6 +3232,7 @@ "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", @@ -3384,9 +3390,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3456,6 +3462,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3622,9 +3629,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "dev": true, "funding": [ { @@ -3867,9 +3874,9 @@ "license": "MIT" }, "node_modules/comment-json": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.5.1.tgz", - "integrity": "sha512-taEtr3ozUmOB7it68Jll7s0Pwm+aoiHyXKrEC8SEodL4rNpdfDLqa7PfBlrgFoCNNdR8ImL+muti5IGvktJAAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.5.0.tgz", + "integrity": "sha512-aKl8CwoMKxVTfAK4dFN4v54AEvuUh9pzmgVIBeK6gBomLwMgceQUKKWHzJdW1u1VQXQuwnJ7nJGWYYMTl5U4yg==", "dev": true, "license": "MIT", "dependencies": { @@ -4987,9 +4994,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, @@ -5103,6 +5110,7 @@ "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", @@ -5410,6 +5418,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5734,9 +5743,9 @@ } }, "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5969,9 +5978,9 @@ } }, "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6176,9 +6185,9 @@ } }, "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", "dev": true, "license": "MIT", "dependencies": { @@ -7746,6 +7755,7 @@ "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^28.1.3", "@jest/types": "^28.1.3", @@ -9732,6 +9742,7 @@ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin-prettier.js" }, @@ -9743,9 +9754,9 @@ } }, "node_modules/prettier-linter-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", - "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "license": "MIT", "dependencies": { @@ -11484,6 +11495,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -11730,6 +11742,7 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11781,9 +11794,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "dev": true, "funding": [ { @@ -11931,9 +11944,9 @@ } }, "node_modules/watchpack": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz", - "integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, "license": "MIT", "dependencies": { @@ -11965,11 +11978,12 @@ } }, "node_modules/webpack": { - "version": "5.104.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", - "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", + "version": "5.103.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", + "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -11979,10 +11993,10 @@ "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.4", - "es-module-lexer": "^2.0.0", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -11993,7 +12007,7 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", + "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, @@ -12019,6 +12033,7 @@ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.2.0", @@ -12138,7 +12153,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 17b3dd1..b712672 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/core", - "version": "1.3.6", + "version": "1.3.8", "type": "commonjs", "main": "./dist/cjs/src/index.js", "types": "./dist/cjs/src/index.d.ts", diff --git a/src/lib/contentstack-core.ts b/src/lib/contentstack-core.ts index 15a1ac9..69f7b3c 100644 --- a/src/lib/contentstack-core.ts +++ b/src/lib/contentstack-core.ts @@ -1,4 +1,4 @@ -import { cloneDeep } from 'lodash'; +import _ from 'lodash'; import { serialize } from './param-serializer'; import axios, { AxiosRequestHeaders, getAdapter } from 'axios'; import { AxiosInstance, HttpClientParams } from './types'; @@ -20,6 +20,7 @@ export function httpClient(options: HttpClientParams): AxiosInstance { const title = [data.name, data.message].filter((a) => a).join(' - '); console.error(ERROR_MESSAGES.CONSOLE.ERROR_WITH_TITLE(title)); } + return; } if (data !== undefined) { @@ -38,7 +39,7 @@ export function httpClient(options: HttpClientParams): AxiosInstance { const config: HttpClientParams = { ...defaultConfig, - ...cloneDeep(options), + ..._.cloneDeep(options), }; if (config.apiKey && config.headers) { diff --git a/test/contentstack-core.spec.ts b/test/contentstack-core.spec.ts index e69a7d3..c1bb031 100644 --- a/test/contentstack-core.spec.ts +++ b/test/contentstack-core.spec.ts @@ -2,9 +2,8 @@ import { AxiosInstance } from '../src'; import { httpClient } from '../src/lib/contentstack-core'; import MockAdapter from 'axios-mock-adapter'; describe('contentstackCore', () => { - it('should return default config when no config is passed', (done) => { - const client = httpClient({}); - done(); + it('should return default config when no config is passed', () => { + httpClient({}); }); describe('logHandler', () => { @@ -17,7 +16,9 @@ describe('contentstackCore', () => { const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(); httpClient({}).defaults.logHandler('error', error); - expect(consoleErrorSpy).toHaveBeenCalledWith('Error: Error - Something went wrong. Review the error details and try again.'); + expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Error: Error - Something went wrong. Review the error details and try again.' + ); consoleErrorSpy.mockRestore(); }); @@ -152,7 +153,7 @@ describe('contentstackCore', () => { it('should call the onError function when an error occurs', async () => { // Suppress expected console.error from network error const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(); - + const onError = jest.fn(); const options = { defaultHostname: 'cdn.contentstack.io', @@ -166,7 +167,7 @@ describe('contentstackCore', () => { } catch (error: unknown) { expect(onError).toBeCalledWith(error); } - + consoleErrorSpy.mockRestore(); }); @@ -188,4 +189,74 @@ describe('contentstackCore', () => { expect(client.httpClientParams.onError).not.toBeCalled(); }); }); + + describe('config deep cloning', () => { + it('should properly handle nested objects in params using cloneDeep', () => { + const options = { + defaultHostname: 'example.com', + params: { + environment: 'test', + nested: { + level1: { + level2: { + value: 'deep-nested', + }, + }, + }, + }, + }; + + const instance = httpClient(options); + + // Verify nested structure is properly accessible + // This test ensures cloneDeep is working correctly (ESM import fix) + expect(instance.httpClientParams.params?.nested?.level1?.level2?.value).toBe('deep-nested'); + expect(instance.httpClientParams.params?.environment).toBe('test'); + }); + + it('should handle complex nested structures in params', () => { + const complexOptions = { + defaultHostname: 'example.com', + params: { + environment: 'production', + filters: { + category: { + name: 'tech', + tags: ['javascript', 'typescript'], + }, + }, + }, + }; + + const instance = httpClient(complexOptions); + + // Verify complex nested structure is properly handled + expect(instance.httpClientParams.params?.filters?.category?.name).toBe('tech'); + expect(instance.httpClientParams.params?.filters?.category?.tags).toEqual(['javascript', 'typescript']); + }); + + it('should work correctly with lodash cloneDeep import (ESM compatibility)', () => { + // This test verifies that the lodash import works correctly in ESM + // by ensuring nested object cloning works as expected + const options = { + defaultHostname: 'example.com', + params: { + query: { + type: 'entry', + include: { + count: true, + schema: true, + }, + }, + }, + }; + + const instance = httpClient(options); + + // If cloneDeep wasn't working (due to import issues), this would fail + expect(instance.httpClientParams.params?.query?.type).toBe('entry'); + expect(instance.httpClientParams.params?.query?.include?.count).toBe(true); + expect(instance.httpClientParams.params?.query?.include?.schema).toBe(true); + }); + }); }); diff --git a/tools/postbuild.js b/tools/postbuild.js index 41b8cb6..45a1f37 100644 --- a/tools/postbuild.js +++ b/tools/postbuild.js @@ -5,6 +5,7 @@ const path = require('path'); * Post-build script to create package.json in dist/esm/ * This marks the ESM output directory as ES modules, resolving * the conflict with root package.json's "type": "commonjs" + * Also adds .js extensions to relative imports for ESM compatibility */ const esmPackageJsonPath = path.join(__dirname, '../dist/esm/package.json'); const esmPackageJson = { @@ -19,3 +20,55 @@ if (!fs.existsSync(esmDir)) { // Write the package.json file fs.writeFileSync(esmPackageJsonPath, JSON.stringify(esmPackageJson, null, 2) + '\n', 'utf8'); + +// Fix relative imports to include .js extensions for ESM compatibility +const esmSrcDir = path.join(__dirname, '../dist/esm/src'); + +function fixImportsInFile(filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + + // Replace relative imports/exports without .js extension + // Matches: './something' or '../something' but not './something.js' or './something.json' + const fixedContent = content + .replace(/(from\s+['"])(\.\.?\/[^'"]+)(['"])/g, (match, prefix, importPath, suffix) => { + // Skip if already has extension or is a JSON import + if (importPath.endsWith('.js') || importPath.endsWith('.json') || importPath.endsWith('.mjs')) { + return match; + } + + // Add .js extension + return `${prefix}${importPath}.js${suffix}`; + }) + .replace(/(export\s+\*\s+from\s+['"])(\.\.?\/[^'"]+)(['"])/g, (match, prefix, importPath, suffix) => { + // Skip if already has extension or is a JSON import + if (importPath.endsWith('.js') || importPath.endsWith('.json') || importPath.endsWith('.mjs')) { + return match; + } + + // Add .js extension + return `${prefix}${importPath}.js${suffix}`; + }); + + if (content !== fixedContent) { + fs.writeFileSync(filePath, fixedContent, 'utf8'); + } +} + +function processDirectory(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + if (entry.isDirectory()) { + processDirectory(fullPath); + } else if (entry.isFile() && entry.name.endsWith('.js')) { + fixImportsInFile(fullPath); + } + } +} + +// Process all .js files in the ESM build +if (fs.existsSync(esmSrcDir)) { + processDirectory(esmSrcDir); +}