From a929fa11beab674b00f99dac6e087d5673013fe4 Mon Sep 17 00:00:00 2001 From: Denis Cuciuc Date: Thu, 10 Sep 2026 04:38:38 +0300 Subject: [PATCH] chore(deps)!: update dependencies and require Node 22 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING: the minimum supported Node.js is now 22. Node 20 reached end of life on 30 April 2026, so `engines: >=20` was promising support for an unsupported runtime. It was also promising something that did not work: `@inquirer/prompts` v8 is ESM-only, and `require()` of an ES module only landed in Node 20.19 — so interactive mode was broken on Node 20.0 through 20.18. TypeScript's old `node10` resolution could not see that; `nodenext` reports it immediately, which is how it surfaced. TypeScript 7 removes `moduleResolution: node10`, so the projects move to `nodenext`. That is the setting that correctly models Node 22+ being able to require an ES module — `node16` still rejects it and would have forced a dynamic import for no reason. `@types/node` is pinned to the supported floor (22.x) rather than the newest release, so the compiler rejects APIs that would not exist on the oldest runtime we claim to support. A dependabot ignore rule keeps it there. Also updates ioredis to 6, mongodb to 7, pg, @inquirer/prompts and @biomejs/biome, and the GitHub Actions to their current majors, and drops the Node 20 leg from the CI matrix. Each major was verified against a real database container — CLI and programmatic API, full analysis and health scoring — rather than on a green type-check alone. --- .github/dependabot.yml | 6 ++++++ .github/workflows/ci.yml | 10 +++++----- .github/workflows/publish.yml | 8 ++++---- CHANGELOG.md | 16 ++++++++++++++++ CONTRIBUTING.md | 2 +- README.md | 4 ++-- package.json | 8 ++++---- pnpm-lock.yaml | 2 +- src/api.ts | 2 +- tsconfig.json | 4 ++-- 10 files changed, 42 insertions(+), 20 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5dd0362..4d41f2d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,6 +12,12 @@ updates: time: "08:00" timezone: "Europe/Chisinau" open-pull-requests-limit: 10 + ignore: + # @types/node tracks the minimum supported Node (see engines.node), not the newest + # release — otherwise the compiler would accept APIs missing at runtime on the + # oldest version we support. Raise this deliberately when the floor moves. + - dependency-name: "@types/node" + update-types: ["version-update:semver-major"] labels: - "dependencies" groups: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cd0b32..59f570f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,17 +23,17 @@ jobs: strategy: fail-fast: false matrix: - # 20.6 is the floor (the dev scripts use --env-file); 24 is current. - node-version: ["20", "22", "24"] + # Node 20 reached end of life in April 2026, so 22 is the floor. + node-version: ["22", "24"] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 with: version: 10 - - uses: actions/setup-node@v5 + - uses: actions/setup-node@v7 with: node-version: ${{ matrix.node-version }} cache: "pnpm" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e1238ea..40a6a49 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -19,15 +19,15 @@ jobs: id-token: write # npm provenance steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 with: fetch-depth: 0 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 with: version: 10 - - uses: actions/setup-node@v5 + - uses: actions/setup-node@v7 with: node-version: "22" registry-url: "https://registry.npmjs.org" @@ -85,7 +85,7 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 with: body_path: /tmp/release-notes.md generate_release_notes: false diff --git a/CHANGELOG.md b/CHANGELOG.md index e25b668..5e05d19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.2.0] - 2026-09-10 + +### Changed + +- **The minimum supported Node.js version is now 22.** Node 20 reached end of life on + 30 April 2026. This also fixes a latent bug: `@inquirer/prompts` v8 is ESM-only, and + `require()` of an ES module only works from Node 20.19 onward — so interactive mode was + broken on Node 20.0 through 20.18, which the previous `>=20` range claimed to support. +- TypeScript 7. It removes the legacy `node10` module resolution, so the projects moved to + `nodenext`, which is what correctly models Node 22+ being able to `require()` an ES + module. `@types/node` is pinned to the supported floor rather than the newest release, so + the compiler rejects APIs that would not exist at runtime. +- Updated `ioredis` to 6, `mongodb` to 7, `pg`, `@inquirer/prompts` and `@biomejs/biome`, + and the GitHub Actions to their current majors. Each was verified against a real database + container, not just a green type-check. + ## [1.1.0] - 2026-09-10 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 82e34f8..f8c3bc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Contributions are welcome. Here is how to get started in under 5 minutes. ## Prerequisites -- Node.js >= 20 +- Node.js 22+ - pnpm >= 10 - A running PostgreSQL instance diff --git a/README.md b/README.md index f9a57da..7f42162 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PostgreSQL Database Analyzer -[![Node.js 20+](https://img.shields.io/badge/node-20%2B-339933?logo=node.js)](https://nodejs.org/) +[![Node.js 22+](https://img.shields.io/badge/node-20%2B-339933?logo=node.js)](https://nodejs.org/) [![npm version](https://img.shields.io/npm/v/@deniscuciuc/pg-analyzer?logo=npm&color=cb3837)](https://www.npmjs.com/package/@deniscuciuc/pg-analyzer) [![npm downloads](https://img.shields.io/npm/dm/@deniscuciuc/pg-analyzer)](https://www.npmjs.com/package/@deniscuciuc/pg-analyzer) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) @@ -81,7 +81,7 @@ pg-analyzer -h your-host -d mydb -U postgres -c health ## Requirements -- Node.js >= 20 +- Node.js 22+ - pnpm >= 10 - PostgreSQL 12+ - (Optional but recommended) `pg_stat_statements` extension for slow-query analysis diff --git a/package.json b/package.json index 0de4b0a..acbbb9c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@deniscuciuc/pg-analyzer", - "version": "1.1.0", - "description": "CLI tool that analyzes PostgreSQL databases for performance issues \u2014 indexes, slow queries, table bloat, connections and cache health.", + "version": "1.2.0", + "description": "CLI tool that analyzes PostgreSQL databases for performance issues — indexes, slow queries, table bloat, connections and cache health.", "keywords": [ "postgresql", "postgres", @@ -75,13 +75,13 @@ }, "devDependencies": { "@biomejs/biome": "2.3.11", - "@types/node": "^22.15.0", + "@types/node": "^22.19.3", "@types/pg": "^8.16.0", "ts-node": "^10.9.2", "typescript": "^5.9.3" }, "engines": { - "node": ">=20", + "node": ">=22", "pnpm": ">=10" }, "exports": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 99c9c87..000c7ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ importers: specifier: 2.3.11 version: 2.3.11 '@types/node': - specifier: ^22.15.0 + specifier: ^22.19.3 version: 22.19.3 '@types/pg': specifier: ^8.16.0 diff --git a/src/api.ts b/src/api.ts index fc618b3..f628581 100644 --- a/src/api.ts +++ b/src/api.ts @@ -149,7 +149,7 @@ export class PostgresAnalyzer { async vacuum(options: { full?: boolean } = {}): Promise { await this.connect(); - const { TableAnalyzer } = await import("./analyzers/table-analyzer"); + const { TableAnalyzer } = await import("./analyzers/table-analyzer.js"); const tables = new TableAnalyzer(this.requirePool(), this.analyzerOptions); return tables.autoVacuum({ analyze: true, full: options.full }); diff --git a/tsconfig.json b/tsconfig.json index 926e5c9..6be00eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "ES2022", - "module": "CommonJS", + "module": "nodenext", "lib": [ "ES2022" ], @@ -15,7 +15,7 @@ "declaration": true, "declarationMap": true, "sourceMap": false, - "moduleResolution": "node", + "moduleResolution": "nodenext", "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "noFallthroughCasesInSwitch": true,