node-mysql2 Agent Skills & AI Rules

GitHub

Zap: fast mysqljs/mysql compatible mysql driver for node.js

4,360 stars TypeScript TypeScript 1 file ยท ~9,219 tokens #database-adapter#mysql#mysql-client#node-js
RAW Rules
5 Discovered Rules โ€ข ~13,034 Estimated Tokens
Quick:
Loading skill content...

Rules Skill

.claude/skills/types/rules/architecture.md anthropic-skill ~4,813 tokens
Raw
# 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               |