blackcat.js-database 1.0.0-test → 1.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/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -17,6 +19,14 @@ var __copyProps = (to, from, except, desc) => {
17
19
  }
18
20
  return to;
19
21
  };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
20
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
31
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
32
 
@@ -24,7 +34,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
24
34
  var index_exports = {};
25
35
  __export(index_exports, {
26
36
  Database: () => Database,
27
- JSONDriver: () => JSONDriver
37
+ JSONDriver: () => JSONDriver,
38
+ MemoryDriver: () => MemoryDriver,
39
+ MongoDriver: () => MongoDriver,
40
+ SQLiteDriver: () => SQLiteDriver
28
41
  });
29
42
  module.exports = __toCommonJS(index_exports);
30
43
 
@@ -135,170 +148,147 @@ var import_node_events = require("events");
135
148
 
136
149
  // src/Database.ts
137
150
  var _Database = class _Database {
151
+ /**
152
+ * Khởi tạo Database instance.
153
+ *
154
+ * @param options Cấu hình database.
155
+ * @param options.driver Driver lưu trữ dữ liệu.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * const db = new Database({
160
+ * driver: new JSONDriver({ filePath: "./database.json" }),
161
+ * })
162
+ * ```
163
+ *
164
+ * Ví dụ với MongoDB:
165
+ *
166
+ * ```ts
167
+ * const db = new Database({
168
+ * driver: new MongoDriver({
169
+ * uri: "mongodb://localhost:27017",
170
+ * databaseName: "mydb"
171
+ * })
172
+ * });
173
+ * ```
174
+ */
138
175
  constructor(options) {
139
176
  /**
140
- * The low-level database driver handling basic operations.
177
+ * Storage driver được sử dụng để đọc và ghi dữ liệu database.
178
+ *
179
+ * Driver phải implement interface `DatabaseDriver`.
180
+ *
181
+ * Ví dụ:
182
+ * ```ts
183
+ * const db = new Database({
184
+ * driver: new JSONDriver({ filePath: "./database.json" }),
185
+ * })
186
+ * ```
141
187
  */
142
188
  __publicField(this, "driver");
143
189
  this.driver = options.driver;
144
190
  }
145
191
  /**
146
- * Gets all the database contents from the cache.
192
+ * Lấy toàn bộ dữ liệu từ database thông qua driver.
147
193
  *
148
- * Type parameters:
149
- *
150
- * - `T` (`object`, defaults to `Record<string, any>`) - The type of object of all the database object to be returned.
151
- *
152
- * @returns {T} Cached database contents.
194
+ * @template T Kiểu dữ liệu object database trả về.
153
195
  *
154
- * @template T (object, defaults to `Record<string, any>`) -
155
- * The type of object of all the database object to be returned.
196
+ * @returns Promise chứa toàn bộ dữ liệu database.
156
197
  *
157
198
  * @example
158
- * const databaseContents = await database.all();
159
- * console.log(databaseContents); // -> { ... (the object of all the data stored in database) }
199
+ * ```ts
200
+ * const data = await db.all();
201
+ * console.log(data.users);
202
+ * ```
160
203
  */
161
204
  async all() {
162
- const allDatabase = await this.driver.all();
163
- return allDatabase;
205
+ return await this.driver.all();
164
206
  }
165
207
  /**
166
- * Retrieves a value from database by a key.
208
+ * Lấy giá trị từ database theo key-path.
209
+ *
210
+ * Key có thể là chuỗi dạng path:
211
+ *
212
+ * ```
213
+ * user.profile.name
214
+ * economy.users.123.balance
215
+ * ```
167
216
  *
168
- * @param {AutocompletableString<P>} key The key to access the target in database by.
169
- * @returns {Maybe<ObjectValue<V, P>>} The value of the target in database.
217
+ * Nếu không truyền `key`, method sẽ trả về **toàn bộ database**.
218
+ *
219
+ * @template {AutocompletableString<ObjectPath<V>>} P Key path trong database.
220
+ *
221
+ * @param {AutocompletableString<P>} key Đường dẫn dữ liệu cần lấy.
222
+ *
223
+ * @returns Giá trị tại key hoặc `null` nếu không tồn tại.
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * const name = await db.get("user.profile.name");
228
+ * ```
170
229
  *
171
230
  * @example
172
- * const simpleValue = await database.get("simpleValue");
173
- * console.log(simpleValue); // -> 123
174
- *
175
- * const databaseObjectPropertyAccessed = await database.get("youCanAlso.accessDatabaseObjectProperties.likeThat");
176
- * console.log(databaseObjectPropertyAccessed); // -> "hello world!"
177
- *
178
- * // Assuming that the initial database object for this example is:
179
- * // {
180
- * // simpleValue: 123,
181
- * // youCanAlso: {
182
- * // accessDatabaseObjectProperties: {
183
- * // likeThat: "hello world!"
184
- * // }
185
- * // }
186
- * // }
231
+ * ```ts
232
+ * const all = await db.get();
233
+ * ```
187
234
  */
188
235
  async get(key) {
189
- if (key !== void 0) {
190
- if (typeof key !== "string") {
191
- throw new BlackCatError("INVALID_TYPE", "key", "string", typeOf(key));
192
- }
193
- return this.driver.get(key);
194
- } else {
195
- return this.all();
236
+ const data = await this.all();
237
+ if (key === void 0) return data;
238
+ if (typeof key !== "string") {
239
+ throw new BlackCatError("INVALID_TYPE", "key", "string", typeOf(key));
196
240
  }
197
- ;
241
+ const keys = key.split(".");
242
+ let result = data;
243
+ for (const k of keys) {
244
+ if (!isObject(result) && !Array.isArray(result)) return null;
245
+ result = result[k];
246
+ if (result === void 0) return null;
247
+ }
248
+ return result;
198
249
  }
199
250
  /**
200
- * Retrieves a value from database by a key.
251
+ * Kiểm tra một key-path có tồn tại trong database hay không.
201
252
  *
202
- * - This method is an alias for {@link Database.get()} method.
253
+ * Method này sử dụng `get()` để xác định giá trị có tồn tại.
203
254
  *
204
- * @param {AutocompletableString<P>} key The key to access the target in database by.
205
- * @returns {Maybe<ObjectValue<V, P>>} The value from database.
255
+ * @template {AutocompletableString<ObjectPath<V>>} P Key path trong database.
206
256
  *
207
- * @example
208
- * const simpleValue = await database.fetch("simpleValue");
209
- * console.log(simpleValue); // -> 123
257
+ * @param {AutocompletableString<P>} key Đường dẫn dữ liệu cần kiểm tra.
210
258
  *
211
- * // You can use the dot notation to access the database object properties:
212
- * const playerInventory = await database.fetch("player.inventory");
213
- * console.log(playerInventory); // -> []
214
- *
215
- * // Assuming that the initial database object for this example is:
216
- * // {
217
- * // simpleValue: 123,
218
- * // player: {
219
- * // inventory: []
220
- * // }
221
- * // }
222
- */
223
- async fetch(key) {
224
- return this.get(key);
225
- }
226
- /**
227
- * Determines if the data is stored in database.
228
- * @param {AutocompletableString<P>} key The key to access the target in database by.
229
- * @returns {boolean} Whether the data is stored in database.
259
+ * @returns `true` nếu key tồn tại, ngược lại `false`.
230
260
  *
231
261
  * @example
232
- * const isSimpleValueInDatabase = await database.has("simpleValue");
233
- * console.log(isSimpleValueInDatabase); // -> true
234
- *
235
- * const somethingElse = await database.has("somethingElse");
236
- * console.log(somethingElse); // -> false
237
- *
238
- * // You can use the dot notation to check the database object properties:
239
- * const isObjectInDatabase = await database.has("youCanAlso.accessObjectProperties.likeThat");
240
- * console.log(isObjectInDatabase); // -> true
241
- *
242
- * // Assuming that the initial database object for this example is:
243
- * // {
244
- * // simpleValue: 123,
245
- * // player: {
246
- * // inventory: []
247
- * // },
248
- * // youCanAlso: {
249
- * // accessObjectProperties: {
250
- * // likeThat: "hello world!"
251
- * // }
252
- * // }
253
- * // }
262
+ * ```ts
263
+ * const exists = await db.has("users.123");
264
+ * ```
254
265
  */
255
266
  async has(key) {
256
- return this.get(key) !== null && this.get(key) !== void 0;
267
+ const value = await this.get(key);
268
+ return value !== null && value !== void 0;
257
269
  }
258
270
  /**
259
- * Writes the specified value into database under the specified key.
260
- *
261
- * @param {AutocompletableString<P>} key The key to write in the target.
262
- * @param {ObjectValue<V, P>} value The value to write.
263
- *
264
- * @returns {Promise<If<IsObject<V>, FirstObjectKey<P>, V>>}
265
- * - If the `value` parameter's type is not an object (string, number, boolean, etc), then the specified
266
- * `value` parameter (type of `ObjectValue<V, P>`) will be returned.
267
- *
268
- * - If an object is specified in the `value` parameter, then the object of the first key will be returned.
269
- * (type of `FirstObjectKey<P>` - first object key (e.g. in key `member.user.id`, the first key will be `member`))
270
- *
271
- * @example
272
- * // Assuming that the initial database object for this example is empty.
273
- *
274
- * await database.set("something", "hello");
275
- * const hello = await database.get("something");
271
+ * Gán giá trị cho một key-path trong database.
276
272
  *
277
- * console.log(hello); // -> "hello"
273
+ * Nếu key-path chưa tồn tại, các object trung gian
274
+ * sẽ được tự động tạo.
278
275
  *
279
- * // You can use the dot notation to write data in objects:
280
- * const dotNotationSetResult = await database.set("member.user.id", 2000);
281
- * console.log(dotNotationSetResult); // -> 2000
276
+ * @template {AutocompletableString<ObjectPath<V>>} P Key path trong database.
282
277
  *
283
- * await database.set("member.inventory", []);
284
- * const inventory = await database.get("member.inventory");
278
+ * @param {AutocompletableString<P>} key Đường dẫn dữ liệu cần gán giá trị.
279
+ * @param {ObjectValue<V, P>} value Giá trị mới.
285
280
  *
286
- * console.log(inventory); // -> []
281
+ * @returns {Promise<If<IsObject<V>, ObjectValue<V, FirstObjectKey<P>>, V>>} Giá trị vừa được set hoặc object root nếu value là object.
287
282
  *
288
- * // Using objects as value will return the object of key `thats`:
289
- * await database.set("member.user", { name: "Jerry" }); // -> { member: { user: { name: "Jerry" } } }
283
+ * @example
284
+ * ```ts
285
+ * await db.set("users.123.name", "Alice");
286
+ * ```
290
287
  *
291
- * // After these manipulations, the database object will look like this:
292
- * // {
293
- * // "something": "hello",
294
- * // "member": {
295
- * // "inventory": [],
296
- * // "user": {
297
- * // "name": "Jerry",
298
- * // "id": 2000
299
- * // }
300
- * // }
301
- * // }
288
+ * @example
289
+ * ```ts
290
+ * await db.set("config.prefix", "!");
291
+ * ```
302
292
  */
303
293
  async set(key, value) {
304
294
  const allDatabase = await this.all();
@@ -322,21 +312,81 @@ var _Database = class _Database {
322
312
  ;
323
313
  }
324
314
  ;
325
- await this.driver.set(keys[0], allDatabase);
315
+ await this.driver.set(allDatabase);
326
316
  return typeof value == "object" && value !== null ? await this.get(keys[0]) : value;
327
317
  }
328
318
  /**
329
- * Update the specified value into database under the specified key.
319
+ * Xóa một key khỏi database.
320
+ *
321
+ * Hỗ trợ nested path bằng dot notation.
322
+ *
323
+ * @typeParam P - Path của object.
324
+ *
325
+ * @param key - Đường dẫn key cần xóa.
330
326
  *
331
- * @param {AutocompletableString<P>} key The key to update the target.
332
- * @param {ObjectValue<V, P>} value The value to update.
327
+ * @returns
328
+ * - `true` nếu xóa thành công
329
+ * - `false` nếu key không tồn tại
333
330
  *
334
- * @returns {Promise<If<IsObject<V>, FirstObjectKey<P>, V>>}
335
- * - If the `value` parameter's type is not an object (string, number, boolean, etc), then the specified
336
- * `value` parameter (type of `ObjectValue<V, P>`) will be returned.
331
+ * @throws BlackCatError
332
+ * - INVALID_TYPE nếu key không phải string
337
333
  *
338
- * - If an object is specified in the `value` parameter, then the object of the first key will be returned.
339
- * (type of `FirstObjectKey<P>` - first object key (e.g. in key `member.user.id`, the first key will be `member`))
334
+ * @example
335
+ * await db.delete("user.name");
336
+ */
337
+ async delete(key) {
338
+ if (typeof key !== "string") {
339
+ throw new BlackCatError("INVALID_TYPE", "key", "string", typeof key);
340
+ }
341
+ const allDatabase = await this.all();
342
+ const keys = key.split(".");
343
+ const lastKey = keys.pop();
344
+ let currentObj = allDatabase;
345
+ for (const k of keys) {
346
+ if (!isObject(currentObj[k])) {
347
+ return false;
348
+ }
349
+ currentObj = currentObj[k];
350
+ }
351
+ if (!(lastKey in currentObj)) return false;
352
+ delete currentObj[lastKey];
353
+ await this.driver.set(allDatabase);
354
+ return true;
355
+ }
356
+ /**
357
+ * Xóa toàn bộ dữ liệu trong database.
358
+ *
359
+ * Method này gọi trực tiếp `driver.delete()` để reset storage.
360
+ *
361
+ * @returns `true` sau khi dữ liệu đã được xóa.
362
+ *
363
+ * @example
364
+ * await db.deleteAll();
365
+ */
366
+ async deleteAll() {
367
+ await this.driver.delete();
368
+ return true;
369
+ }
370
+ /**
371
+ * Cập nhật giá trị của một key-path trong database.
372
+ *
373
+ * Khác với `set()`, method này chỉ ghi đè giá trị của key cuối cùng
374
+ * trong path mà không thay đổi cấu trúc object phía trên.
375
+ *
376
+ * Nếu các object trung gian trong path chưa tồn tại
377
+ * thì chúng sẽ được tự động tạo.
378
+ *
379
+ * @template P Key path trong database.
380
+ *
381
+ * @param key Đường dẫn dữ liệu cần cập nhật.
382
+ * @param value Giá trị mới.
383
+ *
384
+ * @returns Object cha của key vừa cập nhật.
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * await db.update("users.123.name", "Alice");
389
+ * ```
340
390
  */
341
391
  async update(key, value) {
342
392
  const allDatabase = await this.all();
@@ -351,34 +401,25 @@ var _Database = class _Database {
351
401
  }
352
402
  const lastKey = keys[keys.length - 1];
353
403
  current[lastKey] = value;
354
- await this.driver.set(keys[0], allDatabase);
404
+ await this.driver.set(allDatabase);
355
405
  return current;
356
406
  }
357
407
  /**
358
- * Performs an arithmetical addition on a target number in database.
359
- *
360
- * [!!!] The type of target value must be a number.
408
+ * Cộng thêm giá trị vào một key dạng number.
361
409
  *
362
- * @param {AutocompletableString<P>} key The key to access the target in database by.
363
- * @param {number} numberToAdd The number to add to the target number in database.
364
- * @returns {Promise<number>} Addition operation result.
410
+ * Nếu key chưa tồn tại, giá trị mặc định sẽ là `0`.
365
411
  *
366
- * @example
367
- * const additionResult = await database.add("points", 5);
368
- * console.log(additionResult); // -> 10 (5 + 5 = 10)
412
+ * @template P Key path trong database.
369
413
  *
370
- * // Notice that we don't need to assign a value to unexistent properties in database
371
- * // before performing an addition since the initial target value is 0 and will be used
372
- * // as the value of the unexistent property:
373
- * const unexistentAdditionResult = await database.add("somethingElse", 3);
414
+ * @param key Đường dẫn dữ liệu dạng number.
415
+ * @param numberToAdd Số cần cộng thêm.
374
416
  *
375
- * console.log(unexistentAdditionResult); // -> 3 (0 + 3 = 3)
376
- * // the property didn't exist in database, that's why 0 is added to 3
417
+ * @returns Giá trị mới sau khi cộng.
377
418
  *
378
- * // Assuming that the initial database object for this example is:
379
- * // {
380
- * // points: 5
381
- * // }
419
+ * @example
420
+ * ```ts
421
+ * await db.add("economy.users.123.balance", 50);
422
+ * ```
382
423
  */
383
424
  async add(key, numberToAdd) {
384
425
  const targetNumber = await this.get(key) ?? 0;
@@ -394,30 +435,21 @@ var _Database = class _Database {
394
435
  return await this.set(key, targetNumber + numberToAdd);
395
436
  }
396
437
  /**
397
- * Performs an arithmetical subtraction on a target number in database.
438
+ * Trừ giá trị khỏi một key dạng number.
398
439
  *
399
- * [!!!] The type of target value must be a number.
440
+ * Nếu key chưa tồn tại, giá trị mặc định sẽ là `0`.
400
441
  *
401
- * @param {AutocompletableString<P>} key The key to access the target in database by.
402
- * @param {number} numberToSubtract The number to subtract from the target number in database.
403
- * @returns {Promise<number>} Subtraction operation result.
442
+ * @template P Key path trong database.
404
443
  *
405
- * @example
406
- * const subtractionResult = await database.subtract("points", 5)
407
- * console.log(subtractionResult) // -> 5 (10 - 5 = 5)
444
+ * @param key Đường dẫn dữ liệu dạng number.
445
+ * @param numberToSubtract Số cần trừ.
408
446
  *
409
- * // Notice that we don't need to assign a value to unexistent properties in database
410
- * // before performing a subtraction since the initial target value is 0 and will be used
411
- * // as the value of the unexistent property:
412
- * const unexistentSubtractionitionResult = await database.subtract("somethingElse", 3)
447
+ * @returns Giá trị mới sau khi trừ.
413
448
  *
414
- * console.log(unexistentSubtractionitionResult) // -> 3 (0 - 3 = -3)
415
- * // the property didn't exist in database, so 3 is subtracted from 0
416
- *
417
- * // Assuming that the initial database object for this example is:
418
- * // {
419
- * // points: 10
420
- * // }
449
+ * @example
450
+ * ```ts
451
+ * await db.subtract("economy.users.123.balance", 20);
452
+ * ```
421
453
  */
422
454
  async subtract(key, numberToSubtract) {
423
455
  const targetNumber = await this.get(key) ?? 0;
@@ -433,27 +465,31 @@ var _Database = class _Database {
433
465
  return await this.set(key, targetNumber - numberToSubtract);
434
466
  }
435
467
  /**
436
- * Pushes the specified value(s) into the target array in database.
468
+ * Thêm một hoặc nhiều phần tử vào cuối array tại key-path.
469
+ *
470
+ * Method này sẽ:
471
+ * - kiểm tra target có phải array không
472
+ * - chỉ thêm các giá trị **chưa tồn tại** trong array
437
473
  *
438
- * [!!!] The type of target value must be an array.
439
- * [!!!] get only values ​​not stored in the database.
474
+ * ⚠️ Nếu key không tồn tại hoặc target không phải array
475
+ * thì sẽ ném lỗi.
440
476
  *
441
- * @param {AutocompletableString<P>} key The key to access the target in database by.
442
- * @param {RestOrArray<ExtractFromArray<ObjectValue<V, P>>>} values
443
- * The value(s) to be pushed into the target array in database.
477
+ * @template P Key path trong database.
444
478
  *
445
- * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.
479
+ * @param key Đường dẫn tới array cần thêm phần tử.
480
+ * @param values Một hoặc nhiều giá trị cần thêm.
481
+ *
482
+ * @returns Array sau khi thêm phần tử.
446
483
  *
447
484
  * @example
448
- * console.log(await database.push("members", "Jerry")); // -> ["Tom", "Jerry"]
449
- * // You can also pass in multiple values to push into the target array:
450
- * console.log(await database.push("currencies", "VND")); // -> ["USD", "VND"]
485
+ * ```ts
486
+ * await db.push("users.123.roles", "admin");
487
+ * ```
451
488
  *
452
- * // Assuming that the initial database object for this example is:
453
- * // {
454
- * // members: ["Tom"],
455
- * // currencies: ["USD"]
456
- * // }
489
+ * @example
490
+ * ```ts
491
+ * await db.push("queue.songs", song1, song2);
492
+ * ```
457
493
  */
458
494
  async push(key, ...values) {
459
495
  if (!values.length) {
@@ -483,23 +519,25 @@ var _Database = class _Database {
483
519
  return target[pathParts[pathParts.length - 1]];
484
520
  }
485
521
  /**
486
- * Replaces the specified element in target array with the specified value in the target array in database.
487
- *
488
- * [!!!] The type of target value must be an array.
489
- *
490
- * @param {AutocompletableString<P>} key The key to access the target in database by.
491
- * @param {number} targetArrayElementIndex The index to find the element in target array by.
492
- * @param {V} value The value to be pushed into the target array in database.
493
- * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.
494
- *
495
- * @example
496
- * console.log(await database.pull("members", 1, "James")); // -> ["Jerry", "James", "Tom"]
497
- *
498
- * // Assuming that the initial database object for this example is:
499
- * // {
500
- * // members: ["Jerry", "William", "Tom"]
501
- * // }
502
- */
522
+ * Thay thế phần tử trong array theo index.
523
+ *
524
+ * @typeParam P - Path trỏ đến array.
525
+ *
526
+ * @param key - Đường dẫn array.
527
+ * @param targetArrayElementIndex - Index cần thay.
528
+ * @param value - Giá trị mới.
529
+ *
530
+ * @returns Array sau khi thay thế.
531
+ *
532
+ * @throws BlackCatError
533
+ * - INVALID_TYPE nếu index không phải number
534
+ * - REQUIRED_PARAMETER_MISSING nếu thiếu value
535
+ * - INVALID_KEY nếu path không tồn tại
536
+ * - INVALID_TARGET nếu target không phải array
537
+ *
538
+ * @example
539
+ * await db.pull("users", 0, { id: 2 });
540
+ */
503
541
  async pull(key, targetArrayElementIndex, value) {
504
542
  if (!isNumber(targetArrayElementIndex)) {
505
543
  throw new BlackCatError("INVALID_TYPE", "targetArrayElementIndex", "number", typeOf(targetArrayElementIndex));
@@ -539,26 +577,25 @@ var _Database = class _Database {
539
577
  return target[pathParts[pathParts.length - 1]];
540
578
  }
541
579
  /**
542
- * Removes the specified element(s) from the target array in database.
580
+ * Xóa phần tử khỏi array theo index.
543
581
  *
544
- * [!!!] The type of target value must be an array.
582
+ * thể truyền nhiều index hoặc một array index.
545
583
  *
546
- * @param {AutocompletableString<P>} key The key to access the target in database by.
547
- * @param {RestOrArray<ExtractFromArray<number>>} targetArrayElementIndexes
548
- * The index(es) to find the element(s) in target array by.
584
+ * @typeParam P - Path trỏ đến array.
549
585
  *
550
- * @returns {Promise<Array<ExtractFromArray<ObjectValue<V, P>>>>} Updated target array from database.
586
+ * @param key - Đường dẫn array.
587
+ * @param targetArrayElementIndexes - Các index cần xóa.
551
588
  *
552
- * @example
553
- * console.log(await database.pop("members", 1)); // -> ["Jerry", "Tom"]
589
+ * @returns Danh sách phần tử đã bị xóa.
554
590
  *
555
- * console.log(await database.pop("currencies", 1)); // -> ["VND", "Euro"]
591
+ * @throws BlackCatError
592
+ * - INVALID_TARGET nếu target không phải array
593
+ * - REQUIRED_PARAMETER_MISSING nếu thiếu index
594
+ * - ONE_OR_MORE_ARRAY_TYPES_INVALID nếu index không phải number
556
595
  *
557
- * // Assuming that the initial database object for this example is:
558
- * // {
559
- * // members: ["Jerry", "William", "Tom"],
560
- * // currencies: ["VND", "USD", "Euro"]
561
- * // }
596
+ * @example
597
+ * await db.pop("users", 0);
598
+ * await db.pop("numbers", [1, 2, 3]);
562
599
  */
563
600
  async pop(key, ...targetArrayElementIndexes) {
564
601
  const targetArray = await this.get(key) ?? [];
@@ -595,87 +632,52 @@ var _Database = class _Database {
595
632
  return removedElements;
596
633
  }
597
634
  /**
598
- * Determines whether the specified target is an array.
635
+ * Kiểm tra xem giá trị tại key có phải là Array hay không.
599
636
  *
600
- * @param {AutocompletableString<P>} key The key to access the target in database by.
601
- * @returns {Promise<boolean>} Whether the target is an array.
637
+ * @typeParam P - Path của object trong database.
638
+ * @param key - Đường dẫn key cần kiểm tra.
602
639
  *
603
- * @example
604
- * console.log(await databse.isTargetArray("array")); // => true
605
- * console.log(await databse.isTargetArray("notArray")); // => false
640
+ * @returns `true` nếu giá trị là Array, ngược lại `false`.
606
641
  *
607
- * // Assuming that the initial database object for this example is:
608
- * // {
609
- * // array: [],
610
- * // notArray: 123
611
- * // }
642
+ * @example
643
+ * const result = await db.isTargetArray("users");
644
+ * console.log(result);
612
645
  */
613
646
  async isTargetArray(key) {
614
647
  const target = await this.get(key);
615
648
  return Array.isArray(target);
616
649
  }
617
650
  /**
618
- * Determines whether the specified target is a number.
651
+ * Kiểm tra xem giá trị tại key có phải là Number hay không.
619
652
  *
620
- * @param {AutocompletableString<P>} key The key to access the target in database by.
621
- * @returns {Promise<boolean>} Whether the target is a number.
653
+ * @typeParam P - Path của object trong database.
622
654
  *
623
- * @example
624
- * console.log(await database.isTargetNumber("number")); // -> true
625
- * console.log(await database.isTargetNumber("notNumber")); // -> false
655
+ * @param key - Đường dẫn key cần kiểm tra.
656
+ *
657
+ * @returns `true` nếu giá trị là Number, ngược lại `false`.
626
658
  *
627
- * // Assuming that the initial database object for this example is:
628
- * // {
629
- * // number: 123,
630
- * // notNumber: []
631
- * // }
659
+ * @example
660
+ * const result = await db.isTargetNumber("stats.score");
661
+ * console.log(result);
632
662
  */
633
663
  async isTargetNumber(key) {
634
664
  const target = await this.get(key);
635
665
  return isNumber(target);
636
666
  }
637
667
  /**
638
- * Returns an array of object keys by specified database key.
668
+ * Lấy danh sách các key của object trong database.
639
669
  *
640
- * If `key` parameter is omitted, then an array of object keys of database root object will be returned.
670
+ * Nếu không truyền `key` trả về các key cấp cao nhất của database.
641
671
  *
642
- * Type parameters:
672
+ * @typeParam P - Path của object.
643
673
  *
644
- * - `TKeys` (`TupleOrArray<string>`, defaults to `K[]`) - The tuple or array of a type of keys to be returned.
674
+ * @param key - Path của object cần lấy danh sách key.
645
675
  *
646
- * @param {P} [key] The key to access the target in database by.
647
- * @returns {Array<ObjectPath<P>>} Database object keys array.
676
+ * @returns Mảng các key tồn tại (không bao gồm `null` hoặc `undefined`).
648
677
  *
649
678
  * @example
650
- * const prop3Keys = await database.keys("prop3");
651
- * console.log(prop3Keys) // -> ["prop4", "prop5"]
652
- *
653
- * const prop5Keys = await database.keys("prop3.prop5");
654
- * console.log(prop5Keys) // -> ["prop6"]
655
- *
656
- * const prop6Keys = await database.keys("prop3.prop5.prop6");
657
- * console.log(prop6Keys)
658
- * // -> [] (empty since the value in `prop6`, 111, is a primitive value and not an actual object)
659
- *
660
- * const databaseKeys = await database.keys();
661
- * // in this example, `key` parameter is omitted - object keys of database object are being returned
662
- *
663
- * console.log(databaseKeys) // -> ["prop1", "prop2", "prop3"]
664
- *
665
- * const unexistentKeys = await database.keys("somethingElse");
666
- * console.log(unexistentKeys) // -> [] (empty since the key `somethingElse` does not exist in database)
667
- *
668
- * // Assuming that the initial database object for this example is:
669
- * // {
670
- * // prop1: 123,
671
- * // prop2: 456,
672
- * // prop3: {
673
- * // prop4: 789,
674
- * // prop5: {
675
- * // prop6: 111
676
- * // }
677
- * // }
678
- * // }
679
+ * const rootKeys = await db.keys();
680
+ * const userKeys = await db.keys("user");
679
681
  */
680
682
  async keys(key) {
681
683
  if (!key) return TypedObject.keys(await this.all());
@@ -683,51 +685,33 @@ var _Database = class _Database {
683
685
  return TypedObject.keys(data).filter((key2) => data[key2] !== void 0 && data[key2] !== null);
684
686
  }
685
687
  /**
686
- * Determines the number of keys in the root of the database.
687
- * @type {Promise<number>} amount of data.
688
+ * Lấy số lượng key cấp cao nhất trong database.
689
+ *
690
+ * @returns Tổng số key ở root level.
691
+ *
692
+ * @example
693
+ * const count = await db.size();
688
694
  */
689
695
  async size() {
690
696
  const keys = await this.keys();
691
697
  return keys.length;
692
698
  }
693
699
  /**
694
- * Returns an array of object values by specified database key.
695
- *
696
- * If `key` parameter is omitted, then an array of object values of database root object will be returned.
697
- *
698
- * @param {P} [key] The key to access the target in database by.
699
- * @returns {Array<ObjectValue<V, P>>} Database object values array.
700
- *
701
- * @example
702
- * const prop3Values = await database.values("prop3");
703
- * console.log(prop3Values); // -> [789, { prop6: 111 }]
700
+ * Lấy danh sách các giá trị từ database.
704
701
  *
705
- * const prop5Values = await database.values("prop3.prop5");
706
- * console.log(prop5Values); // -> []
702
+ * Nếu không truyền `key` → trả về toàn bộ values ở root level.
703
+ * Nếu truyền `key` → trả về values của object tại path đó.
707
704
  *
708
- * const prop6Values = await database.values("prop3.prop5.prop6");
709
- * console.log(prop6Values);
710
- * // -> [] (empty since the value in `prop6`, 111, is a primitive value and not an actual object)
705
+ * @typeParam P - Path của object trong database.
711
706
  *
712
- * const databaseValues = await database.values();
713
- * // in this example, `key` parameter is omitted - object values of database object are being returned
707
+ * @param key - Đường dẫn object cần lấy values.
714
708
  *
715
- * console.log(databaseValues); // -> [123, 456, { prop4: 789, prop5: { prop6: 111 } }]
709
+ * @returns Mảng các giá trị.
716
710
  *
717
- * const unexistentValues = await database.values("somethingElse");
718
- * console.log(unexistentValues); // -> [] (empty since the key `somethingElse` does not exist in database)
711
+ * @example
712
+ * const allValues = await db.values();
719
713
  *
720
- * // Assuming that the initial database object for this example is:
721
- * // {
722
- * // prop1: 123,
723
- * // prop2: 456,
724
- * // prop3: {
725
- * // prop4: 789,
726
- * // prop5: {
727
- * // prop6: 111
728
- * // }
729
- * // }
730
- * // }
714
+ * const userValues = await db.values("users");
731
715
  */
732
716
  async values(key) {
733
717
  if (!key) return TypedObject.values(await this.all());
@@ -735,160 +719,125 @@ var _Database = class _Database {
735
719
  return TypedObject.values(data);
736
720
  }
737
721
  /**
738
- * This method works the same way as `Array.find()`.
722
+ * Lấy ngẫu nhiên một phần tử từ array tại path được chỉ định.
723
+ *
724
+ * @typeParam P - Path trỏ đến array trong database.
739
725
  *
740
- * Iterates over root database values, finds the element in database values array
741
- * by specified condition in the callback function and returns the result.
726
+ * @param key - Đường dẫn đến array.
742
727
  *
743
- * @param {QueryFunction<V>} queryFunction
744
- * A function that accepts up to three arguments.
745
- * The `find` method calls the `queryFunction` once for each element in database object values array.
728
+ * @returns Một phần tử ngẫu nhiên trong array hoặc `null` nếu array rỗng.
746
729
  *
747
- * @returns {Promise<Maybe<V>>} The search
730
+ * @throws BlackCatError
731
+ * - INVALID_TARGET nếu giá trị tại key không phải array
732
+ *
733
+ * @example
734
+ * const randomUser = await db.random("users");
735
+ */
736
+ async random(key) {
737
+ const array = await this.get(key);
738
+ if (!Array.isArray(array)) {
739
+ throw new BlackCatError("INVALID_TARGET", "array", typeOf(array));
740
+ }
741
+ return array[Math.floor(Math.random() * array.length)] ?? null;
742
+ }
743
+ /**
744
+ * Tìm phần tử đầu tiên thỏa điều kiện.
745
+ *
746
+ * Hoạt động tương tự `Array.prototype.find`.
747
+ *
748
+ * @param queryFunction - Hàm kiểm tra điều kiện.
749
+ *
750
+ * @returns Phần tử đầu tiên thỏa điều kiện hoặc `null` nếu không tìm thấy.
751
+ *
752
+ * @example
753
+ * const user = await db.find(u => u.id === 1);
748
754
  */
749
755
  async find(queryFunction) {
750
756
  const values = await this.values();
751
757
  return values.find(queryFunction) ?? null;
752
758
  }
753
759
  /**
754
- * This method works the same way as `Array.map()`.
760
+ * Biến đổi tất cả giá trị trong database thành một mảng mới.
755
761
  *
756
- * Calls a defined callback function on each element of an array,
757
- * and returns an array that contains the results.
762
+ * Hoạt động giống `Array.prototype.map`.
758
763
  *
759
- * @param {QueryFunction<V, TReturnType>} queryFunction
760
- * A function that accepts up to three arguments.
761
- * The `map` method calls the `queryFunction` once for each element in database object values array.
764
+ * @typeParam TReturnType - Kiểu dữ liệu của phần tử trả về.
762
765
  *
763
- * @returns {Promise<TReturnType[]>}
766
+ * @param queryFunction - Hàm transform từng phần tử.
767
+ *
768
+ * @returns Mảng kết quả sau khi transform.
769
+ *
770
+ * @example
771
+ * const names = await db.map(user => user.name);
764
772
  */
765
773
  async map(queryFunction) {
766
774
  const values = await this.values();
767
775
  return values.map(queryFunction);
768
776
  }
769
777
  /**
770
- * This method works the same way as `Array.findIndex()`.
778
+ * Tìm index của phần tử đầu tiên thỏa điều kiện.
779
+ *
780
+ * Hoạt động giống `Array.prototype.findIndex`.
771
781
  *
772
- * Iterates over root database values, finds the index of the element in database values array
773
- * by specified condition in the callback function and returns the result.
782
+ * @param queryFunction - Hàm kiểm tra điều kiện.
774
783
  *
775
- * @param {QueryFunction<V>} queryFunction
776
- * A function that accepts up to three arguments.
777
- * The `findIndex` method calls the `queryFunction` once for each element in database object values array.
784
+ * @returns Index của phần tử hoặc `-1` nếu không tìm thấy.
778
785
  *
779
- * @returns {Promise<number>}
786
+ * @example
787
+ * const index = await db.findIndex(user => user.id === 1);
780
788
  */
781
789
  async findIndex(queryFunction) {
782
790
  const values = await this.values();
783
791
  return values.findIndex(queryFunction);
784
792
  }
785
793
  /**
786
- * This method works the same way as `Array.filter()`.
794
+ * Lọc các phần tử thỏa điều kiện.
795
+ *
796
+ * Hoạt động giống `Array.prototype.filter`.
787
797
  *
788
- * Iterates over root database values, finds all the element that match the
789
- * specified condition in the callback function and returns the result.
798
+ * @param queryFunction - Hàm kiểm tra điều kiện.
790
799
  *
791
- * @param {QueryFunction<V>} queryFunction
792
- * A function that accepts up to three arguments.
793
- * The `filter` method calls the `queryFunction` once for each element in database object values array.
800
+ * @returns Mảng các phần tử thỏa điều kiện.
794
801
  *
795
- * @returns {Promise<V[]>}
802
+ * @example
803
+ * const admins = await db.filter(user => user.role === "admin");
796
804
  */
797
805
  async filter(queryFunction) {
798
806
  const values = await this.values();
799
807
  return values.filter(queryFunction);
800
808
  }
801
809
  /**
802
- * This method works the same way as `Array.some()`.
810
+ * Kiểm tra ít nhất một phần tử thỏa điều kiện hay không.
803
811
  *
804
- * Iterates over root database values and checks if the
805
- * specified condition in the callback function returns `true`
806
- * for **any** of the elements of the database object values array.
812
+ * Hoạt động giống `Array.prototype.some`.
807
813
  *
808
- * @param {QueryFunction<V>} queryFunction
809
- * A function that accepts up to three arguments.
810
- * The `some` method calls the `queryFunction` once for each element in database object values array.
814
+ * @param queryFunction - Hàm kiểm tra điều kiện.
811
815
  *
812
- * @returns {Promise<boolean>}
816
+ * @returns `true` nếu tồn tại phần tử thỏa điều kiện.
817
+ *
818
+ * @example
819
+ * const hasAdmin = await db.some(user => user.role === "admin");
813
820
  */
814
821
  async some(queryFunction) {
815
822
  const values = await this.values();
816
823
  return values.some(queryFunction);
817
824
  }
818
825
  /**
819
- * This method works the same way as `Array.every()`.
826
+ * Kiểm tra tất cả phần tử thỏa điều kiện hay không.
820
827
  *
821
- * Iterates over root database values and checks if the
822
- * specified condition in the callback function returns `true`
823
- * for **all** of the elements of the database object values array.
828
+ * Hoạt động giống `Array.prototype.every`.
824
829
  *
825
- * @param {QueryFunction<V>} queryFunction
826
- * A function that accepts up to three arguments.
827
- * The `every` method calls the `queryFunction` once for each element in database object values array.
830
+ * @param queryFunction - Hàm kiểm tra điều kiện.
828
831
  *
829
- * @returns {Promise<boolean>}
832
+ * @returns `true` nếu tất cả phần tử đều thỏa điều kiện.
833
+ *
834
+ * @example
835
+ * const allActive = await db.every(user => user.active === true);
830
836
  */
831
837
  async every(queryFunction) {
832
838
  const values = await this.values();
833
839
  return values.every(queryFunction);
834
840
  }
835
- /**
836
- * Picks a random element of array in database and returns the picked array element.
837
- *
838
- * [!!!] The type of target value must be an array.
839
- *
840
- * @param {AutocompletableString<P>} key The key to access the target in database by.
841
- * @returns {Promise<Maybe<ObjectValue<V, P>>>} The randomly picked element in the database array.
842
- *
843
- * @example
844
- * const array = await database.get("array"); // assuming that the array is ['example1', 'example2', 'example3']
845
- * console.log(array); // -> ['example1', 'example2', 'example3']
846
- *
847
- * const randomArrayElement = await database.random("exampleArray");
848
- * console.log(randomArrayElement); // -> randomly picked array element: either 'example1', 'example2', or 'example3'
849
- */
850
- async random(key) {
851
- const array = await this.get(key);
852
- if (!Array.isArray(array)) {
853
- throw new BlackCatError("INVALID_TARGET", "array", typeOf(array));
854
- }
855
- return array[Math.floor(Math.random() * array.length)] ?? null;
856
- }
857
- /**
858
- * Deletes the data from database by key.
859
- * @param {AutocompletableString<P>} key The key to access the target in database by.
860
- * @returns {Promise<boolean>} Whether the deletion was successful.
861
- */
862
- async delete(key) {
863
- if (typeof key !== "string") {
864
- throw new BlackCatError("INVALID_TYPE", "key", "string", typeof key);
865
- }
866
- ;
867
- const allDatabase = await this.all();
868
- const keys = key.split(".");
869
- const lastKey = keys.pop();
870
- let currentObj = allDatabase;
871
- for (const k of keys) {
872
- if (!isObject(currentObj[k])) {
873
- return false;
874
- }
875
- currentObj = currentObj[k];
876
- }
877
- if (!(lastKey in currentObj)) return false;
878
- delete currentObj[lastKey];
879
- await this.driver.delete(allDatabase);
880
- return true;
881
- }
882
- /**
883
- * Deletes everything from the database.
884
- *
885
- * - This method is an alias for {@link QuickMongo.clear()} method.
886
- * @returns {Promise<boolean>} `true` if cleared successfully, `false` otherwise.
887
- */
888
- async deleteAll() {
889
- await this.driver.delete();
890
- return true;
891
- }
892
841
  };
893
842
  __name(_Database, "Database");
894
843
  var Database = _Database;
@@ -897,99 +846,324 @@ var Database = _Database;
897
846
  var import_fs = require("fs");
898
847
  var _JSONDriver = class _JSONDriver {
899
848
  /**
900
- * JSONDriver class.
901
- * @param options.filePath Json database file path.
902
- * @param options.minifyJSON Minifies the JSON content in database file to save some space.
849
+ * Khởi tạo một instance mới của {@link JSONDriver}.
850
+ *
851
+ * @param options - Cấu hình driver
852
+ *
853
+ * @param options.filePath
854
+ * Đường dẫn tới file JSON dùng làm database.
855
+ *
856
+ * @param options.minifyJSON
857
+ * Nếu `true`, nội dung JSON sẽ được minify khi ghi ra file để giảm dung lượng.
858
+ *
859
+ * @example
860
+ * ```ts
861
+ * const database = new Database({
862
+ * driver: db = new JSONDriver({
863
+ * filePath: "./database.json"
864
+ * })
865
+ * });
866
+ * ```
903
867
  */
904
868
  constructor(options) {
905
869
  /**
906
- * JSON database file path.
907
- * @type {string}
870
+ * Đường dẫn tới file database JSON.
908
871
  */
909
872
  __publicField(this, "filePath");
910
873
  /**
911
- * Minifies the JSON content in database file to save some space.
912
- * @type {boolean}
874
+ * Cho biết có minify JSON khi ghi file hay không.
913
875
  */
914
876
  __publicField(this, "minifyJSON");
915
877
  this.filePath = options.filePath || "database.json";
916
878
  this.minifyJSON = options.minifyJSON || false;
917
879
  }
918
880
  /**
919
- * Returns all data from JSON database.
920
- *
921
- * @returns {Promise<any>} All data from JSON database.
922
- *
923
- * @template V The type of data being returned.
881
+ * Đọc toàn bộ dữ liệu từ file database JSON.
882
+ *
883
+ * Nếu file không tồn tại hoặc lỗi parse,
884
+ * method sẽ trả về object rỗng.
885
+ *
886
+ * @template V Kiểu dữ liệu database.
887
+ * @returns Promise chứa toàn bộ dữ liệu database.
924
888
  */
925
889
  async all() {
926
890
  return import_fs.promises.readFile(this.filePath, "utf-8").then((content) => JSON.parse(content)).catch((error) => {
927
- console.error(`Failed to load database file: ${this.filePath}`, error);
891
+ console.error(`Kh\xF4ng th\u1EC3 \u0111\u1ECDc file database: ${this.filePath}`, error);
928
892
  return {};
929
893
  });
930
894
  }
931
895
  /**
932
- * Parses the key and fetches the value from JSON database.
896
+ * Ghi toàn bộ dữ liệu database xuống file JSON.
933
897
  *
934
- * Type parameters:
898
+ * Method này **không xử lý key path**.
899
+ * Logic cập nhật dữ liệu sẽ được xử lý ở class `Database`
900
+ * trước khi truyền object hoàn chỉnh vào đây.
935
901
  *
936
- * - `V` - The type of data being returned.
902
+ * @param data Toàn bộ dữ liệu database sau khi đã được cập nhật.
937
903
  *
938
- * @param {string} key The key in JSON database.
939
- * @returns {Promise<V>} The data from JSON database.
904
+ * @template R Kiểu dữ liệu database.
905
+ * @returns Promise chứa dữ liệu đã ghi.
906
+ */
907
+ async set(data) {
908
+ await import_fs.promises.writeFile(this.filePath, JSON.stringify(data, null, this.minifyJSON ? void 0 : " "));
909
+ return data;
910
+ }
911
+ /**
912
+ * Xóa toàn bộ database.
940
913
  *
941
- * @template V The type of data being returned.
914
+ * Method này chỉ reset file JSON về `{}`.
915
+ *
916
+ * @returns `true` nếu reset thành công.
942
917
  */
943
- async get(key) {
944
- const data = await this.all();
945
- const keys = key.split(".");
946
- let result = data;
947
- for (const k of keys) {
948
- if (result === null || typeof result !== "object") return null;
949
- result = result[k];
950
- }
951
- return result;
918
+ async delete() {
919
+ await import_fs.promises.writeFile(this.filePath, "{}");
920
+ return true;
921
+ }
922
+ };
923
+ __name(_JSONDriver, "JSONDriver");
924
+ var JSONDriver = _JSONDriver;
925
+
926
+ // src/drivers/MemoryDriver.ts
927
+ var _MemoryDriver = class _MemoryDriver {
928
+ /**
929
+ * Khởi tạo MemoryDriver.
930
+ *
931
+ * @param initialData Dữ liệu khởi tạo ban đầu.
932
+ * * @example
933
+ * ```ts
934
+ * const database = new Database({
935
+ * driver: new MemoryDriver({
936
+ * users: {},
937
+ * guilds: {},
938
+ * settings: {
939
+ * prefix: "!"
940
+ * }
941
+ * })
942
+ * });
943
+ * ```
944
+ *
945
+ * hoặc
946
+ *
947
+ * ```ts
948
+ * const database = new Database({
949
+ * driver: new MemoryDriver()
950
+ * });
951
+ * ```
952
+ */
953
+ constructor(initialData = {}) {
954
+ /**
955
+ * Object chứa toàn bộ dữ liệu database trong RAM.
956
+ */
957
+ __publicField(this, "store");
958
+ this.store = initialData;
952
959
  }
953
960
  /**
954
- * Parses the key and sets the value in JSON database.
961
+ * Trả về toàn bộ dữ liệu database.
955
962
  *
956
- * Type parameters:
963
+ * @template T Kiểu dữ liệu database.
964
+ */
965
+ async all() {
966
+ return this.store;
967
+ }
968
+ /**
969
+ * Ghi toàn bộ database vào memory.
957
970
  *
958
- * - `V` - The type of data being set.
959
- * - `R` - The type of data being returned.
971
+ * ⚠️ Method này **không xử key-path**.
972
+ * Dữ liệu đã được xử trước bởi `Database`.
960
973
  *
961
- * @param {string} key The key in JSON database.
962
- * @returns {Promise<R>} The data from JSON database.
974
+ * @param data Toàn bộ database object
975
+ */
976
+ async set(data) {
977
+ this.store = data;
978
+ return data;
979
+ }
980
+ /**
981
+ * Xóa toàn bộ dữ liệu database trong memory.
982
+ */
983
+ async delete() {
984
+ this.store = {};
985
+ return true;
986
+ }
987
+ };
988
+ __name(_MemoryDriver, "MemoryDriver");
989
+ var MemoryDriver = _MemoryDriver;
990
+
991
+ // src/drivers/SQLiteDriver.ts
992
+ var import_better_sqlite3 = __toESM(require("better-sqlite3"));
993
+ var _SQLiteDriver = class _SQLiteDriver {
994
+ /**
995
+ * Khởi tạo SQLiteDriver.
963
996
  *
964
- * @template V The type of data being set.
965
- * @template R The type of data being returned.
997
+ * @param filePath Đường dẫn file SQLite
998
+ * @param table Tên table lưu JSON database
999
+ * @example
1000
+ * ```ts
1001
+ * const database = new Database({
1002
+ * driver: new SQLiteDriver({
1003
+ * filePath: "database.sqlite",
1004
+ * table: "json_store"
1005
+ * })
1006
+ * })
1007
+ * ```
966
1008
  */
967
- async set(key, value) {
968
- const data = await this.all();
969
- await import_fs.promises.writeFile(this.filePath, JSON.stringify(value, null, this.minifyJSON ? void 0 : " "));
1009
+ constructor(options = {}) {
1010
+ /**
1011
+ * SQLite database instance.
1012
+ */
1013
+ __publicField(this, "db");
1014
+ /**
1015
+ * Tên table lưu trữ dữ liệu JSON.
1016
+ */
1017
+ __publicField(this, "table");
1018
+ this.db = new import_better_sqlite3.default(options.filePath ?? "database.sqlite");
1019
+ this.table = options.table ?? "json_store";
1020
+ this.db.prepare(`CREATE TABLE IF NOT EXISTS ${this.table} (id INTEGER PRIMARY KEY, data TEXT)`).run();
1021
+ const row = this.db.prepare(`SELECT * FROM ${this.table} WHERE id = 1`).get();
1022
+ if (!row) {
1023
+ this.db.prepare(`INSERT INTO ${this.table} (id, data) VALUES (1, '{}')`).run();
1024
+ }
1025
+ }
1026
+ /**
1027
+ * Lấy toàn bộ dữ liệu database từ SQLite.
1028
+ *
1029
+ * @template T Kiểu dữ liệu database.
1030
+ */
1031
+ async all() {
1032
+ const row = this.db.prepare(`SELECT data FROM ${this.table} WHERE id = 1`).get();
1033
+ return JSON.parse(row.data);
1034
+ }
1035
+ /**
1036
+ * Ghi toàn bộ database vào SQLite.
1037
+ *
1038
+ * ⚠️ Method này **không xử lý key-path**.
1039
+ * `Database` đã cập nhật object trước khi truyền vào đây.
1040
+ *
1041
+ * @param data Toàn bộ database object
1042
+ */
1043
+ async set(data) {
1044
+ this.db.prepare(`UPDATE ${this.table} SET data = ? WHERE id = 1`).run(JSON.stringify(data));
970
1045
  return data;
971
1046
  }
972
1047
  /**
973
- * Parses the key and deletes it from JSON database. If no key is provided, clears the database.
974
- * @param {V} key The key in JSON database.
975
- * @returns {Promise<boolean>} `true` if deleted successfully.
1048
+ * Reset toàn bộ database.
976
1049
  */
977
- async delete(key) {
978
- if (key === void 0) {
979
- await import_fs.promises.writeFile(this.filePath, "{}");
980
- return true;
981
- } else {
982
- await import_fs.promises.writeFile(this.filePath, JSON.stringify(key, null, this.minifyJSON ? void 0 : " "));
1050
+ async delete() {
1051
+ this.db.prepare(`UPDATE ${this.table} SET data = '{}' WHERE id = 1`).run();
1052
+ return true;
1053
+ }
1054
+ };
1055
+ __name(_SQLiteDriver, "SQLiteDriver");
1056
+ var SQLiteDriver = _SQLiteDriver;
1057
+
1058
+ // src/drivers/MongoDriver.ts
1059
+ var import_mongodb = require("mongodb");
1060
+ var _MongoDriver = class _MongoDriver {
1061
+ /**
1062
+ * Khởi tạo MongoDriver.
1063
+ *
1064
+ * @param options Cấu hình MongoDB driver.
1065
+ *
1066
+ * @example
1067
+ * ```ts
1068
+ * const database = new Database({
1069
+ * driver: new MongoDriver({
1070
+ * mongourl: "mongodb://localhost:27017",
1071
+ * databaseName: "mydb",
1072
+ * collectionName: "store"
1073
+ * })
1074
+ * });
1075
+ */
1076
+ constructor(options = {}) {
1077
+ /**
1078
+ * MongoDB client instance.
1079
+ */
1080
+ __publicField(this, "client");
1081
+ /**
1082
+ * MongoDB database instance.
1083
+ */
1084
+ __publicField(this, "db");
1085
+ /**
1086
+ * Collection lưu dữ liệu JSON.
1087
+ */
1088
+ __publicField(this, "collection");
1089
+ /**
1090
+ * Tên database MongoDB.
1091
+ */
1092
+ __publicField(this, "databaseName");
1093
+ /**
1094
+ * Tên collection MongoDB.
1095
+ */
1096
+ __publicField(this, "collectionName");
1097
+ const {
1098
+ mongourl = "mongodb://localhost:27017",
1099
+ databaseName = "database",
1100
+ collectionName = "json_store"
1101
+ } = options;
1102
+ this.client = new import_mongodb.MongoClient(mongourl);
1103
+ this.databaseName = databaseName;
1104
+ this.collectionName = collectionName;
1105
+ }
1106
+ /**
1107
+ * Thiết lập kết nối MongoDB nếu chưa kết nối.
1108
+ */
1109
+ async connect() {
1110
+ if (!this.db) {
1111
+ await this.client.connect();
1112
+ this.db = this.client.db(this.databaseName);
1113
+ this.collection = this.db.collection(this.collectionName);
1114
+ const doc = await this.collection.findOne({ _id: "database" });
1115
+ if (!doc) {
1116
+ await this.collection.insertOne({
1117
+ _id: "database",
1118
+ data: {}
1119
+ });
1120
+ }
983
1121
  }
984
- ;
1122
+ }
1123
+ /**
1124
+ * Lấy toàn bộ dữ liệu database từ MongoDB.
1125
+ */
1126
+ async all() {
1127
+ await this.connect();
1128
+ const doc = await this.collection.findOne({ _id: "database" });
1129
+ return doc?.data ?? {};
1130
+ }
1131
+ /**
1132
+ * Ghi toàn bộ database vào MongoDB.
1133
+ *
1134
+ * ⚠️ Method này **không xử lý key-path**.
1135
+ * Object database đã được xử lý bởi class `Database`.
1136
+ *
1137
+ * @param data Toàn bộ object database
1138
+ */
1139
+ async set(data) {
1140
+ await this.connect();
1141
+ await this.collection.updateOne(
1142
+ { _id: "database" },
1143
+ { $set: { data } }
1144
+ );
1145
+ return data;
1146
+ }
1147
+ /**
1148
+ * Reset toàn bộ database về object rỗng.
1149
+ */
1150
+ async delete() {
1151
+ await this.connect();
1152
+ await this.collection.updateOne(
1153
+ { _id: "database" },
1154
+ { $set: { data: {} } }
1155
+ );
985
1156
  return true;
986
1157
  }
987
1158
  };
988
- __name(_JSONDriver, "JSONDriver");
989
- var JSONDriver = _JSONDriver;
1159
+ __name(_MongoDriver, "MongoDriver");
1160
+ var MongoDriver = _MongoDriver;
990
1161
  // Annotate the CommonJS export names for ESM import in node:
991
1162
  0 && (module.exports = {
992
1163
  Database,
993
- JSONDriver
1164
+ JSONDriver,
1165
+ MemoryDriver,
1166
+ MongoDriver,
1167
+ SQLiteDriver
994
1168
  });
995
1169
  //# sourceMappingURL=index.js.map