Skip to content

Build without the optional mysql2 and sqlite3 drivers - #580

Merged
GermanBluefox merged 1 commit into
masterfrom
fix/optional-driver-types
Oct 3, 2026
Merged

GermanBluefox merged 1 commit into
masterfrom
fix/optional-driver-types

Conversation

@GermanBluefox

Copy link
Copy Markdown
Contributor

The DB drivers are optionalDependencies and are import()ed lazily, so a missing one is meant to degrade to a log message. The build was stricter than the runtime: import type { Database } from 'sqlite3' makes TypeScript resolve the package while type checking, and so does import('sqlite3') — even though that specifier is only ever evaluated at runtime. Both fail with TS2307 when the driver is absent.

Not hypothetical: adapter-tests-sqlite (24.x, macos-latest) failed exactly this way on #578. npm skipped 38 optional packages on that runner (sqlite3, cpu-features, diskusage, unix-dgram and their trees) with nothing but a warning — 631 packages installed instead of 669 — and npm run build:ts then died:

src/lib/sqlite3-client.ts(5,31): error TS2307: Cannot find module 'sqlite3' or its corresponding type declarations.
src/lib/sqlite3-client.ts(16,25): error TS2307: Cannot find module 'sqlite3' or its corresponding type declarations.

What breaks, measured

Removing one driver at a time from node_modules and running tsc:

driver removed result
sqlite3 2 errors (sqlite3-client.ts:5, :16)
mysql2 3 errors (connection-options.ts:1, mysql-client.ts:5, :13)
mssql ok
pg ok

Only the two drivers that ship their types inside the package break. pg and mssql are covered by @types/pg and @types/mssql, which are regular devDependencies and therefore always installed.

The change

src/lib/optional-drivers.ts declares the sliver of mysql2 and sqlite3 this adapter actually touches — Database.close/.all, the two new Database(...) overloads, Connection.end, and the connection options we set — plus importDriver(), which routes the specifier through a string so the type checker cannot resolve it either.

The emitted code is unchanged in substance:

void (0, optional_drivers_1.importDriver)('sqlite3').then(sqlite3 => { ... })
...
function importDriver(name) { return import(name); }

Verification

  • tsc succeeds with all four drivers absent, and with each one absent individually.
  • Runtime unchanged: opening an in-memory SQLite database, running SELECT 42, sqlite_version() and closing it all still work.
  • The degradation path still holds — with sqlite3 removed, openConnection reports Node.js DB driver "sqlite3" could not be loaded: ERR_MODULE_NOT_FOUND instead of crashing.
  • check:ts and lint (root and src-admin) clean, 195 unit tests passing.

Verified in a checkout outside C:\pWork, because a stray package.json/node_modules there makes every driver resolve from an ancestor directory and hides exactly this class of problem.

🤖 Generated with Claude Code

The drivers are optionalDependencies and are import()ed lazily, so a
missing one is supposed to degrade to a log message. The build was
stricter than the runtime: `import type { Database } from 'sqlite3'`
makes TypeScript resolve the package while type checking, and so does
`import('sqlite3')`, even though that specifier is only evaluated at
runtime. Both fail with TS2307 when the driver is absent.

That is not hypothetical - adapter-tests-sqlite (24.x, macos-latest)
failed exactly this way on #578: npm skipped 38 optional packages on
that runner (sqlite3, cpu-features, diskusage, unix-dgram and their
trees) with nothing but a warning, and `npm run build:ts` then died on
sqlite3-client.ts lines 5 and 16.

Measured, one driver removed at a time:

    without sqlite3   2 errors (sqlite3-client.ts:5, :16)
    without mysql2    3 errors (connection-options.ts:1, mysql-client.ts:5, :13)
    without mssql     ok
    without pg        ok

Only the two drivers that ship their types inside the package break;
`pg` and `mssql` are covered by @types/pg and @types/mssql, which are
regular devDependencies and therefore always installed.

src/lib/optional-drivers.ts now declares the sliver of mysql2 and
sqlite3 this adapter actually touches, and importDriver() routes the
specifier through a `string` so the type checker cannot resolve it
either. The emitted code is unchanged in substance - `import(name)`
instead of `import('sqlite3')` - and tsc now succeeds with all four
drivers absent. Verified at runtime too: opening an in-memory SQLite
database, querying it and closing it still works, and a removed driver
still reports `Node.js DB driver "sqlite3" could not be loaded`
instead of crashing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@GermanBluefox
GermanBluefox merged commit a6f1d01 into master Oct 3, 2026
17 checks passed
@GermanBluefox
GermanBluefox deleted the fix/optional-driver-types branch October 3, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant