blackcat.js-database 1.0.3 → 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/README.md +14 -4
- package/dist/index.d.mts +141 -13
- package/dist/index.d.ts +141 -13
- package/dist/index.js +202 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +202 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,12 +4,16 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
|
|
6
6
|
// src/utils/isObject.function.ts
|
|
7
|
-
var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item
|
|
7
|
+
var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item === "object", "isObject");
|
|
8
8
|
|
|
9
9
|
// src/utils/typeOf.function.ts
|
|
10
10
|
var typeOf = /* @__PURE__ */ __name((input) => {
|
|
11
|
-
if (input == null || typeof input === "number" && Number.isNaN(input))
|
|
12
|
-
|
|
11
|
+
if (input == null || typeof input === "number" && Number.isNaN(input)) {
|
|
12
|
+
return String(input);
|
|
13
|
+
}
|
|
14
|
+
if (typeof input === "function" && input.prototype) {
|
|
15
|
+
return `${input.name} class instance`;
|
|
16
|
+
}
|
|
13
17
|
return input?.constructor?.name ?? typeof input;
|
|
14
18
|
}, "typeOf");
|
|
15
19
|
|
|
@@ -18,20 +22,12 @@ var isNumber = /* @__PURE__ */ __name((input) => !isNaN(input) && input !== "" &
|
|
|
18
22
|
|
|
19
23
|
// src/utils/BlackCatError.ts
|
|
20
24
|
var errors = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
REQUIRED_CONSTRUCTOR_PARAMETER_MISSING: "'{1}' parameter in constructor '{2}' is required but is missing.",
|
|
28
|
-
INVALID_CONSTRUCTOR_PARAMETER_TYPE: "'{1}' parameter in constructor '{2}' must be a type of {3}. Received type: {4}.",
|
|
29
|
-
INVALID_TYPE: "'{1}' must be a type of {2}. Received type: {3}.",
|
|
30
|
-
ONE_OR_MORE_ARRAY_TYPES_INVALID: "All specified elements from array in '{1}' parameter must be a type of {2}. Received array of types: {3}.",
|
|
31
|
-
INVALID_TARGET: "The target in database must be a type of {1}. Received target type: {2}.",
|
|
32
|
-
INVALID_KEY: "{1}",
|
|
33
|
-
INVALID_PARAMETER: "{1} {2}",
|
|
34
|
-
DATABASE_CONNECTION_FAILED: "{1}"
|
|
25
|
+
UNKNOWN_ERROR: "L\u1ED7i kh\xF4ng x\xE1c \u0111\u1ECBnh.",
|
|
26
|
+
REQUIRED_PARAMETER_MISSING: "Tham s\u1ED1 '{1}' l\xE0 b\u1EAFt bu\u1ED9c nh\u01B0ng ch\u01B0a \u0111\u01B0\u1EE3c cung c\u1EA5p.",
|
|
27
|
+
INVALID_TYPE: "'{1}' ph\u1EA3i c\xF3 ki\u1EC3u {2}. Ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c: {3}.",
|
|
28
|
+
ONE_OR_MORE_ARRAY_TYPES_INVALID: "T\u1EA5t c\u1EA3 ph\u1EA7n t\u1EED trong m\u1EA3ng c\u1EE7a tham s\u1ED1 '{1}' ph\u1EA3i c\xF3 ki\u1EC3u {2}. C\xE1c ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c trong m\u1EA3ng: {3}.",
|
|
29
|
+
INVALID_TARGET: "\u0110\u1ED1i t\u01B0\u1EE3ng target trong database ph\u1EA3i c\xF3 ki\u1EC3u {1}. Ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c: {2}.",
|
|
30
|
+
INVALID_KEY: "{1}"
|
|
35
31
|
};
|
|
36
32
|
var createTypesArray = /* @__PURE__ */ __name((...elements) => `[${elements.map((element) => typeOf(element))}]`, "createTypesArray");
|
|
37
33
|
var _BlackCatError = class _BlackCatError extends Error {
|
|
@@ -57,46 +53,107 @@ var BlackCatError = _BlackCatError;
|
|
|
57
53
|
// src/utils/TypedObject.ts
|
|
58
54
|
var _TypedObject = class _TypedObject {
|
|
59
55
|
/**
|
|
60
|
-
*
|
|
56
|
+
* Lấy danh sách key của object với type chính xác.
|
|
57
|
+
*
|
|
58
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
59
|
+
*
|
|
60
|
+
* @param obj - Object cần lấy key
|
|
61
|
+
* @returns Mảng các key của object (`ExtractObjectKeys<TObject>[]`)
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* Khác với `Object.keys`:
|
|
65
|
+
* - `Object.keys(obj)` → `string[]`
|
|
66
|
+
* - `TypedObject.keys(obj)` → union key chính xác
|
|
61
67
|
*
|
|
62
|
-
*
|
|
68
|
+
* ---
|
|
63
69
|
*
|
|
64
|
-
*
|
|
70
|
+
* ### Lưu ý:
|
|
71
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
65
72
|
*
|
|
66
|
-
*
|
|
73
|
+
* ---
|
|
67
74
|
*
|
|
68
|
-
* @
|
|
69
|
-
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const obj = { a: 1, b: 2 };
|
|
78
|
+
*
|
|
79
|
+
* const keys = TypedObject.keys(obj);
|
|
80
|
+
* // ("a" | "b")[]
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @see Object.keys
|
|
70
84
|
*/
|
|
71
85
|
static keys(obj) {
|
|
72
86
|
return Object.keys(obj || {});
|
|
73
87
|
}
|
|
74
88
|
/**
|
|
75
|
-
*
|
|
89
|
+
* Lấy danh sách value của object với type chính xác.
|
|
90
|
+
*
|
|
91
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
92
|
+
*
|
|
93
|
+
* @param obj - Object cần lấy value
|
|
94
|
+
* @returns Mảng các value của object (`ExtractObjectValues<TObject>[]`)
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* Khác với `Object.values`:
|
|
98
|
+
* - `Object.values(obj)` → `any[]`
|
|
99
|
+
* - `TypedObject.values(obj)` → union value chính xác
|
|
76
100
|
*
|
|
77
|
-
*
|
|
101
|
+
* ---
|
|
78
102
|
*
|
|
79
|
-
*
|
|
103
|
+
* ### Lưu ý:
|
|
104
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
105
|
+
*
|
|
106
|
+
* ---
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const obj = { a: 1, b: 2 };
|
|
80
111
|
*
|
|
81
|
-
*
|
|
112
|
+
* const values = TypedObject.values(obj);
|
|
113
|
+
* // number[]
|
|
114
|
+
* ```
|
|
82
115
|
*
|
|
83
|
-
* @
|
|
84
|
-
* Array of values of the enumerable properties of the specified object.
|
|
116
|
+
* @see Object.values
|
|
85
117
|
*/
|
|
86
118
|
static values(obj) {
|
|
87
119
|
return Object.values(obj || {});
|
|
88
120
|
}
|
|
89
121
|
/**
|
|
90
|
-
*
|
|
122
|
+
* Lấy danh sách entry (key-value) của object với type chính xác.
|
|
123
|
+
*
|
|
124
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
125
|
+
*
|
|
126
|
+
* @param obj - Object cần lấy entries
|
|
127
|
+
* @returns Mảng các cặp `[key, value]` (`ExtractObjectEntries<TObject>[]`)
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* Khác với `Object.entries`:
|
|
131
|
+
* - `Object.entries(obj)` → `[string, any][]`
|
|
132
|
+
* - `TypedObject.entries(obj)` → typed tuple chính xác
|
|
133
|
+
*
|
|
134
|
+
* ---
|
|
91
135
|
*
|
|
92
|
-
*
|
|
136
|
+
* ### Lưu ý:
|
|
137
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
93
138
|
*
|
|
94
|
-
*
|
|
139
|
+
* ---
|
|
95
140
|
*
|
|
96
|
-
* @
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const obj = { a: 1, b: 2 };
|
|
144
|
+
*
|
|
145
|
+
* const entries = TypedObject.entries(obj);
|
|
146
|
+
* // ["a" | "b", number][]
|
|
147
|
+
* ```
|
|
97
148
|
*
|
|
98
|
-
* @
|
|
99
|
-
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* for (const [key, value] of TypedObject.entries(obj)) {
|
|
152
|
+
* // key & value được infer đúng type
|
|
153
|
+
* }
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* @see Object.entries
|
|
100
157
|
*/
|
|
101
158
|
static entries(obj) {
|
|
102
159
|
return Object.entries(obj || {});
|
|
@@ -105,9 +162,6 @@ var _TypedObject = class _TypedObject {
|
|
|
105
162
|
__name(_TypedObject, "TypedObject");
|
|
106
163
|
var TypedObject = _TypedObject;
|
|
107
164
|
|
|
108
|
-
// src/utils/Emitter.ts
|
|
109
|
-
import { EventEmitter } from "events";
|
|
110
|
-
|
|
111
165
|
// src/Database.ts
|
|
112
166
|
var _Database = class _Database {
|
|
113
167
|
/**
|
|
@@ -428,41 +482,86 @@ var _Database = class _Database {
|
|
|
428
482
|
return originalLength - filtered.length;
|
|
429
483
|
}
|
|
430
484
|
/**
|
|
431
|
-
* Cập nhật
|
|
485
|
+
* Cập nhật dữ liệu trong database theo đường dẫn key.
|
|
432
486
|
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
487
|
+
* Hàm này sẽ tìm đến vị trí của `key` trong database và gán `value` vào đó.
|
|
488
|
+
* Nếu `value` và giá trị hiện tại tại key đều là object thì sẽ thực hiện
|
|
489
|
+
* **shallow merge** thay vì ghi đè toàn bộ object.
|
|
435
490
|
*
|
|
436
|
-
*
|
|
437
|
-
* thì chúng sẽ được tự động tạo.
|
|
491
|
+
* Điều này giúp tránh việc làm mất các thuộc tính đã tồn tại.
|
|
438
492
|
*
|
|
439
|
-
* @template P
|
|
493
|
+
* @template P - Đường dẫn key hợp lệ trong object database.
|
|
440
494
|
*
|
|
441
|
-
* @param key Đường dẫn
|
|
442
|
-
*
|
|
495
|
+
* @param key - Đường dẫn tới giá trị cần cập nhật.
|
|
496
|
+
* Hỗ trợ nested path dạng `"a.b.c"`.
|
|
443
497
|
*
|
|
444
|
-
* @
|
|
498
|
+
* @param value - Giá trị mới sẽ được cập nhật tại key.
|
|
499
|
+
*
|
|
500
|
+
* @returns
|
|
501
|
+
* Trả về giá trị cuối cùng sau khi cập nhật.
|
|
445
502
|
*
|
|
446
503
|
* @example
|
|
504
|
+
* Database ban đầu:
|
|
505
|
+
* ```json
|
|
506
|
+
* {
|
|
507
|
+
* "123": {
|
|
508
|
+
* "guildID": "123",
|
|
509
|
+
* "guildName": "BlackCat",
|
|
510
|
+
* "history": []
|
|
511
|
+
* }
|
|
512
|
+
* }
|
|
513
|
+
* ```
|
|
514
|
+
*
|
|
515
|
+
* Cập nhật:
|
|
447
516
|
* ```ts
|
|
448
|
-
* await db.update("
|
|
517
|
+
* await db.update("123", {
|
|
518
|
+
* history: [1,2,3]
|
|
519
|
+
* });
|
|
449
520
|
* ```
|
|
521
|
+
*
|
|
522
|
+
* Kết quả:
|
|
523
|
+
* ```json
|
|
524
|
+
* {
|
|
525
|
+
* "123": {
|
|
526
|
+
* "guildID": "123",
|
|
527
|
+
* "guildName": "BlackCat",
|
|
528
|
+
* "history": [1,2,3]
|
|
529
|
+
* }
|
|
530
|
+
* }
|
|
531
|
+
* ```
|
|
532
|
+
*
|
|
533
|
+
* @throws {BlackCatError}
|
|
534
|
+
* - `REQUIRED_PARAMETER_MISSING` nếu key không được cung cấp
|
|
535
|
+
* - `INVALID_TYPE` nếu key không phải string
|
|
450
536
|
*/
|
|
451
537
|
async update(key, value) {
|
|
538
|
+
if (!key) {
|
|
539
|
+
throw new BlackCatError("REQUIRED_PARAMETER_MISSING", "key");
|
|
540
|
+
}
|
|
541
|
+
if (typeof key !== "string") {
|
|
542
|
+
throw new BlackCatError("INVALID_TYPE", "key", "string", typeOf(key));
|
|
543
|
+
}
|
|
452
544
|
const allDatabase = await this.all();
|
|
453
545
|
const keys = key.split(".");
|
|
454
546
|
let current = allDatabase;
|
|
455
547
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
456
548
|
const part = keys[i];
|
|
457
|
-
if (!(part
|
|
549
|
+
if (!isObject(current[part])) {
|
|
458
550
|
current[part] = {};
|
|
459
551
|
}
|
|
460
552
|
current = current[part];
|
|
461
553
|
}
|
|
462
554
|
const lastKey = keys[keys.length - 1];
|
|
463
|
-
current[lastKey]
|
|
555
|
+
if (isObject(value) && isObject(current[lastKey])) {
|
|
556
|
+
current[lastKey] = {
|
|
557
|
+
...current[lastKey],
|
|
558
|
+
...value
|
|
559
|
+
};
|
|
560
|
+
} else {
|
|
561
|
+
current[lastKey] = value;
|
|
562
|
+
}
|
|
464
563
|
await this.driver.set(allDatabase);
|
|
465
|
-
return current;
|
|
564
|
+
return current[lastKey];
|
|
466
565
|
}
|
|
467
566
|
/**
|
|
468
567
|
* Cộng thêm giá trị vào một key dạng number.
|
|
@@ -1139,11 +1238,21 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1139
1238
|
*
|
|
1140
1239
|
* @example
|
|
1141
1240
|
* ```ts
|
|
1241
|
+
* import { Database, MongoDriver } from "blackcat.js-database";
|
|
1242
|
+
*
|
|
1142
1243
|
* const database = new Database({
|
|
1143
1244
|
* driver: new MongoDriver({
|
|
1144
1245
|
* mongourl: "mongodb://localhost:27017",
|
|
1145
1246
|
* databaseName: "mydb",
|
|
1146
|
-
* collectionName: "store"
|
|
1247
|
+
* collectionName: "store",
|
|
1248
|
+
* onLoad: ({ db, collection, databaseName }) => {
|
|
1249
|
+
* console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
|
|
1250
|
+
* console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
|
|
1251
|
+
* },
|
|
1252
|
+
* onError: ({ error, databaseName }) => {
|
|
1253
|
+
* console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
|
|
1254
|
+
* console.error(error);
|
|
1255
|
+
* }
|
|
1147
1256
|
* })
|
|
1148
1257
|
* });
|
|
1149
1258
|
*/
|
|
@@ -1168,6 +1277,18 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1168
1277
|
* Tên collection MongoDB.
|
|
1169
1278
|
*/
|
|
1170
1279
|
__publicField(this, "collectionName");
|
|
1280
|
+
/**
|
|
1281
|
+
* Callback khi kết nối thành công.
|
|
1282
|
+
*/
|
|
1283
|
+
__publicField(this, "onLoad");
|
|
1284
|
+
/**
|
|
1285
|
+
* Callback khi xảy ra lỗi.
|
|
1286
|
+
*/
|
|
1287
|
+
__publicField(this, "onError");
|
|
1288
|
+
/**
|
|
1289
|
+
* Trạng thái đã gọi onLoad chưa (tránh spam)
|
|
1290
|
+
*/
|
|
1291
|
+
__publicField(this, "isLoaded", false);
|
|
1171
1292
|
const {
|
|
1172
1293
|
mongourl = "mongodb://localhost:27017",
|
|
1173
1294
|
databaseName = "database",
|
|
@@ -1176,21 +1297,42 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1176
1297
|
this.client = new MongoClient(mongourl);
|
|
1177
1298
|
this.databaseName = databaseName;
|
|
1178
1299
|
this.collectionName = collectionName;
|
|
1300
|
+
this.onLoad = options.onLoad;
|
|
1301
|
+
this.onError = options.onError;
|
|
1179
1302
|
}
|
|
1180
1303
|
/**
|
|
1181
1304
|
* Thiết lập kết nối MongoDB nếu chưa kết nối.
|
|
1182
1305
|
*/
|
|
1183
1306
|
async connect() {
|
|
1184
1307
|
if (!this.db) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1308
|
+
try {
|
|
1309
|
+
await this.client.connect();
|
|
1310
|
+
this.db = this.client.db(this.databaseName);
|
|
1311
|
+
this.collection = this.db.collection(this.collectionName);
|
|
1312
|
+
const doc = await this.collection.findOne({ _id: "database" });
|
|
1313
|
+
if (!doc) {
|
|
1314
|
+
await this.collection.insertOne({
|
|
1315
|
+
_id: "database",
|
|
1316
|
+
data: {}
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
if (!this.isLoaded) {
|
|
1320
|
+
this.isLoaded = true;
|
|
1321
|
+
this.onLoad?.({
|
|
1322
|
+
client: this.client,
|
|
1323
|
+
db: this.db,
|
|
1324
|
+
collection: this.collection,
|
|
1325
|
+
databaseName: this.databaseName,
|
|
1326
|
+
collectionName: this.collectionName
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
} catch (error) {
|
|
1330
|
+
this.onError?.({
|
|
1331
|
+
error,
|
|
1332
|
+
databaseName: this.databaseName,
|
|
1333
|
+
collectionName: this.collectionName
|
|
1193
1334
|
});
|
|
1335
|
+
throw error;
|
|
1194
1336
|
}
|
|
1195
1337
|
}
|
|
1196
1338
|
}
|