@groundbrick/db-mysql 0.1.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 +153 -0
- package/dist/adapter.d.ts +13 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +24 -0
- package/dist/adapter.js.map +1 -0
- package/dist/client.d.ts +26 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +158 -0
- package/dist/client.js.map +1 -0
- package/dist/factory.d.ts +19 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +45 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/migrator.d.ts +31 -0
- package/dist/migrator.d.ts.map +1 -0
- package/dist/migrator.js +149 -0
- package/dist/migrator.js.map +1 -0
- package/dist/result.d.ts +12 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +38 -0
- package/dist/result.js.map +1 -0
- package/dist/transaction.d.ts +16 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +43 -0
- package/dist/transaction.js.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# @groundbrick/db-mysql
|
|
2
|
+
|
|
3
|
+
Cliente MySQL para o microframework TypeScript, implementando o contrato
|
|
4
|
+
`@groundbrick/db-core` (espelho do `@groundbrick/db-postgres`): connection pooling,
|
|
5
|
+
gerenciamento de transações, monitoramento de saúde e sistema de migrações.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **🔗 Connection Pooling** — usando `mysql2` com pool configurável
|
|
10
|
+
- **🏭 Singleton Factory** — gerenciamento centralizado de instâncias de clientes
|
|
11
|
+
- **🔄 Transaction Management** — transações automáticas e manuais via `BaseTransaction`
|
|
12
|
+
- **📊 Health Monitoring** — verificações de saúde com métricas de timing
|
|
13
|
+
- **🗃️ Migration System** — migrações com seções `UP`/`DOWN` e checksum
|
|
14
|
+
- **⚙️ TypeScript Support** — tipagem completa para queries e configurações
|
|
15
|
+
- **🛡️ Error Handling** — tipos de erro específicos (`ConnectionError`, `QueryError`, etc.)
|
|
16
|
+
|
|
17
|
+
## Instalação
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @groundbrick/db-mysql
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer Dependencies
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install mysql2
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### 1. Configuração
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// src/database.ts
|
|
35
|
+
import { MysqlFactory, MysqlConfig } from '@groundbrick/db-mysql';
|
|
36
|
+
import { createLogger } from '@groundbrick/logger';
|
|
37
|
+
|
|
38
|
+
const config: MysqlConfig = {
|
|
39
|
+
host: process.env.DB_HOST || 'localhost',
|
|
40
|
+
port: parseInt(process.env.DB_PORT || '3306'),
|
|
41
|
+
database: process.env.DB_NAME || 'myapp',
|
|
42
|
+
user: process.env.DB_USER || 'root',
|
|
43
|
+
password: process.env.DB_PASSWORD || 'secret',
|
|
44
|
+
|
|
45
|
+
// Pool de conexões
|
|
46
|
+
connectionLimit: 10,
|
|
47
|
+
connectTimeout: 60000,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const logger = createLogger({ context: 'database' });
|
|
51
|
+
export const dbClient = MysqlFactory.getInstance(config, logger);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Inicialização e Queries
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { dbClient } from './database.js';
|
|
58
|
+
|
|
59
|
+
await dbClient.initialize();
|
|
60
|
+
|
|
61
|
+
const users = await dbClient.query<{ id: number; name: string; email: string }>(
|
|
62
|
+
'SELECT id, name, email FROM users WHERE active = ?',
|
|
63
|
+
[true]
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
console.log(`Found ${users.rowCount} users:`, users.rows);
|
|
67
|
+
|
|
68
|
+
process.on('SIGTERM', async () => {
|
|
69
|
+
await dbClient.close();
|
|
70
|
+
process.exit(0);
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. Transações
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Transação automática (recomendado)
|
|
78
|
+
const result = await dbClient.transaction(async (trx) => {
|
|
79
|
+
await trx.query('INSERT INTO audit_logs (action, user_id) VALUES (?, ?)',
|
|
80
|
+
['USER_CREATED', 123]);
|
|
81
|
+
|
|
82
|
+
const insert = await trx.query(
|
|
83
|
+
'INSERT INTO users (name, email) VALUES (?, ?)',
|
|
84
|
+
['João Silva', 'joao@example.com']
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return insert;
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Sistema de Migrações
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { MysqlMigrator } from '@groundbrick/db-mysql';
|
|
95
|
+
|
|
96
|
+
const migrator = new MysqlMigrator(dbClient, './migrations', logger.child('migrator'));
|
|
97
|
+
|
|
98
|
+
await migrator.migrate(); // aplica pendentes
|
|
99
|
+
await migrator.rollback(2); // desfaz as últimas 2
|
|
100
|
+
const status = await migrator.getStatus();
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Formato de arquivo de migração
|
|
104
|
+
|
|
105
|
+
```sql
|
|
106
|
+
-- Criar tabela de usuários
|
|
107
|
+
CREATE TABLE users (
|
|
108
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
109
|
+
name VARCHAR(100) NOT NULL,
|
|
110
|
+
email VARCHAR(100) UNIQUE NOT NULL,
|
|
111
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
-- DOWN
|
|
115
|
+
DROP TABLE IF EXISTS users;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Regras:** seção `UP` antes de `-- DOWN`, seção `DOWN` depois; primeira linha `--`
|
|
119
|
+
vira a descrição; arquivos aplicados em ordem lexicográfica; rollback executa `DOWN`
|
|
120
|
+
em ordem reversa.
|
|
121
|
+
|
|
122
|
+
## Error Handling
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { ConnectionError, QueryError, TransactionError, MigrationError } from '@groundbrick/db-core';
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
await dbClient.query('SELECT * FROM users');
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (error instanceof ConnectionError) {
|
|
131
|
+
// reconectar / fallback
|
|
132
|
+
} else if (error instanceof QueryError) {
|
|
133
|
+
// erro na query
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## API
|
|
139
|
+
|
|
140
|
+
Exporta `MysqlClient`, `MysqlTransaction`, `MysqlDatabaseFactory`, `MysqlFactory`,
|
|
141
|
+
`MysqlMigrator`, `MysqlSqlAdapter`, `normalizeResult` e o tipo `MysqlConfig`. A
|
|
142
|
+
superfície segue o contrato `DatabaseClient`/`QueryResult` de `@groundbrick/db-core`,
|
|
143
|
+
idêntica ao `@groundbrick/db-postgres` (apenas placeholders `?` em vez de `$1`).
|
|
144
|
+
|
|
145
|
+
## Dependencies
|
|
146
|
+
|
|
147
|
+
- `@groundbrick/db-core` — abstrações de banco de dados
|
|
148
|
+
- `@groundbrick/logger` — sistema de logging
|
|
149
|
+
- **peer:** `mysql2` — driver MySQL para Node.js (^3.11.0)
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseSqlAdapter } from '@groundbrick/db-core';
|
|
2
|
+
/**
|
|
3
|
+
* MySQL SQL adapter. MySQL uses `?` positional placeholders natively, so
|
|
4
|
+
* adaptSql is a passthrough. MySQL does NOT support the RETURNING clause.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MysqlSqlAdapter extends BaseSqlAdapter {
|
|
7
|
+
getDatabaseType(): 'mysql';
|
|
8
|
+
supportsReturning(): boolean;
|
|
9
|
+
adaptSql(sql: string): string;
|
|
10
|
+
getNowFunction(): string;
|
|
11
|
+
protected createPlaceholder(_index: number): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,cAAc;IACjD,eAAe,IAAI,OAAO;IAI1B,iBAAiB,IAAI,OAAO;IAI5B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAK7B,cAAc,IAAI,MAAM;IAIxB,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAGpD"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseSqlAdapter } from '@groundbrick/db-core';
|
|
2
|
+
/**
|
|
3
|
+
* MySQL SQL adapter. MySQL uses `?` positional placeholders natively, so
|
|
4
|
+
* adaptSql is a passthrough. MySQL does NOT support the RETURNING clause.
|
|
5
|
+
*/
|
|
6
|
+
export class MysqlSqlAdapter extends BaseSqlAdapter {
|
|
7
|
+
getDatabaseType() {
|
|
8
|
+
return 'mysql';
|
|
9
|
+
}
|
|
10
|
+
supportsReturning() {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
adaptSql(sql) {
|
|
14
|
+
// MySQL uses ? placeholders as-is.
|
|
15
|
+
return sql;
|
|
16
|
+
}
|
|
17
|
+
getNowFunction() {
|
|
18
|
+
return 'NOW()';
|
|
19
|
+
}
|
|
20
|
+
createPlaceholder(_index) {
|
|
21
|
+
return '?';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,cAAc;IACjD,eAAe;QACb,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,mCAAmC;QACnC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,cAAc;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,iBAAiB,CAAC,MAAc;QACxC,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Logger } from '@groundbrick/logger';
|
|
2
|
+
import { DatabaseClient, QueryResult, HealthCheckResult, SqlAdapter } from '@groundbrick/db-core';
|
|
3
|
+
import { MysqlConfig } from './types.js';
|
|
4
|
+
import { MysqlTransaction } from './transaction.js';
|
|
5
|
+
/**
|
|
6
|
+
* MySQL database client implementing the db-core DatabaseClient contract.
|
|
7
|
+
* Mirrors PostgresClient so application code can switch engines transparently.
|
|
8
|
+
*/
|
|
9
|
+
export declare class MysqlClient implements DatabaseClient {
|
|
10
|
+
private pool;
|
|
11
|
+
private logger;
|
|
12
|
+
private sqlAdapter;
|
|
13
|
+
private isInitialized;
|
|
14
|
+
constructor(config: MysqlConfig, logger: Logger);
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
getDatabaseType(): 'mysql';
|
|
18
|
+
getSqlAdapter(): SqlAdapter;
|
|
19
|
+
supportsReturning(): boolean;
|
|
20
|
+
query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
|
|
21
|
+
transaction<T>(callback: (tx: MysqlTransaction) => Promise<T>): Promise<T>;
|
|
22
|
+
healthCheck(): Promise<HealthCheckResult>;
|
|
23
|
+
isReady(): boolean;
|
|
24
|
+
}
|
|
25
|
+
export { type MysqlConfig, MysqlTransaction };
|
|
26
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EACL,cAAc,EACd,WAAW,EACX,iBAAiB,EAIjB,UAAU,EACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIpD;;;GAGG;AACH,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,aAAa,CAAS;gBAElB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM;IAwBzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,eAAe,IAAI,OAAO;IAI1B,aAAa,IAAI,UAAU;IAI3B,iBAAiB,IAAI,OAAO;IAItB,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IA+BxE,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA+B1E,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA4B/C,OAAO,IAAI,OAAO;CAGnB;AAED,OAAO,EAAE,KAAK,WAAW,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import mysql from 'mysql2/promise';
|
|
2
|
+
import { ConnectionError, QueryError, TransactionError } from '@groundbrick/db-core';
|
|
3
|
+
import { MysqlTransaction } from './transaction.js';
|
|
4
|
+
import { MysqlSqlAdapter } from './adapter.js';
|
|
5
|
+
import { normalizeResult } from './result.js';
|
|
6
|
+
/**
|
|
7
|
+
* MySQL database client implementing the db-core DatabaseClient contract.
|
|
8
|
+
* Mirrors PostgresClient so application code can switch engines transparently.
|
|
9
|
+
*/
|
|
10
|
+
export class MysqlClient {
|
|
11
|
+
pool;
|
|
12
|
+
logger;
|
|
13
|
+
sqlAdapter;
|
|
14
|
+
isInitialized = false;
|
|
15
|
+
constructor(config, logger) {
|
|
16
|
+
this.logger = logger.child('mysql-client');
|
|
17
|
+
this.sqlAdapter = new MysqlSqlAdapter();
|
|
18
|
+
this.pool = mysql.createPool({
|
|
19
|
+
host: config.host,
|
|
20
|
+
port: config.port,
|
|
21
|
+
database: config.database,
|
|
22
|
+
user: config.user,
|
|
23
|
+
password: config.password,
|
|
24
|
+
connectionLimit: config.max || 10,
|
|
25
|
+
idleTimeout: config.idleTimeoutMillis || 30000,
|
|
26
|
+
connectTimeout: config.connectionTimeoutMillis || 60000,
|
|
27
|
+
// Needed so multi-statement migration files run like they do under `pg`.
|
|
28
|
+
multipleStatements: config.multipleStatements ?? false,
|
|
29
|
+
timezone: config.timezone || 'Z',
|
|
30
|
+
charset: config.charset || 'utf8mb4',
|
|
31
|
+
waitForConnections: true,
|
|
32
|
+
enableKeepAlive: true,
|
|
33
|
+
// Keep DECIMAL/BIGINT as JS-safe values.
|
|
34
|
+
decimalNumbers: true
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async initialize() {
|
|
38
|
+
if (this.isInitialized) {
|
|
39
|
+
this.logger.warn('Database already initialized');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const conn = await this.pool.getConnection();
|
|
44
|
+
await conn.query('SELECT 1');
|
|
45
|
+
conn.release();
|
|
46
|
+
this.isInitialized = true;
|
|
47
|
+
this.logger.info('MySQL client initialized');
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.logger.error('Failed to initialize MySQL client', error);
|
|
51
|
+
throw new ConnectionError(`Failed to initialize MySQL client: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async close() {
|
|
55
|
+
if (!this.isInitialized || !this.pool)
|
|
56
|
+
return;
|
|
57
|
+
try {
|
|
58
|
+
await this.pool.end();
|
|
59
|
+
this.isInitialized = false;
|
|
60
|
+
this.logger.info('MySQL client closed');
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
this.logger.error('Failed to close MySQL client', error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
getDatabaseType() {
|
|
68
|
+
return 'mysql';
|
|
69
|
+
}
|
|
70
|
+
getSqlAdapter() {
|
|
71
|
+
return this.sqlAdapter;
|
|
72
|
+
}
|
|
73
|
+
supportsReturning() {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
async query(sql, params = []) {
|
|
77
|
+
if (!this.isInitialized || !this.pool) {
|
|
78
|
+
throw new ConnectionError('MySQL client not initialized');
|
|
79
|
+
}
|
|
80
|
+
const timer = this.logger.startTimer('query');
|
|
81
|
+
try {
|
|
82
|
+
this.logger.debug('Executing query', {
|
|
83
|
+
sql: sql.substring(0, 100) + (sql.length > 100 ? '...' : ''),
|
|
84
|
+
paramCount: params.length
|
|
85
|
+
});
|
|
86
|
+
const [rows, fields] = await this.pool.query(sql, params);
|
|
87
|
+
return normalizeResult(rows, fields);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.logger.error('Query execution failed', error instanceof Error ? error : new Error(String(error)), { error, sql, params });
|
|
91
|
+
throw new QueryError(`Query execution failed: ${error.message}`, sql, params, error);
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
timer();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async transaction(callback) {
|
|
98
|
+
if (!this.isInitialized || !this.pool) {
|
|
99
|
+
throw new ConnectionError('MySQL client not initialized');
|
|
100
|
+
}
|
|
101
|
+
const connection = await this.pool.getConnection();
|
|
102
|
+
const transactionLogger = this.logger.child('transaction');
|
|
103
|
+
const timer = transactionLogger.startTimer('transaction');
|
|
104
|
+
const transaction = new MysqlTransaction(connection, this.logger);
|
|
105
|
+
try {
|
|
106
|
+
await connection.beginTransaction();
|
|
107
|
+
transactionLogger.debug('Transaction started');
|
|
108
|
+
const result = await callback(transaction);
|
|
109
|
+
await transaction.commit();
|
|
110
|
+
transactionLogger.debug('MySQL transaction committed');
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// rollback() is safe to call once; it also releases the connection.
|
|
115
|
+
await transaction.rollback().catch(() => {
|
|
116
|
+
/* connection may already be released */
|
|
117
|
+
});
|
|
118
|
+
transactionLogger.error('Transaction rolled back', error);
|
|
119
|
+
throw new TransactionError(`Transaction failed: ${error.message}`, error);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
timer();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async healthCheck() {
|
|
126
|
+
const startTime = Date.now();
|
|
127
|
+
try {
|
|
128
|
+
if (!this.pool) {
|
|
129
|
+
return {
|
|
130
|
+
status: 'unhealthy',
|
|
131
|
+
message: 'Connection pool not initialized',
|
|
132
|
+
timestamp: new Date(),
|
|
133
|
+
responseTime: Date.now() - startTime
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
await this.pool.query('SELECT 1');
|
|
137
|
+
return {
|
|
138
|
+
status: 'healthy',
|
|
139
|
+
message: 'Connection successful',
|
|
140
|
+
timestamp: new Date(),
|
|
141
|
+
responseTime: Date.now() - startTime
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
status: 'unhealthy',
|
|
147
|
+
message: error.message,
|
|
148
|
+
timestamp: new Date(),
|
|
149
|
+
responseTime: Date.now() - startTime
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
isReady() {
|
|
154
|
+
return this.isInitialized && this.pool !== null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export { MysqlTransaction };
|
|
158
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Logger } from '@groundbrick/logger';
|
|
2
|
+
import { DatabaseFactory, DatabaseConfig } from '@groundbrick/db-core';
|
|
3
|
+
import { MysqlClient } from './client.js';
|
|
4
|
+
/**
|
|
5
|
+
* MySQL database factory (singleton). Caches one client per connection key,
|
|
6
|
+
* mirroring PostgresDatabaseFactory.
|
|
7
|
+
*/
|
|
8
|
+
export declare class MysqlDatabaseFactory implements DatabaseFactory {
|
|
9
|
+
private static instance;
|
|
10
|
+
private clients;
|
|
11
|
+
private defaultLogger;
|
|
12
|
+
private constructor();
|
|
13
|
+
static getInstance(): MysqlDatabaseFactory;
|
|
14
|
+
getInstance(config: DatabaseConfig, logger?: Logger): MysqlClient;
|
|
15
|
+
closeInstance(): Promise<void>;
|
|
16
|
+
private generateClientKey;
|
|
17
|
+
}
|
|
18
|
+
export declare const MysqlFactory: MysqlDatabaseFactory;
|
|
19
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO;IAIP,MAAM,CAAC,WAAW,IAAI,oBAAoB;IAO1C,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;IAc3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBpC,OAAO,CAAC,iBAAiB;CAG1B;AAGD,eAAO,MAAM,YAAY,sBAAqC,CAAC"}
|
package/dist/factory.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createLogger } from '@groundbrick/logger';
|
|
2
|
+
import { MysqlClient } from './client.js';
|
|
3
|
+
/**
|
|
4
|
+
* MySQL database factory (singleton). Caches one client per connection key,
|
|
5
|
+
* mirroring PostgresDatabaseFactory.
|
|
6
|
+
*/
|
|
7
|
+
export class MysqlDatabaseFactory {
|
|
8
|
+
static instance = null;
|
|
9
|
+
clients = new Map();
|
|
10
|
+
defaultLogger;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.defaultLogger = createLogger({ context: 'mysql-factory' });
|
|
13
|
+
}
|
|
14
|
+
static getInstance() {
|
|
15
|
+
if (!MysqlDatabaseFactory.instance) {
|
|
16
|
+
MysqlDatabaseFactory.instance = new MysqlDatabaseFactory();
|
|
17
|
+
}
|
|
18
|
+
return MysqlDatabaseFactory.instance;
|
|
19
|
+
}
|
|
20
|
+
getInstance(config, logger) {
|
|
21
|
+
const clientKey = this.generateClientKey(config);
|
|
22
|
+
if (this.clients.has(clientKey)) {
|
|
23
|
+
this.defaultLogger.debug('Reusing existing MySQL client', { key: clientKey });
|
|
24
|
+
return this.clients.get(clientKey);
|
|
25
|
+
}
|
|
26
|
+
const clientLogger = logger || this.defaultLogger;
|
|
27
|
+
const client = new MysqlClient(config, clientLogger.child('mysql-client'));
|
|
28
|
+
this.clients.set(clientKey, client);
|
|
29
|
+
this.defaultLogger.info('Created new MySQL client', { key: clientKey });
|
|
30
|
+
return client;
|
|
31
|
+
}
|
|
32
|
+
async closeInstance() {
|
|
33
|
+
this.defaultLogger.info('Closing all MySQL connections');
|
|
34
|
+
const closePromises = Array.from(this.clients.values()).map((client) => client.close().catch((error) => this.defaultLogger.error('Error closing client', error instanceof Error ? error : new Error(String(error)), { error })));
|
|
35
|
+
await Promise.all(closePromises);
|
|
36
|
+
this.clients.clear();
|
|
37
|
+
MysqlDatabaseFactory.instance = null;
|
|
38
|
+
}
|
|
39
|
+
generateClientKey(config) {
|
|
40
|
+
return `${config.host}:${config.port}:${config.database}:${config.user}`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Default factory instance for convenience.
|
|
44
|
+
export const MysqlFactory = MysqlDatabaseFactory.getInstance();
|
|
45
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAC,QAAQ,GAAgC,IAAI,CAAC;IACpD,OAAO,GAA6B,IAAI,GAAG,EAAE,CAAC;IAC9C,aAAa,CAAS;IAE9B;QACE,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC;YACnC,oBAAoB,CAAC,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7D,CAAC;QACD,OAAO,oBAAoB,CAAC,QAAQ,CAAC;IACvC,CAAC;IAED,WAAW,CAAC,MAAsB,EAAE,MAAe;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;YAC9E,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;QACtC,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAqB,EAAE,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACzD,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACrE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7B,IAAI,CAAC,aAAa,CAAC,KAAK,CACtB,sBAAsB,EACtB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACzD,EAAE,KAAK,EAAE,CACV,CACF,CACF,CAAC;QACF,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,oBAAoB,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvC,CAAC;IAEO,iBAAiB,CAAC,MAAsB;QAC9C,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;;AAGH,4CAA4C;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { MysqlClient, MysqlTransaction } from './client.js';
|
|
2
|
+
export { MysqlDatabaseFactory, MysqlFactory } from './factory.js';
|
|
3
|
+
export { MysqlMigrator } from './migrator.js';
|
|
4
|
+
export { MysqlSqlAdapter } from './adapter.js';
|
|
5
|
+
export { normalizeResult } from './result.js';
|
|
6
|
+
export type { MysqlConfig } from './types.js';
|
|
7
|
+
export type { DatabaseClient, QueryResult, Transaction, Migration, MigrationRecord, HealthCheckResult, ConnectionError, QueryError, MigrationError } from '@groundbrick/db-core';
|
|
8
|
+
export { createLogger } from '@groundbrick/logger';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { MysqlClient, MysqlTransaction } from './client.js';
|
|
2
|
+
export { MysqlDatabaseFactory, MysqlFactory } from './factory.js';
|
|
3
|
+
export { MysqlMigrator } from './migrator.js';
|
|
4
|
+
export { MysqlSqlAdapter } from './adapter.js';
|
|
5
|
+
export { normalizeResult } from './result.js';
|
|
6
|
+
export { createLogger } from '@groundbrick/logger';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgB9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Logger } from '@groundbrick/logger';
|
|
2
|
+
import { DatabaseClient, Migration, MigrationRecord } from '@groundbrick/db-core';
|
|
3
|
+
/**
|
|
4
|
+
* MySQL migrator. Mirrors PostgresMigrator: reads `NNN_name.sql` files (each
|
|
5
|
+
* with `-- UP` / `-- DOWN` sections), tracks applied ones in `schema_migrations`.
|
|
6
|
+
*
|
|
7
|
+
* Note: MySQL implicitly commits on DDL, so a failed multi-statement migration
|
|
8
|
+
* is not atomically rolled back the way it is in PostgreSQL. Keep each migration
|
|
9
|
+
* focused and idempotent (use IF NOT EXISTS / IF EXISTS).
|
|
10
|
+
*/
|
|
11
|
+
export declare class MysqlMigrator {
|
|
12
|
+
private client;
|
|
13
|
+
private migrationsPath;
|
|
14
|
+
private logger;
|
|
15
|
+
constructor(client: DatabaseClient, migrationsPath: string, logger: Logger);
|
|
16
|
+
initialize(): Promise<void>;
|
|
17
|
+
migrate(): Promise<void>;
|
|
18
|
+
rollback(steps?: number): Promise<void>;
|
|
19
|
+
getPending(): Promise<Migration[]>;
|
|
20
|
+
getApplied(): Promise<MigrationRecord[]>;
|
|
21
|
+
getStatus(): Promise<{
|
|
22
|
+
total: number;
|
|
23
|
+
applied: number;
|
|
24
|
+
pending: string[];
|
|
25
|
+
}>;
|
|
26
|
+
private loadMigrations;
|
|
27
|
+
private parseMigration;
|
|
28
|
+
private applyMigration;
|
|
29
|
+
private rollbackMigration;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=migrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAkB,MAAM,sBAAsB,CAAC;AAElG;;;;;;;GAOG;AACH,qBAAa,aAAa;IAEtB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,MAAM;gBAFN,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM;IAGlB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBxB,QAAQ,CAAC,KAAK,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlC,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAMlC,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAOxC,SAAS,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;YASnE,cAAc;IAsB5B,OAAO,CAAC,cAAc;YAoBR,cAAc;YAuBd,iBAAiB;CAsBhC"}
|
package/dist/migrator.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { readdir, readFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { createHash } from 'crypto';
|
|
4
|
+
import { MigrationError } from '@groundbrick/db-core';
|
|
5
|
+
/**
|
|
6
|
+
* MySQL migrator. Mirrors PostgresMigrator: reads `NNN_name.sql` files (each
|
|
7
|
+
* with `-- UP` / `-- DOWN` sections), tracks applied ones in `schema_migrations`.
|
|
8
|
+
*
|
|
9
|
+
* Note: MySQL implicitly commits on DDL, so a failed multi-statement migration
|
|
10
|
+
* is not atomically rolled back the way it is in PostgreSQL. Keep each migration
|
|
11
|
+
* focused and idempotent (use IF NOT EXISTS / IF EXISTS).
|
|
12
|
+
*/
|
|
13
|
+
export class MysqlMigrator {
|
|
14
|
+
client;
|
|
15
|
+
migrationsPath;
|
|
16
|
+
logger;
|
|
17
|
+
constructor(client, migrationsPath, logger) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
this.migrationsPath = migrationsPath;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
}
|
|
22
|
+
async initialize() {
|
|
23
|
+
try {
|
|
24
|
+
await this.client.query(`
|
|
25
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
26
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
27
|
+
description TEXT NOT NULL,
|
|
28
|
+
checksum VARCHAR(64) NOT NULL,
|
|
29
|
+
applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
30
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
|
31
|
+
`);
|
|
32
|
+
this.logger.info('Migration table initialized');
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
this.logger.error('Failed to initialize migration table', error instanceof Error ? error : new Error(String(error)), { error });
|
|
36
|
+
throw new MigrationError(`Failed to initialize migration table: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async migrate() {
|
|
40
|
+
await this.initialize();
|
|
41
|
+
const pending = await this.getPending();
|
|
42
|
+
if (pending.length === 0) {
|
|
43
|
+
this.logger.info('No pending migrations');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.logger.info(`Applying ${pending.length} migrations`, { migrations: pending.map((m) => m.id) });
|
|
47
|
+
for (const migration of pending) {
|
|
48
|
+
await this.applyMigration(migration);
|
|
49
|
+
}
|
|
50
|
+
this.logger.info('All migrations applied successfully');
|
|
51
|
+
}
|
|
52
|
+
async rollback(steps = 1) {
|
|
53
|
+
await this.initialize();
|
|
54
|
+
const applied = await this.getApplied();
|
|
55
|
+
const toRollback = applied.slice(-steps);
|
|
56
|
+
if (toRollback.length === 0) {
|
|
57
|
+
this.logger.info('No migrations to rollback');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.logger.info(`Rolling back ${toRollback.length} migrations`, {
|
|
61
|
+
migrations: toRollback.map((m) => m.id)
|
|
62
|
+
});
|
|
63
|
+
for (const migration of toRollback.reverse()) {
|
|
64
|
+
await this.rollbackMigration(migration);
|
|
65
|
+
}
|
|
66
|
+
this.logger.info('Rollback completed successfully');
|
|
67
|
+
}
|
|
68
|
+
async getPending() {
|
|
69
|
+
const [allMigrations, appliedRecords] = await Promise.all([this.loadMigrations(), this.getApplied()]);
|
|
70
|
+
const appliedIds = new Set(appliedRecords.map((r) => r.id));
|
|
71
|
+
return allMigrations.filter((m) => !appliedIds.has(m.id));
|
|
72
|
+
}
|
|
73
|
+
async getApplied() {
|
|
74
|
+
const result = await this.client.query('SELECT * FROM schema_migrations ORDER BY applied_at, id');
|
|
75
|
+
return result.rows;
|
|
76
|
+
}
|
|
77
|
+
async getStatus() {
|
|
78
|
+
const [allMigrations, pending] = await Promise.all([this.loadMigrations(), this.getPending()]);
|
|
79
|
+
return {
|
|
80
|
+
total: allMigrations.length,
|
|
81
|
+
applied: allMigrations.length - pending.length,
|
|
82
|
+
pending: pending.map((m) => m.id)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async loadMigrations() {
|
|
86
|
+
try {
|
|
87
|
+
const files = await readdir(this.migrationsPath);
|
|
88
|
+
const migrationFiles = files.filter((file) => file.endsWith('.sql')).sort();
|
|
89
|
+
const migrations = [];
|
|
90
|
+
for (const file of migrationFiles) {
|
|
91
|
+
const content = await readFile(join(this.migrationsPath, file), 'utf8');
|
|
92
|
+
migrations.push(this.parseMigration(file, content));
|
|
93
|
+
}
|
|
94
|
+
return migrations;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
this.logger.error('Failed to load migrations', error instanceof Error ? error : new Error(String(error)), { error, path: this.migrationsPath });
|
|
98
|
+
throw new MigrationError(`Failed to load migrations: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
parseMigration(filename, content) {
|
|
102
|
+
const id = filename.replace('.sql', '');
|
|
103
|
+
const firstLine = content.split('\n')[0];
|
|
104
|
+
const description = firstLine.startsWith('--') ? firstLine.slice(2).trim() : id;
|
|
105
|
+
const downIndex = content.toLowerCase().indexOf('-- down');
|
|
106
|
+
if (downIndex === -1) {
|
|
107
|
+
throw new MigrationError(`Migration ${id} missing DOWN section`);
|
|
108
|
+
}
|
|
109
|
+
const up = content.substring(0, downIndex).trim();
|
|
110
|
+
const down = content.substring(downIndex + 7).trim();
|
|
111
|
+
if (!up || !down) {
|
|
112
|
+
throw new MigrationError(`Migration ${id} has empty UP or DOWN section`);
|
|
113
|
+
}
|
|
114
|
+
const checksum = createHash('sha256').update(content).digest('hex');
|
|
115
|
+
return { id, description, up, down, checksum };
|
|
116
|
+
}
|
|
117
|
+
async applyMigration(migration) {
|
|
118
|
+
try {
|
|
119
|
+
this.logger.info(`Applying migration: ${migration.id} - ${migration.description}`);
|
|
120
|
+
// Run the DDL outside an explicit transaction (MySQL auto-commits DDL),
|
|
121
|
+
// then record it. Migrations must be idempotent.
|
|
122
|
+
await this.client.query(migration.up);
|
|
123
|
+
await this.client.query('INSERT INTO schema_migrations (id, description, checksum) VALUES (?, ?, ?)', [migration.id, migration.description, migration.checksum]);
|
|
124
|
+
this.logger.info(`Migration applied successfully: ${migration.id}`);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
this.logger.error(`Failed to apply migration: ${migration.id}`, error instanceof Error ? error : new Error(String(error)), { error });
|
|
128
|
+
throw new MigrationError(`Failed to apply migration ${migration.id}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async rollbackMigration(record) {
|
|
132
|
+
try {
|
|
133
|
+
this.logger.info(`Rolling back migration: ${record.id} - ${record.description}`);
|
|
134
|
+
const migrations = await this.loadMigrations();
|
|
135
|
+
const migration = migrations.find((m) => m.id === record.id);
|
|
136
|
+
if (!migration) {
|
|
137
|
+
throw new MigrationError(`Migration file not found for ${record.id}`);
|
|
138
|
+
}
|
|
139
|
+
await this.client.query(migration.down);
|
|
140
|
+
await this.client.query('DELETE FROM schema_migrations WHERE id = ?', [record.id]);
|
|
141
|
+
this.logger.info(`Migration rolled back successfully: ${record.id}`);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
this.logger.error(`Failed to rollback migration: ${record.id}`, error instanceof Error ? error : new Error(String(error)), { error });
|
|
145
|
+
throw new MigrationError(`Failed to rollback migration ${record.id}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=migrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FieldPacket } from 'mysql2/promise';
|
|
2
|
+
import { QueryResult } from '@groundbrick/db-core';
|
|
3
|
+
/**
|
|
4
|
+
* Normaliza o tuplo `[result, fields]` do mysql2 para o formato QueryResult.
|
|
5
|
+
*
|
|
6
|
+
* - SELECT / SHOW → `result` é um array de row objects.
|
|
7
|
+
* - INSERT / UPDATE / DELETE / DDL → `result` é um ResultSetHeader.
|
|
8
|
+
* - Multi-statement (migrations) → `result` é um array de ResultSetHeaders/arrays;
|
|
9
|
+
* agregamos os affectedRows e não devolvemos linhas.
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizeResult<T>(raw: any, fields?: FieldPacket[]): QueryResult<T>;
|
|
12
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAanD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAsBnF"}
|
package/dist/result.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function safeFields(fields) {
|
|
2
|
+
if (!Array.isArray(fields))
|
|
3
|
+
return undefined;
|
|
4
|
+
return fields
|
|
5
|
+
.filter((f) => f && typeof f === 'object' && 'name' in f)
|
|
6
|
+
.map((f) => ({ name: f.name }));
|
|
7
|
+
}
|
|
8
|
+
function isResultSetHeader(r) {
|
|
9
|
+
return r && typeof r === 'object' && ('affectedRows' in r || 'fieldCount' in r || 'insertId' in r);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Normaliza o tuplo `[result, fields]` do mysql2 para o formato QueryResult.
|
|
13
|
+
*
|
|
14
|
+
* - SELECT / SHOW → `result` é um array de row objects.
|
|
15
|
+
* - INSERT / UPDATE / DELETE / DDL → `result` é um ResultSetHeader.
|
|
16
|
+
* - Multi-statement (migrations) → `result` é um array de ResultSetHeaders/arrays;
|
|
17
|
+
* agregamos os affectedRows e não devolvemos linhas.
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeResult(raw, fields) {
|
|
20
|
+
if (Array.isArray(raw)) {
|
|
21
|
+
// Multi-statement: elementos são headers (ou arrays de rows por statement).
|
|
22
|
+
const multi = raw.length > 0 && raw.some((r) => isResultSetHeader(r) || Array.isArray(r));
|
|
23
|
+
if (multi) {
|
|
24
|
+
const total = raw.reduce((acc, r) => acc + (r && typeof r.affectedRows === 'number' ? r.affectedRows : 0), 0);
|
|
25
|
+
return { rows: [], rowCount: total, fields: [] };
|
|
26
|
+
}
|
|
27
|
+
// SELECT de um único statement: array de row objects.
|
|
28
|
+
return { rows: raw, rowCount: raw.length, fields: safeFields(fields) };
|
|
29
|
+
}
|
|
30
|
+
// ResultSetHeader (não-SELECT, statement único).
|
|
31
|
+
const header = raw ?? {};
|
|
32
|
+
return {
|
|
33
|
+
rows: [],
|
|
34
|
+
rowCount: typeof header.affectedRows === 'number' ? header.affectedRows : 0,
|
|
35
|
+
fields: []
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAGA,SAAS,UAAU,CAAC,MAAsB;IACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAK,CAAS,CAAC;SACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAG,CAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAM;IAC/B,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC;AACrG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAI,GAAQ,EAAE,MAAsB;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,4EAA4E;QAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CACtB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAChF,CAAC,CACF,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACnD,CAAC;QACD,sDAAsD;QACtD,OAAO,EAAE,IAAI,EAAE,GAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IAChF,CAAC;IAED,iDAAiD;IACjD,MAAM,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC;IACzB,OAAO;QACL,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3E,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PoolConnection } from 'mysql2/promise';
|
|
2
|
+
import { Logger } from '@groundbrick/logger';
|
|
3
|
+
import { BaseTransaction, QueryResult } from '@groundbrick/db-core';
|
|
4
|
+
/**
|
|
5
|
+
* MySQL transaction implementation using the unified BaseTransaction.
|
|
6
|
+
* Holds a single pooled connection for the lifetime of the transaction.
|
|
7
|
+
*/
|
|
8
|
+
export declare class MysqlTransaction extends BaseTransaction {
|
|
9
|
+
private readonly connection;
|
|
10
|
+
constructor(connection: PoolConnection, logger: Logger);
|
|
11
|
+
query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
|
|
12
|
+
protected doCommit(): Promise<void>;
|
|
13
|
+
protected doRollback(): Promise<void>;
|
|
14
|
+
protected doCleanup(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAc,eAAe,EAAE,WAAW,EAAoB,MAAM,sBAAsB,CAAC;AAGlG;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,eAAe;IAEjD,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,cAAc,EAC3C,MAAM,EAAE,MAAM;IAKV,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;cA6B9D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;cAKzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cAK3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAG3C"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { QueryError, BaseTransaction, TransactionError } from '@groundbrick/db-core';
|
|
2
|
+
import { normalizeResult } from './result.js';
|
|
3
|
+
/**
|
|
4
|
+
* MySQL transaction implementation using the unified BaseTransaction.
|
|
5
|
+
* Holds a single pooled connection for the lifetime of the transaction.
|
|
6
|
+
*/
|
|
7
|
+
export class MysqlTransaction extends BaseTransaction {
|
|
8
|
+
connection;
|
|
9
|
+
constructor(connection, logger) {
|
|
10
|
+
super(logger, 'mysql');
|
|
11
|
+
this.connection = connection;
|
|
12
|
+
}
|
|
13
|
+
async query(sql, params = []) {
|
|
14
|
+
if (this.completed) {
|
|
15
|
+
throw new TransactionError('Transaction has already been completed');
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
this.logger.debug('Executing MySQL transaction query', {
|
|
19
|
+
sql: sql.substring(0, 100) + (sql.length > 100 ? '...' : ''),
|
|
20
|
+
paramCount: params.length,
|
|
21
|
+
dbType: this.dbType
|
|
22
|
+
});
|
|
23
|
+
const [rows, fields] = await this.connection.query(sql, params);
|
|
24
|
+
return normalizeResult(rows, fields);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
this.logger.error('MySQL transaction query failed', error instanceof Error ? error : new Error(String(error)), { error, sql, params, dbType: this.dbType });
|
|
28
|
+
throw new QueryError(`MySQL transaction query failed: ${error.message}`, sql, params, error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async doCommit() {
|
|
32
|
+
await this.connection.commit();
|
|
33
|
+
await this.ensureCleanup();
|
|
34
|
+
}
|
|
35
|
+
async doRollback() {
|
|
36
|
+
await this.connection.rollback();
|
|
37
|
+
await this.ensureCleanup();
|
|
38
|
+
}
|
|
39
|
+
async doCleanup() {
|
|
40
|
+
this.connection.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAe,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,eAAe;IAEhC;IADnB,YACmB,UAA0B,EAC3C,MAAc;QAEd,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAHN,eAAU,GAAV,UAAU,CAAgB;IAI7C,CAAC;IAED,KAAK,CAAC,KAAK,CAAU,GAAW,EAAE,SAAgB,EAAE;QAClD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,gBAAgB,CAAC,wCAAwC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;gBACrD,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,UAAU,EAAE,MAAM,CAAC,MAAM;gBACzB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAChE,OAAO,eAAe,CAAI,IAAI,EAAE,MAAa,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,gCAAgC,EAChC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACzD,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAC5C,CAAC;YACF,MAAM,IAAI,UAAU,CAClB,mCAAoC,KAAe,CAAC,OAAO,EAAE,EAC7D,GAAG,EACH,MAAM,EACN,KAAc,CACf,CAAC;QACJ,CAAC;IACH,CAAC;IAES,KAAK,CAAC,QAAQ;QACtB,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,UAAU;QACxB,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DatabaseConfig as CoreDatabaseConfig, DatabaseClient, QueryResult, Transaction, Migration, MigrationRecord, HealthCheckResult, ConnectionError, QueryError, MigrationError } from '@groundbrick/db-core';
|
|
2
|
+
/**
|
|
3
|
+
* MySQL-specific configuration extending the core contract.
|
|
4
|
+
*/
|
|
5
|
+
export interface MysqlConfig extends CoreDatabaseConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Allow more than one SQL statement per query() call. Required for running
|
|
8
|
+
* migration files that contain several DDL statements (mirrors how `pg`
|
|
9
|
+
* accepts multi-statement strings). App-level queries always use single,
|
|
10
|
+
* parameterized statements.
|
|
11
|
+
*/
|
|
12
|
+
multipleStatements?: boolean;
|
|
13
|
+
timezone?: string;
|
|
14
|
+
charset?: string;
|
|
15
|
+
}
|
|
16
|
+
export type { DatabaseClient, QueryResult, Transaction, Migration, MigrationRecord, HealthCheckResult, ConnectionError, QueryError, MigrationError };
|
|
17
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,IAAI,kBAAkB,EACpC,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,YAAY,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,cAAc,EACf,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@groundbrick/db-mysql",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MySQL database client implementing the @groundbrick/db-core contract (mirror of db-postgres).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/**/*",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
24
|
+
"test": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"typescript",
|
|
28
|
+
"mysql",
|
|
29
|
+
"database",
|
|
30
|
+
"migrations",
|
|
31
|
+
"connection-pooling",
|
|
32
|
+
"microframework"
|
|
33
|
+
],
|
|
34
|
+
"author": "Cleiton Marques <cleiton.marques@200.systems>",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/200Systems/bitbrick-microframework.git",
|
|
39
|
+
"directory": "packages/db-mysql"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@groundbrick/db-core": "^0.2.1",
|
|
43
|
+
"@groundbrick/logger": "^0.4.1"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"mysql2": "^3.11.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.10.0",
|
|
50
|
+
"mysql2": "^3.11.0",
|
|
51
|
+
"typescript": "^5.8.3",
|
|
52
|
+
"vitest": "^2.0.0"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|