@orion-js/mongodb 4.1.10 → 4.2.1
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.cjs +150 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -2
- package/dist/index.d.ts +81 -2
- package/dist/index.js +146 -18
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -36,13 +36,17 @@ __export(index_exports, {
|
|
|
36
36
|
MongoDB: () => MongoDB,
|
|
37
37
|
Repository: () => Repository,
|
|
38
38
|
allConnectionPromises: () => allConnectionPromises,
|
|
39
|
+
collectionsRegistry: () => collectionsRegistry,
|
|
39
40
|
configureConnection: () => configureConnection,
|
|
40
41
|
connections: () => connections,
|
|
41
42
|
createCollection: () => createCollection,
|
|
42
43
|
createIndexesPromises: () => createIndexesPromises,
|
|
44
|
+
deleteAllUnusedIndexes: () => deleteAllUnusedIndexes,
|
|
43
45
|
getDBName: () => getDBName,
|
|
44
46
|
getMongoConnection: () => getMongoConnection,
|
|
45
47
|
getOrCreateEncryptionKey: () => getOrCreateEncryptionKey,
|
|
48
|
+
getRegisteredCollections: () => getRegisteredCollections,
|
|
49
|
+
registerCollection: () => registerCollection,
|
|
46
50
|
typedId: () => typedId
|
|
47
51
|
});
|
|
48
52
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -295,6 +299,12 @@ var BaseCollection = class {
|
|
|
295
299
|
*/
|
|
296
300
|
createIndexes;
|
|
297
301
|
createIndexesPromise;
|
|
302
|
+
/**
|
|
303
|
+
* Deletes indexes that exist in MongoDB but are not defined in the collection configuration.
|
|
304
|
+
* This helps clean up stale indexes that are no longer needed.
|
|
305
|
+
* Always preserves the _id_ index.
|
|
306
|
+
*/
|
|
307
|
+
deleteUnusedIndexes;
|
|
298
308
|
/**
|
|
299
309
|
* @deprecated Use startConnection() instead. This property is not guaranteed to be resolved if the connection is not started.
|
|
300
310
|
* When using async calls startConnection or connectionPromise is no longer needed. Orion will automatically start the connection if it is not already started.
|
|
@@ -1187,12 +1197,82 @@ var generateId_default = getIdGenerator;
|
|
|
1187
1197
|
|
|
1188
1198
|
// src/createCollection/createIndexes.ts
|
|
1189
1199
|
var import_mongodb2 = require("mongodb");
|
|
1200
|
+
var import_logger3 = require("@orion-js/logger");
|
|
1201
|
+
|
|
1202
|
+
// src/createCollection/deleteUnusedIndexes.ts
|
|
1190
1203
|
var import_logger2 = require("@orion-js/logger");
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1204
|
+
|
|
1205
|
+
// src/createCollection/getIndexOptions.ts
|
|
1206
|
+
function getIndexOptions(indexDef) {
|
|
1207
|
+
const { keys: _keys, options: deprecatedOptions, ...flatOptions } = indexDef;
|
|
1208
|
+
if (deprecatedOptions) {
|
|
1209
|
+
return { ...deprecatedOptions, ...flatOptions };
|
|
1210
|
+
}
|
|
1211
|
+
return Object.keys(flatOptions).length > 0 ? flatOptions : void 0;
|
|
1212
|
+
}
|
|
1213
|
+
function getIndexName(indexDef) {
|
|
1214
|
+
var _a;
|
|
1215
|
+
if (indexDef.name) {
|
|
1216
|
+
return indexDef.name;
|
|
1217
|
+
}
|
|
1218
|
+
return (_a = indexDef.options) == null ? void 0 : _a.name;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
// src/createCollection/deleteUnusedIndexes.ts
|
|
1222
|
+
function keysMatch(definitionKeys, currentIndexKey) {
|
|
1223
|
+
const defEntries = Object.entries(definitionKeys);
|
|
1224
|
+
const curEntries = Object.entries(currentIndexKey);
|
|
1225
|
+
if (defEntries.length !== curEntries.length) return false;
|
|
1226
|
+
for (let i = 0; i < defEntries.length; i++) {
|
|
1227
|
+
const [defKey, defValue] = defEntries[i];
|
|
1228
|
+
const [curKey, curValue] = curEntries[i];
|
|
1229
|
+
if (defKey !== curKey || defValue !== curValue) return false;
|
|
1230
|
+
}
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
function isIndexDefined(definedIndexes, currentIndex) {
|
|
1234
|
+
return definedIndexes.some((defIndex) => {
|
|
1235
|
+
const customName = getIndexName(defIndex);
|
|
1236
|
+
if (customName && customName === currentIndex.name) return true;
|
|
1237
|
+
return keysMatch(defIndex.keys, currentIndex.key);
|
|
1238
|
+
});
|
|
1195
1239
|
}
|
|
1240
|
+
async function deleteUnusedIndexes(collection) {
|
|
1241
|
+
await collection.connectionPromise;
|
|
1242
|
+
const result = {
|
|
1243
|
+
deletedIndexes: [],
|
|
1244
|
+
collectionName: collection.name
|
|
1245
|
+
};
|
|
1246
|
+
let currentIndexes = [];
|
|
1247
|
+
try {
|
|
1248
|
+
currentIndexes = await collection.rawCollection.indexes();
|
|
1249
|
+
} catch (error) {
|
|
1250
|
+
if (error.codeName === "NamespaceNotFound") {
|
|
1251
|
+
return result;
|
|
1252
|
+
}
|
|
1253
|
+
throw error;
|
|
1254
|
+
}
|
|
1255
|
+
if (!collection.indexes || collection.indexes.length === 0) {
|
|
1256
|
+
return result;
|
|
1257
|
+
}
|
|
1258
|
+
const unusedIndexes = currentIndexes.filter(
|
|
1259
|
+
(index) => index.name !== "_id_" && !isIndexDefined(collection.indexes, index)
|
|
1260
|
+
);
|
|
1261
|
+
for (const index of unusedIndexes) {
|
|
1262
|
+
try {
|
|
1263
|
+
await collection.rawCollection.dropIndex(index.name);
|
|
1264
|
+
result.deletedIndexes.push(index.name);
|
|
1265
|
+
import_logger2.logger.info(`Deleted unused index "${index.name}" from collection "${collection.name}"`);
|
|
1266
|
+
} catch (error) {
|
|
1267
|
+
import_logger2.logger.error(`Failed to delete index "${index.name}" from collection "${collection.name}"`, {
|
|
1268
|
+
error
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
return result;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// src/createCollection/createIndexes.ts
|
|
1196
1276
|
async function checkIndexes(collection) {
|
|
1197
1277
|
await collection.connectionPromise;
|
|
1198
1278
|
let currentIndexes = [];
|
|
@@ -1200,13 +1280,17 @@ async function checkIndexes(collection) {
|
|
|
1200
1280
|
currentIndexes = await collection.rawCollection.indexes();
|
|
1201
1281
|
} catch (error) {
|
|
1202
1282
|
if (error.codeName !== "NamespaceNotFound") throw error;
|
|
1283
|
+
return;
|
|
1203
1284
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1285
|
+
if (!collection.indexes || collection.indexes.length === 0) {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
const unexpectedIndexes = currentIndexes.filter(
|
|
1289
|
+
(index) => index.name !== "_id_" && !isIndexDefined(collection.indexes, index)
|
|
1290
|
+
);
|
|
1291
|
+
if (unexpectedIndexes.length > 0) {
|
|
1292
|
+
import_logger3.logger.warn(
|
|
1293
|
+
`${unexpectedIndexes.length} unexpected indexes found in collection "${collection.name}": ${unexpectedIndexes.map((i) => i.name).join(", ")} | Delete the index or fix the collection definition`
|
|
1210
1294
|
);
|
|
1211
1295
|
}
|
|
1212
1296
|
}
|
|
@@ -1215,7 +1299,9 @@ async function loadIndexes(collection) {
|
|
|
1215
1299
|
if (!collection.indexes.length) return;
|
|
1216
1300
|
await collection.connectionPromise;
|
|
1217
1301
|
const results = Promise.all(
|
|
1218
|
-
collection.indexes.map(async (
|
|
1302
|
+
collection.indexes.map(async (indexDef) => {
|
|
1303
|
+
const { keys } = indexDef;
|
|
1304
|
+
const options = getIndexOptions(indexDef);
|
|
1219
1305
|
try {
|
|
1220
1306
|
return await collection.rawCollection.createIndex(keys, options);
|
|
1221
1307
|
} catch (error) {
|
|
@@ -1245,6 +1331,43 @@ async function loadIndexes(collection) {
|
|
|
1245
1331
|
return results;
|
|
1246
1332
|
}
|
|
1247
1333
|
|
|
1334
|
+
// src/createCollection/collectionsRegistry.ts
|
|
1335
|
+
var import_logger4 = require("@orion-js/logger");
|
|
1336
|
+
var collectionsRegistry = /* @__PURE__ */ new Map();
|
|
1337
|
+
function registerCollection(connectionName, collection) {
|
|
1338
|
+
if (!collectionsRegistry.has(connectionName)) {
|
|
1339
|
+
collectionsRegistry.set(connectionName, /* @__PURE__ */ new Map());
|
|
1340
|
+
}
|
|
1341
|
+
collectionsRegistry.get(connectionName).set(collection.name, collection);
|
|
1342
|
+
}
|
|
1343
|
+
function getRegisteredCollections(connectionName = "main") {
|
|
1344
|
+
const connectionCollections = collectionsRegistry.get(connectionName);
|
|
1345
|
+
if (!connectionCollections) {
|
|
1346
|
+
return [];
|
|
1347
|
+
}
|
|
1348
|
+
return Array.from(connectionCollections.values());
|
|
1349
|
+
}
|
|
1350
|
+
async function deleteAllUnusedIndexes(connectionName = "main") {
|
|
1351
|
+
const collections = getRegisteredCollections(connectionName);
|
|
1352
|
+
if (collections.length === 0) {
|
|
1353
|
+
import_logger4.logger.warn(`No collections registered for connection "${connectionName}"`);
|
|
1354
|
+
return [];
|
|
1355
|
+
}
|
|
1356
|
+
import_logger4.logger.info(
|
|
1357
|
+
`Deleting unused indexes from ${collections.length} collections on connection "${connectionName}"`
|
|
1358
|
+
);
|
|
1359
|
+
const results = [];
|
|
1360
|
+
for (const collection of collections) {
|
|
1361
|
+
const result = await collection.deleteUnusedIndexes();
|
|
1362
|
+
if (result.deletedIndexes.length > 0) {
|
|
1363
|
+
results.push(result);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
const totalDeleted = results.reduce((sum, r) => sum + r.deletedIndexes.length, 0);
|
|
1367
|
+
import_logger4.logger.info(`Deleted ${totalDeleted} unused indexes from ${results.length} collections`);
|
|
1368
|
+
return results;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1248
1371
|
// src/createCollection/getSchemaAndModel.ts
|
|
1249
1372
|
var import_helpers7 = require("@orion-js/helpers");
|
|
1250
1373
|
Symbol.metadata ?? (Symbol.metadata = Symbol("Symbol.metadata"));
|
|
@@ -1277,7 +1400,7 @@ function getSchema(options) {
|
|
|
1277
1400
|
}
|
|
1278
1401
|
|
|
1279
1402
|
// src/createCollection/wrapMethods.ts
|
|
1280
|
-
var
|
|
1403
|
+
var import_logger5 = require("@orion-js/logger");
|
|
1281
1404
|
function wrapMethods(collection) {
|
|
1282
1405
|
const methodsWithPromises = [
|
|
1283
1406
|
"findOne",
|
|
@@ -1313,7 +1436,7 @@ function wrapMethods(collection) {
|
|
|
1313
1436
|
collection[methodName2] = (...args) => {
|
|
1314
1437
|
collection.startConnection();
|
|
1315
1438
|
if (!collection.rawCollection) {
|
|
1316
|
-
|
|
1439
|
+
import_logger5.logger.error("Method called before connection was initialized", {
|
|
1317
1440
|
collectionName: collection.name,
|
|
1318
1441
|
connectionName: collection.connectionName,
|
|
1319
1442
|
methodName: methodName2
|
|
@@ -1414,11 +1537,16 @@ function createCollection(options) {
|
|
|
1414
1537
|
return createIndexPromise;
|
|
1415
1538
|
};
|
|
1416
1539
|
mainCollection.createIndexes = createIndexes;
|
|
1540
|
+
mainCollection.deleteUnusedIndexes = async () => {
|
|
1541
|
+
await orionConnection.startConnection();
|
|
1542
|
+
return deleteUnusedIndexes(mainCollection);
|
|
1543
|
+
};
|
|
1417
1544
|
if (!process.env.DONT_CREATE_INDEXES_AUTOMATICALLY) {
|
|
1418
1545
|
createIndexes();
|
|
1419
1546
|
}
|
|
1420
1547
|
wrapMethods(mainCollection);
|
|
1421
1548
|
wrapMethods(encryptedCollection);
|
|
1549
|
+
registerCollection(connectionName, mainCollection);
|
|
1422
1550
|
return mainCollection;
|
|
1423
1551
|
}
|
|
1424
1552
|
|
|
@@ -1449,7 +1577,7 @@ function MongoCollection(options) {
|
|
|
1449
1577
|
}
|
|
1450
1578
|
|
|
1451
1579
|
// src/encrypted/getOrCreateEncryptionKey.ts
|
|
1452
|
-
var
|
|
1580
|
+
var import_logger6 = require("@orion-js/logger");
|
|
1453
1581
|
var import_mongodb3 = require("mongodb");
|
|
1454
1582
|
async function getOrCreateEncryptionKey({
|
|
1455
1583
|
keyAltName,
|
|
@@ -1461,7 +1589,7 @@ async function getOrCreateEncryptionKey({
|
|
|
1461
1589
|
kmsProviders
|
|
1462
1590
|
}) {
|
|
1463
1591
|
const keyVaultNamespace = `${keyVaultDatabase}.${keyVaultCollection}`;
|
|
1464
|
-
|
|
1592
|
+
import_logger6.logger.info("Connecting to database to get or create the encryption key", {
|
|
1465
1593
|
keyVaultNamespace,
|
|
1466
1594
|
keyAltName
|
|
1467
1595
|
});
|
|
@@ -1479,14 +1607,14 @@ async function getOrCreateEncryptionKey({
|
|
|
1479
1607
|
});
|
|
1480
1608
|
const key = await clientEncryption.getKeyByAltName(keyAltName);
|
|
1481
1609
|
if (key) {
|
|
1482
|
-
|
|
1610
|
+
import_logger6.logger.info("Key found on the key vault", {
|
|
1483
1611
|
keyVaultNamespace,
|
|
1484
1612
|
keyAltName,
|
|
1485
1613
|
UUID: key._id
|
|
1486
1614
|
});
|
|
1487
1615
|
return { key: key._id, keyVaultNamespace };
|
|
1488
1616
|
}
|
|
1489
|
-
|
|
1617
|
+
import_logger6.logger.info("Key not found on the key vault, creating a new one", {
|
|
1490
1618
|
keyVaultNamespace,
|
|
1491
1619
|
keyAltName
|
|
1492
1620
|
});
|
|
@@ -1494,7 +1622,7 @@ async function getOrCreateEncryptionKey({
|
|
|
1494
1622
|
keyAltNames: [keyAltName],
|
|
1495
1623
|
...masterKey ? { masterKey } : {}
|
|
1496
1624
|
});
|
|
1497
|
-
|
|
1625
|
+
import_logger6.logger.info("New encryption key created", {
|
|
1498
1626
|
keyVaultNamespace,
|
|
1499
1627
|
keyAltName,
|
|
1500
1628
|
UUID: newKey
|
|
@@ -1514,13 +1642,17 @@ var ENCRYPTION_ALGORITHMS = {
|
|
|
1514
1642
|
MongoDB,
|
|
1515
1643
|
Repository,
|
|
1516
1644
|
allConnectionPromises,
|
|
1645
|
+
collectionsRegistry,
|
|
1517
1646
|
configureConnection,
|
|
1518
1647
|
connections,
|
|
1519
1648
|
createCollection,
|
|
1520
1649
|
createIndexesPromises,
|
|
1650
|
+
deleteAllUnusedIndexes,
|
|
1521
1651
|
getDBName,
|
|
1522
1652
|
getMongoConnection,
|
|
1523
1653
|
getOrCreateEncryptionKey,
|
|
1654
|
+
getRegisteredCollections,
|
|
1655
|
+
registerCollection,
|
|
1524
1656
|
typedId
|
|
1525
1657
|
});
|
|
1526
1658
|
//# sourceMappingURL=index.cjs.map
|