Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fileignoreconfig:
ignore_detectors:
- filecontent
- filename: package-lock.json
checksum: 61066aedc29ef5bd8904d1ee2384dad828e8f9aab1a6b0360797ec7926e7f8dd
checksum: 61741bf02cfbc74f1ca4e7b0bda74d27d295616a13a31a95c2d7818fcc3d1cba
- filename: .husky/pre-commit
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
- filename: test/request.spec.ts
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Change log

### Version: 1.3.3
#### Date: Nov-10-2025
- Fix: Added 'exports' field to package.json to fix ESM import error where '@contentstack/core' does not provide an export named 'getData' in modern ESM environments (e.g., Nuxt.js, Vite)

### Version: 1.3.2
#### Date: Oct-27-2025
- Fix: Used common serialize method for query params
Expand Down
49 changes: 31 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
{
"name": "@contentstack/core",
"version": "1.3.2",
"version": "1.3.3",
"type": "commonjs",
"main": "./dist/cjs/src/index.js",
"types": "./dist/cjs/src/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/types/src/index.d.ts",
"default": "./dist/esm/src/index.js"
},
"require": {
"types": "./dist/types/src/index.d.ts",
"default": "./dist/cjs/src/index.js"
}
},
"./package.json": "./package.json"
},
"license": "MIT",
"scripts": {
"prepare": "npm run build && npm run husky-check",
Expand Down
121 changes: 121 additions & 0 deletions test/esm-exports.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
* ESM Exports Test Suite
*
* Purpose: Verify that ESM and CJS builds export correctly and package.json
* has proper exports field configuration for ESM compatibility.
*/

import * as fs from 'fs';
import * as path from 'path';

describe('ESM Exports Tests', () => {
const distPath = path.join(__dirname, '..', 'dist');
const esmIndexPath = path.join(distPath, 'esm', 'src', 'index.js');
const cjsIndexPath = path.join(distPath, 'cjs', 'src', 'index.js');
const esmRequestPath = path.join(distPath, 'esm', 'src', 'lib', 'request.js');
const cjsRequestPath = path.join(distPath, 'cjs', 'src', 'lib', 'request.js');

describe('ESM Build Exports', () => {
it('should have ESM build index.js file', () => {
expect(fs.existsSync(esmIndexPath)).toBe(true);
});

it('should export getData from ESM request.js', () => {
expect(fs.existsSync(esmRequestPath)).toBe(true);
const requestContent = fs.readFileSync(esmRequestPath, 'utf-8');
expect(requestContent).toContain('export function getData');
});

it('should re-export getData from ESM index.js', () => {
const indexContent = fs.readFileSync(esmIndexPath, 'utf-8');
expect(indexContent).toContain("export * from './lib/request'");
});

it('should verify getData is a named export in ESM build', () => {
const requestContent = fs.readFileSync(esmRequestPath, 'utf-8');
expect(requestContent).toMatch(/export\s+(async\s+)?function\s+getData/);
});
});

describe('CJS Build Exports', () => {
it('should have CJS build index.js file', () => {
expect(fs.existsSync(cjsIndexPath)).toBe(true);
});

it('should export getData from CJS request.js using exports.getData', () => {
expect(fs.existsSync(cjsRequestPath)).toBe(true);
const requestContent = fs.readFileSync(cjsRequestPath, 'utf-8');
expect(requestContent).toContain('exports.getData');
});

it('should re-export getData from CJS index.js using __exportStar', () => {
const indexContent = fs.readFileSync(cjsIndexPath, 'utf-8');
expect(indexContent).toContain('__exportStar(require("./lib/request")');
});
});

describe('Package.json Exports Configuration', () => {
it('should have exports field in package.json', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
expect(packageJson.exports).toBeDefined();
expect(packageJson.exports['.']).toBeDefined();
});

it('should have import condition pointing to ESM build', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
expect(packageJson.exports['.'].import).toBeDefined();
const importPath = packageJson.exports['.'].import.default || packageJson.exports['.'].import;
expect(importPath).toContain('esm');
});

it('should have require condition pointing to CJS build', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
expect(packageJson.exports['.'].require).toBeDefined();
const requirePath = packageJson.exports['.'].require.default || packageJson.exports['.'].require;
expect(requirePath).toContain('cjs');
});

it('should have types specified for both import and require', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const exports = packageJson.exports['.'];
expect(exports.import.types).toBeDefined();
expect(exports.require.types).toBeDefined();
expect(exports.import.types).toContain('types');
expect(exports.require.types).toContain('types');
});

it('should verify ESM build file exists at exports path', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const importPath = packageJson.exports['.'].import.default || packageJson.exports['.'].import;
const fullPath = path.join(__dirname, '..', importPath);
expect(fs.existsSync(fullPath)).toBe(true);
});

it('should verify CJS build file exists at exports path', () => {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const requirePath = packageJson.exports['.'].require.default || packageJson.exports['.'].require;
const fullPath = path.join(__dirname, '..', requirePath);
expect(fs.existsSync(fullPath)).toBe(true);
});
});

describe('Source Code Imports', () => {
it('should be able to import getData as named export from source', async () => {
const { getData } = await import('../src');
expect(getData).toBeDefined();
expect(typeof getData).toBe('function');
});

it('should verify getData is available in all exports from source', async () => {
const allExports = await import('../src');
expect(allExports.getData).toBeDefined();
expect(typeof allExports.getData).toBe('function');
});
});
});
Loading