@grest-ts/db-mysql 0.0.5
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/LICENSE +21 -0
- package/dist/src/GGMysql.d.ts +30 -0
- package/dist/src/GGMysql.d.ts.map +1 -0
- package/dist/src/GGMysql.js +122 -0
- package/dist/src/GGMysql.js.map +1 -0
- package/dist/src/GGMysqlConfig.d.ts +26 -0
- package/dist/src/GGMysqlConfig.d.ts.map +1 -0
- package/dist/src/GGMysqlConfig.js +32 -0
- package/dist/src/GGMysqlConfig.js.map +1 -0
- package/dist/src/GGMysqlConnection.d.ts +82 -0
- package/dist/src/GGMysqlConnection.d.ts.map +1 -0
- package/dist/src/GGMysqlConnection.js +147 -0
- package/dist/src/GGMysqlConnection.js.map +1 -0
- package/dist/src/index-node.d.ts +5 -0
- package/dist/src/index-node.d.ts.map +1 -0
- package/dist/src/index-node.js +4 -0
- package/dist/src/index-node.js.map +1 -0
- package/dist/src/tsconfig.json +16 -0
- package/dist/testkit/GGMysqlSchemaCloner.d.ts +13 -0
- package/dist/testkit/GGMysqlSchemaCloner.d.ts.map +1 -0
- package/dist/testkit/GGMysqlSchemaCloner.js +51 -0
- package/dist/testkit/GGMysqlSchemaCloner.js.map +1 -0
- package/dist/testkit/GGMysqlSchemaOperations.d.ts +20 -0
- package/dist/testkit/GGMysqlSchemaOperations.d.ts.map +1 -0
- package/dist/testkit/GGMysqlSchemaOperations.js +95 -0
- package/dist/testkit/GGMysqlSchemaOperations.js.map +1 -0
- package/dist/testkit/GGMysqlTestMethods.d.ts +47 -0
- package/dist/testkit/GGMysqlTestMethods.d.ts.map +1 -0
- package/dist/testkit/GGMysqlTestMethods.js +106 -0
- package/dist/testkit/GGMysqlTestMethods.js.map +1 -0
- package/dist/testkit/index-testkit.d.ts +3 -0
- package/dist/testkit/index-testkit.d.ts.map +1 -0
- package/dist/testkit/index-testkit.js +3 -0
- package/dist/testkit/index-testkit.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +61 -0
- package/src/GGMysql.ts +142 -0
- package/src/GGMysqlConfig.ts +39 -0
- package/src/GGMysqlConnection.ts +156 -0
- package/src/index-node.ts +4 -0
- package/src/tsconfig.json +16 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Grest Games OÜ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ResultSetHeader, RowDataPacket } from 'mysql2/promise';
|
|
2
|
+
import { GGMysqlConnection } from './GGMysqlConnection';
|
|
3
|
+
import type { GGMysqlConfig } from "./GGMysqlConfig";
|
|
4
|
+
export declare class GGMysql {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private started;
|
|
7
|
+
private pool;
|
|
8
|
+
private unwatchHost;
|
|
9
|
+
private unwatchUser;
|
|
10
|
+
constructor(config: GGMysqlConfig);
|
|
11
|
+
private connect;
|
|
12
|
+
private start;
|
|
13
|
+
private teardown;
|
|
14
|
+
private getPool;
|
|
15
|
+
query<T extends RowDataPacket[]>(sql: string, params?: unknown[]): Promise<T>;
|
|
16
|
+
execute(sql: string, params?: unknown[]): Promise<ResultSetHeader>;
|
|
17
|
+
/**
|
|
18
|
+
* Get a dedicated connection from the pool.
|
|
19
|
+
* Use this for transactions or when you need multiple queries on the same connection.
|
|
20
|
+
*
|
|
21
|
+
* IMPORTANT: Always call release() on the connection when done.
|
|
22
|
+
*/
|
|
23
|
+
getConnection(): Promise<GGMysqlConnection>;
|
|
24
|
+
/**
|
|
25
|
+
* Run a callback within a transaction.
|
|
26
|
+
* Automatically handles connection lifecycle, commits on success, rolls back on failure.
|
|
27
|
+
*/
|
|
28
|
+
runInTransaction<T>(callback: (conn: GGMysqlConnection) => Promise<T>): Promise<T>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=GGMysql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysql.d.ts","sourceRoot":"","sources":["../../src/GGMysql.ts"],"names":[],"mappings":"AAAA,OAAc,EAAO,eAAe,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAG3E,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAEnD,qBAAa,OAAO;IAEhB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAuC;gBAE9C,MAAM,EAAE,aAAa;YAanB,OAAO;YAiDP,KAAK;YAKL,QAAQ;IAYtB,OAAO,CAAC,OAAO;IAOF,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAO7E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAS/E;;;;;OAKG;IACU,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAKxD;;;OAGG;IACU,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAQlG"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import mysql from 'mysql2/promise';
|
|
2
|
+
import { GGLocator, GGLocatorServiceType } from '@grest-ts/locator';
|
|
3
|
+
import { GGLog } from '@grest-ts/logger';
|
|
4
|
+
import { GGMysqlConnection } from './GGMysqlConnection.js';
|
|
5
|
+
export class GGMysql {
|
|
6
|
+
config;
|
|
7
|
+
started = false;
|
|
8
|
+
pool = null;
|
|
9
|
+
unwatchHost = undefined;
|
|
10
|
+
unwatchUser = undefined;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.unwatchHost = this.config.host.watch(() => this.connect().catch(() => { }));
|
|
14
|
+
this.unwatchUser = this.config.user.watch(() => this.connect().catch(() => { }));
|
|
15
|
+
GGLocator.getScope().setWithLifecycle(this.config.token, this, {
|
|
16
|
+
type: GGLocatorServiceType.DATABASE,
|
|
17
|
+
start: () => this.start(),
|
|
18
|
+
teardown: () => this.teardown(),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async connect() {
|
|
22
|
+
if (!this.started) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const config = this.config.host.get();
|
|
26
|
+
const user = this.config.user.reveal();
|
|
27
|
+
const connectionsLimit = config.connectionLimit ?? 20;
|
|
28
|
+
const newPool = mysql.createPool({
|
|
29
|
+
host: config.host ?? "localhost",
|
|
30
|
+
port: config.port ?? 3306,
|
|
31
|
+
user: user.username,
|
|
32
|
+
password: user.password,
|
|
33
|
+
database: config.database,
|
|
34
|
+
connectionLimit: connectionsLimit,
|
|
35
|
+
waitForConnections: true,
|
|
36
|
+
queueLimit: connectionsLimit * 2,
|
|
37
|
+
decimalNumbers: true,
|
|
38
|
+
dateStrings: true,
|
|
39
|
+
});
|
|
40
|
+
try {
|
|
41
|
+
const conn = await newPool.getConnection();
|
|
42
|
+
await conn.ping();
|
|
43
|
+
conn.release();
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
GGLog.critical(this, 'Failed to connect to database!', {
|
|
47
|
+
database: config.database,
|
|
48
|
+
host: config.host,
|
|
49
|
+
error: err instanceof Error ? err.message : String(err)
|
|
50
|
+
});
|
|
51
|
+
await newPool.end();
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
if (this.pool) {
|
|
55
|
+
this.pool.end().catch(err => {
|
|
56
|
+
GGLog.warn(this, 'Config change: error closing old pool', {
|
|
57
|
+
error: err instanceof Error ? err.message : String(err)
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
this.pool = newPool;
|
|
62
|
+
GGLog.info(this, 'Mysql connected!', { database: config.database });
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
this.started = true;
|
|
66
|
+
await this.connect();
|
|
67
|
+
}
|
|
68
|
+
async teardown() {
|
|
69
|
+
this.unwatchHost();
|
|
70
|
+
this.unwatchHost = undefined;
|
|
71
|
+
this.unwatchUser();
|
|
72
|
+
this.unwatchUser = undefined;
|
|
73
|
+
if (this.pool) {
|
|
74
|
+
await this.pool.end();
|
|
75
|
+
this.pool = undefined;
|
|
76
|
+
GGLog.debug(this, 'disconnected');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
getPool() {
|
|
80
|
+
if (!this.pool) {
|
|
81
|
+
throw new Error(`Mysql '${this.config.name}' not connected. Are you calling this before runtime.start()?`);
|
|
82
|
+
}
|
|
83
|
+
return this.pool;
|
|
84
|
+
}
|
|
85
|
+
async query(sql, params) {
|
|
86
|
+
GGLog.debug(this, 'query', { sql, params });
|
|
87
|
+
const [rows] = await this.getPool().query(sql, params);
|
|
88
|
+
GGLog.debug(this, 'query result', { rowCount: rows.length });
|
|
89
|
+
return rows;
|
|
90
|
+
}
|
|
91
|
+
async execute(sql, params) {
|
|
92
|
+
GGLog.debug(this, 'execute', { sql, params });
|
|
93
|
+
const [result] = await this.getPool().execute(sql, params);
|
|
94
|
+
GGLog.debug(this, 'execute result', { affectedRows: result.affectedRows, insertId: result.insertId });
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
// ==================== Connection for transactions ====================
|
|
98
|
+
/**
|
|
99
|
+
* Get a dedicated connection from the pool.
|
|
100
|
+
* Use this for transactions or when you need multiple queries on the same connection.
|
|
101
|
+
*
|
|
102
|
+
* IMPORTANT: Always call release() on the connection when done.
|
|
103
|
+
*/
|
|
104
|
+
async getConnection() {
|
|
105
|
+
const poolConn = await this.getPool().getConnection();
|
|
106
|
+
return new GGMysqlConnection(poolConn);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Run a callback within a transaction.
|
|
110
|
+
* Automatically handles connection lifecycle, commits on success, rolls back on failure.
|
|
111
|
+
*/
|
|
112
|
+
async runInTransaction(callback) {
|
|
113
|
+
const conn = await this.getConnection();
|
|
114
|
+
try {
|
|
115
|
+
return await conn.runInTransaction(() => callback(conn));
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
conn.release();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=GGMysql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysql.js","sourceRoot":"","sources":["../../src/GGMysql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { GGResource, GGSecret } from "@grest-ts/config";
|
|
2
|
+
import { GGMysql } from "./GGMysql";
|
|
3
|
+
import { GGLocatorKey } from "@grest-ts/locator";
|
|
4
|
+
declare const IsMysqlResource: import("@grest-ts/schema").ObjectSchema<{
|
|
5
|
+
database: string;
|
|
6
|
+
host?: string;
|
|
7
|
+
port?: number;
|
|
8
|
+
connectionLimit?: number;
|
|
9
|
+
}>;
|
|
10
|
+
export type GGMysqlHostData = typeof IsMysqlResource.infer;
|
|
11
|
+
declare const IsMysqlUserData: import("@grest-ts/schema").ObjectSchema<{
|
|
12
|
+
username?: string;
|
|
13
|
+
password?: string;
|
|
14
|
+
}>;
|
|
15
|
+
export type GGMysqlUserData = typeof IsMysqlUserData.infer;
|
|
16
|
+
export declare class GGMysqlConfig {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly token: GGLocatorKey<GGMysql>;
|
|
19
|
+
readonly host: GGResource<GGMysqlHostData>;
|
|
20
|
+
readonly user: GGSecret<GGMysqlUserData>;
|
|
21
|
+
readonly schemaFile?: string;
|
|
22
|
+
constructor(name: string, schemaFile?: string);
|
|
23
|
+
newMysqlPool(): GGMysql;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=GGMysqlConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlConfig.d.ts","sourceRoot":"","sources":["../../src/GGMysqlConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,QAAA,MAAM,eAAe;;;;;EAKnB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,KAAK,CAAA;AAE1D,QAAA,MAAM,eAAe;;;EAGnB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,KAAK,CAAA;AAE1D,qBAAa,aAAa;IAEtB,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7C,SAAgB,IAAI,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAClD,SAAgB,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAChD,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;gBAExB,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAQtC,YAAY;CAGtB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GGResource, GGSecret } from "@grest-ts/config";
|
|
2
|
+
import { GGMysql } from "./GGMysql.js";
|
|
3
|
+
import { IsNumber, IsObject, IsString } from "@grest-ts/schema";
|
|
4
|
+
import { GGLocatorKey } from "@grest-ts/locator";
|
|
5
|
+
const IsMysqlResource = IsObject({
|
|
6
|
+
host: IsString.orUndefined,
|
|
7
|
+
port: IsNumber.orUndefined,
|
|
8
|
+
database: IsString,
|
|
9
|
+
connectionLimit: IsNumber.orUndefined
|
|
10
|
+
});
|
|
11
|
+
const IsMysqlUserData = IsObject({
|
|
12
|
+
username: IsString.orUndefined,
|
|
13
|
+
password: IsString.orUndefined
|
|
14
|
+
});
|
|
15
|
+
export class GGMysqlConfig {
|
|
16
|
+
name;
|
|
17
|
+
token;
|
|
18
|
+
host;
|
|
19
|
+
user;
|
|
20
|
+
schemaFile;
|
|
21
|
+
constructor(name, schemaFile) {
|
|
22
|
+
this.name = name;
|
|
23
|
+
this.token = new GGLocatorKey(`Mysql:${name}`);
|
|
24
|
+
this.host = new GGResource(name + "/host", IsMysqlResource, "Mysql host configuration");
|
|
25
|
+
this.user = new GGSecret(name + "/user", IsMysqlUserData, "Mysql user credentials");
|
|
26
|
+
this.schemaFile = schemaFile;
|
|
27
|
+
}
|
|
28
|
+
newMysqlPool() {
|
|
29
|
+
return new GGMysql(this);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=GGMysqlConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlConfig.js","sourceRoot":"","sources":["../../src/GGMysqlConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,MAAM,eAAe,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,QAAQ,CAAC,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC,WAAW;IAC1B,QAAQ,EAAE,QAAQ;IAClB,eAAe,EAAE,QAAQ,CAAC,WAAW;CACxC,CAAC,CAAC;AAGH,MAAM,eAAe,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC,WAAW;IAC9B,QAAQ,EAAE,QAAQ,CAAC,WAAW;CACjC,CAAC,CAAC;AAGH,MAAM,OAAO,aAAa;IAEN,IAAI,CAAS;IACb,KAAK,CAAwB;IAC7B,IAAI,CAA8B;IAClC,IAAI,CAA4B;IAChC,UAAU,CAAU;IAEpC,YAAY,IAAY,EAAE,UAAmB;QACzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAU,SAAS,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,OAAO,EAAE,eAAe,EAAE,0BAA0B,CAAC,CAAA;QACvF,IAAI,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,GAAG,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAA;QACnF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAEM,YAAY;QACf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PoolConnection, RowDataPacket, ResultSetHeader } from 'mysql2/promise';
|
|
2
|
+
/**
|
|
3
|
+
* MysqlConnection - A single connection from the pool.
|
|
4
|
+
*
|
|
5
|
+
* Use this when you need:
|
|
6
|
+
* - Transactions (BEGIN, COMMIT, ROLLBACK)
|
|
7
|
+
* - Multiple queries that must use the same connection
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: Always call release() when done to return the connection to the pool.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const conn = await db.getConnection();
|
|
14
|
+
* try {
|
|
15
|
+
* await conn.beginTransaction();
|
|
16
|
+
* await conn.execute('INSERT INTO users ...', [...]);
|
|
17
|
+
* await conn.execute('INSERT INTO profiles ...', [...]);
|
|
18
|
+
* await conn.commit();
|
|
19
|
+
* } catch (err) {
|
|
20
|
+
* await conn.rollback();
|
|
21
|
+
* throw err;
|
|
22
|
+
* } finally {
|
|
23
|
+
* conn.release();
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class GGMysqlConnection {
|
|
28
|
+
private conn;
|
|
29
|
+
private released;
|
|
30
|
+
constructor(conn: PoolConnection);
|
|
31
|
+
/**
|
|
32
|
+
* Execute a SELECT query and return rows.
|
|
33
|
+
*/
|
|
34
|
+
query<T extends RowDataPacket[]>(sql: string, params?: unknown[]): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Execute an INSERT, UPDATE, or DELETE query.
|
|
37
|
+
*/
|
|
38
|
+
execute(sql: string, params?: unknown[]): Promise<ResultSetHeader>;
|
|
39
|
+
/**
|
|
40
|
+
* Run a callback within a transaction.
|
|
41
|
+
* Automatically commits on success, rolls back on failure.
|
|
42
|
+
*
|
|
43
|
+
* Note: Does NOT release the connection. Call release() when done.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const conn = await db.getConnection();
|
|
48
|
+
* try {
|
|
49
|
+
* const result = await conn.runInTransaction(async () => {
|
|
50
|
+
* await conn.execute('INSERT INTO orders ...', [...]);
|
|
51
|
+
* await conn.execute('UPDATE inventory ...', [...]);
|
|
52
|
+
* return orderId;
|
|
53
|
+
* });
|
|
54
|
+
* } finally {
|
|
55
|
+
* conn.release();
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
runInTransaction<T>(callback: () => Promise<T>): Promise<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Start a transaction.
|
|
62
|
+
*/
|
|
63
|
+
beginTransaction(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Commit the current transaction.
|
|
66
|
+
*/
|
|
67
|
+
commit(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Rollback the current transaction.
|
|
70
|
+
*/
|
|
71
|
+
rollback(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Release this connection back to the pool.
|
|
74
|
+
* MUST be called when done with the connection.
|
|
75
|
+
*/
|
|
76
|
+
release(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Check if connection has been released.
|
|
79
|
+
*/
|
|
80
|
+
private checkReleased;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=GGMysqlConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlConnection.d.ts","sourceRoot":"","sources":["../../src/GGMysqlConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,cAAc;IAIhC;;OAEG;IACG,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAanF;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAexE;;;;;;;;;;;;;;;;;;;OAmBG;IACG,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgBjE;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMvC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf;;OAEG;IACH,OAAO,CAAC,aAAa;CAKxB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { GGLog } from '@grest-ts/logger';
|
|
2
|
+
/**
|
|
3
|
+
* MysqlConnection - A single connection from the pool.
|
|
4
|
+
*
|
|
5
|
+
* Use this when you need:
|
|
6
|
+
* - Transactions (BEGIN, COMMIT, ROLLBACK)
|
|
7
|
+
* - Multiple queries that must use the same connection
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: Always call release() when done to return the connection to the pool.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const conn = await db.getConnection();
|
|
14
|
+
* try {
|
|
15
|
+
* await conn.beginTransaction();
|
|
16
|
+
* await conn.execute('INSERT INTO users ...', [...]);
|
|
17
|
+
* await conn.execute('INSERT INTO profiles ...', [...]);
|
|
18
|
+
* await conn.commit();
|
|
19
|
+
* } catch (err) {
|
|
20
|
+
* await conn.rollback();
|
|
21
|
+
* throw err;
|
|
22
|
+
* } finally {
|
|
23
|
+
* conn.release();
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class GGMysqlConnection {
|
|
28
|
+
conn;
|
|
29
|
+
released = false;
|
|
30
|
+
constructor(conn) {
|
|
31
|
+
this.conn = conn;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute a SELECT query and return rows.
|
|
35
|
+
*/
|
|
36
|
+
async query(sql, params) {
|
|
37
|
+
this.checkReleased();
|
|
38
|
+
GGLog.debug(this, 'query', { sql, params });
|
|
39
|
+
try {
|
|
40
|
+
const [rows] = await this.conn.query(sql, params);
|
|
41
|
+
GGLog.debug(this, 'query result', { rowCount: rows.length });
|
|
42
|
+
return rows;
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const msg = err?.message || String(err);
|
|
46
|
+
throw new Error(`SQL query failed: ${msg}\n Query: ${sql}` + (params?.length ? `\n Params: ${JSON.stringify(params)}` : ''));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Execute an INSERT, UPDATE, or DELETE query.
|
|
51
|
+
*/
|
|
52
|
+
async execute(sql, params) {
|
|
53
|
+
this.checkReleased();
|
|
54
|
+
GGLog.debug(this, 'execute', { sql, params });
|
|
55
|
+
try {
|
|
56
|
+
const [result] = await this.conn.execute(sql, params);
|
|
57
|
+
GGLog.debug(this, 'execute result', { affectedRows: result.affectedRows, insertId: result.insertId });
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const msg = err?.message || String(err);
|
|
62
|
+
throw new Error(`SQL execute failed: ${msg}\n Query: ${sql}` + (params?.length ? `\n Params: ${JSON.stringify(params)}` : ''));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ==================== Transaction methods ====================
|
|
66
|
+
/**
|
|
67
|
+
* Run a callback within a transaction.
|
|
68
|
+
* Automatically commits on success, rolls back on failure.
|
|
69
|
+
*
|
|
70
|
+
* Note: Does NOT release the connection. Call release() when done.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const conn = await db.getConnection();
|
|
75
|
+
* try {
|
|
76
|
+
* const result = await conn.runInTransaction(async () => {
|
|
77
|
+
* await conn.execute('INSERT INTO orders ...', [...]);
|
|
78
|
+
* await conn.execute('UPDATE inventory ...', [...]);
|
|
79
|
+
* return orderId;
|
|
80
|
+
* });
|
|
81
|
+
* } finally {
|
|
82
|
+
* conn.release();
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
async runInTransaction(callback) {
|
|
87
|
+
this.checkReleased();
|
|
88
|
+
await this.conn.beginTransaction();
|
|
89
|
+
GGLog.debug(this, 'beginTransaction');
|
|
90
|
+
try {
|
|
91
|
+
const result = await callback();
|
|
92
|
+
await this.conn.commit();
|
|
93
|
+
GGLog.debug(this, 'commit');
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
await this.conn.rollback();
|
|
98
|
+
GGLog.debug(this, 'rollback', { error: err });
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Start a transaction.
|
|
104
|
+
*/
|
|
105
|
+
async beginTransaction() {
|
|
106
|
+
this.checkReleased();
|
|
107
|
+
GGLog.debug(this, 'beginTransaction');
|
|
108
|
+
await this.conn.beginTransaction();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Commit the current transaction.
|
|
112
|
+
*/
|
|
113
|
+
async commit() {
|
|
114
|
+
this.checkReleased();
|
|
115
|
+
GGLog.debug(this, 'commit');
|
|
116
|
+
await this.conn.commit();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Rollback the current transaction.
|
|
120
|
+
*/
|
|
121
|
+
async rollback() {
|
|
122
|
+
this.checkReleased();
|
|
123
|
+
GGLog.debug(this, 'rollback');
|
|
124
|
+
await this.conn.rollback();
|
|
125
|
+
}
|
|
126
|
+
// ==================== Lifecycle ====================
|
|
127
|
+
/**
|
|
128
|
+
* Release this connection back to the pool.
|
|
129
|
+
* MUST be called when done with the connection.
|
|
130
|
+
*/
|
|
131
|
+
release() {
|
|
132
|
+
if (!this.released) {
|
|
133
|
+
this.conn.release();
|
|
134
|
+
this.released = true;
|
|
135
|
+
GGLog.debug(this, 'released');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if connection has been released.
|
|
140
|
+
*/
|
|
141
|
+
checkReleased() {
|
|
142
|
+
if (this.released) {
|
|
143
|
+
throw new Error('Connection has been released. Cannot perform operations on a released connection.');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=GGMysqlConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlConnection.js","sourceRoot":"","sources":["../../src/GGMysqlConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-node.d.ts","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,YAAY,EAAC,aAAa,EAAE,eAAe,EAAE,WAAW,EAAC,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-node.js","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GGMysqlHostData, GGMysqlUserData } from "../src/GGMysqlConfig";
|
|
2
|
+
export interface GGMysqlCloneOptions {
|
|
3
|
+
/** SQL files to seed the test schema after cloning */
|
|
4
|
+
seedFiles?: string[];
|
|
5
|
+
/** SQL schema file to create the source schema if it doesn't exist */
|
|
6
|
+
schemaFile?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class GGMysqlSchemaCloner {
|
|
9
|
+
static clone(sourceConfig: GGMysqlHostData, credentials: GGMysqlUserData, schemaName: string, options?: GGMysqlCloneOptions | string[]): Promise<GGMysqlHostData>;
|
|
10
|
+
static cleanup(testConfig: GGMysqlHostData, credentials: GGMysqlUserData): Promise<void>;
|
|
11
|
+
private static getSchemaOps;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=GGMysqlSchemaCloner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlSchemaCloner.d.ts","sourceRoot":"","sources":["../../testkit/GGMysqlSchemaCloner.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,eAAe,EAAE,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAChC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,mBAAmB;WAER,KAAK,CAAC,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;WAiC1J,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;mBAShF,YAAY;CAUpC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { GGMysqlSchemaOperations } from './GGMysqlSchemaOperations.js';
|
|
2
|
+
export class GGMysqlSchemaCloner {
|
|
3
|
+
static async clone(sourceConfig, credentials, schemaName, options) {
|
|
4
|
+
// Handle backward compatibility: if options is an array, treat it as sqlFiles
|
|
5
|
+
const opts = Array.isArray(options)
|
|
6
|
+
? { seedFiles: options }
|
|
7
|
+
: (options ?? {});
|
|
8
|
+
const ops = await this.getSchemaOps(sourceConfig, credentials);
|
|
9
|
+
try {
|
|
10
|
+
// If schemaFile is provided, ensure source schema exists first
|
|
11
|
+
if (opts.schemaFile) {
|
|
12
|
+
const exists = await ops.schemaExists(sourceConfig.database);
|
|
13
|
+
if (!exists) {
|
|
14
|
+
await ops.createSchema(sourceConfig.database);
|
|
15
|
+
await ops.runSeedFiles(sourceConfig.database, [opts.schemaFile]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
await ops.cloneSchema(sourceConfig.database, schemaName);
|
|
19
|
+
if (opts.seedFiles?.length) {
|
|
20
|
+
await ops.runSeedFiles(schemaName, opts.seedFiles);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
...sourceConfig,
|
|
24
|
+
database: schemaName,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await ops.disconnect();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
static async cleanup(testConfig, credentials) {
|
|
32
|
+
const ops = await this.getSchemaOps(testConfig, credentials);
|
|
33
|
+
try {
|
|
34
|
+
await ops.dropSchema(testConfig.database);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
await ops.disconnect();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
static async getSchemaOps(config, credentials) {
|
|
41
|
+
const schemaOps = new GGMysqlSchemaOperations({
|
|
42
|
+
host: config.host,
|
|
43
|
+
port: config.port,
|
|
44
|
+
user: credentials.username,
|
|
45
|
+
password: credentials.password,
|
|
46
|
+
});
|
|
47
|
+
await schemaOps.connect();
|
|
48
|
+
return schemaOps;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=GGMysqlSchemaCloner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlSchemaCloner.js","sourceRoot":"","sources":["../../testkit/GGMysqlSchemaCloner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAUlE,MAAM,OAAO,mBAAmB;IAErB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAA6B,EAAE,WAA4B,EAAE,UAAkB,EAAE,OAAwC;QAC/I,8EAA8E;QAC9E,MAAM,IAAI,GAAwB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACpD,CAAC,CAAC,EAAC,SAAS,EAAE,OAAO,EAAC;YACtB,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAEtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAE/D,IAAI,CAAC;YACD,+DAA+D;YAC/D,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;oBACV,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;oBAC9C,MAAM,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;gBACrE,CAAC;YACL,CAAC;YAED,MAAM,GAAG,CAAC,WAAW,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAEzD,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;gBACzB,MAAM,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,CAAC;YAED,OAAO;gBACH,GAAG,YAAY;gBACf,QAAQ,EAAE,UAAU;aACvB,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAA2B,EAAE,WAA4B;QACjF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC;YACD,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;gBAAS,CAAC;YACP,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAuB,EAAE,WAA4B;QACnF,MAAM,SAAS,GAAG,IAAI,uBAAuB,CAAC;YAC1C,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,WAAW,CAAC,QAAQ;YAC1B,QAAQ,EAAE,WAAW,CAAC,QAAQ;SACjC,CAAC,CAAC;QACH,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface GGMysqlSchemaOperationsConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
user: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class GGMysqlSchemaOperations {
|
|
8
|
+
private connection;
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config: GGMysqlSchemaOperationsConfig);
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
disconnect(): Promise<void>;
|
|
13
|
+
private getConnection;
|
|
14
|
+
schemaExists(schema: string): Promise<boolean>;
|
|
15
|
+
createSchema(schema: string): Promise<void>;
|
|
16
|
+
dropSchema(schema: string): Promise<void>;
|
|
17
|
+
cloneSchema(sourceSchema: string, targetSchema: string): Promise<void>;
|
|
18
|
+
runSeedFiles(schema: string, seedFiles: string[]): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=GGMysqlSchemaOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGMysqlSchemaOperations.d.ts","sourceRoot":"","sources":["../../testkit/GGMysqlSchemaOperations.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,6BAA6B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,uBAAuB;IAChC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,MAAM,CAAgC;gBAElC,MAAM,EAAE,6BAA6B;IAI3C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAYxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC,OAAO,CAAC,aAAa;IASf,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU9C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAiDzE"}
|