@benjosivo/mysql 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -176
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +26 -26
package/README.md
CHANGED
|
@@ -1,176 +1,176 @@
|
|
|
1
|
-
# @benjosivo/mysql
|
|
2
|
-
|
|
3
|
-
Shared MySQL client (pooling, automatic retry on deadlock/lock-timeout, transaction helpers) for use across multiple projects. Nothing connects until you call `init()` — the package has no side effects at import time and no dependency on any particular env var naming.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
npm install @benjosivo/mysql
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { init, executeMySQLQuery, closeMySQLConnection } from '@benjosivo/mysql';
|
|
15
|
-
|
|
16
|
-
await init({
|
|
17
|
-
host: process.env.DB_HOST!,
|
|
18
|
-
user: process.env.DB_USER!,
|
|
19
|
-
password: process.env.DB_PASSWORD!,
|
|
20
|
-
database: process.env.DB_NAME!,
|
|
21
|
-
onError: (error, context) => myLogger.error(context, error), // optional, defaults to console.error
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const rows = await executeMySQLQuery('SELECT * FROM users WHERE id = ?', [userId]);
|
|
25
|
-
|
|
26
|
-
// on shutdown
|
|
27
|
-
await closeMySQLConnection();
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Call `init()` once per process, at startup. Each consuming project supplies its own credentials and (optionally) its own error reporting — this package has no opinion on either.
|
|
31
|
-
|
|
32
|
-
### Config
|
|
33
|
-
|
|
34
|
-
| Field | Required | Default | Description |
|
|
35
|
-
|---|---|---|---|
|
|
36
|
-
| `host`, `user`, `password`, `database` | yes | — | MySQL connection details |
|
|
37
|
-
| `waitForConnections` | no | `true` | passed through to `mysql2` pool |
|
|
38
|
-
| `connectionLimit` | no | `50` | passed through to `mysql2` pool |
|
|
39
|
-
| `queueLimit` | no | `0` | passed through to `mysql2` pool |
|
|
40
|
-
| `multipleStatements` | no | `true` | passed through to `mysql2` pool |
|
|
41
|
-
| `staleTransactionMs` | no | `300000` (5 min) | a transaction with no statement activity for this long is auto rolled back |
|
|
42
|
-
| `defaultQueryTimeoutMs` | no | — (off) | default per-statement timeout; overridable per call with `timeoutMs` |
|
|
43
|
-
| `onError` | no | `console.error` | called with `(error, context)` whenever the client can't throw the error directly (e.g. background retry loops) |
|
|
44
|
-
|
|
45
|
-
Calling `init()` again (e.g. to reconfigure) closes the previous pool first.
|
|
46
|
-
|
|
47
|
-
### Queries
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
executeMySQLQuery3<T>({ query, values?, connKey?, returnFieldTypes?, returnListTables?, timeoutMs? })
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Preferred for new code.** Always resolves to a wrapper — it never throws and never returns
|
|
54
|
-
bare rows, so every result is safe to inspect before use:
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
const res = await executeMySQLQuery3<User[]>({ query: 'SELECT * FROM users WHERE id = ?', values: [userId] });
|
|
58
|
-
|
|
59
|
-
if (!res.ok) {
|
|
60
|
-
// res.error is always a non-empty string
|
|
61
|
-
logger.error(res.error, res.code, res.errno, res.sqlState);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
res.rows[0].email; // narrowed by `ok` — TypeScript knows rows is present
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
`T` types the rows: `User[]` for a SELECT, `ResultSetHeader` for an INSERT/UPDATE. It defaults to
|
|
69
|
-
`any`, so untyped calls keep working.
|
|
70
|
-
|
|
71
|
-
| On success | On failure |
|
|
72
|
-
|---|---|
|
|
73
|
-
| `ok: true` | `ok: false` |
|
|
74
|
-
| `rows: T` | `error: string` (never empty), `code?`, `errno?`, `sqlState?`, `cause?` |
|
|
75
|
-
| `fieldsType: []` unless `returnFieldTypes` | `stage`: which step failed (`execute`, `transaction-lookup`, `procedure`, …) |
|
|
76
|
-
| `tables: []` unless `returnListTables` | `values`: the parameters that were sent |
|
|
77
|
-
| `connKey: string \| null` | `connKey: string \| null` |
|
|
78
|
-
|
|
79
|
-
Because the union is discriminated on `ok`, TypeScript will not let you read `rows` off a result
|
|
80
|
-
you haven't checked.
|
|
81
|
-
|
|
82
|
-
#### Retries
|
|
83
|
-
|
|
84
|
-
Only *transient* failures are retried (up to 5 attempts, with a backoff): deadlocks, lock timeouts,
|
|
85
|
-
lost connections, and a server that is out of connections. Deterministic failures — duplicate key,
|
|
86
|
-
bad syntax, constraint violations, unknown column, access denied — are returned on the **first**
|
|
87
|
-
attempt, since re-sending them can only produce the same error.
|
|
88
|
-
|
|
89
|
-
#### Timeouts
|
|
90
|
-
|
|
91
|
-
`timeoutMs` (or `defaultQueryTimeoutMs` in the config) bounds a statement, covering both the wait
|
|
92
|
-
for a pooled connection and the query itself. On expiry the statement is aborted server-side with
|
|
93
|
-
`KILL QUERY` so it stops consuming resources, and the failure comes back as
|
|
94
|
-
`{ ok: false, code: 'ETIMEDOUT' }`. Timed-out statements are never retried — a killed write must
|
|
95
|
-
not be silently re-applied.
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
const res = await executeMySQLQuery3({ query: 'SELECT ...', values, timeoutMs: 10_000 });
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
#### Legacy shape
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
executeMySQLQuery(query, values?, returnFieldTypes?, connKey?, timeoutMs?)
|
|
105
|
-
executeMySQLQuery2({ query, values?, connKey?, returnFieldTypes?, returnListTables?, timeoutMs? })
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Unchanged: these return the rows directly on success (or `{ rows, fieldsType, connKey, tables }`
|
|
109
|
-
when a transaction or extra metadata was requested), and `{ error, values, connKey }` on failure
|
|
110
|
-
instead of throwing. Failures now also carry `code`, `errno` and `sqlState` alongside the message.
|
|
111
|
-
They share the retry, timeout and transaction handling described above; `executeMySQLQuery2` is a
|
|
112
|
-
thin adapter over `executeMySQLQuery3`.
|
|
113
|
-
|
|
114
|
-
### Statements prepared statements can't run
|
|
115
|
-
|
|
116
|
-
`executeMySQLQuery` uses `execute()` (MySQL's prepared-statement protocol), and MySQL rejects a
|
|
117
|
-
number of statements there with *"This command is not supported in the prepared statement protocol
|
|
118
|
-
yet"* — `SET GLOBAL ...`, `USE ...`, `LOCK TABLES`, several `SHOW` variants, and so on. For those,
|
|
119
|
-
use `runMySQLQuery`, which goes through `query()` (text protocol) instead:
|
|
120
|
-
|
|
121
|
-
```ts
|
|
122
|
-
import { runMySQLQuery } from '@benjosivo/mysql';
|
|
123
|
-
|
|
124
|
-
await runMySQLQuery("SET GLOBAL general_log = 'OFF'");
|
|
125
|
-
|
|
126
|
-
// placeholders still work — mysql2 escapes and interpolates them client-side
|
|
127
|
-
await runMySQLQuery('SET GLOBAL general_log = ?', ['OFF']);
|
|
128
|
-
|
|
129
|
-
// optionally run inside an existing transaction
|
|
130
|
-
await runMySQLQuery('SELECT * FROM users WHERE id = ?', [userId], connKey);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
runMySQLQuery(query, values?, connKey?, timeoutMs?)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Same result shape as `executeMySQLQuery`: rows on success, `{ error, values, connKey }` on failure
|
|
138
|
-
(with `code`/`errno`/`sqlState` when MySQL supplied them).
|
|
139
|
-
It's deliberately simple — no deadlock/lock-timeout retry — so prefer `executeMySQLQuery` for
|
|
140
|
-
regular application queries and keep this one for statements the prepared-statement protocol
|
|
141
|
-
refuses.
|
|
142
|
-
|
|
143
|
-
### Transactions
|
|
144
|
-
|
|
145
|
-
```ts
|
|
146
|
-
const opened = await executeMySQLQuery3({ query: 'INSERT ...', values, connKey: true });
|
|
147
|
-
if (!opened.ok) return opened.error;
|
|
148
|
-
|
|
149
|
-
await executeMySQLQuery3({ query: 'UPDATE ...', values, connKey: opened.connKey }); // same transaction
|
|
150
|
-
|
|
151
|
-
await connectionCommit(opened.connKey!);
|
|
152
|
-
// or: await connectionRollback(opened.connKey!);
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
A transaction is retired as soon as it can no longer be used — MySQL rolled it back after a
|
|
156
|
-
deadlock, its connection was lost, or the background sweep found it idle. Its connection is
|
|
157
|
-
released immediately, and any later use reports *why*:
|
|
158
|
-
|
|
159
|
-
```ts
|
|
160
|
-
// Transaction <key> is no longer usable: MySQL rolled it back after a deadlock
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
`connectionRollback` on a transaction that was already retired succeeds (there is nothing left to
|
|
164
|
-
undo); `connectionCommit` reports an error, because the data did not make it. Both always free the
|
|
165
|
-
connection, even if the COMMIT or ROLLBACK itself fails.
|
|
166
|
-
|
|
167
|
-
`staleTransactionMs` measures **idle** time: a transaction is swept only when no statement has run
|
|
168
|
-
on it for that long, so a long-running but active transaction is left alone.
|
|
169
|
-
|
|
170
|
-
### Shutdown
|
|
171
|
-
|
|
172
|
-
```ts
|
|
173
|
-
await closeMySQLConnection();
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Rolls back any open transactions, ends the pool, and stops the background sweep. Safe to call even if `init()` was never called.
|
|
1
|
+
# @benjosivo/mysql
|
|
2
|
+
|
|
3
|
+
Shared MySQL client (pooling, automatic retry on deadlock/lock-timeout, transaction helpers) for use across multiple projects. Nothing connects until you call `init()` — the package has no side effects at import time and no dependency on any particular env var naming.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @benjosivo/mysql
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { init, executeMySQLQuery, closeMySQLConnection } from '@benjosivo/mysql';
|
|
15
|
+
|
|
16
|
+
await init({
|
|
17
|
+
host: process.env.DB_HOST!,
|
|
18
|
+
user: process.env.DB_USER!,
|
|
19
|
+
password: process.env.DB_PASSWORD!,
|
|
20
|
+
database: process.env.DB_NAME!,
|
|
21
|
+
onError: (error, context) => myLogger.error(context, error), // optional, defaults to console.error
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const rows = await executeMySQLQuery('SELECT * FROM users WHERE id = ?', [userId]);
|
|
25
|
+
|
|
26
|
+
// on shutdown
|
|
27
|
+
await closeMySQLConnection();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Call `init()` once per process, at startup. Each consuming project supplies its own credentials and (optionally) its own error reporting — this package has no opinion on either.
|
|
31
|
+
|
|
32
|
+
### Config
|
|
33
|
+
|
|
34
|
+
| Field | Required | Default | Description |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| `host`, `user`, `password`, `database` | yes | — | MySQL connection details |
|
|
37
|
+
| `waitForConnections` | no | `true` | passed through to `mysql2` pool |
|
|
38
|
+
| `connectionLimit` | no | `50` | passed through to `mysql2` pool |
|
|
39
|
+
| `queueLimit` | no | `0` | passed through to `mysql2` pool |
|
|
40
|
+
| `multipleStatements` | no | `true` | passed through to `mysql2` pool |
|
|
41
|
+
| `staleTransactionMs` | no | `300000` (5 min) | a transaction with no statement activity for this long is auto rolled back |
|
|
42
|
+
| `defaultQueryTimeoutMs` | no | — (off) | default per-statement timeout; overridable per call with `timeoutMs` |
|
|
43
|
+
| `onError` | no | `console.error` | called with `(error, context)` whenever the client can't throw the error directly (e.g. background retry loops) |
|
|
44
|
+
|
|
45
|
+
Calling `init()` again (e.g. to reconfigure) closes the previous pool first.
|
|
46
|
+
|
|
47
|
+
### Queries
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
executeMySQLQuery3<T>({ query, values?, connKey?, returnFieldTypes?, returnListTables?, timeoutMs? })
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Preferred for new code.** Always resolves to a wrapper — it never throws and never returns
|
|
54
|
+
bare rows, so every result is safe to inspect before use:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const res = await executeMySQLQuery3<User[]>({ query: 'SELECT * FROM users WHERE id = ?', values: [userId] });
|
|
58
|
+
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
// res.error is always a non-empty string
|
|
61
|
+
logger.error(res.error, res.code, res.errno, res.sqlState);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
res.rows[0].email; // narrowed by `ok` — TypeScript knows rows is present
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`T` types the rows: `User[]` for a SELECT, `ResultSetHeader` for an INSERT/UPDATE. It defaults to
|
|
69
|
+
`any`, so untyped calls keep working.
|
|
70
|
+
|
|
71
|
+
| On success | On failure |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `ok: true` | `ok: false` |
|
|
74
|
+
| `rows: T` | `error: string` (never empty), `code?`, `errno?`, `sqlState?`, `cause?` |
|
|
75
|
+
| `fieldsType: []` unless `returnFieldTypes` | `stage`: which step failed (`execute`, `transaction-lookup`, `procedure`, …) |
|
|
76
|
+
| `tables: []` unless `returnListTables` | `values`: the parameters that were sent |
|
|
77
|
+
| `connKey: string \| null` | `connKey: string \| null` |
|
|
78
|
+
|
|
79
|
+
Because the union is discriminated on `ok`, TypeScript will not let you read `rows` off a result
|
|
80
|
+
you haven't checked.
|
|
81
|
+
|
|
82
|
+
#### Retries
|
|
83
|
+
|
|
84
|
+
Only *transient* failures are retried (up to 5 attempts, with a backoff): deadlocks, lock timeouts,
|
|
85
|
+
lost connections, and a server that is out of connections. Deterministic failures — duplicate key,
|
|
86
|
+
bad syntax, constraint violations, unknown column, access denied — are returned on the **first**
|
|
87
|
+
attempt, since re-sending them can only produce the same error.
|
|
88
|
+
|
|
89
|
+
#### Timeouts
|
|
90
|
+
|
|
91
|
+
`timeoutMs` (or `defaultQueryTimeoutMs` in the config) bounds a statement, covering both the wait
|
|
92
|
+
for a pooled connection and the query itself. On expiry the statement is aborted server-side with
|
|
93
|
+
`KILL QUERY` so it stops consuming resources, and the failure comes back as
|
|
94
|
+
`{ ok: false, code: 'ETIMEDOUT' }`. Timed-out statements are never retried — a killed write must
|
|
95
|
+
not be silently re-applied.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const res = await executeMySQLQuery3({ query: 'SELECT ...', values, timeoutMs: 10_000 });
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Legacy shape
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
executeMySQLQuery(query, values?, returnFieldTypes?, connKey?, timeoutMs?)
|
|
105
|
+
executeMySQLQuery2({ query, values?, connKey?, returnFieldTypes?, returnListTables?, timeoutMs? })
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Unchanged: these return the rows directly on success (or `{ rows, fieldsType, connKey, tables }`
|
|
109
|
+
when a transaction or extra metadata was requested), and `{ error, values, connKey }` on failure
|
|
110
|
+
instead of throwing. Failures now also carry `code`, `errno` and `sqlState` alongside the message.
|
|
111
|
+
They share the retry, timeout and transaction handling described above; `executeMySQLQuery2` is a
|
|
112
|
+
thin adapter over `executeMySQLQuery3`.
|
|
113
|
+
|
|
114
|
+
### Statements prepared statements can't run
|
|
115
|
+
|
|
116
|
+
`executeMySQLQuery` uses `execute()` (MySQL's prepared-statement protocol), and MySQL rejects a
|
|
117
|
+
number of statements there with *"This command is not supported in the prepared statement protocol
|
|
118
|
+
yet"* — `SET GLOBAL ...`, `USE ...`, `LOCK TABLES`, several `SHOW` variants, and so on. For those,
|
|
119
|
+
use `runMySQLQuery`, which goes through `query()` (text protocol) instead:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { runMySQLQuery } from '@benjosivo/mysql';
|
|
123
|
+
|
|
124
|
+
await runMySQLQuery("SET GLOBAL general_log = 'OFF'");
|
|
125
|
+
|
|
126
|
+
// placeholders still work — mysql2 escapes and interpolates them client-side
|
|
127
|
+
await runMySQLQuery('SET GLOBAL general_log = ?', ['OFF']);
|
|
128
|
+
|
|
129
|
+
// optionally run inside an existing transaction
|
|
130
|
+
await runMySQLQuery('SELECT * FROM users WHERE id = ?', [userId], connKey);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
runMySQLQuery(query, values?, connKey?, timeoutMs?)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Same result shape as `executeMySQLQuery`: rows on success, `{ error, values, connKey }` on failure
|
|
138
|
+
(with `code`/`errno`/`sqlState` when MySQL supplied them).
|
|
139
|
+
It's deliberately simple — no deadlock/lock-timeout retry — so prefer `executeMySQLQuery` for
|
|
140
|
+
regular application queries and keep this one for statements the prepared-statement protocol
|
|
141
|
+
refuses.
|
|
142
|
+
|
|
143
|
+
### Transactions
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const opened = await executeMySQLQuery3({ query: 'INSERT ...', values, connKey: true });
|
|
147
|
+
if (!opened.ok) return opened.error;
|
|
148
|
+
|
|
149
|
+
await executeMySQLQuery3({ query: 'UPDATE ...', values, connKey: opened.connKey }); // same transaction
|
|
150
|
+
|
|
151
|
+
await connectionCommit(opened.connKey!);
|
|
152
|
+
// or: await connectionRollback(opened.connKey!);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
A transaction is retired as soon as it can no longer be used — MySQL rolled it back after a
|
|
156
|
+
deadlock, its connection was lost, or the background sweep found it idle. Its connection is
|
|
157
|
+
released immediately, and any later use reports *why*:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
// Transaction <key> is no longer usable: MySQL rolled it back after a deadlock
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`connectionRollback` on a transaction that was already retired succeeds (there is nothing left to
|
|
164
|
+
undo); `connectionCommit` reports an error, because the data did not make it. Both always free the
|
|
165
|
+
connection, even if the COMMIT or ROLLBACK itself fails.
|
|
166
|
+
|
|
167
|
+
`staleTransactionMs` measures **idle** time: a transaction is swept only when no statement has run
|
|
168
|
+
on it for that long, so a long-running but active transaction is left alone.
|
|
169
|
+
|
|
170
|
+
### Shutdown
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
await closeMySQLConnection();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Rolls back any open transactions, ends the pool, and stops the background sweep. Safe to call even if `init()` was never called.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import mysql from 'mysql2/promise';
|
|
1
2
|
export interface MySQLClientConfig {
|
|
2
3
|
host: string;
|
|
3
4
|
user: string;
|
|
@@ -16,6 +17,7 @@ export interface MySQLClientConfig {
|
|
|
16
17
|
defaultQueryTimeoutMs?: number;
|
|
17
18
|
/** Called whenever this client encounters an error it can't throw directly (e.g. inside retry loops). Defaults to console.error. */
|
|
18
19
|
onError?: (error: unknown, context: string) => void;
|
|
20
|
+
otherOtions: mysql.PoolOptions;
|
|
19
21
|
}
|
|
20
22
|
export interface MySQLFieldType {
|
|
21
23
|
fieldName: string;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@benjosivo/mysql",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"main": "dist/index.js",
|
|
5
|
-
"types": "dist/index.d.ts",
|
|
6
|
-
"files": [
|
|
7
|
-
"dist"
|
|
8
|
-
],
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"prepublishOnly": "npm run build"
|
|
12
|
-
},
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"mysql2": "^3.x",
|
|
15
|
-
"node-sql-parser": "^5.4.0"
|
|
16
|
-
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@types/node": "^26.1.2",
|
|
19
|
-
"typescript": "^7.0.2"
|
|
20
|
-
},
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/benjosivo/mysql.git"
|
|
24
|
-
},
|
|
25
|
-
"license": "MIT"
|
|
26
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@benjosivo/mysql",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"mysql2": "^3.x",
|
|
15
|
+
"node-sql-parser": "^5.4.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^26.1.2",
|
|
19
|
+
"typescript": "^7.0.2"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/benjosivo/mysql.git"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT"
|
|
26
|
+
}
|