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.js
CHANGED
|
@@ -42,12 +42,16 @@ __export(index_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(index_exports);
|
|
43
43
|
|
|
44
44
|
// src/utils/isObject.function.ts
|
|
45
|
-
var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item
|
|
45
|
+
var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item === "object", "isObject");
|
|
46
46
|
|
|
47
47
|
// src/utils/typeOf.function.ts
|
|
48
48
|
var typeOf = /* @__PURE__ */ __name((input) => {
|
|
49
|
-
if (input == null || typeof input === "number" && Number.isNaN(input))
|
|
50
|
-
|
|
49
|
+
if (input == null || typeof input === "number" && Number.isNaN(input)) {
|
|
50
|
+
return String(input);
|
|
51
|
+
}
|
|
52
|
+
if (typeof input === "function" && input.prototype) {
|
|
53
|
+
return `${input.name} class instance`;
|
|
54
|
+
}
|
|
51
55
|
return input?.constructor?.name ?? typeof input;
|
|
52
56
|
}, "typeOf");
|
|
53
57
|
|
|
@@ -56,20 +60,12 @@ var isNumber = /* @__PURE__ */ __name((input) => !isNaN(input) && input !== "" &
|
|
|
56
60
|
|
|
57
61
|
// src/utils/BlackCatError.ts
|
|
58
62
|
var errors = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
REQUIRED_CONSTRUCTOR_PARAMETER_MISSING: "'{1}' parameter in constructor '{2}' is required but is missing.",
|
|
66
|
-
INVALID_CONSTRUCTOR_PARAMETER_TYPE: "'{1}' parameter in constructor '{2}' must be a type of {3}. Received type: {4}.",
|
|
67
|
-
INVALID_TYPE: "'{1}' must be a type of {2}. Received type: {3}.",
|
|
68
|
-
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}.",
|
|
69
|
-
INVALID_TARGET: "The target in database must be a type of {1}. Received target type: {2}.",
|
|
70
|
-
INVALID_KEY: "{1}",
|
|
71
|
-
INVALID_PARAMETER: "{1} {2}",
|
|
72
|
-
DATABASE_CONNECTION_FAILED: "{1}"
|
|
63
|
+
UNKNOWN_ERROR: "L\u1ED7i kh\xF4ng x\xE1c \u0111\u1ECBnh.",
|
|
64
|
+
REQUIRED_PARAMETER_MISSING: "Tham s\u1ED1 '{1}' l\xE0 b\u1EAFt bu\u1ED9c nh\u01B0ng ch\u01B0a \u0111\u01B0\u1EE3c cung c\u1EA5p.",
|
|
65
|
+
INVALID_TYPE: "'{1}' ph\u1EA3i c\xF3 ki\u1EC3u {2}. Ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c: {3}.",
|
|
66
|
+
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}.",
|
|
67
|
+
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}.",
|
|
68
|
+
INVALID_KEY: "{1}"
|
|
73
69
|
};
|
|
74
70
|
var createTypesArray = /* @__PURE__ */ __name((...elements) => `[${elements.map((element) => typeOf(element))}]`, "createTypesArray");
|
|
75
71
|
var _BlackCatError = class _BlackCatError extends Error {
|
|
@@ -95,46 +91,107 @@ var BlackCatError = _BlackCatError;
|
|
|
95
91
|
// src/utils/TypedObject.ts
|
|
96
92
|
var _TypedObject = class _TypedObject {
|
|
97
93
|
/**
|
|
98
|
-
*
|
|
94
|
+
* Lấy danh sách key của object với type chính xác.
|
|
95
|
+
*
|
|
96
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
97
|
+
*
|
|
98
|
+
* @param obj - Object cần lấy key
|
|
99
|
+
* @returns Mảng các key của object (`ExtractObjectKeys<TObject>[]`)
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* Khác với `Object.keys`:
|
|
103
|
+
* - `Object.keys(obj)` → `string[]`
|
|
104
|
+
* - `TypedObject.keys(obj)` → union key chính xác
|
|
99
105
|
*
|
|
100
|
-
*
|
|
106
|
+
* ---
|
|
101
107
|
*
|
|
102
|
-
*
|
|
108
|
+
* ### Lưu ý:
|
|
109
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
103
110
|
*
|
|
104
|
-
*
|
|
111
|
+
* ---
|
|
105
112
|
*
|
|
106
|
-
* @
|
|
107
|
-
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const obj = { a: 1, b: 2 };
|
|
116
|
+
*
|
|
117
|
+
* const keys = TypedObject.keys(obj);
|
|
118
|
+
* // ("a" | "b")[]
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @see Object.keys
|
|
108
122
|
*/
|
|
109
123
|
static keys(obj) {
|
|
110
124
|
return Object.keys(obj || {});
|
|
111
125
|
}
|
|
112
126
|
/**
|
|
113
|
-
*
|
|
127
|
+
* Lấy danh sách value của object với type chính xác.
|
|
128
|
+
*
|
|
129
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
130
|
+
*
|
|
131
|
+
* @param obj - Object cần lấy value
|
|
132
|
+
* @returns Mảng các value của object (`ExtractObjectValues<TObject>[]`)
|
|
133
|
+
*
|
|
134
|
+
* @remarks
|
|
135
|
+
* Khác với `Object.values`:
|
|
136
|
+
* - `Object.values(obj)` → `any[]`
|
|
137
|
+
* - `TypedObject.values(obj)` → union value chính xác
|
|
114
138
|
*
|
|
115
|
-
*
|
|
139
|
+
* ---
|
|
116
140
|
*
|
|
117
|
-
*
|
|
141
|
+
* ### Lưu ý:
|
|
142
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
143
|
+
*
|
|
144
|
+
* ---
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const obj = { a: 1, b: 2 };
|
|
118
149
|
*
|
|
119
|
-
*
|
|
150
|
+
* const values = TypedObject.values(obj);
|
|
151
|
+
* // number[]
|
|
152
|
+
* ```
|
|
120
153
|
*
|
|
121
|
-
* @
|
|
122
|
-
* Array of values of the enumerable properties of the specified object.
|
|
154
|
+
* @see Object.values
|
|
123
155
|
*/
|
|
124
156
|
static values(obj) {
|
|
125
157
|
return Object.values(obj || {});
|
|
126
158
|
}
|
|
127
159
|
/**
|
|
128
|
-
*
|
|
160
|
+
* Lấy danh sách entry (key-value) của object với type chính xác.
|
|
161
|
+
*
|
|
162
|
+
* @typeParam TObject - Kiểu object đầu vào
|
|
163
|
+
*
|
|
164
|
+
* @param obj - Object cần lấy entries
|
|
165
|
+
* @returns Mảng các cặp `[key, value]` (`ExtractObjectEntries<TObject>[]`)
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* Khác với `Object.entries`:
|
|
169
|
+
* - `Object.entries(obj)` → `[string, any][]`
|
|
170
|
+
* - `TypedObject.entries(obj)` → typed tuple chính xác
|
|
171
|
+
*
|
|
172
|
+
* ---
|
|
129
173
|
*
|
|
130
|
-
*
|
|
174
|
+
* ### Lưu ý:
|
|
175
|
+
* - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
|
|
131
176
|
*
|
|
132
|
-
*
|
|
177
|
+
* ---
|
|
133
178
|
*
|
|
134
|
-
* @
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const obj = { a: 1, b: 2 };
|
|
182
|
+
*
|
|
183
|
+
* const entries = TypedObject.entries(obj);
|
|
184
|
+
* // ["a" | "b", number][]
|
|
185
|
+
* ```
|
|
135
186
|
*
|
|
136
|
-
* @
|
|
137
|
-
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* for (const [key, value] of TypedObject.entries(obj)) {
|
|
190
|
+
* // key & value được infer đúng type
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
194
|
+
* @see Object.entries
|
|
138
195
|
*/
|
|
139
196
|
static entries(obj) {
|
|
140
197
|
return Object.entries(obj || {});
|
|
@@ -143,9 +200,6 @@ var _TypedObject = class _TypedObject {
|
|
|
143
200
|
__name(_TypedObject, "TypedObject");
|
|
144
201
|
var TypedObject = _TypedObject;
|
|
145
202
|
|
|
146
|
-
// src/utils/Emitter.ts
|
|
147
|
-
var import_node_events = require("events");
|
|
148
|
-
|
|
149
203
|
// src/Database.ts
|
|
150
204
|
var _Database = class _Database {
|
|
151
205
|
/**
|
|
@@ -466,41 +520,86 @@ var _Database = class _Database {
|
|
|
466
520
|
return originalLength - filtered.length;
|
|
467
521
|
}
|
|
468
522
|
/**
|
|
469
|
-
* Cập nhật
|
|
523
|
+
* Cập nhật dữ liệu trong database theo đường dẫn key.
|
|
470
524
|
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
525
|
+
* Hàm này sẽ tìm đến vị trí của `key` trong database và gán `value` vào đó.
|
|
526
|
+
* Nếu `value` và giá trị hiện tại tại key đều là object thì sẽ thực hiện
|
|
527
|
+
* **shallow merge** thay vì ghi đè toàn bộ object.
|
|
473
528
|
*
|
|
474
|
-
*
|
|
475
|
-
* thì chúng sẽ được tự động tạo.
|
|
529
|
+
* Điều này giúp tránh việc làm mất các thuộc tính đã tồn tại.
|
|
476
530
|
*
|
|
477
|
-
* @template P
|
|
531
|
+
* @template P - Đường dẫn key hợp lệ trong object database.
|
|
478
532
|
*
|
|
479
|
-
* @param key Đường dẫn
|
|
480
|
-
*
|
|
533
|
+
* @param key - Đường dẫn tới giá trị cần cập nhật.
|
|
534
|
+
* Hỗ trợ nested path dạng `"a.b.c"`.
|
|
481
535
|
*
|
|
482
|
-
* @
|
|
536
|
+
* @param value - Giá trị mới sẽ được cập nhật tại key.
|
|
537
|
+
*
|
|
538
|
+
* @returns
|
|
539
|
+
* Trả về giá trị cuối cùng sau khi cập nhật.
|
|
483
540
|
*
|
|
484
541
|
* @example
|
|
542
|
+
* Database ban đầu:
|
|
543
|
+
* ```json
|
|
544
|
+
* {
|
|
545
|
+
* "123": {
|
|
546
|
+
* "guildID": "123",
|
|
547
|
+
* "guildName": "BlackCat",
|
|
548
|
+
* "history": []
|
|
549
|
+
* }
|
|
550
|
+
* }
|
|
551
|
+
* ```
|
|
552
|
+
*
|
|
553
|
+
* Cập nhật:
|
|
485
554
|
* ```ts
|
|
486
|
-
* await db.update("
|
|
555
|
+
* await db.update("123", {
|
|
556
|
+
* history: [1,2,3]
|
|
557
|
+
* });
|
|
487
558
|
* ```
|
|
559
|
+
*
|
|
560
|
+
* Kết quả:
|
|
561
|
+
* ```json
|
|
562
|
+
* {
|
|
563
|
+
* "123": {
|
|
564
|
+
* "guildID": "123",
|
|
565
|
+
* "guildName": "BlackCat",
|
|
566
|
+
* "history": [1,2,3]
|
|
567
|
+
* }
|
|
568
|
+
* }
|
|
569
|
+
* ```
|
|
570
|
+
*
|
|
571
|
+
* @throws {BlackCatError}
|
|
572
|
+
* - `REQUIRED_PARAMETER_MISSING` nếu key không được cung cấp
|
|
573
|
+
* - `INVALID_TYPE` nếu key không phải string
|
|
488
574
|
*/
|
|
489
575
|
async update(key, value) {
|
|
576
|
+
if (!key) {
|
|
577
|
+
throw new BlackCatError("REQUIRED_PARAMETER_MISSING", "key");
|
|
578
|
+
}
|
|
579
|
+
if (typeof key !== "string") {
|
|
580
|
+
throw new BlackCatError("INVALID_TYPE", "key", "string", typeOf(key));
|
|
581
|
+
}
|
|
490
582
|
const allDatabase = await this.all();
|
|
491
583
|
const keys = key.split(".");
|
|
492
584
|
let current = allDatabase;
|
|
493
585
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
494
586
|
const part = keys[i];
|
|
495
|
-
if (!(part
|
|
587
|
+
if (!isObject(current[part])) {
|
|
496
588
|
current[part] = {};
|
|
497
589
|
}
|
|
498
590
|
current = current[part];
|
|
499
591
|
}
|
|
500
592
|
const lastKey = keys[keys.length - 1];
|
|
501
|
-
current[lastKey]
|
|
593
|
+
if (isObject(value) && isObject(current[lastKey])) {
|
|
594
|
+
current[lastKey] = {
|
|
595
|
+
...current[lastKey],
|
|
596
|
+
...value
|
|
597
|
+
};
|
|
598
|
+
} else {
|
|
599
|
+
current[lastKey] = value;
|
|
600
|
+
}
|
|
502
601
|
await this.driver.set(allDatabase);
|
|
503
|
-
return current;
|
|
602
|
+
return current[lastKey];
|
|
504
603
|
}
|
|
505
604
|
/**
|
|
506
605
|
* Cộng thêm giá trị vào một key dạng number.
|
|
@@ -1177,11 +1276,21 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1177
1276
|
*
|
|
1178
1277
|
* @example
|
|
1179
1278
|
* ```ts
|
|
1279
|
+
* import { Database, MongoDriver } from "blackcat.js-database";
|
|
1280
|
+
*
|
|
1180
1281
|
* const database = new Database({
|
|
1181
1282
|
* driver: new MongoDriver({
|
|
1182
1283
|
* mongourl: "mongodb://localhost:27017",
|
|
1183
1284
|
* databaseName: "mydb",
|
|
1184
|
-
* collectionName: "store"
|
|
1285
|
+
* collectionName: "store",
|
|
1286
|
+
* onLoad: ({ db, collection, databaseName }) => {
|
|
1287
|
+
* console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
|
|
1288
|
+
* console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
|
|
1289
|
+
* },
|
|
1290
|
+
* onError: ({ error, databaseName }) => {
|
|
1291
|
+
* console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
|
|
1292
|
+
* console.error(error);
|
|
1293
|
+
* }
|
|
1185
1294
|
* })
|
|
1186
1295
|
* });
|
|
1187
1296
|
*/
|
|
@@ -1206,6 +1315,18 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1206
1315
|
* Tên collection MongoDB.
|
|
1207
1316
|
*/
|
|
1208
1317
|
__publicField(this, "collectionName");
|
|
1318
|
+
/**
|
|
1319
|
+
* Callback khi kết nối thành công.
|
|
1320
|
+
*/
|
|
1321
|
+
__publicField(this, "onLoad");
|
|
1322
|
+
/**
|
|
1323
|
+
* Callback khi xảy ra lỗi.
|
|
1324
|
+
*/
|
|
1325
|
+
__publicField(this, "onError");
|
|
1326
|
+
/**
|
|
1327
|
+
* Trạng thái đã gọi onLoad chưa (tránh spam)
|
|
1328
|
+
*/
|
|
1329
|
+
__publicField(this, "isLoaded", false);
|
|
1209
1330
|
const {
|
|
1210
1331
|
mongourl = "mongodb://localhost:27017",
|
|
1211
1332
|
databaseName = "database",
|
|
@@ -1214,21 +1335,42 @@ var _MongoDriver = class _MongoDriver {
|
|
|
1214
1335
|
this.client = new import_mongodb.MongoClient(mongourl);
|
|
1215
1336
|
this.databaseName = databaseName;
|
|
1216
1337
|
this.collectionName = collectionName;
|
|
1338
|
+
this.onLoad = options.onLoad;
|
|
1339
|
+
this.onError = options.onError;
|
|
1217
1340
|
}
|
|
1218
1341
|
/**
|
|
1219
1342
|
* Thiết lập kết nối MongoDB nếu chưa kết nối.
|
|
1220
1343
|
*/
|
|
1221
1344
|
async connect() {
|
|
1222
1345
|
if (!this.db) {
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1346
|
+
try {
|
|
1347
|
+
await this.client.connect();
|
|
1348
|
+
this.db = this.client.db(this.databaseName);
|
|
1349
|
+
this.collection = this.db.collection(this.collectionName);
|
|
1350
|
+
const doc = await this.collection.findOne({ _id: "database" });
|
|
1351
|
+
if (!doc) {
|
|
1352
|
+
await this.collection.insertOne({
|
|
1353
|
+
_id: "database",
|
|
1354
|
+
data: {}
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
if (!this.isLoaded) {
|
|
1358
|
+
this.isLoaded = true;
|
|
1359
|
+
this.onLoad?.({
|
|
1360
|
+
client: this.client,
|
|
1361
|
+
db: this.db,
|
|
1362
|
+
collection: this.collection,
|
|
1363
|
+
databaseName: this.databaseName,
|
|
1364
|
+
collectionName: this.collectionName
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
this.onError?.({
|
|
1369
|
+
error,
|
|
1370
|
+
databaseName: this.databaseName,
|
|
1371
|
+
collectionName: this.collectionName
|
|
1231
1372
|
});
|
|
1373
|
+
throw error;
|
|
1232
1374
|
}
|
|
1233
1375
|
}
|
|
1234
1376
|
}
|