@pma-network/sql 1.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.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PMA
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.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # @pma-network/sql
2
+
3
+ MySQL wrapper built on mysql2 with promise-based async operations, connection pooling, and named parameter support.
4
+
5
+ ## Features
6
+
7
+ - Auto-configuration from environment variables
8
+ - Promise-based async operations
9
+ - Connection pooling
10
+ - Named parameters (`:paramName`) and positional (`?`) placeholders
11
+ - Full TypeScript support
12
+ - Transaction handling with automatic rollback
13
+ - Resource-specific connection strings for FiveM
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add @pma-network/sql
19
+ ```
20
+
21
+ Or with npm:
22
+
23
+ ```bash
24
+ npm install @pma-network/sql
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ Set the connection string environment variable:
30
+
31
+ ```bash
32
+ # server.cfg (resource-specific):
33
+ set pma_characters_connection_string "mysql://user:password@localhost:3306/fivem"
34
+
35
+ # server.cfg (global fallback):
36
+ set mysql_connection_string "mysql://user:password@localhost:3306/fivem"
37
+
38
+ # Node.js:
39
+ export mysql_connection_string="mysql://user:password@localhost:3306/mydb"
40
+ ```
41
+
42
+ Import and use:
43
+
44
+ ```typescript
45
+ import db from '@pma-network/sql';
46
+
47
+ const users = await db.query('SELECT * FROM users WHERE age > :age', { age: 18 });
48
+ const result = await db.insert('INSERT INTO users (name, sex, identifier) VALUES (:name, :sex, :identifier)', {
49
+ name: 'John Doe',
50
+ sex: 'm',
51
+ identifier: 'discord:123456789',
52
+ });
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### Custom Instances
58
+
59
+ Create multiple database connections:
60
+
61
+ ```typescript
62
+ import { MySQL } from '@pma-network/sql';
63
+
64
+ const db1 = new MySQL({
65
+ host: 'localhost',
66
+ user: 'root',
67
+ password: 'password',
68
+ database: 'mydb',
69
+ });
70
+
71
+ const db2 = new MySQL({
72
+ connectionString: 'mysql://user:password@remote:3306/otherdb',
73
+ });
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ ### Configuration
79
+
80
+ Configuration is read using `GetConvar` (FiveM) with `process.env` fallback.
81
+
82
+ Priority order:
83
+
84
+ 1. Resource-specific: `{resource_name}_connection_string`
85
+ - Resource name detected via `GetCurrentResourceName()`
86
+ - Dashes converted to underscores: `pma-characters` → `pma_characters_connection_string`
87
+
88
+ 2. Global fallback: `mysql_connection_string`
89
+
90
+ Connection string format: `mysql://username:password@hostname:port/database`
91
+
92
+ Required: `mysql://` protocol, username, hostname, database name
93
+
94
+ Optional: password, port (default: 3306)
95
+
96
+ ## Examples
97
+
98
+ Named parameters:
99
+ ```typescript
100
+ await db.query('SELECT * FROM users WHERE name = :name AND age > :age', {
101
+ name: 'John',
102
+ age: 18,
103
+ });
104
+ ```
105
+
106
+ Positional parameters:
107
+ ```typescript
108
+ await db.query('SELECT * FROM users WHERE name = ? AND age > ?', ['John', 18]);
109
+ ```
110
+
111
+ TypeScript with type definitions:
112
+ ```typescript
113
+ import { MySQL, type RowDataPacket } from '@pma-network/sql';
114
+
115
+ interface User extends RowDataPacket {
116
+ id: number;
117
+ name: string;
118
+ email: string;
119
+ }
120
+
121
+ const users = await db.query<User[]>('SELECT * FROM users');
122
+ ```
@@ -0,0 +1,183 @@
1
+ import type { Pool, PoolConnection, RowDataPacket } from 'mysql2/promise';
2
+ import mysql from 'mysql2/promise';
3
+ import type { ConnectionConfig, InsertResult, QueryParameters, TransactionCallback, UpdateResult } from './types.js';
4
+ /**
5
+ * MySQL database wrapper with connection pooling and named parameter support.
6
+ * Automatically reads connection configuration from environment variables.
7
+ */
8
+ export declare class MySQL {
9
+ private pool;
10
+ private namedPlaceholdersCompiler;
11
+ private debug;
12
+ private slowQueryThreshold;
13
+ private resourceName;
14
+ private collectMetrics;
15
+ private versionPrefix;
16
+ private metricsExportResource;
17
+ private metricsExportFunction;
18
+ /**
19
+ * Creates a new MySQL instance with connection pooling.
20
+ * If no config is provided, it will automatically look for connection strings in environment variables.
21
+ *
22
+ * @param config - Optional database configuration. If omitted, uses environment variables.
23
+ */
24
+ constructor(config?: ConnectionConfig);
25
+ private fetchDatabaseVersion;
26
+ private getConvar;
27
+ private getConvarInt;
28
+ private getConvarBool;
29
+ private getResourceName;
30
+ private formatResourceConvar;
31
+ private getDefaultConfig;
32
+ private validateConnectionString;
33
+ private parseConnectionString;
34
+ private normalizeParameters;
35
+ private setupConvarListeners;
36
+ private scheduleResourceTick;
37
+ private exportMetric;
38
+ private processParameters;
39
+ private logQuery;
40
+ private handleError;
41
+ /**
42
+ * Executes a SQL query and returns the raw results.
43
+ * Supports SELECT, INSERT, UPDATE, DELETE, and other SQL statements.
44
+ *
45
+ * @param query - SQL query with :name or ? placeholders
46
+ * @param parameters - Parameter values as object or array
47
+ * @returns Query result
48
+ * @example
49
+ * const result = await db.execute('SELECT * FROM users WHERE id = :id', { id: 1 });
50
+ */
51
+ execute<T = unknown>(query: string, parameters?: QueryParameters): Promise<T | null>;
52
+ /**
53
+ * Executes a SELECT query and returns rows.
54
+ * Use for queries returning multiple rows.
55
+ *
56
+ * @param query - SELECT query with :name or ? placeholders
57
+ * @param parameters - Parameter values
58
+ * @returns Array of rows
59
+ * @example
60
+ * const users = await db.query('SELECT * FROM users WHERE age > :age', { age: 18 });
61
+ */
62
+ query<T extends RowDataPacket[] = RowDataPacket[]>(query: string, parameters?: QueryParameters): Promise<T | null>;
63
+ /**
64
+ * Inserts a row into the database.
65
+ * Returns the auto-generated ID and affected row count.
66
+ *
67
+ * @param query - INSERT query with :name or ? placeholders
68
+ * @param parameters - Values to insert
69
+ * @returns Object with insertId and affectedRows
70
+ * @example
71
+ * const result = await db.insert(
72
+ * 'INSERT INTO users (name, email) VALUES (:name, :email)',
73
+ * { name: 'John', email: 'john@example.com' }
74
+ * );
75
+ * console.log(result.insertId);
76
+ */
77
+ insert(query: string, parameters?: QueryParameters): Promise<InsertResult | null>;
78
+ /**
79
+ * Updates rows in the database.
80
+ * Returns the number of affected rows.
81
+ *
82
+ * @param query - UPDATE query with :name or ? placeholders
83
+ * @param parameters - Values to update
84
+ * @returns Object with affectedRows count
85
+ * @example
86
+ * const result = await db.update(
87
+ * 'UPDATE users SET verified = 1 WHERE id = :id',
88
+ * { id: 123 }
89
+ * );
90
+ * console.log(result.affectedRows);
91
+ */
92
+ update(query: string, parameters?: QueryParameters): Promise<UpdateResult | null>;
93
+ /**
94
+ * Returns a single value from the database.
95
+ * Use for COUNT, SUM, or single column queries.
96
+ *
97
+ * @param query - SELECT query returning one column
98
+ * @param parameters - Parameter values
99
+ * @returns Value from first column of first row, or null
100
+ * @example
101
+ * const count = await db.scalar('SELECT COUNT(*) FROM users');
102
+ * const name = await db.scalar('SELECT name FROM users WHERE id = :id', { id: 1 });
103
+ */
104
+ scalar<T = unknown>(query: string, parameters?: QueryParameters): Promise<T | null>;
105
+ /**
106
+ * Returns a single row from the database.
107
+ * Returns null if no rows match.
108
+ *
109
+ * @param query - SELECT query with :name or ? placeholders
110
+ * @param parameters - Parameter values
111
+ * @returns Single row or null
112
+ * @example
113
+ * const user = await db.single('SELECT * FROM users WHERE id = :id', { id: 1 });
114
+ * if (user) {
115
+ * console.log(user.name);
116
+ * }
117
+ */
118
+ single<T extends RowDataPacket = RowDataPacket>(query: string, parameters?: QueryParameters): Promise<T | null>;
119
+ /**
120
+ * Prepares a statement for execution.
121
+ * Use for executing the same query multiple times with different parameters.
122
+ *
123
+ * @param query - SQL query to prepare
124
+ * @returns Prepared statement
125
+ * @example
126
+ * const stmt = await db.prepare('SELECT * FROM users WHERE id = ?');
127
+ */
128
+ prepare(query: string): Promise<mysql.PreparedStatementInfo>;
129
+ /**
130
+ * Executes multiple queries as an atomic transaction.
131
+ * All changes are rolled back if any query fails.
132
+ *
133
+ * @param callback - Function receiving an execute function for queries
134
+ * @returns Value returned by callback
135
+ * @example
136
+ * await db.transaction(async (execute) => {
137
+ * await execute('INSERT INTO accounts (balance) VALUES (:balance)', { balance: 100 });
138
+ * await execute('UPDATE users SET has_account = 1 WHERE id = :id', { id: 1 });
139
+ * });
140
+ */
141
+ transaction<T = unknown>(callback: TransactionCallback): Promise<T | null>;
142
+ /**
143
+ * Executes a query with positional parameters.
144
+ * Skips named parameter processing. Use ? placeholders only.
145
+ *
146
+ * @param query - SQL query with ? placeholders
147
+ * @param parameters - Array of values for placeholders
148
+ * @returns Query result
149
+ * @example
150
+ * const result = await db.rawExecute('SELECT * FROM users WHERE id = ?', [1]);
151
+ */
152
+ rawExecute<T = unknown>(query: string, parameters?: unknown[]): Promise<T | null>;
153
+ /**
154
+ * Returns a connection from the pool.
155
+ * Must call connection.release() when finished.
156
+ *
157
+ * @returns Database connection
158
+ * @example
159
+ * const connection = await db.getConnection();
160
+ * try {
161
+ * await connection.query('SELECT * FROM users');
162
+ * } finally {
163
+ * connection.release();
164
+ * }
165
+ */
166
+ getConnection(): Promise<PoolConnection>;
167
+ /**
168
+ * Closes all connections in the pool.
169
+ * Call when shutting down the application.
170
+ *
171
+ * @example
172
+ * await db.end();
173
+ */
174
+ end(): Promise<void>;
175
+ /**
176
+ * Returns the underlying mysql2 connection pool.
177
+ * Use for direct access to pool-specific methods.
178
+ *
179
+ * @returns mysql2 Pool instance
180
+ */
181
+ getPool(): Pool;
182
+ }
183
+ //# sourceMappingURL=MySQL.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MySQL.d.ts","sourceRoot":"","sources":["../src/MySQL.ts"],"names":[],"mappings":"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"}
package/dist/MySQL.js ADDED
@@ -0,0 +1,574 @@
1
+ import { performance } from 'node:perf_hooks';
2
+ import mysql from 'mysql2/promise';
3
+ import namedPlaceholders from 'named-placeholders';
4
+ /**
5
+ * MySQL database wrapper with connection pooling and named parameter support.
6
+ * Automatically reads connection configuration from environment variables.
7
+ */
8
+ export class MySQL {
9
+ pool;
10
+ namedPlaceholdersCompiler;
11
+ debug;
12
+ slowQueryThreshold;
13
+ resourceName;
14
+ collectMetrics;
15
+ versionPrefix = '';
16
+ metricsExportResource;
17
+ metricsExportFunction;
18
+ /**
19
+ * Creates a new MySQL instance with connection pooling.
20
+ * If no config is provided, it will automatically look for connection strings in environment variables.
21
+ *
22
+ * @param config - Optional database configuration. If omitted, uses environment variables.
23
+ */
24
+ constructor(config) {
25
+ this.resourceName = this.getResourceName();
26
+ this.debug = this.getConvarBool('mysql_debug', false);
27
+ this.slowQueryThreshold = this.getConvarInt('mysql_slow_query_warning', 150);
28
+ this.collectMetrics = this.getConvarBool('mysql_query_metrics', false);
29
+ this.metricsExportResource = this.getConvar('mysql_metrics_export_resource');
30
+ this.metricsExportFunction = this.getConvar('mysql_metrics_export_function');
31
+ this.setupConvarListeners();
32
+ const finalConfig = config || this.getDefaultConfig();
33
+ const poolConfig = finalConfig.connectionString
34
+ ? this.parseConnectionString(finalConfig.connectionString)
35
+ : finalConfig;
36
+ this.pool = mysql.createPool({
37
+ waitForConnections: true,
38
+ connectionLimit: 10,
39
+ queueLimit: 0,
40
+ ...poolConfig,
41
+ });
42
+ this.namedPlaceholdersCompiler = namedPlaceholders();
43
+ this.fetchDatabaseVersion();
44
+ }
45
+ async fetchDatabaseVersion() {
46
+ try {
47
+ const connection = await this.pool.getConnection();
48
+ try {
49
+ const serverVersion = connection.connection?._handshakePacket?.serverVersion;
50
+ if (serverVersion) {
51
+ this.versionPrefix = `^4[${serverVersion}]^0 `;
52
+ }
53
+ }
54
+ finally {
55
+ connection.release();
56
+ }
57
+ }
58
+ catch {
59
+ }
60
+ }
61
+ getConvar(varName) {
62
+ if (typeof globalThis.GetConvar === 'function') {
63
+ return globalThis.GetConvar(varName, '') || null;
64
+ }
65
+ return process.env[varName] || null;
66
+ }
67
+ getConvarInt(varName, defaultValue) {
68
+ if (typeof globalThis.GetConvarInt === 'function') {
69
+ return globalThis.GetConvarInt(varName, defaultValue);
70
+ }
71
+ const envValue = process.env[varName];
72
+ if (envValue) {
73
+ const parsed = parseInt(envValue, 10);
74
+ return Number.isNaN(parsed) ? defaultValue : parsed;
75
+ }
76
+ return defaultValue;
77
+ }
78
+ getConvarBool(varName, defaultValue) {
79
+ if (typeof globalThis.GetConvarBool === 'function') {
80
+ return globalThis.GetConvarBool(varName, defaultValue);
81
+ }
82
+ const envValue = process.env[varName];
83
+ if (envValue !== undefined) {
84
+ return envValue === 'true' || envValue === '1';
85
+ }
86
+ return defaultValue;
87
+ }
88
+ getResourceName() {
89
+ if (typeof globalThis.GetCurrentResourceName === 'function') {
90
+ return globalThis.GetCurrentResourceName() || null;
91
+ }
92
+ return this.getConvar('RESOURCE_NAME');
93
+ }
94
+ formatResourceConvar(resourceName) {
95
+ return resourceName.replace(/-/g, '_').toLowerCase();
96
+ }
97
+ getDefaultConfig() {
98
+ let connectionString = null;
99
+ const resourceName = this.getResourceName();
100
+ if (resourceName) {
101
+ const resourceConvar = this.formatResourceConvar(resourceName);
102
+ connectionString = this.getConvar(`${resourceConvar}_connection_string`);
103
+ }
104
+ if (!connectionString) {
105
+ connectionString = this.getConvar('mysql_connection_string');
106
+ }
107
+ if (!connectionString) {
108
+ const resourceHint = resourceName
109
+ ? `\nTried: ${this.formatResourceConvar(resourceName)}_connection_string and mysql_connection_string`
110
+ : '\nTried: mysql_connection_string';
111
+ throw new Error('No MySQL connection string found. ' +
112
+ 'Please set a connection string: ' +
113
+ 'mysql://user:password@host:port/database' +
114
+ resourceHint);
115
+ }
116
+ this.validateConnectionString(connectionString);
117
+ return { connectionString };
118
+ }
119
+ validateConnectionString(connectionString) {
120
+ try {
121
+ const url = new URL(connectionString);
122
+ if (url.protocol !== 'mysql:') {
123
+ throw new Error(`Invalid protocol "${url.protocol}". Expected "mysql:". ` +
124
+ 'Connection string must start with mysql://');
125
+ }
126
+ if (!url.hostname) {
127
+ throw new Error('Connection string must include a hostname');
128
+ }
129
+ if (!url.pathname || url.pathname === '/') {
130
+ throw new Error('Connection string must include a database name');
131
+ }
132
+ if (!url.username) {
133
+ throw new Error('Connection string must include a username');
134
+ }
135
+ }
136
+ catch (error) {
137
+ if (error instanceof TypeError) {
138
+ throw new Error('Invalid connection string format. Expected: mysql://user:password@host:port/database');
139
+ }
140
+ throw error;
141
+ }
142
+ }
143
+ parseConnectionString(connectionString) {
144
+ const url = new URL(connectionString);
145
+ return {
146
+ host: url.hostname,
147
+ port: url.port ? parseInt(url.port, 10) : 3306,
148
+ user: url.username,
149
+ password: url.password,
150
+ database: url.pathname.slice(1),
151
+ };
152
+ }
153
+ normalizeParameters(parameters) {
154
+ if (Array.isArray(parameters)) {
155
+ for (let i = 0; i < parameters.length; i++) {
156
+ if (parameters[i] === undefined) {
157
+ parameters[i] = null;
158
+ }
159
+ }
160
+ }
161
+ else {
162
+ for (const key in parameters) {
163
+ if (parameters[key] === undefined) {
164
+ parameters[key] = null;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ setupConvarListeners() {
170
+ if (typeof globalThis.AddConvarChangeListener === 'function') {
171
+ globalThis.AddConvarChangeListener('mysql_*', (convarName) => {
172
+ if (convarName === 'mysql_debug') {
173
+ this.debug = this.getConvarBool('mysql_debug', false);
174
+ console.log(`^2Convar changed: mysql_debug = ${this.debug}^0`);
175
+ }
176
+ else if (convarName === 'mysql_slow_query_warning') {
177
+ this.slowQueryThreshold = this.getConvarInt('mysql_slow_query_warning', 150);
178
+ console.log(`^2Convar changed: mysql_slow_query_warning = ${this.slowQueryThreshold}^0`);
179
+ }
180
+ else if (convarName === 'mysql_query_metrics') {
181
+ this.collectMetrics = this.getConvarBool('mysql_query_metrics', false);
182
+ console.log(`^2Convar changed: mysql_query_metrics = ${this.collectMetrics}^0`);
183
+ }
184
+ else if (convarName === 'mysql_metrics_export_resource') {
185
+ this.metricsExportResource = this.getConvar('mysql_metrics_export_resource');
186
+ console.log(`^2Convar changed: mysql_metrics_export_resource = ${this.metricsExportResource}^0`);
187
+ }
188
+ else if (convarName === 'mysql_metrics_export_function') {
189
+ this.metricsExportFunction = this.getConvar('mysql_metrics_export_function');
190
+ console.log(`^2Convar changed: mysql_metrics_export_function = ${this.metricsExportFunction}^0`);
191
+ }
192
+ });
193
+ }
194
+ }
195
+ scheduleResourceTick() {
196
+ if (typeof globalThis.ScheduleResourceTick === 'function' && this.resourceName) {
197
+ globalThis.ScheduleResourceTick(this.resourceName);
198
+ }
199
+ }
200
+ exportMetric(metric) {
201
+ if (this.metricsExportResource && this.metricsExportFunction) {
202
+ try {
203
+ exports[this.metricsExportResource]?.[this.metricsExportFunction]?.(metric);
204
+ }
205
+ catch (error) { }
206
+ }
207
+ }
208
+ processParameters(query, parameters) {
209
+ const processedQuery = query.replace(/@/g, ':');
210
+ if (!parameters) {
211
+ return [processedQuery, []];
212
+ }
213
+ this.normalizeParameters(parameters);
214
+ if (Array.isArray(parameters)) {
215
+ return [processedQuery, parameters];
216
+ }
217
+ const [finalQuery, processedParams] = this.namedPlaceholdersCompiler(processedQuery, parameters);
218
+ return [finalQuery, processedParams];
219
+ }
220
+ logQuery(query, executionTime, parameters, error) {
221
+ if (this.collectMetrics) {
222
+ const metric = {
223
+ query,
224
+ executionTime,
225
+ timestamp: Date.now(),
226
+ resource: this.resourceName || undefined,
227
+ };
228
+ this.exportMetric(metric);
229
+ }
230
+ const isSlowQuery = executionTime >= this.slowQueryThreshold;
231
+ if (this.debug || isSlowQuery || error) {
232
+ const resourceName = this.resourceName || 'pma-sql';
233
+ let color;
234
+ let statusText;
235
+ if (error) {
236
+ color = '^1';
237
+ statusText = `${this.versionPrefix}${color}Query failed^0`;
238
+ }
239
+ else {
240
+ color = isSlowQuery ? '^3' : '^2';
241
+ statusText = `${this.versionPrefix}${color}${resourceName} took ${executionTime.toFixed(4)}ms to execute a query!^0`;
242
+ }
243
+ console.log(statusText);
244
+ console.log(`${color}${query} [${parameters && parameters.length > 0 ? parameters.join(',') : ''}]^0`);
245
+ if (error) {
246
+ console.log(`^1Error: ${error.message}^0`);
247
+ }
248
+ }
249
+ }
250
+ handleError(error) {
251
+ if (typeof globalThis.printError === 'function') {
252
+ globalThis.printError(error);
253
+ }
254
+ else {
255
+ throw error;
256
+ }
257
+ }
258
+ /**
259
+ * Executes a SQL query and returns the raw results.
260
+ * Supports SELECT, INSERT, UPDATE, DELETE, and other SQL statements.
261
+ *
262
+ * @param query - SQL query with :name or ? placeholders
263
+ * @param parameters - Parameter values as object or array
264
+ * @returns Query result
265
+ * @example
266
+ * const result = await db.execute('SELECT * FROM users WHERE id = :id', { id: 1 });
267
+ */
268
+ async execute(query, parameters) {
269
+ this.scheduleResourceTick();
270
+ const startTime = performance.now();
271
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
272
+ try {
273
+ const [results] = await this.pool.execute(processedQuery, processedParams);
274
+ const executionTime = performance.now() - startTime;
275
+ this.logQuery(processedQuery, executionTime, processedParams);
276
+ return results;
277
+ }
278
+ catch (error) {
279
+ const executionTime = performance.now() - startTime;
280
+ this.logQuery(processedQuery, executionTime, processedParams, error);
281
+ this.handleError(error);
282
+ return null;
283
+ }
284
+ }
285
+ /**
286
+ * Executes a SELECT query and returns rows.
287
+ * Use for queries returning multiple rows.
288
+ *
289
+ * @param query - SELECT query with :name or ? placeholders
290
+ * @param parameters - Parameter values
291
+ * @returns Array of rows
292
+ * @example
293
+ * const users = await db.query('SELECT * FROM users WHERE age > :age', { age: 18 });
294
+ */
295
+ async query(query, parameters) {
296
+ this.scheduleResourceTick();
297
+ const startTime = performance.now();
298
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
299
+ try {
300
+ const [rows] = await this.pool.query(processedQuery, processedParams);
301
+ const executionTime = performance.now() - startTime;
302
+ this.logQuery(processedQuery, executionTime, processedParams);
303
+ return rows;
304
+ }
305
+ catch (error) {
306
+ const executionTime = performance.now() - startTime;
307
+ this.logQuery(processedQuery, executionTime, processedParams, error);
308
+ this.handleError(error);
309
+ return null;
310
+ }
311
+ }
312
+ /**
313
+ * Inserts a row into the database.
314
+ * Returns the auto-generated ID and affected row count.
315
+ *
316
+ * @param query - INSERT query with :name or ? placeholders
317
+ * @param parameters - Values to insert
318
+ * @returns Object with insertId and affectedRows
319
+ * @example
320
+ * const result = await db.insert(
321
+ * 'INSERT INTO users (name, email) VALUES (:name, :email)',
322
+ * { name: 'John', email: 'john@example.com' }
323
+ * );
324
+ * console.log(result.insertId);
325
+ */
326
+ async insert(query, parameters) {
327
+ const startTime = performance.now();
328
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
329
+ try {
330
+ const [result] = await this.pool.execute(processedQuery, processedParams);
331
+ const executionTime = performance.now() - startTime;
332
+ this.logQuery(processedQuery, executionTime, processedParams);
333
+ return {
334
+ insertId: result.insertId,
335
+ affectedRows: result.affectedRows,
336
+ };
337
+ }
338
+ catch (error) {
339
+ const executionTime = performance.now() - startTime;
340
+ this.logQuery(processedQuery, executionTime, processedParams, error);
341
+ this.handleError(error);
342
+ return null;
343
+ }
344
+ }
345
+ /**
346
+ * Updates rows in the database.
347
+ * Returns the number of affected rows.
348
+ *
349
+ * @param query - UPDATE query with :name or ? placeholders
350
+ * @param parameters - Values to update
351
+ * @returns Object with affectedRows count
352
+ * @example
353
+ * const result = await db.update(
354
+ * 'UPDATE users SET verified = 1 WHERE id = :id',
355
+ * { id: 123 }
356
+ * );
357
+ * console.log(result.affectedRows);
358
+ */
359
+ async update(query, parameters) {
360
+ const startTime = performance.now();
361
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
362
+ try {
363
+ const [result] = await this.pool.execute(processedQuery, processedParams);
364
+ const executionTime = performance.now() - startTime;
365
+ this.logQuery(processedQuery, executionTime, processedParams);
366
+ return {
367
+ affectedRows: result.affectedRows,
368
+ };
369
+ }
370
+ catch (error) {
371
+ const executionTime = performance.now() - startTime;
372
+ this.logQuery(processedQuery, executionTime, processedParams, error);
373
+ this.handleError(error);
374
+ return null;
375
+ }
376
+ }
377
+ /**
378
+ * Returns a single value from the database.
379
+ * Use for COUNT, SUM, or single column queries.
380
+ *
381
+ * @param query - SELECT query returning one column
382
+ * @param parameters - Parameter values
383
+ * @returns Value from first column of first row, or null
384
+ * @example
385
+ * const count = await db.scalar('SELECT COUNT(*) FROM users');
386
+ * const name = await db.scalar('SELECT name FROM users WHERE id = :id', { id: 1 });
387
+ */
388
+ async scalar(query, parameters) {
389
+ const startTime = performance.now();
390
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
391
+ try {
392
+ const [rows] = await this.pool.query(processedQuery, processedParams);
393
+ const executionTime = performance.now() - startTime;
394
+ this.logQuery(processedQuery, executionTime, processedParams);
395
+ if (!rows || rows.length === 0) {
396
+ return null;
397
+ }
398
+ const firstRow = rows[0];
399
+ const firstColumn = Object.values(firstRow)[0];
400
+ return firstColumn;
401
+ }
402
+ catch (error) {
403
+ const executionTime = performance.now() - startTime;
404
+ this.logQuery(processedQuery, executionTime, processedParams, error);
405
+ this.handleError(error);
406
+ return null;
407
+ }
408
+ }
409
+ /**
410
+ * Returns a single row from the database.
411
+ * Returns null if no rows match.
412
+ *
413
+ * @param query - SELECT query with :name or ? placeholders
414
+ * @param parameters - Parameter values
415
+ * @returns Single row or null
416
+ * @example
417
+ * const user = await db.single('SELECT * FROM users WHERE id = :id', { id: 1 });
418
+ * if (user) {
419
+ * console.log(user.name);
420
+ * }
421
+ */
422
+ async single(query, parameters) {
423
+ const startTime = performance.now();
424
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
425
+ try {
426
+ const [rows] = await this.pool.query(processedQuery, processedParams);
427
+ const executionTime = performance.now() - startTime;
428
+ this.logQuery(processedQuery, executionTime, processedParams);
429
+ return rows.length > 0 ? rows[0] : null;
430
+ }
431
+ catch (error) {
432
+ const executionTime = performance.now() - startTime;
433
+ this.logQuery(processedQuery, executionTime, processedParams, error);
434
+ this.handleError(error);
435
+ return null;
436
+ }
437
+ }
438
+ /**
439
+ * Prepares a statement for execution.
440
+ * Use for executing the same query multiple times with different parameters.
441
+ *
442
+ * @param query - SQL query to prepare
443
+ * @returns Prepared statement
444
+ * @example
445
+ * const stmt = await db.prepare('SELECT * FROM users WHERE id = ?');
446
+ */
447
+ async prepare(query) {
448
+ this.scheduleResourceTick();
449
+ const connection = await this.pool.getConnection();
450
+ try {
451
+ const processedQuery = query.replace(/@/g, ':');
452
+ const statement = await connection.prepare(processedQuery);
453
+ return statement;
454
+ }
455
+ finally {
456
+ connection.release();
457
+ }
458
+ }
459
+ /**
460
+ * Executes multiple queries as an atomic transaction.
461
+ * All changes are rolled back if any query fails.
462
+ *
463
+ * @param callback - Function receiving an execute function for queries
464
+ * @returns Value returned by callback
465
+ * @example
466
+ * await db.transaction(async (execute) => {
467
+ * await execute('INSERT INTO accounts (balance) VALUES (:balance)', { balance: 100 });
468
+ * await execute('UPDATE users SET has_account = 1 WHERE id = :id', { id: 1 });
469
+ * });
470
+ */
471
+ async transaction(callback) {
472
+ this.scheduleResourceTick();
473
+ const connection = await this.pool.getConnection();
474
+ try {
475
+ await connection.beginTransaction();
476
+ const executeInTransaction = async (query, parameters) => {
477
+ this.scheduleResourceTick();
478
+ const startTime = performance.now();
479
+ const [processedQuery, processedParams] = this.processParameters(query, parameters);
480
+ try {
481
+ const [result] = await connection.execute(processedQuery, processedParams);
482
+ const executionTime = performance.now() - startTime;
483
+ this.logQuery(processedQuery, executionTime, processedParams);
484
+ return result;
485
+ }
486
+ catch (error) {
487
+ const executionTime = performance.now() - startTime;
488
+ this.logQuery(processedQuery, executionTime, processedParams, error);
489
+ throw error;
490
+ }
491
+ };
492
+ const result = await callback(executeInTransaction);
493
+ await connection.commit();
494
+ return result;
495
+ }
496
+ catch (error) {
497
+ await connection.rollback();
498
+ this.handleError(error);
499
+ return null;
500
+ }
501
+ finally {
502
+ connection.release();
503
+ }
504
+ }
505
+ /**
506
+ * Executes a query with positional parameters.
507
+ * Skips named parameter processing. Use ? placeholders only.
508
+ *
509
+ * @param query - SQL query with ? placeholders
510
+ * @param parameters - Array of values for placeholders
511
+ * @returns Query result
512
+ * @example
513
+ * const result = await db.rawExecute('SELECT * FROM users WHERE id = ?', [1]);
514
+ */
515
+ async rawExecute(query, parameters) {
516
+ this.scheduleResourceTick();
517
+ const startTime = performance.now();
518
+ const processedQuery = query.replace(/@/g, ':');
519
+ const params = parameters || [];
520
+ for (let i = 0; i < params.length; i++) {
521
+ if (params[i] === undefined) {
522
+ params[i] = null;
523
+ }
524
+ }
525
+ try {
526
+ const [results] = await this.pool.execute(processedQuery, params);
527
+ const executionTime = performance.now() - startTime;
528
+ this.logQuery(processedQuery, executionTime, params);
529
+ return results;
530
+ }
531
+ catch (error) {
532
+ const executionTime = performance.now() - startTime;
533
+ this.logQuery(processedQuery, executionTime, params, error);
534
+ this.handleError(error);
535
+ return null;
536
+ }
537
+ }
538
+ /**
539
+ * Returns a connection from the pool.
540
+ * Must call connection.release() when finished.
541
+ *
542
+ * @returns Database connection
543
+ * @example
544
+ * const connection = await db.getConnection();
545
+ * try {
546
+ * await connection.query('SELECT * FROM users');
547
+ * } finally {
548
+ * connection.release();
549
+ * }
550
+ */
551
+ async getConnection() {
552
+ return this.pool.getConnection();
553
+ }
554
+ /**
555
+ * Closes all connections in the pool.
556
+ * Call when shutting down the application.
557
+ *
558
+ * @example
559
+ * await db.end();
560
+ */
561
+ async end() {
562
+ await this.pool.end();
563
+ }
564
+ /**
565
+ * Returns the underlying mysql2 connection pool.
566
+ * Use for direct access to pool-specific methods.
567
+ *
568
+ * @returns mysql2 Pool instance
569
+ */
570
+ getPool() {
571
+ return this.pool;
572
+ }
573
+ }
574
+ //# sourceMappingURL=MySQL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MySQL.js","sourceRoot":"","sources":["../src/MySQL.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { MySQL } from './MySQL.js';
2
+ export { MySQL };
3
+ export type { ConnectionConfig, FieldPacket, InsertResult, Pool, PoolOptions, QueryMetrics, QueryParameters, QueryResult, ResultSetHeader, RowDataPacket, TransactionCallback, UpdateResult, } from './types.js';
4
+ export declare const db: MySQL;
5
+ export default db;
6
+ //# 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,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,EAAE,OAAc,CAAC;AAC9B,eAAe,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import { MySQL } from './MySQL.js';
2
+ export { MySQL };
3
+ export const db = new MySQL();
4
+ export default db;
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,CAAC;AAgBjB,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC;AAC9B,eAAe,EAAE,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Pool, PoolOptions, RowDataPacket, ResultSetHeader, FieldPacket } from 'mysql2/promise';
2
+ export interface ConnectionConfig extends PoolOptions {
3
+ connectionString?: string;
4
+ }
5
+ export type QueryParameters = Record<string, any> | any[];
6
+ export type QueryResult<T = any> = T extends RowDataPacket[] ? T : any;
7
+ export interface InsertResult {
8
+ insertId: number;
9
+ affectedRows: number;
10
+ }
11
+ export interface UpdateResult {
12
+ affectedRows: number;
13
+ }
14
+ export interface TransactionCallback {
15
+ (execute: (query: string, parameters?: QueryParameters) => Promise<any>): Promise<any>;
16
+ }
17
+ export interface QueryMetrics {
18
+ query: string;
19
+ executionTime: number;
20
+ timestamp: number;
21
+ resource?: string;
22
+ }
23
+ export { Pool, PoolOptions, RowDataPacket, ResultSetHeader, FieldPacket };
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAErG,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;AAE1D,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,aAAa,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACxF;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@pma-network/sql",
3
+ "version": "1.0.5",
4
+ "description": "MySQL wrapper with promise-based async operations, connection pooling, and named parameters support",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "keywords": [
13
+ "mysql",
14
+ "mysql2",
15
+ "database",
16
+ "sql",
17
+ "async",
18
+ "promise",
19
+ "typescript",
20
+ "fivem",
21
+ "connection-pooling",
22
+ "named-parameters"
23
+ ],
24
+ "author": "",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/pma-rp/pma-sql.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/pma-rp/pma-sql/issues"
32
+ },
33
+ "homepage": "https://github.com/pma-rp/pma-sql#readme",
34
+ "dependencies": {
35
+ "mysql2": "^3.11.3",
36
+ "named-placeholders": "^1.1.3"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.10.0",
40
+ "typescript": "^5.6.2"
41
+ },
42
+ "engines": {
43
+ "node": ">=16.9.0"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc",
47
+ "watch": "tsc --watch"
48
+ }
49
+ }