@onurege3467/zerohelper 10.2.6 → 11.0.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 +9 -704
- package/dist/index.js +19 -44
- package/package.json +21 -70
- package/dist/bin/commands/cache.d.ts +0 -2
- package/dist/bin/commands/cache.js +0 -92
- package/dist/bin/commands/db-backup.d.ts +0 -3
- package/dist/bin/commands/db-backup.js +0 -118
- package/dist/bin/commands/db.d.ts +0 -2
- package/dist/bin/commands/db.js +0 -334
- package/dist/bin/commands/import-export.d.ts +0 -3
- package/dist/bin/commands/import-export.js +0 -123
- package/dist/bin/commands/init.d.ts +0 -2
- package/dist/bin/commands/init.js +0 -85
- package/dist/bin/commands/migrate.d.ts +0 -3
- package/dist/bin/commands/migrate.js +0 -167
- package/dist/bin/commands/repl.d.ts +0 -2
- package/dist/bin/commands/repl.js +0 -96
- package/dist/bin/commands/seed.d.ts +0 -2
- package/dist/bin/commands/seed.js +0 -76
- package/dist/bin/commands/zpack.d.ts +0 -2
- package/dist/bin/commands/zpack.js +0 -36
- package/dist/bin/index.d.ts +0 -2
- package/dist/bin/index.js +0 -28
- package/dist/bin/types.d.ts +0 -22
- package/dist/bin/types.js +0 -2
- package/dist/bin/utils/config.d.ts +0 -3
- package/dist/bin/utils/config.js +0 -78
- package/dist/bin/utils/prompts.d.ts +0 -3
- package/dist/bin/utils/prompts.js +0 -115
- package/dist/bin/zero.d.ts +0 -2
- package/dist/bin/zero.js +0 -849
- package/dist/database/IDatabase.d.ts +0 -71
- package/dist/database/IDatabase.js +0 -48
- package/dist/database/cacheWrapper.d.ts +0 -34
- package/dist/database/cacheWrapper.js +0 -214
- package/dist/database/index.d.ts +0 -12
- package/dist/database/index.js +0 -100
- package/dist/database/json.d.ts +0 -32
- package/dist/database/json.js +0 -208
- package/dist/database/migration.d.ts +0 -21
- package/dist/database/migration.js +0 -97
- package/dist/database/mongodb.d.ts +0 -26
- package/dist/database/mongodb.js +0 -145
- package/dist/database/mysql.d.ts +0 -29
- package/dist/database/mysql.js +0 -282
- package/dist/database/pg.d.ts +0 -28
- package/dist/database/pg.js +0 -200
- package/dist/database/redis.d.ts +0 -31
- package/dist/database/redis.js +0 -176
- package/dist/database/seeder.d.ts +0 -20
- package/dist/database/seeder.js +0 -37
- package/dist/database/sqlite.d.ts +0 -26
- package/dist/database/sqlite.js +0 -211
- package/dist/database/telemetry.d.ts +0 -35
- package/dist/database/telemetry.js +0 -41
- package/dist/database/toon.d.ts +0 -33
- package/dist/database/toon.js +0 -244
- package/dist/database/types.d.ts +0 -71
- package/dist/database/types.js +0 -2
- package/dist/database/zpack.d.ts +0 -75
- package/dist/database/zpack.js +0 -616
- package/dist/functions/index.d.ts +0 -199
- package/dist/functions/index.js +0 -682
- package/dist/functions/security.d.ts +0 -15
- package/dist/functions/security.js +0 -46
- package/dist/functions/toon.d.ts +0 -10
- package/dist/functions/toon.js +0 -214
- package/dist/functions/worker.d.ts +0 -5
- package/dist/functions/worker.js +0 -35
- package/dist/index.d.ts +0 -8
- package/dist/migrations/1767521950635_test_migration.d.ts +0 -3
- package/dist/migrations/1767521950635_test_migration.js +0 -11
- package/dist/migrations/1767522158826_create_users_table.d.ts +0 -2
- package/dist/migrations/1767522158826_create_users_table.js +0 -11
- package/dist/package.json +0 -79
- package/dist/tests/test.d.ts +0 -1
- package/dist/tests/test.js +0 -26
- package/dist/zero.config.d.ts +0 -10
- package/dist/zero.config.js +0 -13
package/dist/database/mysql.js
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MySQLDatabase = void 0;
|
|
7
|
-
const IDatabase_1 = require("./IDatabase");
|
|
8
|
-
const promise_1 = __importDefault(require("mysql2/promise"));
|
|
9
|
-
class MySQLDatabase extends IDatabase_1.IDatabase {
|
|
10
|
-
constructor(config) {
|
|
11
|
-
super();
|
|
12
|
-
this.pool = null;
|
|
13
|
-
this._queue = [];
|
|
14
|
-
this._connected = false;
|
|
15
|
-
this.config = config;
|
|
16
|
-
this._connectionPromise = new Promise(async (resolve, reject) => {
|
|
17
|
-
try {
|
|
18
|
-
const connection = await promise_1.default.createConnection({
|
|
19
|
-
host: config.host || 'localhost',
|
|
20
|
-
port: config.port || 3306,
|
|
21
|
-
user: config.username,
|
|
22
|
-
password: config.password,
|
|
23
|
-
});
|
|
24
|
-
await connection.query(`CREATE DATABASE IF NOT EXISTS
|
|
25
|
-
${config.database}
|
|
26
|
-
`);
|
|
27
|
-
await connection.end();
|
|
28
|
-
this.pool = promise_1.default.createPool({
|
|
29
|
-
host: config.host || 'localhost',
|
|
30
|
-
port: config.port || 3306,
|
|
31
|
-
user: config.username,
|
|
32
|
-
password: config.password,
|
|
33
|
-
database: config.database,
|
|
34
|
-
waitForConnections: true,
|
|
35
|
-
connectionLimit: config.poolSize || 15, // Balanced limit
|
|
36
|
-
queueLimit: 0,
|
|
37
|
-
enableKeepAlive: true,
|
|
38
|
-
keepAliveInitialDelay: 10000
|
|
39
|
-
});
|
|
40
|
-
this._connected = true;
|
|
41
|
-
resolve(this.pool);
|
|
42
|
-
this._processQueue();
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
this._queue.forEach(q => q.reject(error));
|
|
46
|
-
this._queue = [];
|
|
47
|
-
reject(error);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
async _execute(op, table, fn) {
|
|
52
|
-
const start = Date.now();
|
|
53
|
-
const execute = async () => {
|
|
54
|
-
const res = await fn();
|
|
55
|
-
this.recordMetric(op, table, Date.now() - start);
|
|
56
|
-
return res;
|
|
57
|
-
};
|
|
58
|
-
if (this._connected)
|
|
59
|
-
return execute();
|
|
60
|
-
return new Promise((resolve, reject) => this._queue.push({ operation: execute, resolve, reject }));
|
|
61
|
-
}
|
|
62
|
-
async _processQueue() {
|
|
63
|
-
if (!this._connected)
|
|
64
|
-
return;
|
|
65
|
-
while (this._queue.length > 0) {
|
|
66
|
-
const item = this._queue.shift();
|
|
67
|
-
if (item) {
|
|
68
|
-
try {
|
|
69
|
-
item.resolve(await item.operation());
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
item.reject(error);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
async query(sql, params = []) {
|
|
78
|
-
const pool = await this._connectionPromise;
|
|
79
|
-
let retries = 3;
|
|
80
|
-
while (retries > 0) {
|
|
81
|
-
try {
|
|
82
|
-
const [rows] = await pool.execute(sql, params);
|
|
83
|
-
return rows;
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
if ((error.code === 'ER_CON_COUNT_ERROR' || error.message.includes('Too many connections')) && retries > 1) {
|
|
87
|
-
retries--;
|
|
88
|
-
await new Promise(r => setTimeout(r, 1000)); // Wait 1s and retry
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
async _ensureMissingColumns(table, data) {
|
|
96
|
-
const existingColumns = await this.query(`DESCRIBE
|
|
97
|
-
${table}
|
|
98
|
-
`).catch(() => []);
|
|
99
|
-
const columnNames = existingColumns.map(col => col.Field);
|
|
100
|
-
for (const key of Object.keys(data)) {
|
|
101
|
-
if (key !== '_id' && !columnNames.includes(key)) {
|
|
102
|
-
await this.query(`ALTER TABLE
|
|
103
|
-
${table}
|
|
104
|
-
ADD COLUMN
|
|
105
|
-
${key}
|
|
106
|
-
TEXT`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
async ensureTable(table, data = {}) {
|
|
111
|
-
const escapedTable = promise_1.default.escape(table);
|
|
112
|
-
const tables = await this.query(`SHOW TABLES LIKE ${escapedTable}`);
|
|
113
|
-
if (tables.length === 0) {
|
|
114
|
-
const defs = Object.keys(data).map(k => `
|
|
115
|
-
${k}
|
|
116
|
-
TEXT`);
|
|
117
|
-
const columnsPart = defs.length > 0 ? ', ' + defs.join(", ") : '';
|
|
118
|
-
await this.query(`CREATE TABLE
|
|
119
|
-
${table}
|
|
120
|
-
(_id INT PRIMARY KEY AUTO_INCREMENT ${columnsPart}) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`);
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
await this._ensureMissingColumns(table, data);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
async insert(table, data) {
|
|
127
|
-
await this.runHooks('beforeInsert', table, data);
|
|
128
|
-
return this._execute('insert', table, async () => {
|
|
129
|
-
await this.ensureTable(table, data);
|
|
130
|
-
const keys = Object.keys(data);
|
|
131
|
-
const sql = `INSERT INTO
|
|
132
|
-
${table}
|
|
133
|
-
(${keys.map(k => `
|
|
134
|
-
${k}
|
|
135
|
-
`).join(",")}) VALUES (${keys.map(() => '?').join(",")})`;
|
|
136
|
-
const result = await this.query(sql, Object.values(data).map(v => typeof v === 'object' ? JSON.stringify(v) : v));
|
|
137
|
-
const finalData = { _id: result.insertId, ...data };
|
|
138
|
-
await this.runHooks('afterInsert', table, finalData);
|
|
139
|
-
return result.insertId;
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
async update(table, data, where) {
|
|
143
|
-
await this.runHooks('beforeUpdate', table, { data, where });
|
|
144
|
-
return this._execute('update', table, async () => {
|
|
145
|
-
await this.ensureTable(table, { ...data, ...where });
|
|
146
|
-
const set = Object.keys(data).map(k => `
|
|
147
|
-
${k}
|
|
148
|
-
= ?`).join(", ");
|
|
149
|
-
const wKeys = Object.keys(where);
|
|
150
|
-
const sql = `UPDATE
|
|
151
|
-
${table}
|
|
152
|
-
SET ${set} WHERE ${wKeys.map(k => `
|
|
153
|
-
${k}
|
|
154
|
-
= ?`).join(" AND ")}`;
|
|
155
|
-
const result = await this.query(sql, [...Object.values(data).map(v => typeof v === 'object' ? JSON.stringify(v) : v), ...Object.values(where).map(v => typeof v === 'object' ? JSON.stringify(v) : v)]);
|
|
156
|
-
return result.affectedRows;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
async delete(table, where) {
|
|
160
|
-
await this.runHooks('beforeDelete', table, where);
|
|
161
|
-
return this._execute('delete', table, async () => {
|
|
162
|
-
await this.ensureTable(table, where);
|
|
163
|
-
const keys = Object.keys(where);
|
|
164
|
-
const whereClause = keys.length > 0 ? `WHERE ${keys.map(k => `
|
|
165
|
-
${k}
|
|
166
|
-
= ?`).join(" AND ")}` : '';
|
|
167
|
-
const sql = `DELETE FROM
|
|
168
|
-
${table}
|
|
169
|
-
${whereClause}`;
|
|
170
|
-
const result = await this.query(sql, Object.values(where).map(v => typeof v === 'object' ? JSON.stringify(v) : v));
|
|
171
|
-
return result.affectedRows;
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
async select(table, where = null) {
|
|
175
|
-
return this._execute('select', table, async () => {
|
|
176
|
-
await this.ensureTable(table, where || {});
|
|
177
|
-
const keys = where ? Object.keys(where) : [];
|
|
178
|
-
const sql = `SELECT * FROM
|
|
179
|
-
${table}
|
|
180
|
-
` + (keys.length ? ' WHERE ' + keys.map(k => `
|
|
181
|
-
${k}
|
|
182
|
-
= ?`).join(" AND ") : '');
|
|
183
|
-
const rows = await this.query(sql, keys.map(k => typeof where[k] === 'object' ? JSON.stringify(where[k]) : where[k]));
|
|
184
|
-
return rows.map((row) => {
|
|
185
|
-
const nr = {};
|
|
186
|
-
for (const k in row) {
|
|
187
|
-
try {
|
|
188
|
-
nr[k] = JSON.parse(row[k]);
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
nr[k] = row[k];
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return nr;
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
async selectOne(table, where = null) {
|
|
199
|
-
const res = await this.select(table, where);
|
|
200
|
-
return res[0] || null;
|
|
201
|
-
}
|
|
202
|
-
async set(table, data, where) {
|
|
203
|
-
const existing = await this.selectOne(table, where);
|
|
204
|
-
return existing ? this.update(table, data, where) : this.insert(table, { ...where, ...data });
|
|
205
|
-
}
|
|
206
|
-
async bulkInsert(table, dataArray) {
|
|
207
|
-
if (!dataArray.length)
|
|
208
|
-
return 0;
|
|
209
|
-
return this._execute('bulkInsert', table, async () => {
|
|
210
|
-
await this.ensureTable(table, dataArray[0]);
|
|
211
|
-
const keys = Object.keys(dataArray[0]);
|
|
212
|
-
const placeholders = dataArray.map(() => `(${keys.map(() => '?').join(',')})`).join(',');
|
|
213
|
-
const values = dataArray.flatMap(obj => keys.map(k => this._serializeValue(obj[k])));
|
|
214
|
-
const sql = `INSERT INTO
|
|
215
|
-
${table}
|
|
216
|
-
(${keys.map(k => `
|
|
217
|
-
${k}
|
|
218
|
-
`).join(",")}) VALUES ${placeholders}`;
|
|
219
|
-
const result = await this.query(sql, values);
|
|
220
|
-
return result.affectedRows;
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
async increment(table, incs, where) {
|
|
224
|
-
return this._execute('increment', table, async () => {
|
|
225
|
-
await this.ensureTable(table, where);
|
|
226
|
-
const set = Object.keys(incs).map(f => `
|
|
227
|
-
${f}
|
|
228
|
-
=
|
|
229
|
-
${f}
|
|
230
|
-
+ ?`).join(', ');
|
|
231
|
-
const wKeys = Object.keys(where);
|
|
232
|
-
const sql = `UPDATE
|
|
233
|
-
${table}
|
|
234
|
-
SET ${set} WHERE ${wKeys.map(k => `
|
|
235
|
-
${k}
|
|
236
|
-
= ?`).join(" AND ")}`;
|
|
237
|
-
const result = await this.query(sql, [...Object.values(incs), ...Object.values(where).map(v => typeof v === 'object' ? JSON.stringify(v) : v)]);
|
|
238
|
-
return result.affectedRows;
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
async decrement(table, decs, where) {
|
|
242
|
-
const incs = {};
|
|
243
|
-
for (const k in decs)
|
|
244
|
-
incs[k] = -decs[k];
|
|
245
|
-
return this.increment(table, incs, where);
|
|
246
|
-
}
|
|
247
|
-
async close() { if (this.pool)
|
|
248
|
-
await this.pool.end(); }
|
|
249
|
-
_getColumnType(v) {
|
|
250
|
-
if (v === null || v === undefined)
|
|
251
|
-
return 'TEXT';
|
|
252
|
-
if (typeof v === 'boolean')
|
|
253
|
-
return 'BOOLEAN';
|
|
254
|
-
if (typeof v === 'number')
|
|
255
|
-
return Number.isInteger(v) ? 'INT' : 'DOUBLE';
|
|
256
|
-
if (v instanceof Date)
|
|
257
|
-
return 'DATETIME';
|
|
258
|
-
if (typeof v === 'object')
|
|
259
|
-
return 'JSON';
|
|
260
|
-
return 'TEXT';
|
|
261
|
-
}
|
|
262
|
-
_serializeValue(v) {
|
|
263
|
-
if (v instanceof Date)
|
|
264
|
-
return v.toISOString().slice(0, 19).replace('T', ' ');
|
|
265
|
-
return (typeof v === 'object' && v !== null) ? JSON.stringify(v) : v;
|
|
266
|
-
}
|
|
267
|
-
_buildWhereClause(where) {
|
|
268
|
-
if (!where)
|
|
269
|
-
return { whereClause: '', values: [] };
|
|
270
|
-
const keys = Object.keys(where);
|
|
271
|
-
if (!keys.length)
|
|
272
|
-
return { whereClause: '', values: [] };
|
|
273
|
-
return {
|
|
274
|
-
whereClause: 'WHERE ' + keys.map(k => `
|
|
275
|
-
${k}
|
|
276
|
-
= ?`).join(' AND '),
|
|
277
|
-
values: Object.values(where).map(v => this._serializeValue(v))
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
exports.MySQLDatabase = MySQLDatabase;
|
|
282
|
-
exports.default = MySQLDatabase;
|
package/dist/database/pg.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { IDatabase } from './IDatabase';
|
|
2
|
-
import { PostgreSQLConfig } from './types';
|
|
3
|
-
export declare class PostgreSQLDatabase extends IDatabase {
|
|
4
|
-
private config;
|
|
5
|
-
private pool;
|
|
6
|
-
private _queue;
|
|
7
|
-
private _connected;
|
|
8
|
-
private _connectionPromise;
|
|
9
|
-
constructor(config: PostgreSQLConfig);
|
|
10
|
-
private _execute;
|
|
11
|
-
private _processQueue;
|
|
12
|
-
query(sql: string, params?: any[]): Promise<any>;
|
|
13
|
-
ensureTable(table: string, data?: any): Promise<void>;
|
|
14
|
-
insert(table: string, data: any): Promise<any>;
|
|
15
|
-
update(table: string, data: any, where: any): Promise<number>;
|
|
16
|
-
delete(table: string, where: any): Promise<number>;
|
|
17
|
-
select<T = any>(table: string, where?: any): Promise<T[]>;
|
|
18
|
-
selectOne<T = any>(table: string, where?: any): Promise<T | null>;
|
|
19
|
-
set(table: string, data: any, where: any): Promise<any>;
|
|
20
|
-
bulkInsert(table: string, dataArray: any[]): Promise<number>;
|
|
21
|
-
increment(table: string, incs: Record<string, number>, where: any): Promise<number>;
|
|
22
|
-
decrement(table: string, decs: Record<string, number>, where: any): Promise<number>;
|
|
23
|
-
close(): Promise<void>;
|
|
24
|
-
private _getColumnType;
|
|
25
|
-
private _serializeValue;
|
|
26
|
-
private _buildWhereClause;
|
|
27
|
-
}
|
|
28
|
-
export default PostgreSQLDatabase;
|
package/dist/database/pg.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PostgreSQLDatabase = void 0;
|
|
4
|
-
const IDatabase_1 = require("./IDatabase");
|
|
5
|
-
const pg_1 = require("pg");
|
|
6
|
-
class PostgreSQLDatabase extends IDatabase_1.IDatabase {
|
|
7
|
-
constructor(config) {
|
|
8
|
-
super();
|
|
9
|
-
this.pool = null;
|
|
10
|
-
this._queue = [];
|
|
11
|
-
this._connected = false;
|
|
12
|
-
this.config = config;
|
|
13
|
-
this._connectionPromise = new Promise(async (resolve, reject) => {
|
|
14
|
-
try {
|
|
15
|
-
const tempPool = new pg_1.Pool({ host: config.host || 'localhost', port: config.port || 5432, user: config.username, password: config.password, database: 'postgres' });
|
|
16
|
-
try {
|
|
17
|
-
await tempPool.query(`CREATE DATABASE "${config.database}"`);
|
|
18
|
-
}
|
|
19
|
-
catch (e) {
|
|
20
|
-
if (!e.message.includes('already exists'))
|
|
21
|
-
console.warn(e.message);
|
|
22
|
-
}
|
|
23
|
-
await tempPool.end();
|
|
24
|
-
this.pool = new pg_1.Pool({ host: config.host || 'localhost', port: config.port || 5432, user: config.username, password: config.password, database: config.database, max: config.poolSize || 10 });
|
|
25
|
-
this._connected = true;
|
|
26
|
-
resolve(this.pool);
|
|
27
|
-
this._processQueue();
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
this._queue.forEach(q => q.reject(error));
|
|
31
|
-
this._queue = [];
|
|
32
|
-
reject(error);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
async _execute(op, table, fn) {
|
|
37
|
-
const start = Date.now();
|
|
38
|
-
const res = await fn();
|
|
39
|
-
this.recordMetric(op, table, Date.now() - start);
|
|
40
|
-
return res;
|
|
41
|
-
}
|
|
42
|
-
;
|
|
43
|
-
async _processQueue() {
|
|
44
|
-
if (!this._connected)
|
|
45
|
-
return;
|
|
46
|
-
while (this._queue.length > 0) {
|
|
47
|
-
const item = this._queue.shift();
|
|
48
|
-
if (item) {
|
|
49
|
-
try {
|
|
50
|
-
item.resolve(await item.operation());
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
item.reject(error);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async query(sql, params = []) {
|
|
59
|
-
const pool = await this._connectionPromise;
|
|
60
|
-
const res = await pool.query(sql, params);
|
|
61
|
-
return res.rows;
|
|
62
|
-
}
|
|
63
|
-
async ensureTable(table, data = {}) {
|
|
64
|
-
const tables = await this.query(`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1`, [table]);
|
|
65
|
-
if (tables.length === 0) {
|
|
66
|
-
const defs = Object.keys(data).map(k => `"${k}" ${this._getColumnType(data[k])}`);
|
|
67
|
-
await this.query(`CREATE TABLE "${table}" ("_id" SERIAL PRIMARY KEY ${defs.length ? ', ' + defs.join(",") : ''})`);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
const existing = await this.query(`SELECT column_name FROM information_schema.columns WHERE table_name = $1 AND table_schema = 'public'`, [table]);
|
|
71
|
-
const names = existing.map((c) => c.column_name);
|
|
72
|
-
for (const key of Object.keys(data)) {
|
|
73
|
-
if (key !== '_id' && !names.includes(key)) {
|
|
74
|
-
await this.query(`ALTER TABLE "${table}" ADD COLUMN "${key}" ${this._getColumnType(data[key])}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
async insert(table, data) {
|
|
80
|
-
await this.runHooks('beforeInsert', table, data);
|
|
81
|
-
return this._execute('insert', table, async () => {
|
|
82
|
-
await this.ensureTable(table, data);
|
|
83
|
-
const keys = Object.keys(data);
|
|
84
|
-
const sql = `INSERT INTO "${table}" (${keys.map(k => `"${k}"`).join(",")}) VALUES (${keys.map((_, i) => `$${i + 1}`).join(",")}) RETURNING "_id"`;
|
|
85
|
-
const res = await this.query(sql, Object.values(data).map(v => this._serializeValue(v)));
|
|
86
|
-
const finalData = { _id: res[0]._id, ...data };
|
|
87
|
-
await this.runHooks('afterInsert', table, finalData);
|
|
88
|
-
return res[0]._id;
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
async update(table, data, where) {
|
|
92
|
-
await this.runHooks('beforeUpdate', table, { data, where });
|
|
93
|
-
return this._execute('update', table, async () => {
|
|
94
|
-
await this.ensureTable(table, { ...data, ...where });
|
|
95
|
-
const dataKeys = Object.keys(data);
|
|
96
|
-
const set = dataKeys.map((k, i) => `"${k}" = $${i + 1}`).join(",");
|
|
97
|
-
const { whereClause, values: whereValues } = this._buildWhereClause(where, dataKeys.length);
|
|
98
|
-
const sql = `UPDATE "${table}" SET ${set} ${whereClause}`;
|
|
99
|
-
const pool = await this._connectionPromise;
|
|
100
|
-
const res = await pool.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...whereValues]);
|
|
101
|
-
return res.rowCount ?? 0;
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
async delete(table, where) {
|
|
105
|
-
await this.runHooks('beforeDelete', table, where);
|
|
106
|
-
return this._execute('delete', table, async () => {
|
|
107
|
-
await this.ensureTable(table, where);
|
|
108
|
-
const { whereClause, values } = this._buildWhereClause(where);
|
|
109
|
-
const sql = `DELETE FROM "${table}" ${whereClause}`;
|
|
110
|
-
const pool = await this._connectionPromise;
|
|
111
|
-
const res = await pool.query(sql, values);
|
|
112
|
-
return res.rowCount ?? 0;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
async select(table, where = null) {
|
|
116
|
-
return this._execute('select', table, async () => {
|
|
117
|
-
await this.ensureTable(table, where || {});
|
|
118
|
-
const { whereClause, values } = this._buildWhereClause(where);
|
|
119
|
-
const rows = await this.query(`SELECT * FROM "${table}" ${whereClause}`, values);
|
|
120
|
-
return rows.map((r) => {
|
|
121
|
-
const nr = {};
|
|
122
|
-
for (const k in r) {
|
|
123
|
-
// Postgres returns numbers as strings for safety sometimes,
|
|
124
|
-
// but since we used correct types now, driver might handle it better.
|
|
125
|
-
// If not, we can cast if it looks like a number.
|
|
126
|
-
// For now, let's trust the driver + schema.
|
|
127
|
-
nr[k] = r[k];
|
|
128
|
-
}
|
|
129
|
-
return nr;
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
async selectOne(table, where = null) {
|
|
134
|
-
const res = await this.select(table, where);
|
|
135
|
-
return res[0] || null;
|
|
136
|
-
}
|
|
137
|
-
async set(table, data, where) {
|
|
138
|
-
const ex = await this.selectOne(table, where);
|
|
139
|
-
return ex ? this.update(table, data, where) : this.insert(table, { ...where, ...data });
|
|
140
|
-
}
|
|
141
|
-
async bulkInsert(table, dataArray) {
|
|
142
|
-
if (!dataArray.length)
|
|
143
|
-
return 0;
|
|
144
|
-
for (const d of dataArray)
|
|
145
|
-
await this.insert(table, d);
|
|
146
|
-
return dataArray.length;
|
|
147
|
-
}
|
|
148
|
-
async increment(table, incs, where) {
|
|
149
|
-
return this._execute('increment', table, async () => {
|
|
150
|
-
await this.ensureTable(table, where);
|
|
151
|
-
const incKeys = Object.keys(incs);
|
|
152
|
-
const set = incKeys.map((f, i) => `"${f}" = "${f}" + $${i + 1}`).join(',');
|
|
153
|
-
const { whereClause, values } = this._buildWhereClause(where, incKeys.length);
|
|
154
|
-
const sql = `UPDATE "${table}" SET ${set} ${whereClause}`;
|
|
155
|
-
const pool = await this._connectionPromise;
|
|
156
|
-
const res = await pool.query(sql, [...Object.values(incs), ...values]);
|
|
157
|
-
return res.rowCount ?? 0;
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
async decrement(table, decs, where) {
|
|
161
|
-
const incs = {};
|
|
162
|
-
for (const k in decs)
|
|
163
|
-
incs[k] = -decs[k];
|
|
164
|
-
return this.increment(table, incs, where);
|
|
165
|
-
}
|
|
166
|
-
async close() { if (this.pool)
|
|
167
|
-
await this.pool.end(); }
|
|
168
|
-
_getColumnType(v) {
|
|
169
|
-
if (v === null || v === undefined)
|
|
170
|
-
return 'TEXT';
|
|
171
|
-
if (typeof v === 'boolean')
|
|
172
|
-
return 'BOOLEAN';
|
|
173
|
-
if (typeof v === 'number')
|
|
174
|
-
return Number.isInteger(v) ? 'INTEGER' : 'DOUBLE PRECISION';
|
|
175
|
-
if (v instanceof Date)
|
|
176
|
-
return 'TIMESTAMP';
|
|
177
|
-
if (typeof v === 'object')
|
|
178
|
-
return 'JSONB';
|
|
179
|
-
return 'TEXT';
|
|
180
|
-
}
|
|
181
|
-
_serializeValue(v) {
|
|
182
|
-
if (v instanceof Date)
|
|
183
|
-
return v.toISOString();
|
|
184
|
-
return (typeof v === 'object' && v !== null) ? JSON.stringify(v) : v;
|
|
185
|
-
}
|
|
186
|
-
_buildWhereClause(where, offset = 0) {
|
|
187
|
-
if (!where)
|
|
188
|
-
return { whereClause: '', values: [] };
|
|
189
|
-
const safeWhere = where;
|
|
190
|
-
const keys = Object.keys(safeWhere);
|
|
191
|
-
if (!keys.length)
|
|
192
|
-
return { whereClause: '', values: [] };
|
|
193
|
-
return {
|
|
194
|
-
whereClause: 'WHERE ' + keys.map((k, i) => `"${k}" = $${i + 1 + offset}`).join(' AND '),
|
|
195
|
-
values: keys.map(k => this._serializeValue(safeWhere[k]))
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
exports.PostgreSQLDatabase = PostgreSQLDatabase;
|
|
200
|
-
exports.default = PostgreSQLDatabase;
|
package/dist/database/redis.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { IDatabase } from './IDatabase';
|
|
2
|
-
import { RedisConfig } from './types';
|
|
3
|
-
export declare class RedisDatabase extends IDatabase {
|
|
4
|
-
private config;
|
|
5
|
-
private client;
|
|
6
|
-
private keyPrefix;
|
|
7
|
-
private _queue;
|
|
8
|
-
private _isReady;
|
|
9
|
-
private _connectionPromise;
|
|
10
|
-
constructor(config: RedisConfig);
|
|
11
|
-
private _ensureConnection;
|
|
12
|
-
private _flushQueue;
|
|
13
|
-
private _flushQueueWithError;
|
|
14
|
-
private _execute;
|
|
15
|
-
private _getKey;
|
|
16
|
-
private _getTableKey;
|
|
17
|
-
select<T = any>(table: string, where?: Record<string, any>): Promise<T[]>;
|
|
18
|
-
selectOne<T = any>(table: string, where?: Record<string, any>): Promise<T | null>;
|
|
19
|
-
insert(table: string, data: Record<string, any>): Promise<any>;
|
|
20
|
-
update(table: string, data: Record<string, any>, where: Record<string, any>): Promise<number>;
|
|
21
|
-
delete(table: string, where: Record<string, any>): Promise<number>;
|
|
22
|
-
set(table: string, data: Record<string, any>, where: Record<string, any>): Promise<any>;
|
|
23
|
-
bulkInsert(table: string, dataArray: Record<string, any>[]): Promise<number>;
|
|
24
|
-
/**
|
|
25
|
-
* Atomic Increment using Lua for Redis
|
|
26
|
-
*/
|
|
27
|
-
increment(table: string, incs: Record<string, number>, where?: Record<string, any>): Promise<number>;
|
|
28
|
-
decrement(table: string, decs: Record<string, number>, where?: Record<string, any>): Promise<number>;
|
|
29
|
-
close(): Promise<void>;
|
|
30
|
-
}
|
|
31
|
-
export default RedisDatabase;
|