diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml
index 8f76be39c..e320676ae 100644
--- a/.github/workflows/bump-version.yml
+++ b/.github/workflows/bump-version.yml
@@ -1,5 +1,10 @@
name: "bump-version"
+# Manually bump a single package's version and open a release PR against main.
+# Each package has its own job; the required `package` input selects which one
+# runs. Packages are versioned independently, so there is no "bump everything"
+# option - dispatch the workflow once per package you want to release.
+
on:
workflow_dispatch:
inputs:
@@ -11,14 +16,26 @@ on:
- patch
- minor
- major
+ package:
+ description: "Package to bump"
+ required: true
+ type: choice
+ options:
+ - "@clickhouse/client"
+ - "@clickhouse/client-web"
+ # The common package is deprecated, but can still be bumped on its own.
+ - "@clickhouse/client-common"
permissions: {}
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}
cancel-in-progress: false
+
jobs:
- bump:
+ bump_client:
+ name: "Bump @clickhouse/client"
+ if: inputs.package == '@clickhouse/client'
runs-on: ubuntu-latest
permissions:
contents: write
@@ -34,41 +51,134 @@ jobs:
with:
node-version: 24
- - name: Calculate new version
+ - name: Bump version
id: version
env:
BUMP_TYPE: ${{ inputs.bump_type }}
run: |
- CURRENT=$(node -p "require('./packages/client-common/package.json').version")
- NEW=$(CURRENT="$CURRENT" node -e "
- const m = process.env.CURRENT.match(/^(\d+)\.(\d+)\.(\d+)$/);
- if (!m) throw new Error('Version ' + process.env.CURRENT + ' is not a strict x.y.z release; bump manually.');
- const [, major, minor, patch] = m.map(Number);
- if (process.env.BUMP_TYPE === 'major') process.stdout.write((major+1) + '.0.0');
- else if (process.env.BUMP_TYPE === 'minor') process.stdout.write(major + '.' + (minor+1) + '.0');
- else process.stdout.write(major + '.' + minor + '.' + (patch+1));
- ")
+ CURRENT=$(node -p "require('./packages/client-node/package.json').version")
+ npm --workspace @clickhouse/client version --no-git-tag-version "$BUMP_TYPE"
+ NEW=$(node -p "require('./packages/client-node/package.json').version")
+ echo "export default \"$NEW\";" > packages/client-node/src/version.ts
echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
echo "new=$NEW" >> "$GITHUB_OUTPUT"
- - name: Bump version in packages
- run: .scripts/update_version.sh "${{ steps.version.outputs.new }}"
+ - name: Commit, push branch, and open PR
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NEW: ${{ steps.version.outputs.new }}
+ CURRENT: ${{ steps.version.outputs.current }}
+ BUMP_TYPE: ${{ inputs.bump_type }}
+ run: |
+ BRANCH="release-client-${NEW}"
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git checkout -b "$BRANCH"
+ git add .
+ git commit -m "chore: bump @clickhouse/client version to ${NEW}"
+ git push origin "$BRANCH"
+ gh pr create \
+ --title "chore: bump @clickhouse/client version to ${NEW}" \
+ --body "Bumps \`@clickhouse/client\` from \`${CURRENT}\` to \`${NEW}\` (${BUMP_TYPE} bump)." \
+ --base main \
+ --head "$BRANCH"
- - name: Commit and push branch
+ bump_client_web:
+ name: "Bump @clickhouse/client-web"
+ if: inputs.package == '@clickhouse/client-web'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ ref: main
+
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+
+ - name: Bump version
+ id: version
+ env:
+ BUMP_TYPE: ${{ inputs.bump_type }}
run: |
+ CURRENT=$(node -p "require('./packages/client-web/package.json').version")
+ npm --workspace @clickhouse/client-web version --no-git-tag-version "$BUMP_TYPE"
+ NEW=$(node -p "require('./packages/client-web/package.json').version")
+ echo "export default \"$NEW\";" > packages/client-web/src/version.ts
+ echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
+ echo "new=$NEW" >> "$GITHUB_OUTPUT"
+
+ - name: Commit, push branch, and open PR
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NEW: ${{ steps.version.outputs.new }}
+ CURRENT: ${{ steps.version.outputs.current }}
+ BUMP_TYPE: ${{ inputs.bump_type }}
+ run: |
+ BRANCH="release-client-web-${NEW}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- git checkout -b "release-${{ steps.version.outputs.new }}"
+ git checkout -b "$BRANCH"
git add .
- git commit -m "chore: bump version to ${{ steps.version.outputs.new }}"
- git push origin "release-${{ steps.version.outputs.new }}"
+ git commit -m "chore: bump @clickhouse/client-web version to ${NEW}"
+ git push origin "$BRANCH"
+ gh pr create \
+ --title "chore: bump @clickhouse/client-web version to ${NEW}" \
+ --body "Bumps \`@clickhouse/client-web\` from \`${CURRENT}\` to \`${NEW}\` (${BUMP_TYPE} bump)." \
+ --base main \
+ --head "$BRANCH"
+
+ bump_client_common:
+ name: "Bump @clickhouse/client-common (deprecated)"
+ if: inputs.package == '@clickhouse/client-common'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ ref: main
- - name: Create pull request
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+
+ - name: Bump version
+ id: version
+ env:
+ BUMP_TYPE: ${{ inputs.bump_type }}
+ run: |
+ CURRENT=$(node -p "require('./packages/client-common/package.json').version")
+ npm --workspace @clickhouse/client-common version --no-git-tag-version "$BUMP_TYPE"
+ NEW=$(node -p "require('./packages/client-common/package.json').version")
+ echo "export default \"$NEW\";" > packages/client-common/src/version.ts
+ echo "current=$CURRENT" >> "$GITHUB_OUTPUT"
+ echo "new=$NEW" >> "$GITHUB_OUTPUT"
+
+ - name: Commit, push branch, and open PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NEW: ${{ steps.version.outputs.new }}
+ CURRENT: ${{ steps.version.outputs.current }}
+ BUMP_TYPE: ${{ inputs.bump_type }}
run: |
+ BRANCH="release-client-common-${NEW}"
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git checkout -b "$BRANCH"
+ git add .
+ git commit -m "chore: bump @clickhouse/client-common version to ${NEW}"
+ git push origin "$BRANCH"
gh pr create \
- --title "chore: bump version to ${{ steps.version.outputs.new }}" \
- --body "Bumps version from \`${{ steps.version.outputs.current }}\` to \`${{ steps.version.outputs.new }}\` (${{ inputs.bump_type }} bump)." \
+ --title "chore: bump @clickhouse/client-common version to ${NEW}" \
+ --body "Bumps \`@clickhouse/client-common\` from \`${CURRENT}\` to \`${NEW}\` (${BUMP_TYPE} bump)." \
--base main \
- --head "release-${{ steps.version.outputs.new }}"
+ --head "$BRANCH"
diff --git a/.github/workflows/e2e-skills.yml b/.github/workflows/e2e-skills.yml
index 1ad18db0b..ea0a22579 100644
--- a/.github/workflows/e2e-skills.yml
+++ b/.github/workflows/e2e-skills.yml
@@ -11,6 +11,12 @@ on:
- packages/client-common/package.json
- packages/client-node/package.json
- packages/client-web/package.json
+ # Always validate the full skills packaging E2E on pull requests that target
+ # the release branch, regardless of which paths changed, so every release is
+ # gated by the same QA suite as the other test workflows.
+ pull_request:
+ branches:
+ - release
jobs:
skills-packaging:
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 63743dbab..968207041 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -7,27 +7,52 @@ name: "publish"
# The `main` branch is reserved for development and does not publish.
# For both it uses NPM OIDC authentication with provenance support.
#
+# The manual ("latest") trigger takes a required `package` input and runs the
+# matching per-package job, so a single package can be published on its own -
+# for example, a final release of the deprecated `@clickhouse/client-common`.
+# The automatic head publish runs one per-package job for every package (each
+# computes its own `-head..` version from its package.json).
+#
+# Before each Node.js client publish, a smoke test packs the freshly built
+# package into a tarball, installs that tarball into a throwaway app, and runs
+# ESM + CJS checks against it (.scripts/smoke_test_pack.sh). This catches
+# packaging problems before anything reaches npm.
+#
# After a successful publish, the `e2e` job waits for the freshly published
# version to become available on the npm registry, installs that exact
-# version into a tiny downstream project, and verifies it is usable.
+# version into a tiny downstream project, and verifies it is usable. It only
+# runs when `@clickhouse/client` was published (the head job or the client job).
permissions:
contents: read
id-token: write # Required for npm OIDC authentication and provenance
concurrency:
- group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
+ # Scope manual publishes by package so dispatching a release for one package
+ # does not cancel an in-progress release of another. `github.event.inputs` is
+ # empty for the head (push) trigger, so head runs still share a single group.
+ group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-${{ github.event.inputs.package }}
cancel-in-progress: true
on:
# for the latest workflow
workflow_dispatch:
+ inputs:
+ package:
+ description: "Package to publish"
+ required: true
+ type: choice
+ options:
+ - "@clickhouse/client"
+ - "@clickhouse/client-web"
+ # The common package is deprecated, but can still be published on its own.
+ - "@clickhouse/client-common"
# for the head workflow
push:
branches:
- release
# Only run the head publishing workflow when files relevant to the
- # published packages change. The web and node packages depend on the
- # common package, so any change under packages/** triggers an
+ # published packages change. The web and node packages bundle the
+ # common package sources, so any change under packages/** triggers an
# all-or-nothing publish of every package.
paths:
- "packages/**"
@@ -37,16 +62,17 @@ on:
- "README.md"
- "LICENSE"
- "skills/**"
- - ".scripts/update_version.sh"
- ".github/workflows/publish.yml"
jobs:
- head:
+ head_client:
+ name: "Publish @clickhouse/client (head)"
if: github.ref == 'refs/heads/release' && github.event_name == 'push'
runs-on: ubuntu-latest
environment: npm-publish
outputs:
version: ${{ steps.version.outputs.version }}
+ packages: "@clickhouse/client"
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
@@ -63,24 +89,101 @@ jobs:
- name: Set head pre-release version
id: version
run: |
- BASE_VERSION=$(node -p "require('./packages/client-common/package.json').version")
+ BASE_VERSION=$(node -p "require('./packages/client-node/package.json').version")
HEAD_VERSION="${BASE_VERSION}-head.${GITHUB_SHA::7}.${GITHUB_RUN_ATTEMPT}"
echo "Setting version to: $HEAD_VERSION"
- .scripts/update_version.sh "$HEAD_VERSION"
+ npm --workspace @clickhouse/client version --no-git-tag-version "$HEAD_VERSION"
+ echo "export default \"$HEAD_VERSION\";" > packages/client-node/src/version.ts
echo "version=$HEAD_VERSION" >> "$GITHUB_OUTPUT"
- - name: Build packages
- run: npm --workspaces run build
+ - name: Build the package
+ run: npm --workspace @clickhouse/client run build
- - name: Publish packages with head tag
+ - name: Smoke test the packed tarball
+ run: .scripts/smoke_test_pack.sh @clickhouse/client
+
+ - name: Publish @clickhouse/client with head tag
run: |
- npm --workspaces publish \
+ npm --workspace @clickhouse/client publish \
--access public \
--provenance \
--tag head
- latest:
- if: github.ref == 'refs/heads/release' && github.event_name == 'workflow_dispatch'
+ head_client_web:
+ name: "Publish @clickhouse/client-web (head)"
+ if: github.ref == 'refs/heads/release' && github.event_name == 'push'
+ runs-on: ubuntu-latest
+ environment: npm-publish
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+ registry-url: "https://registry.npmjs.org"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Set head pre-release version
+ run: |
+ BASE_VERSION=$(node -p "require('./packages/client-web/package.json').version")
+ HEAD_VERSION="${BASE_VERSION}-head.${GITHUB_SHA::7}.${GITHUB_RUN_ATTEMPT}"
+ echo "Setting version to: $HEAD_VERSION"
+ npm --workspace @clickhouse/client-web version --no-git-tag-version "$HEAD_VERSION"
+ echo "export default \"$HEAD_VERSION\";" > packages/client-web/src/version.ts
+
+ - name: Build the package
+ run: npm --workspace @clickhouse/client-web run build
+
+ - name: Publish @clickhouse/client-web with head tag
+ run: |
+ npm --workspace @clickhouse/client-web publish \
+ --access public \
+ --provenance \
+ --tag head
+
+ head_client_common:
+ name: "Publish @clickhouse/client-common (head)"
+ if: github.ref == 'refs/heads/release' && github.event_name == 'push'
+ runs-on: ubuntu-latest
+ environment: npm-publish
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+ registry-url: "https://registry.npmjs.org"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Set head pre-release version
+ run: |
+ BASE_VERSION=$(node -p "require('./packages/client-common/package.json').version")
+ HEAD_VERSION="${BASE_VERSION}-head.${GITHUB_SHA::7}.${GITHUB_RUN_ATTEMPT}"
+ echo "Setting version to: $HEAD_VERSION"
+ npm --workspace @clickhouse/client-common version --no-git-tag-version "$HEAD_VERSION"
+ echo "export default \"$HEAD_VERSION\";" > packages/client-common/src/version.ts
+
+ - name: Build the package
+ run: npm --workspace @clickhouse/client-common run build
+
+ - name: Publish @clickhouse/client-common with head tag
+ run: |
+ npm --workspace @clickhouse/client-common publish \
+ --access public \
+ --provenance \
+ --tag head
+
+ publish_client:
+ name: "Publish @clickhouse/client"
+ if: github.ref == 'refs/heads/release' && github.event_name == 'workflow_dispatch' && inputs.package == '@clickhouse/client'
runs-on: ubuntu-latest
environment: npm-publish
permissions:
@@ -88,6 +191,7 @@ jobs:
id-token: write # Required for npm OIDC authentication and provenance
outputs:
version: ${{ steps.version.outputs.version }}
+ packages: "@clickhouse/client"
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
@@ -104,40 +208,125 @@ jobs:
- name: Get the release version
id: version
run: |
- BASE_VERSION=$(node -p "require('./packages/client-common/package.json').version")
+ BASE_VERSION=$(node -p "require('./packages/client-node/package.json').version")
echo "Using version: $BASE_VERSION"
echo "version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
- - name: Build packages
- run: npm --workspaces run build
+ - name: Build the package
+ run: npm --workspace @clickhouse/client run build
+
+ - name: Smoke test the packed tarball
+ run: .scripts/smoke_test_pack.sh @clickhouse/client
- - name: Publish packages to the latest tag (implicit)
+ - name: Publish @clickhouse/client to the latest tag (implicit)
run: |
- npm --workspaces publish \
+ npm --workspace @clickhouse/client publish \
--access public \
--provenance
- name: Create and push release git tag
env:
RELEASE_VERSION: ${{ steps.version.outputs.version }}
+ run: .scripts/push_release_tag.sh "client-${RELEASE_VERSION}"
+
+ publish_client_web:
+ name: "Publish @clickhouse/client-web"
+ if: github.ref == 'refs/heads/release' && github.event_name == 'workflow_dispatch' && inputs.package == '@clickhouse/client-web'
+ runs-on: ubuntu-latest
+ environment: npm-publish
+ permissions:
+ contents: write # Required to push the release git tag
+ id-token: write # Required for npm OIDC authentication and provenance
+ outputs:
+ version: ${{ steps.version.outputs.version }}
+ packages: "@clickhouse/client-web"
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+ registry-url: "https://registry.npmjs.org"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Get the release version
+ id: version
run: |
- if git ls-remote --exit-code --tags origin "refs/tags/${RELEASE_VERSION}" >/dev/null 2>&1; then
- echo "Tag ${RELEASE_VERSION} already exists on origin; skipping."
- exit 0
- fi
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git tag -a "${RELEASE_VERSION}" -m "Release ${RELEASE_VERSION}"
- git push origin "refs/tags/${RELEASE_VERSION}"
+ BASE_VERSION=$(node -p "require('./packages/client-web/package.json').version")
+ echo "Using version: $BASE_VERSION"
+ echo "version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
+
+ - name: Build the package
+ run: npm --workspace @clickhouse/client-web run build
+
+ - name: Publish @clickhouse/client-web to the latest tag (implicit)
+ run: |
+ npm --workspace @clickhouse/client-web publish \
+ --access public \
+ --provenance
+
+ - name: Create and push release git tag
+ env:
+ RELEASE_VERSION: ${{ steps.version.outputs.version }}
+ run: .scripts/push_release_tag.sh "client-web-${RELEASE_VERSION}"
+
+ publish_client_common:
+ name: "Publish @clickhouse/client-common (deprecated)"
+ if: github.ref == 'refs/heads/release' && github.event_name == 'workflow_dispatch' && inputs.package == '@clickhouse/client-common'
+ runs-on: ubuntu-latest
+ environment: npm-publish
+ permissions:
+ contents: write # Required to push the release git tag
+ id-token: write # Required for npm OIDC authentication and provenance
+ outputs:
+ version: ${{ steps.version.outputs.version }}
+ packages: "@clickhouse/client-common"
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+
+ - name: Setup Node.js
+ uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 24
+ registry-url: "https://registry.npmjs.org"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Get the release version
+ id: version
+ run: |
+ BASE_VERSION=$(node -p "require('./packages/client-common/package.json').version")
+ echo "Using version: $BASE_VERSION"
+ echo "version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
+
+ - name: Build the package
+ run: npm --workspace @clickhouse/client-common run build
+
+ - name: Publish @clickhouse/client-common to the latest tag (implicit)
+ run: |
+ npm --workspace @clickhouse/client-common publish \
+ --access public \
+ --provenance
+
+ - name: Create and push release git tag
+ env:
+ RELEASE_VERSION: ${{ steps.version.outputs.version }}
+ run: .scripts/push_release_tag.sh "client-common-${RELEASE_VERSION}"
e2e:
name: e2e (node ${{ matrix.node }})
- needs: [head, latest]
- # Run when at least one of the publish jobs succeeded. The other one is
- # skipped (not failed) by its `if:` condition for this trigger.
+ needs: [head_client, publish_client]
+ # The e2e project imports `@clickhouse/client`, so it only runs when the
+ # Node.js client was published - either via the head job or the client job.
if: |
always() &&
- (needs.head.result == 'success' || needs.latest.result == 'success')
+ (needs.head_client.result == 'success' || needs.publish_client.result == 'success')
runs-on: ubuntu-latest
strategy:
fail-fast: true
@@ -147,7 +336,8 @@ jobs:
run:
working-directory: tests/e2e/install
env:
- PUBLISHED_VERSION: ${{ needs.head.outputs.version || needs.latest.outputs.version }}
+ PUBLISHED_VERSION: ${{ needs.head_client.outputs.version || needs.publish_client.outputs.version }}
+ PUBLISHED_PACKAGES: ${{ needs.head_client.outputs.packages || needs.publish_client.outputs.packages }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
@@ -157,18 +347,18 @@ jobs:
node-version: ${{ matrix.node }}
registry-url: "https://registry.npmjs.org"
- - name: Wait for ${{ needs.head.outputs.version || needs.latest.outputs.version }} to be available on npm
+ - name: Wait for ${{ env.PUBLISHED_VERSION }} to be available on npm
run: |
set -euo pipefail
if [ -z "${PUBLISHED_VERSION}" ]; then
echo "PUBLISHED_VERSION is empty; cannot wait for npm publication." >&2
exit 1
fi
- packages=(
- "@clickhouse/client-common"
- "@clickhouse/client"
- "@clickhouse/client-web"
- )
+ if [ -z "${PUBLISHED_PACKAGES}" ]; then
+ echo "PUBLISHED_PACKAGES is empty; cannot wait for npm publication." >&2
+ exit 1
+ fi
+ read -r -a packages <<< "${PUBLISHED_PACKAGES}"
# Poll the registry for up to ~5 minutes per package. New versions
# usually surface in seconds, but the registry CDN can lag.
max_attempts=60
@@ -196,10 +386,13 @@ jobs:
- name: Install the packages at the published version
run: |
- npm install \
- "@clickhouse/client@${PUBLISHED_VERSION}" \
- "@clickhouse/client-common@${PUBLISHED_VERSION}" \
- "@clickhouse/client-web@${PUBLISHED_VERSION}"
+ set -euo pipefail
+ read -r -a packages <<< "${PUBLISHED_PACKAGES}"
+ specs=()
+ for pkg in "${packages[@]}"; do
+ specs+=("${pkg}@${PUBLISHED_VERSION}")
+ done
+ npm install "${specs[@]}"
- name: Type check
run: npx tsc --noEmit
diff --git a/.scripts/push_release_tag.sh b/.scripts/push_release_tag.sh
new file mode 100755
index 000000000..e05500566
--- /dev/null
+++ b/.scripts/push_release_tag.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Create and push an annotated release git tag, skipping if it already exists
+# on origin. Single-package releases use a package-scoped tag (e.g.
+# `client-web-1.2.3`) so they do not collide with the shared release tag.
+
+set -euo pipefail
+
+tag=${1:-}
+if [ -z "$tag" ]; then
+ echo "Usage: $0 " >&2
+ exit 1
+fi
+
+if git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null 2>&1; then
+ echo "Tag ${tag} already exists on origin; skipping."
+ exit 0
+fi
+
+git config user.name "github-actions[bot]"
+git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+git tag -a "${tag}" -m "Release ${tag}"
+git push origin "refs/tags/${tag}"
diff --git a/.scripts/smoke_test_pack.sh b/.scripts/smoke_test_pack.sh
new file mode 100755
index 000000000..33c217f34
--- /dev/null
+++ b/.scripts/smoke_test_pack.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+#
+# Pre-publish smoke test.
+#
+# Packs an already-built workspace into a tarball, installs that tarball into a
+# throwaway app (install-from-artifact only, exactly as a downstream consumer
+# would), and runs ESM + CJS checks against it. This catches packaging problems
+# - missing files, broken exports, unexpected transitive deps - before the
+# package is published to npm, rather than after.
+#
+# Usage: .scripts/smoke_test_pack.sh [workspace]
+# workspace defaults to @clickhouse/client.
+#
+# Run from the repository root, after `npm run build` (or a per-workspace build).
+set -euo pipefail
+
+WORKSPACE="${1:-@clickhouse/client}"
+REPO="$(pwd)"
+SMOKE_DIR="$REPO/tests/e2e/smoke"
+
+APP="$(mktemp -d)/smoke-app"
+mkdir -p "$APP"
+# Clean up the throwaway app even if a check fails.
+trap 'rm -rf "$(dirname "$APP")"' EXIT
+
+TARBALL="$(npm pack -w "$WORKSPACE" --pack-destination "$APP" --json \
+ | node -e "console.log(JSON.parse(require('fs').readFileSync(0))[0].filename)")"
+echo "Packed $WORKSPACE -> $TARBALL"
+
+cp "$SMOKE_DIR/check.mjs" "$SMOKE_DIR/check.cjs" "$APP/"
+cd "$APP"
+npm init -y >/dev/null
+npm install "./$TARBALL"
+
+echo "--- installed @clickhouse packages ---"
+ls node_modules/@clickhouse/
+
+echo "--- ESM check ---"
+node check.mjs
+echo "--- CJS check ---"
+node check.cjs
+
+cd "$REPO"
+echo "Smoke test passed for $WORKSPACE."
diff --git a/.scripts/update_version.sh b/.scripts/update_version.sh
deleted file mode 100755
index 7f4ca3278..000000000
--- a/.scripts/update_version.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-version=${1:-}
-if [ -z "$version" ]; then
- echo "Usage: $0 "
- exit 1
-fi
-
-echo "Setting the version to: $version"
-
-for package in packages/client-node packages/client-web; do
- if [ -f "$package/package.json" ]; then
- echo "Updating client-common version in $package/package.json"
- json=$(cat "$package/package.json")
- echo "$json" | jq --arg version "$version" '.dependencies["@clickhouse/client-common"] = $version' > "$package/package.json"
- fi
-done
-
-for package in packages/client-common packages/client-node packages/client-web; do
- if [ -f "$package/package.json" ]; then
- echo "Updating version in $package/src/version.ts"
- echo "export default \"$version\";" > "$package/src/version.ts"
- fi
-done
-
-npm --workspaces version --no-git-tag-version "$version"
diff --git a/AGENTS.md b/AGENTS.md
index 01ff68904..a24d8cf5e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -29,6 +29,10 @@ The source packages under [`packages/`](packages) are:
- `client-common` — platform-agnostic shared code (config, query-param formatting, multipart
assembly, URL handling, result sets, etc.). It must not depend on Node.js-only or Web-only APIs.
+ The published `@clickhouse/client-common` package is **deprecated**: `client-node` and `client-web`
+ no longer depend on it and instead bundle its sources via the `src/common` symlink
+ (`packages/client-node/src/common` and `packages/client-web/src/common` both point to
+ `packages/client-common/src`), importing from it with relative paths (e.g. `./common/index`).
- `client-node` (`@clickhouse/client`) — the Node.js client.
- `client-web` (`@clickhouse/client-web`) — the Web/edge client.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a30fc3a0b..3140c1a67 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# 1.23.0
+## Migration Notes
+
+- The `@clickhouse/client-common` package is deprecated. `@clickhouse/client` (Node.js) and `@clickhouse/client-web` (Web) no longer depend on it; the shared code is now bundled into each client package. Everything previously importable from `@clickhouse/client-common` should be imported from `@clickhouse/client` or `@clickhouse/client-web` instead. The `@clickhouse/client-common` package itself will no longer receive updates. ([#845])
+
## New features
- (Node.js) Added a RowBinary reader library and agent skill under [`skills/clickhouse-js-node-rowbinary-parser`](./skills/clickhouse-js-node-rowbinary-parser). It ships type-specific, monomorphizable building blocks for decoding `RowBinary` / `RowBinaryWithNames` / `RowBinaryWithNamesAndTypes` streams (full-buffer and chunked), plus a skill that guides an agent to generate bespoke high-performance parsers from a query's column types. The skill is bundled into `@clickhouse/client` (registered in `agents.skills`) and is also published independently as the [`@clickhouse/rowbinary`](https://www.npmjs.com/package/@clickhouse/rowbinary) package. A matching RowBinary writer is planned. ([#864])
@@ -70,6 +74,7 @@ await client.query({
[#825]: https://github.com/ClickHouse/clickhouse-js/pull/825
[#827]: https://github.com/ClickHouse/clickhouse-js/pull/827
[#828]: https://github.com/ClickHouse/clickhouse-js/pull/828
+[#845]: https://github.com/ClickHouse/clickhouse-js/pull/845
[#864]: https://github.com/ClickHouse/clickhouse-js/pull/864
## Bug Fixes
diff --git a/RELEASING.md b/RELEASING.md
index a5c9d9274..f1ffa5f6d 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -1,44 +1,28 @@
# Release process
-Tools required:
+Tools required (for verifying a published build and promoting npm tags locally):
- Node.js >= `20.x`
-- NPM >= `11.x`
-- jq (https://stedolan.github.io/jq/)
+- npm >= `11.x` — newer than the npm bundled with Node.js `20.x`/`22.x` (`10.x`). Either upgrade npm in place (`npm install -g npm@latest`) or use Node.js `24.x`, which already ships npm `11.x`.
-We prefer to keep versions the same across the packages, and release all at once, even if there were no changes in some.
+Packages are versioned and released independently. Release one package at a time; to release several, repeat the steps below for each. Versions are bumped through the GitHub Actions workflows — there is no local version-bump script.
-Bump the version:
+## Bump the version
-```bash
-# get the current version
-cat packages/client-common/package.json | grep '"version":'
-# update the version appropriately and set it to the environment variable
-export NEW_VERSION=[new_version]
-```
+Run the [`bump-version`](.github/workflows/bump-version.yml) workflow from the GitHub Actions tab. Select:
-Make sure that the working directory is up to date and clean:
+- `package` — the package to release: `@clickhouse/client`, `@clickhouse/client-web`, or `@clickhouse/client-common` (the last is deprecated, but can still be cut a final standalone release).
+- `bump_type` — `patch`, `minor`, or `major`.
-```bash
-git checkout main
-git pull
-git clean -dfX
-```
+The workflow computes the next version, bumps that package's `package.json` and `src/version.ts`, and opens a release PR against `main`.
-```bash
-git checkout -b release-$NEW_VERSION
-.scripts/update_version.sh "$NEW_VERSION"
-```
+Review and merge the PR into `main`.
-Commit the version update and push it to the repository:
+## Publish the `head` build
-```bash
-git add .
-git commit -m "chore: bump version to $NEW_VERSION"
-git push -u origin release-$NEW_VERSION
-```
+The signed `head` build is published by the [`publish`](.github/workflows/publish.yml) workflow on push to the long-lived `release` branch — not on merge to `main`. After the bump PR is merged, update `release` from `main` (open a PR from `main` into `release` and merge it). That push triggers the `head` publish for every package.
-Create a PR and merge it. Wait for the CI/CD pipeline to publish a signed `head` version.
+## Test the `head` build
After the package is published it can be tested in a separate project by installing it with the `head` tag:
@@ -48,16 +32,24 @@ npm install @clickhouse/client@head
and run a simple e2e test: https://github.com/ClickHouse/clickhouse-js/actions/workflows/npm.yml
-Promote the `head` tag to `latest`:
+## Promote the `head` tag to `latest`
+
+Run this for the package(s) you released:
```bash
-npm dist-tag add @clickhouse/client-common@head latest
npm dist-tag add @clickhouse/client@head latest
npm dist-tag add @clickhouse/client-web@head latest
+npm dist-tag add @clickhouse/client-common@head latest
+```
+
+Mark the deprecated `@clickhouse/client-common` package as such on npm (it is no longer used by `@clickhouse/client` or `@clickhouse/client-web`; the shared code is bundled into each client package):
+
+```bash
+npm deprecate @clickhouse/client-common "This package is deprecated and no longer used by @clickhouse/client or @clickhouse/client-web. Import everything from @clickhouse/client (Node.js) or @clickhouse/client-web (Web) instead."
```
Check that the packages have been published correctly:
-Then create a new release in GitHub for `$NEW_VERSION` and include the corresponding changelog notes.
+Then create a new release in GitHub for the published version and include the corresponding changelog notes.
All done, thanks!
diff --git a/package-lock.json b/package-lock.json
index 84678bc89..eb4e6e5f0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7199,9 +7199,6 @@
"name": "@clickhouse/client",
"version": "1.23.0",
"license": "Apache-2.0",
- "dependencies": {
- "@clickhouse/client-common": "1.23.0"
- },
"devDependencies": {
"simdjson": "^0.9.2"
},
@@ -7212,10 +7209,7 @@
"packages/client-web": {
"name": "@clickhouse/client-web",
"version": "1.23.0",
- "license": "Apache-2.0",
- "dependencies": {
- "@clickhouse/client-common": "1.23.0"
- }
+ "license": "Apache-2.0"
},
"tests/clickhouse-test-runner": {
"name": "@clickhouse/clickhouse-test-runner",
diff --git a/packages/client-common/package.json b/packages/client-common/package.json
index 10c76ed79..187b11982 100644
--- a/packages/client-common/package.json
+++ b/packages/client-common/package.json
@@ -1,6 +1,6 @@
{
"name": "@clickhouse/client-common",
- "description": "Official JS client for ClickHouse DB - common types",
+ "description": "DEPRECATED: this package is no longer used by @clickhouse/client or @clickhouse/client-web; the shared code is now bundled into each client package. Install @clickhouse/client (Node.js) or @clickhouse/client-web (Web) instead.",
"homepage": "https://clickhouse.com",
"version": "1.23.0",
"license": "Apache-2.0",
diff --git a/packages/client-common/src/index.ts b/packages/client-common/src/index.ts
index 3b86b3989..a3ce616be 100644
--- a/packages/client-common/src/index.ts
+++ b/packages/client-common/src/index.ts
@@ -1,3 +1,12 @@
+/**
+ * @deprecated The `@clickhouse/client-common` package is deprecated. It is no longer used by
+ * `@clickhouse/client` or `@clickhouse/client-web`; the shared code is bundled into each client
+ * package instead. Import everything from `@clickhouse/client` (Node.js) or
+ * `@clickhouse/client-web` (Web) instead.
+ *
+ * @packageDocumentation
+ */
+
/** Should be re-exported by the implementation */
export {
type BaseQueryParams,
diff --git a/packages/client-node/package.json b/packages/client-node/package.json
index bd592db8b..d275b92de 100644
--- a/packages/client-node/package.json
+++ b/packages/client-node/package.json
@@ -47,9 +47,7 @@
"lint:fix": "eslint . --fix",
"build": "rm -rf dist; tsc"
},
- "dependencies": {
- "@clickhouse/client-common": "1.23.0"
- },
+ "dependencies": {},
"devDependencies": {
"simdjson": "^0.9.2"
}
diff --git a/packages/client-node/src/client.ts b/packages/client-node/src/client.ts
index 93f0ef4e1..e57482fc3 100644
--- a/packages/client-node/src/client.ts
+++ b/packages/client-node/src/client.ts
@@ -1,9 +1,5 @@
-import type {
- DataFormat,
- IsSame,
- QueryParamsWithFormat,
-} from "@clickhouse/client-common";
-import { ClickHouseClient } from "@clickhouse/client-common";
+import type { DataFormat, IsSame, QueryParamsWithFormat } from "./common/index";
+import { ClickHouseClient } from "./common/index";
import type Stream from "stream";
import type { NodeClickHouseClientConfigOptions } from "./config";
import { NodeConfigImpl } from "./config";
diff --git a/packages/client-node/src/common b/packages/client-node/src/common
new file mode 120000
index 000000000..d35367737
--- /dev/null
+++ b/packages/client-node/src/common
@@ -0,0 +1 @@
+../../client-common/src
\ No newline at end of file
diff --git a/packages/client-node/src/config.ts b/packages/client-node/src/config.ts
index 2e1a42f2d..ff7e5ffdc 100644
--- a/packages/client-node/src/config.ts
+++ b/packages/client-node/src/config.ts
@@ -4,13 +4,13 @@ import type {
ImplementationDetails,
JSONHandling,
ResponseHeaders,
-} from "@clickhouse/client-common";
+} from "./common/index";
import {
type BaseClickHouseClientConfigOptions,
type CompressionMethod,
type ConnectionParams,
numberConfigURLValue,
-} from "@clickhouse/client-common";
+} from "./common/index";
import type http from "http";
import type https from "node:https";
import type Stream from "stream";
diff --git a/packages/client-node/src/connection/compression.ts b/packages/client-node/src/connection/compression.ts
index 0854bff92..546a9c113 100644
--- a/packages/client-node/src/connection/compression.ts
+++ b/packages/client-node/src/connection/compression.ts
@@ -1,5 +1,5 @@
-import type { LogWriter, RequestCompression } from "@clickhouse/client-common";
-import { ClickHouseLogLevel } from "@clickhouse/client-common";
+import type { LogWriter, RequestCompression } from "../common/index";
+import { ClickHouseLogLevel } from "../common/index";
import type Http from "http";
import Stream from "stream";
import Zlib from "zlib";
diff --git a/packages/client-node/src/connection/create_connection.ts b/packages/client-node/src/connection/create_connection.ts
index 8a8e31ca8..8e3470245 100644
--- a/packages/client-node/src/connection/create_connection.ts
+++ b/packages/client-node/src/connection/create_connection.ts
@@ -1,4 +1,4 @@
-import type { ConnectionParams } from "@clickhouse/client-common";
+import type { ConnectionParams } from "../common/index";
import type http from "http";
import type https from "node:https";
import type {
diff --git a/packages/client-node/src/connection/node_base_connection.ts b/packages/client-node/src/connection/node_base_connection.ts
index 337508ac0..3608ff532 100644
--- a/packages/client-node/src/connection/node_base_connection.ts
+++ b/packages/client-node/src/connection/node_base_connection.ts
@@ -12,7 +12,7 @@ import type {
ConnPingResult,
ConnQueryResult,
ResponseHeaders,
-} from "@clickhouse/client-common";
+} from "../common/index";
import {
buildMultipartBody,
serializeQueryParamsForUrl,
@@ -23,8 +23,8 @@ import {
transformUrl,
withHttpSettings,
ClickHouseLogLevel,
-} from "@clickhouse/client-common";
-import { type ConnPingParams } from "@clickhouse/client-common";
+} from "../common/index";
+import { type ConnPingParams } from "../common/index";
import crypto from "crypto";
import type Http from "http";
import type Https from "node:https";
diff --git a/packages/client-node/src/connection/node_custom_agent_connection.ts b/packages/client-node/src/connection/node_custom_agent_connection.ts
index 6000be525..4d8073044 100644
--- a/packages/client-node/src/connection/node_custom_agent_connection.ts
+++ b/packages/client-node/src/connection/node_custom_agent_connection.ts
@@ -3,7 +3,7 @@ import Https from "https";
import type { NodeConnectionParams } from "./node_base_connection";
import type { RequestParams } from "./socket_pool";
import { NodeBaseConnection } from "./node_base_connection";
-import { withCompressionHeaders } from "@clickhouse/client-common";
+import { withCompressionHeaders } from "../common/index";
export class NodeCustomAgentConnection extends NodeBaseConnection {
private readonly httpRequestFn: typeof Http.request | typeof Https.request;
diff --git a/packages/client-node/src/connection/node_http_connection.ts b/packages/client-node/src/connection/node_http_connection.ts
index 12edaa884..d2071f249 100644
--- a/packages/client-node/src/connection/node_http_connection.ts
+++ b/packages/client-node/src/connection/node_http_connection.ts
@@ -1,4 +1,4 @@
-import { withCompressionHeaders } from "@clickhouse/client-common";
+import { withCompressionHeaders } from "../common/index";
import Http from "http";
import type { NodeConnectionParams } from "./node_base_connection";
import type { RequestParams } from "./socket_pool";
diff --git a/packages/client-node/src/connection/node_https_connection.ts b/packages/client-node/src/connection/node_https_connection.ts
index d9a35319d..3247e8ddb 100644
--- a/packages/client-node/src/connection/node_https_connection.ts
+++ b/packages/client-node/src/connection/node_https_connection.ts
@@ -2,7 +2,7 @@ import {
type ConnBaseQueryParams,
isCredentialsAuth,
withCompressionHeaders,
-} from "@clickhouse/client-common";
+} from "../common/index";
import type Http from "http";
import Https from "https";
import type { NodeConnectionParams } from "./node_base_connection";
diff --git a/packages/client-node/src/connection/socket_pool.ts b/packages/client-node/src/connection/socket_pool.ts
index 6e2a42823..260d35017 100644
--- a/packages/client-node/src/connection/socket_pool.ts
+++ b/packages/client-node/src/connection/socket_pool.ts
@@ -15,7 +15,7 @@ import {
type JSONHandling,
type CompressionMethod,
type RequestCompression,
-} from "@clickhouse/client-common";
+} from "../common/index";
import { getAsText, isStream } from "../utils";
import {
createRequestCompressor,
diff --git a/packages/client-node/src/connection/stream.ts b/packages/client-node/src/connection/stream.ts
index 142689073..9423b1b2c 100644
--- a/packages/client-node/src/connection/stream.ts
+++ b/packages/client-node/src/connection/stream.ts
@@ -2,7 +2,7 @@ import {
type LogWriter,
type ConnOperation,
ClickHouseLogLevel,
-} from "@clickhouse/client-common";
+} from "../common/index";
import type Stream from "stream";
export interface Context {
diff --git a/packages/client-node/src/index.ts b/packages/client-node/src/index.ts
index a73f1a037..ba04008b0 100644
--- a/packages/client-node/src/index.ts
+++ b/packages/client-node/src/index.ts
@@ -7,7 +7,7 @@ export { type NodeClickHouseClientConfigOptions as ClickHouseClientConfigOptions
export { ResultSet, type StreamReadable } from "./result_set";
export { drainStream } from "./connection/stream";
-/** Re-export @clickhouse/client-common types */
+/** Re-export common (formerly @clickhouse/client-common) types */
export {
type BaseClickHouseClientConfigOptions,
type BaseQueryParams,
@@ -61,14 +61,14 @@ export {
type ClickHouseSpanAttributes,
type ClickHouseSpanStatus,
type ClickHouseSpanName,
-} from "@clickhouse/client-common";
+} from "./common/index";
/**
- * Re-export @clickhouse/client-common runtime values.
+ * Re-export common (formerly @clickhouse/client-common) runtime values.
*
* These are intentionally re-exported through local bindings (rather than a direct
- * `export { ... } from '@clickhouse/client-common'`) so that the `@deprecated` JSDoc tags
- * applied to them in `@clickhouse/client-common` are NOT propagated to consumers of this package.
+ * `export { ... } from './common/index'`) so that the `@deprecated` JSDoc tags
+ * applied to them in `./common/index` are NOT propagated to consumers of this package.
* Importing these values from `@clickhouse/client` is the recommended, non-deprecated path.
*/
import {
@@ -92,7 +92,7 @@ import {
ClickHouseSpanStatusCode as ClickHouseSpanStatusCode_,
ClickHouseSpanKind as ClickHouseSpanKind_,
defaultJSONHandling as defaultJSONHandling_,
-} from "@clickhouse/client-common";
+} from "./common/index";
export const ClickHouseError = ClickHouseError_;
export type ClickHouseError = ClickHouseError_;
diff --git a/packages/client-node/src/result_set.ts b/packages/client-node/src/result_set.ts
index 3d97c16ef..6c1f6347c 100644
--- a/packages/client-node/src/result_set.ts
+++ b/packages/client-node/src/result_set.ts
@@ -8,19 +8,19 @@ import type {
ResultJSONType,
ResultStream,
Row,
-} from "@clickhouse/client-common";
+} from "./common/index";
import {
extractErrorAtTheEndOfChunk,
defaultJSONHandling,
EXCEPTION_TAG_HEADER_NAME,
CARET_RETURN,
recordSpanError,
-} from "@clickhouse/client-common";
+} from "./common/index";
import {
isNotStreamableJSONFamily,
isStreamableJSONFamily,
validateStreamFormat,
-} from "@clickhouse/client-common";
+} from "./common/index";
import { Buffer } from "buffer";
import type { Readable, TransformCallback } from "stream";
import Stream, { Transform } from "stream";
diff --git a/packages/client-node/src/utils/encoder.ts b/packages/client-node/src/utils/encoder.ts
index 0bda89e5b..63fc3a082 100644
--- a/packages/client-node/src/utils/encoder.ts
+++ b/packages/client-node/src/utils/encoder.ts
@@ -3,8 +3,8 @@ import type {
InsertValues,
JSONHandling,
ValuesEncoder,
-} from "@clickhouse/client-common";
-import { encodeJSON, isSupportedRawFormat } from "@clickhouse/client-common";
+} from "../common/index";
+import { encodeJSON, isSupportedRawFormat } from "../common/index";
import Stream from "stream";
import { isStream, mapStream } from "./stream";
diff --git a/packages/client-web/package.json b/packages/client-web/package.json
index a25d0a77e..ce37e87e3 100644
--- a/packages/client-web/package.json
+++ b/packages/client-web/package.json
@@ -30,7 +30,5 @@
"lint:fix": "eslint . --fix",
"build": "rm -rf dist; tsc"
},
- "dependencies": {
- "@clickhouse/client-common": "1.23.0"
- }
+ "dependencies": {}
}
diff --git a/packages/client-web/src/client.ts b/packages/client-web/src/client.ts
index 653adeea8..f8cb5697b 100644
--- a/packages/client-web/src/client.ts
+++ b/packages/client-web/src/client.ts
@@ -10,8 +10,8 @@ import type {
InsertResult,
IsSame,
QueryParamsWithFormat,
-} from "@clickhouse/client-common";
-import { ClickHouseClient } from "@clickhouse/client-common";
+} from "./common/index";
+import { ClickHouseClient } from "./common/index";
import type { WebClickHouseClientConfigOptions } from "./config";
import { WebImpl } from "./config";
import type { ResultSet } from "./result_set";
diff --git a/packages/client-web/src/common b/packages/client-web/src/common
new file mode 120000
index 000000000..d35367737
--- /dev/null
+++ b/packages/client-web/src/common
@@ -0,0 +1 @@
+../../client-common/src
\ No newline at end of file
diff --git a/packages/client-web/src/config.ts b/packages/client-web/src/config.ts
index 289e315bc..a5e457b24 100644
--- a/packages/client-web/src/config.ts
+++ b/packages/client-web/src/config.ts
@@ -7,7 +7,7 @@ import type {
ImplementationDetails,
JSONHandling,
ResponseHeaders,
-} from "@clickhouse/client-common";
+} from "./common/index";
import { WebConnection } from "./connection";
import { ResultSet } from "./result_set";
import { WebValuesEncoder } from "./utils";
diff --git a/packages/client-web/src/connection/web_connection.ts b/packages/client-web/src/connection/web_connection.ts
index 6ea633c71..3698059be 100644
--- a/packages/client-web/src/connection/web_connection.ts
+++ b/packages/client-web/src/connection/web_connection.ts
@@ -8,7 +8,7 @@ import type {
ConnPingResult,
ConnQueryResult,
ResponseHeaders,
-} from "@clickhouse/client-common";
+} from "../common/index";
import {
buildMultipartBody,
serializeQueryParamsForUrl,
@@ -21,7 +21,7 @@ import {
transformUrl,
withCompressionHeaders,
withHttpSettings,
-} from "@clickhouse/client-common";
+} from "../common/index";
import { getAsText } from "../utils";
type WebInsertParams = Omit<
diff --git a/packages/client-web/src/index.ts b/packages/client-web/src/index.ts
index b283af44b..6cd07a9e7 100644
--- a/packages/client-web/src/index.ts
+++ b/packages/client-web/src/index.ts
@@ -6,7 +6,7 @@ export { createClient } from "./client";
export { type WebClickHouseClientConfigOptions as ClickHouseClientConfigOptions } from "./config";
export { ResultSet } from "./result_set";
-/** Re-export @clickhouse/client-common types */
+/** Re-export common (formerly @clickhouse/client-common) types */
export {
type BaseClickHouseClientConfigOptions,
type BaseQueryParams,
@@ -60,14 +60,14 @@ export {
type ClickHouseSpanAttributes,
type ClickHouseSpanStatus,
type ClickHouseSpanName,
-} from "@clickhouse/client-common";
+} from "./common/index";
/**
- * Re-export @clickhouse/client-common runtime values.
+ * Re-export common (formerly @clickhouse/client-common) runtime values.
*
* These are intentionally re-exported through local bindings (rather than a direct
- * `export { ... } from '@clickhouse/client-common'`) so that the `@deprecated` JSDoc tags
- * applied to them in `@clickhouse/client-common` are NOT propagated to consumers of this package.
+ * `export { ... } from './common/index'`) so that the `@deprecated` JSDoc tags
+ * applied to them in `./common/index` are NOT propagated to consumers of this package.
* Importing these values from `@clickhouse/client-web` is the recommended, non-deprecated path.
*/
import {
@@ -91,7 +91,7 @@ import {
ClickHouseSpanStatusCode as ClickHouseSpanStatusCode_,
ClickHouseSpanKind as ClickHouseSpanKind_,
defaultJSONHandling as defaultJSONHandling_,
-} from "@clickhouse/client-common";
+} from "./common/index";
export const ClickHouseError = ClickHouseError_;
export type ClickHouseError = ClickHouseError_;
diff --git a/packages/client-web/src/result_set.ts b/packages/client-web/src/result_set.ts
index 3c57cbd7e..8a1fb1578 100644
--- a/packages/client-web/src/result_set.ts
+++ b/packages/client-web/src/result_set.ts
@@ -8,17 +8,17 @@ import type {
ResultJSONType,
ResultStream,
Row,
-} from "@clickhouse/client-common";
+} from "./common/index";
import {
CARET_RETURN,
extractErrorAtTheEndOfChunk,
recordSpanError,
-} from "@clickhouse/client-common";
+} from "./common/index";
import {
isNotStreamableJSONFamily,
isStreamableJSONFamily,
validateStreamFormat,
-} from "@clickhouse/client-common";
+} from "./common/index";
import { getAsText } from "./utils";
const NEWLINE = 0x0a as const;
diff --git a/packages/client-web/src/utils/encoder.ts b/packages/client-web/src/utils/encoder.ts
index b4f7b3a6b..4901035a5 100644
--- a/packages/client-web/src/utils/encoder.ts
+++ b/packages/client-web/src/utils/encoder.ts
@@ -1,9 +1,5 @@
-import type {
- DataFormat,
- InsertValues,
- ValuesEncoder,
-} from "@clickhouse/client-common";
-import { encodeJSON, type JSONHandling } from "@clickhouse/client-common";
+import type { DataFormat, InsertValues, ValuesEncoder } from "../common/index";
+import { encodeJSON, type JSONHandling } from "../common/index";
import { isStream } from "./stream";
export class WebValuesEncoder implements ValuesEncoder {
diff --git a/tests/e2e/smoke/check.cjs b/tests/e2e/smoke/check.cjs
new file mode 100644
index 000000000..024016fb5
--- /dev/null
+++ b/tests/e2e/smoke/check.cjs
@@ -0,0 +1,25 @@
+// Pre-publish smoke test (CommonJS).
+//
+// Same intent as check.mjs, but resolves the package via `require()` to cover
+// the CJS entry point of the published artifact.
+const assert = require("node:assert");
+const {
+ parseColumnType,
+ SettingsMap,
+ ClickHouseError,
+} = require("@clickhouse/client");
+
+const t = parseColumnType("Array(String)");
+console.log('parseColumnType("Array(String)") =>', JSON.stringify(t));
+assert.strictEqual(t.type, "Array");
+assert.strictEqual(t.value.columnType, "String");
+
+const sm = SettingsMap.from({ max_block_size: "1000" });
+console.log("SettingsMap.toString() =>", sm.toString());
+assert.strictEqual(typeof sm.toString(), "string");
+
+assert.strictEqual(typeof ClickHouseError, "function");
+
+console.log(
+ "OK (CJS): all common-origin imports resolved and executed from the installed package",
+);
diff --git a/tests/e2e/smoke/check.mjs b/tests/e2e/smoke/check.mjs
new file mode 100644
index 000000000..b5dc82a5c
--- /dev/null
+++ b/tests/e2e/smoke/check.mjs
@@ -0,0 +1,28 @@
+// Pre-publish smoke test (ESM).
+//
+// Imports symbols that originate in the (now bundled) `common` sources and are
+// re-exported from `@clickhouse/client` via `./common/index`. Exercising them
+// from a tarball install proves the bundled common code is compiled into the
+// published artifact and usable by consumers - without `@clickhouse/client-common`
+// as a runtime dependency.
+import {
+ parseColumnType,
+ SettingsMap,
+ ClickHouseError,
+} from "@clickhouse/client";
+import assert from "node:assert";
+
+const t = parseColumnType("Nullable(UInt64)");
+console.log('parseColumnType("Nullable(UInt64)") =>', JSON.stringify(t));
+assert.strictEqual(t.type, "Nullable");
+assert.strictEqual(t.value.columnType, "UInt64");
+
+const sm = SettingsMap.from({ max_block_size: "1000" });
+console.log("SettingsMap.toString() =>", sm.toString());
+assert.strictEqual(typeof sm.toString(), "string");
+
+assert.strictEqual(typeof ClickHouseError, "function");
+
+console.log(
+ "OK (ESM): all common-origin imports resolved and executed from the installed package",
+);