Zap: fast mysqljs/mysql compatible mysql driver for node.js
# MySQL2 โ Type Architecture
Internal structure of the `.d.ts` files in `/typings`: how the types are organized, connected, and composed.
A โ ๏ธ marks a spot where the declarations do not match the runtime. This file records the symptom only. [`gaps.md`](gaps.md) owns what each hole is, which tests hit it, and how to close it.
---
## 1. Mixin Pattern
`Connection` and `Pool` get `query()` and `execute()` from mixin functions rather than direct declarations, which is what makes the whole query and execute API work.
`QueryableBase<T>(Base?)` and `ExecutableBase<T>(Base?)` are higher-order functions: each takes a base class constructor and returns an extended class carrying the method overloads.
### Callback versions (return `Query`)
Each method has 4 overloads: `(sql, cb?)`, `(sql, values, cb?)`, `(options, cb?)`, `(options, values, cb?)`.
- `typings/mysql/lib/protocol/sequences/QueryableBase.d.ts`
- `typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts`
### Promise versions (return `Promise<[T, FieldPacket[]]>`)
Each method has 2 overloads: `(sql, values?)`, `(options, values?)`.
- `typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts`
- `typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts`
### Who uses the mixins
| Class/Interface | Mixin Usage |
| -------------------------- | ---------------------------------------------------------------------------- |
| `Connection` (callback) | `extends QueryableBase(ExecutableBase(EventEmitter))` |
| `Pool` (callback) | `extends QueryableBase(ExecutableBase(EventEmitter))` |
| `PoolCluster` (callback) | `extends EventEmitter` directly, with **no mixins** |
| `PoolNamespace` (callback) | interface extends `QueryableAndExecutableBase` |
| `Connection` (promise) | `extends QueryableAndExecutableBase` (anonymous class composing both mixins) |
| `Pool` (promise) | interface extends `Connection` (inherits mixins transitively) |
| `PoolNamespace` (promise) | interface extends `QueryableAndExecutableBase` |
### Helper type
The constraint on every mixin base class parameter:
```ts
type QueryableConstructor<T = object> = new (...args: any[]) => T;
```
---
## 2. Dual API (Callback vs Promise)
MySQL2 exposes two parallel APIs: callback-based and promise-based.
### Entry points
| API | Entry File | Primary Type Source |
| -------- | --------------------- | ------------------------------- |
| Callback | `index.d.ts` (root) | `typings/mysql/index.d.ts` |
| Promise | `promise.d.ts` (root) | declares promise classes inline |
### How promise wraps callback
1. `promise.d.ts` re-exports everything from `index.js`.
2. It imports the promise-specific mixin functions from `typings/mysql/lib/protocol/sequences/promise/`.
3. It composes an anonymous `QueryableAndExecutableBase` class:
```ts
declare class QueryableAndExecutableBase extends QueryableBaseClass(
ExecutableBaseClass(EventEmitter)
) {}
```
4. The promise classes extend or implement that base.
### Key differences
| Aspect | Callback | Promise |
| ---------------------------- | ----------------------------- | ----------------------------- |
| `query()`/`execute()` return | `Query` | `Promise<[T, FieldPacket[]]>` |
| `createConnection()` return | `Connection` (sync) | `Promise<Connection>` (async) |
| `createPool()` return | `Pool` (sync) | `Pool` (sync) |
| `end()` | `void` with optional callback | `Promise<void>` |
| Resource disposal | `Symbol.dispose` (sync) | `Symbol.asyncDispose` (async) |
| `.promise()` method | Available on callback classes | Not applicable |
### Bridging
Callback classes carry a `.promise()` method returning the promise-wrapped version:
- `Connection.promise()` returns `PromiseConnection`.
- `Pool.promise()` returns `PromisePool`.
- `PoolConnection.promise()` returns `PromisePool`. โ ๏ธ
---
## 3. Class Hierarchy
### Callback
```
EventEmitter
โโโ Connection extends QueryableBase(ExecutableBase(EventEmitter))
โ โโโ .config: ConnectionOptions
โ โโโ .threadId: number
โ โโโ .authorized: boolean
โ โโโ .state: ConnectionState (readonly)
โ โโโ .sequenceId: number
โ โโโ static createQuery(): Query
โ โโโ beginTransaction(), connect(), commit(), rollback()
โ โโโ changeUser(), end(), destroy(), pause(), resume()
โ โโโ escape(), escapeId(), format()
โ โโโ prepare(), unprepare(), ping()
โ โโโ serverHandshake(), writeOk(), writeError(), writeEof()
โ โโโ writeTextResult(), writePacket()
โ โโโ promise(): PromiseConnection
โ โโโ Symbol.dispose
โ
โ โโโ PoolConnection extends Connection
โ โโโ .connection: Connection
โ โโโ release(): void
โ โโโ promise(): PromisePool โ ๏ธ
โ โโโ Symbol.dispose
โ
โโโ Pool extends QueryableBase(ExecutableBase(EventEmitter))
โ โโโ .config: PoolOptions
โ โโโ getConnection(cb), releaseConnection(conn)
โ โโโ end(cb?), unprepare(sql)
โ โโโ promise(): PromisePool
โ โโโ on: 'connection' | 'acquire' | 'release' | 'enqueue'
โ โโโ Symbol.dispose
โ โ ๏ธ escape(), escapeId(), format() exist at runtime and are undeclared
โ
โโโ PoolCluster extends EventEmitter (NO mixins)
โ โโโ .config: PoolClusterOptions
โ โโโ add(config), add(group, uri), add(group, config)
โ โโโ remove(pattern), end(cb?)
โ โโโ getConnection(cb), getConnection(group, cb), getConnection(group, selector, cb)
โ โโโ of(pattern, selector?): PoolNamespace
โ โโโ on: 'online' | 'offline' | 'remove' | 'warn'
โ โโโ Symbol.dispose
โ
โโโ Server extends EventEmitter
โ โโโ .connections: Connection[]
โ โโโ listen(port): Server
โ โโโ close(callback): void
โ โ ๏ธ listen(port, cb) and close() without a callback are undeclared
โ
โโโ Sequence extends EventEmitter
โโโ Query extends Sequence
โ โโโ .sql: string
โ โโโ start(), determinePacket(), stream()
โ โโโ on: 'error' | 'fields' | 'result' | 'end'
โ
โโโ Prepare extends Sequence
โโโ .sql: string
โโโ start(), determinePacket(), stream()
โโโ on: 'error' | 'fields' | 'result' | 'end'
PoolNamespace (interface extends QueryableAndExecutableBase)
โโโ getConnection(cb)
```
### Promise
```
EventEmitter
โโโ Connection extends QueryableAndExecutableBase
โ โโโ .config: ConnectionOptions
โ โโโ .threadId: number
โ โโโ .state: ConnectionState (readonly)
โ โโโ connect(), ping(), beginTransaction(), commit(), rollback()
โ โโโ changeUser(), prepare(), unprepare()
โ โโโ end(), destroy(), pause(), resume()
โ โโโ escape(), escapeId(), format()
โ โโโ Symbol.asyncDispose
โ
โ โโโ PoolConnection extends Connection
โ โโโ .connection: Connection
โ โโโ release(): void
โ โโโ Symbol.asyncDispose
โ
โโโ Pool (interface extends Connection)
โ โโโ .pool: CorePool (callback Pool reference)
โ โโโ getConnection(): Promise<PoolConnection>
โ โโโ releaseConnection(conn)
โ โโโ end(): Promise<void>
โ โโโ on: 'connection' | 'acquire' | 'release' | 'enqueue'
โ
โโโ PoolCluster (interface extends EventEmitter)
โ โโโ .config: PoolClusterOptions
โ โโโ add(config), add(group, uri), add(group, config)
โ โโโ end(): Promise<void>
โ โโโ getConnection(), getConnection(group), getConnection(group, selector)
โ โโโ of(pattern, selector?): PoolNamespace
โ โโโ on: 'remove' | 'warn'
โ โโโ Symbol.asyncDispose
โ โ ๏ธ on 'online' and 'offline' are declared in the callback version only
โ โ ๏ธ remove() is undeclared
โ
โโโ PoolNamespace (interface extends QueryableAndExecutableBase)
โโโ getConnection(): Promise<PoolConnection>
```
---
## 4. File Map
Every type definition file, its purpose, and its key exports.
### Root entry points
| File | Purpose | Key Exports |
| --------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/index.d.ts` | Root callback entry | Re-exports from `typings/mysql/index.js` |
| `/promise.d.ts` | Root promise entry | `Connection`, `Pool`, `PoolConnection`, `PoolCluster`, `PoolNamespace`, `PreparedStatementInfo`, `createConnection()`, `createPool()`, `createPoolCluster()` |
### Main API (`typings/mysql/`)
| File | Purpose | Key Exports |
| ------------ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `index.d.ts` | Callback API hub | `createConnection()`, `createPool()`, `createPoolCluster()`, `createServer()`, `escape`, `escapeId`, `format`, `raw`, `ConnectionConfig`, re-exports all sub-modules |
### Core classes (`typings/mysql/lib/`)
| File | Purpose | Key Exports |
| --------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Connection.d.ts` | Connection class + options | `Connection`, `ConnectionOptions` (40+ props), `SslOptions`, `ConnectionState` |
| `Pool.d.ts` | Connection pool | `Pool`, `PoolOptions` |
| `PoolCluster.d.ts` | Pool cluster | `PoolCluster`, `PoolClusterOptions`, `PoolNamespace` |
| `PoolConnection.d.ts` | Pool connection | `PoolConnection` |
| `Server.d.ts` | MySQL server (testing) | `Server` |
| `Auth.d.ts` | Auth plugins | `AuthPlugin`, `authPlugins` (4 built-in plugins) |
| `Tracing.d.ts` | diagnostics_channel | `QueryTraceContext`, `ExecuteTraceContext`, `ConnectTraceContext`, `PoolConnectTraceContext`, `dc`, `hasTracingChannel`, `shouldTrace()`, `traceCallback()`, `tracePromise()`, channel variables |
### Protocol sequences (`typings/mysql/lib/protocol/sequences/`)
| File | Purpose | Key Exports |
| --------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| `Sequence.d.ts` | Base class | `Sequence` (extends EventEmitter, minimal) |
| `Query.d.ts` | Query sequence | `Query`, `QueryOptions`, `QueryError`, `QueryValues`, `ExecuteValues`, `StreamOptions`, `QueryableConstructor` |
| `Prepare.d.ts` | Prepare sequence | `Prepare`, `PrepareStatementInfo` |
| `ExecutableBase.d.ts` | Callback execute mixin | `ExecutableBase()` |
| `QueryableBase.d.ts` | Callback query mixin | `QueryableBase()` |
### Promise sequences (`typings/mysql/lib/protocol/sequences/promise/`)
| File | Purpose | Key Exports |
| --------------------- | --------------------- | ------------------ |
| `ExecutableBase.d.ts` | Promise execute mixin | `ExecutableBase()` |
| `QueryableBase.d.ts` | Promise query mixin | `QueryableBase()` |
### Packets (`typings/mysql/lib/protocol/packets/`)
| File | Purpose | Key Exports |
| ------------------------------- | ----------------------------------- | ------------------------------------------------------- |
| `index.d.ts` | Packet hub | `QueryResult` (union type), re-exports all packet types |
| `OkPacket.d.ts` | OK result _(deprecated)_ | `OkPacket` |
| `ResultSetHeader.d.ts` | Result metadata | `ResultSetHeader` |
| `RowDataPacket.d.ts` | Data row | `RowDataPacket` |
| `FieldPacket.d.ts` | Column metadata | `FieldPacket` |
| `Field.d.ts` | TypeCast field _(deprecated alias)_ | `Field`, an alias of `TypeCastField` |
| `ProcedurePacket.d.ts` | Stored procedure result | `ProcedureCallPacket<T>` |
| `params/OkPacketParams.d.ts` | Server OK params | `OkPacketParams` |
| `params/ErrorPacketParams.d.ts` | Server error params | `ErrorPacketParams` |
### Constants (`typings/mysql/lib/constants/`)
| File | Purpose | Key Exports |
| ------------------------ | ----------------------- | ------------------------------------------------------------------- |
| `index.d.ts` | Constants hub | Re-exports Types, Charsets, CharsetToEncoding |
| `Types.d.ts` | MySQL column types | `Types` (hex codes 0x00-0xff + named: DECIMAL, TINY, ..., GEOMETRY) |
| `Charsets.d.ts` | Charset/collation IDs | `Charsets` (270+ named entries) |
| `CharsetToEncoding.d.ts` | Charset to encoding map | `CharsetToEncoding` (string[]) |
### Parsers (`typings/mysql/lib/parsers/`)
| File | Purpose | Key Exports |
| ------------------ | --------------- | --------------------------------------------------------------------------------- |
| `index.d.ts` | Parsers hub | Re-exports as `TypeCastField`, `TypeCastGeometry`, `TypeCastNext`, `TypeCastType` |
| `typeCast.d.ts` | Type casting | `TypeCast`, `Field` (= TypeCastField), `Geometry`, `Next`, `Type` |
| `ParserCache.d.ts` | Cache utilities | `setMaxParserCache()`, `clearParserCache()` |
---
## 5. ConnectionOptions property map
Every property declared in `typings/mysql/lib/Connection.d.ts`.
### With JSDoc documentation
| Property | Type | Default | Description |
| ----------------------- | ------------------------------------------------------- | ------------------- | ------------------------------------ |
| `decimalNumbers` | `boolean` | `false` | Return DECIMAL/NEWDECIMAL as numbers |
| `user` | `string` | none | MySQL user |
| `password` | `string` | none | MySQL password |
| `password1` | `string` | none | Alias for password (MFA) |
| `password2` | `string` | none | 2nd factor auth password |
| `password3` | `string` | none | 3rd factor auth password |
| `database` | `string` | none | Database name |
| `charset` | `string` | `'UTF8_GENERAL_CI'` | Connection charset/collation |
| `host` | `string` | `'localhost'` | Database hostname |
| `port` | `number` | `3306` | Port number |
| `localAddress` | `string` | none | Source IP for TCP |
| `socketPath` | `string` | none | Unix socket path |
| `timezone` | `Timezone` | `'local'` | Timezone for dates |
| `connectTimeout` | `number` | `10000` | Connection timeout (ms) |
| `stringifyObjects` | `boolean` | `false` | Stringify objects in queries |
| `insecureAuth` | `boolean` | `false` | Allow old auth method |
| `infileStreamFactory` | `(path: string) => Readable` | none | Custom stream for LOAD DATA INFILE |
| `typeCast` | `TypeCast` | `true` | Column value conversion |
| `queryFormat` | `(query: string, values: any) => void` | none | Custom query format |
| `supportBigNumbers` | `boolean` | `false` | Handle BIGINT/DECIMAL |
| `bigNumberStrings` | `boolean` | `false` | Return big numbers as strings |
| `dateStrings` | `boolean \| Array<'TIMESTAMP' \| 'DATETIME' \| 'DATE'>` | `false` | Return dates as strings |
| `debug` | `any` | `false` | Print packets to stdout |
| `trace` | `boolean` | `true` | Stack traces on errors |
| `multipleStatements` | `boolean` | `false` | Allow multiple statements |
| `flags` | `Array<string>` | none | Connection flags |
| `ssl` | `string \| SslOptions` | none | SSL configuration |
| `rowsAsArray` | `boolean` | none | Return rows as arrays |
| `enableKeepAlive` | `boolean` | `true` | Socket keep-alive |
| `keepAliveInitialDelay` | `number` | `0` | Keep-alive initial delay |
### Without JSDoc documentation
| Property | Type | Notes |
| ----------------------- | ------------------------------------------ | ------------------------------ |
| `charsetNumber` | `number` | Numeric charset ID |
| `compress` | `boolean` | Protocol compression |
| `authSwitchHandler` | `(data: any, callback: () => void) => any` | Auth switch handler |
| `connectAttributes` | `{ [param: string]: any }` | Connection attributes |
| `isServer` | `boolean` | Server mode flag |
| `maxPreparedStatements` | `number` | LRU cache limit |
| `namedPlaceholders` | `boolean` | Named placeholder support |
| `nestTables` | `boolean \| string` | Nest tables in results |
| `passwordSha1` | `string` | Pre-hashed password |
| `pool` | `any` | Pool reference |
| `stream` | `any` | Custom stream |
| `uri` | `string` | Connection URI |
| `connectionLimit` | `number` | โ ๏ธ Duplicated from PoolOptions |
| `maxIdle` | `number` | โ ๏ธ Duplicated from PoolOptions |
| `idleTimeout` | `number` | โ ๏ธ Duplicated from PoolOptions |
| `Promise` | `any` | Promise constructor |
| `queueLimit` | `number` | โ ๏ธ Duplicated from PoolOptions |
| `waitForConnections` | `boolean` | โ ๏ธ Duplicated from PoolOptions |
| `disableEval` | `boolean` | Disable eval in parsers |
| `authPlugins` | `{ [key: string]: AuthPlugin }` | Custom auth plugins |
| `jsonStrings` | `boolean` | Force JSON as string |
| `gracefulEnd` | `boolean` | Graceful pool end |
### PoolOptions (extends ConnectionOptions)
Adds these properties with JSDoc, in `typings/mysql/lib/Pool.d.ts`:
| Property | Type | Default |
| -------------------- | --------- | ------------------------- |
| `waitForConnections` | `boolean` | `true` |
| `connectionLimit` | `number` | `10` |
| `maxIdle` | `number` | same as `connectionLimit` |
| `idleTimeout` | `number` | `60000` |
| `queueLimit` | `number` | `0` |
---
## 6. QueryOptions vs ConnectionOptions
### Shared options (override per-query)
These exist in both `ConnectionOptions` and `QueryOptions`, so a query can override the connection:
| Option | ConnectionOptions | QueryOptions |
| --------------------- | ------------------------ | ------------- |
| `typeCast` | โ
| โ
|
| `nestTables` | โ
(`boolean \| string`) | โ
(`any` โ ๏ธ) |
| `rowsAsArray` | โ
| โ
|
| `supportBigNumbers` | โ
| โ
|
| `bigNumberStrings` | โ
| โ
|
| `dateStrings` | โ
| โ
|
| `timezone` | โ
| โ
|
| `infileStreamFactory` | โ
| โ
|
| `namedPlaceholders` | โ
(undocumented) | โ
|
### QueryOptions-only
| Option | Type | Description |
| --------- | ------------- | ------------------------ |
| `sql` | `string` | The SQL query (required) |
| `values` | `QueryValues` | Query parameter values |
| `timeout` | `number` | Operation timeout (ms) |
### Not in QueryOptions but available at runtime
| Option | Status |
| ------------------ | ------------------------------------------------------------ |
| `insertIdAsNumber` | Missing from both QueryOptions and ConnectionOptions typings |
| `decimalNumbers` | Only in ConnectionOptions, not in QueryOptions |