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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened]

jobs:
test:
name: Run Tests
uses: ./.github/workflows/test.yml

integration-test:
name: Run Integration Tests
uses: ./.github/workflows/integration-test.yml

compatibility-test:
name: Run Compatibility Tests
uses: ./.github/workflows/compatibility.yml
37 changes: 37 additions & 0 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Compatibility Tests

on:
workflow_call:
workflow_dispatch:

jobs:
compatibility-test:
name: Compatibility Tests
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['20', '22']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Build
run: pnpm run build

- name: Run compatibility tests
run: pnpm run test:compatibility
7 changes: 2 additions & 5 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
name: Integration Tests

on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
workflow_call:
workflow_dispatch:

jobs:
integration-test:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/preview-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
node-version: 20
cache: 'pnpm'

- name: Install dependencies
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
name: Test

on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
workflow_call:
workflow_dispatch:

jobs:
test:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ coverage/
.env.local
tmp/

# Compatibility test artifacts
test-compatibility/**/package-lock.json
test-compatibility/**/node_modules/

CLAUDE.md
WARP.md
.claude/
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

## [0.5.1](https://github.com/supabase/iceberg-js/compare/iceberg-js-v0.5.0...iceberg-js-v0.5.1) (2025-11-21)


### Bug Fixes

* format all files ([#11](https://github.com/supabase/iceberg-js/issues/11)) ([f95874b](https://github.com/supabase/iceberg-js/commit/f95874b3b94bb7fff32970ebebbbeb7745263e02))
* update npm to latest for release ([#10](https://github.com/supabase/iceberg-js/issues/10)) ([7943aca](https://github.com/supabase/iceberg-js/commit/7943acab02005ad5e5be249a201fe2dce810b57b))
- format all files ([#11](https://github.com/supabase/iceberg-js/issues/11)) ([f95874b](https://github.com/supabase/iceberg-js/commit/f95874b3b94bb7fff32970ebebbbeb7745263e02))
- update npm to latest for release ([#10](https://github.com/supabase/iceberg-js/issues/10)) ([7943aca](https://github.com/supabase/iceberg-js/commit/7943acab02005ad5e5be249a201fe2dce810b57b))

## [0.5.0](https://github.com/supabase/iceberg-js/compare/iceberg-js-v0.4.0...iceberg-js-v0.5.0) (2025-11-21)

Expand Down
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# iceberg-js

[![CI](https://github.com/supabase/iceberg-js/actions/workflows/ci.yml/badge.svg)](https://github.com/supabase/iceberg-js/actions/workflows/ci.yml)
[![npm version](https://badge.fury.io/js/iceberg-js.svg)](https://www.npmjs.com/package/iceberg-js)

A small, framework-agnostic JavaScript/TypeScript client for the **Apache Iceberg REST Catalog**.

## Features
Expand All @@ -11,6 +14,28 @@ A small, framework-agnostic JavaScript/TypeScript client for the **Apache Iceber
- **Universal**: Targets Node 20+ and modern browsers (ES2020)
- **Catalog-only**: Focused on catalog operations (no data reading/Parquet support in v0.1.0)

## Compatibility

This package is built to work in **all** Node.js and JavaScript environments:

| Environment | Module System | Import Method | Status |
| ------------------- | -------------------- | --------------------------------------- | --------------------- |
| Node.js ESM | `"type": "module"` | `import { ... } from 'iceberg-js'` | ✅ Fully supported |
| Node.js CommonJS | Default | `const { ... } = require('iceberg-js')` | ✅ Fully supported |
| TypeScript ESM | `module: "ESNext"` | `import { ... } from 'iceberg-js'` | ✅ Full type support |
| TypeScript CommonJS | `module: "CommonJS"` | `import { ... } from 'iceberg-js'` | ✅ Full type support |
| Bundlers | Any | Webpack, Vite, esbuild, Rollup, etc. | ✅ Auto-detected |
| Browsers | ESM | `<script type="module">` | ✅ Modern browsers |
| Deno | ESM | `import` from npm: | ✅ With npm specifier |

**Package exports:**

- ESM: `dist/index.mjs` with `dist/index.d.ts`
- CommonJS: `dist/index.cjs` with `dist/index.d.cts`
- Proper `exports` field for Node.js 12+ module resolution

All scenarios are tested in CI on Node.js 20 and 22.

## Installation

```bash
Expand Down Expand Up @@ -338,6 +363,9 @@ pnpm test:integration
# Run integration tests with cleanup (for CI)
pnpm test:integration:ci

# Run compatibility tests (all module systems)
pnpm test:compatibility

# Format code
pnpm run format

Expand All @@ -359,6 +387,17 @@ npx tsx test/integration/test-local-catalog.ts
docker compose down -v
```

### Compatibility Testing

The `test:compatibility` script verifies the package works correctly in all JavaScript/TypeScript environments:

- **Pure JavaScript ESM** - Projects with `"type": "module"`
- **Pure JavaScript CommonJS** - Traditional Node.js projects
- **TypeScript ESM** - TypeScript with `module: "ESNext"`
- **TypeScript CommonJS** - TypeScript with `module: "CommonJS"`

These tests ensure proper module resolution, type definitions, and runtime behavior across all supported environments. See [test-compatibility/README.md](./test-compatibility/README.md) for more details.

## License

MIT
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist/**/*'], 'Ignore Build Directory'),
globalIgnores(['CLAUDE.md', 'WARP.md', 'tmp/**/*']),
globalIgnores(['CLAUDE.md', 'WARP.md', 'tmp/**/*', 'test-compatibility/**/*']),
{
files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
plugins: { js },
Expand Down
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
},
"default": "./dist/index.mjs"
}
},
"files": [
Expand All @@ -26,6 +32,7 @@
"test:watch": "vitest watch",
"test:integration": "bash scripts/test-integration.sh",
"test:integration:ci": "bash scripts/test-integration.sh --cleanup",
"test:compatibility": "bash test-compatibility/run-all.sh",
"check": "pnpm lint && pnpm type-check && pnpm test && pnpm build"
},
"keywords": [
Expand Down
38 changes: 38 additions & 0 deletions test-compatibility/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Compatibility Tests

This directory contains test projects to verify that `iceberg-js` works in all common Node.js environments.

## Test Scenarios

1. **esm-project/** - Pure JavaScript ESM (`"type": "module"`)
2. **cjs-project/** - Pure JavaScript CommonJS (no type field)
3. **ts-esm-project/** - TypeScript with ESM (`module: "ESNext"`)
4. **ts-cjs-project/** - TypeScript with CommonJS (`module: "CommonJS"`)

## Running Tests

From the root of the `iceberg-js` project:

```bash
# Build the package first
pnpm build

# Run all compatibility tests
bash test-compatibility/run-all.sh
```

Or test individually:

```bash
cd test-compatibility/esm-project
npm install
npm test
```

## What Gets Tested

- ✅ Package can be imported/required
- ✅ Classes and types are available
- ✅ Instances can be created
- ✅ TypeScript types resolve correctly
- ✅ No module resolution errors
19 changes: 19 additions & 0 deletions test-compatibility/cjs-project/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// CommonJS Test - tests that the package works in CJS mode
const { IcebergRestCatalog } = require('iceberg-js')

console.log('✅ CJS: Successfully required IcebergRestCatalog')
console.log('✅ CJS: Type:', typeof IcebergRestCatalog)
console.log('✅ CJS: Constructor name:', IcebergRestCatalog.name)

// Test instantiation
try {
const catalog = new IcebergRestCatalog({
baseUrl: 'http://localhost:8181',
auth: { type: 'none' },
})
console.log('✅ CJS: Successfully created catalog instance')
console.log('✅ CJS: ALL TESTS PASSED!')
} catch (error) {
console.error('❌ CJS: Failed to create instance:', error)
process.exit(1)
}
11 changes: 11 additions & 0 deletions test-compatibility/cjs-project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "test-cjs-compatibility",
"version": "1.0.0",
"private": true,
"scripts": {
"test": "node index.js"
},
"dependencies": {
"iceberg-js": "file:../.."
}
}
19 changes: 19 additions & 0 deletions test-compatibility/esm-project/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// ESM Test - tests that the package works in ESM mode
import { IcebergRestCatalog } from 'iceberg-js'

console.log('✅ ESM: Successfully imported IcebergRestCatalog')
console.log('✅ ESM: Type:', typeof IcebergRestCatalog)
console.log('✅ ESM: Constructor name:', IcebergRestCatalog.name)

// Test instantiation
try {
const catalog = new IcebergRestCatalog({
baseUrl: 'http://localhost:8181',
auth: { type: 'none' },
})
console.log('✅ ESM: Successfully created catalog instance')
console.log('✅ ESM: ALL TESTS PASSED!')
} catch (error) {
console.error('❌ ESM: Failed to create instance:', error)
process.exit(1)
}
12 changes: 12 additions & 0 deletions test-compatibility/esm-project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test-esm-compatibility",
"version": "1.0.0",
"type": "module",
"private": true,
"scripts": {
"test": "node index.js"
},
"dependencies": {
"iceberg-js": "file:../.."
}
}
64 changes: 64 additions & 0 deletions test-compatibility/run-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash
set -e

# Get the directory where the script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

echo "🧪 Running compatibility tests for iceberg-js..."
echo ""

# Make sure the package is built
if [ ! -d "$ROOT_DIR/dist" ]; then
echo "❌ Error: dist/ folder not found. Run 'pnpm build' first."
exit 1
fi

# Change to test-compatibility directory
cd "$SCRIPT_DIR"

# Test ESM
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔵 Testing ESM (Pure JavaScript)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd esm-project
npm install ../..
npm test
cd ..
echo ""

# Test CJS
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🟢 Testing CommonJS (Pure JavaScript)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd cjs-project
npm install ../..
npm test
cd ..
echo ""

# Test TS ESM
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔷 Testing TypeScript ESM"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd ts-esm-project
npm install
npm install ../..
npm test
cd ..
echo ""

# Test TS CJS
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🟩 Testing TypeScript CommonJS"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd ts-cjs-project
npm install
npm install ../..
npm test
cd ..
echo ""

echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✨ ALL COMPATIBILITY TESTS PASSED!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
Loading
Loading