@orion-js/mongodb 4.2.3 → 4.2.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/dist/index.cjs +96 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +95 -78
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -335,6 +335,14 @@ declare function registerCollection(connectionName: string, collection: Collecti
|
|
|
335
335
|
* @returns Array of registered collections for the connection
|
|
336
336
|
*/
|
|
337
337
|
declare function getRegisteredCollections(connectionName?: string): Array<Collection<ModelClassBase>>;
|
|
338
|
+
/**
|
|
339
|
+
* Gets the merged indexes for a specific collection from the registry.
|
|
340
|
+
* This includes all indexes from all createCollection() calls for the same collection name.
|
|
341
|
+
* @param connectionName - The name of the MongoDB connection
|
|
342
|
+
* @param collectionName - The name of the collection
|
|
343
|
+
* @returns Array of merged index definitions, or empty array if collection not registered
|
|
344
|
+
*/
|
|
345
|
+
declare function getMergedIndexes(connectionName: string, collectionName: string): CollectionIndex[];
|
|
338
346
|
/**
|
|
339
347
|
* Deletes unused indexes from all registered collections for a connection.
|
|
340
348
|
* Iterates over all collections registered via createCollection() and
|
|
@@ -380,4 +388,4 @@ declare const ENCRYPTION_ALGORITHMS: {
|
|
|
380
388
|
RANDOM: string;
|
|
381
389
|
};
|
|
382
390
|
|
|
383
|
-
export { BaseCollection, Collection, type CollectionIndex, type CountDocuments, type CreateCollectionOptions, type CreateCollectionOptionsWithSchemaType, type CreateCollectionOptionsWithTypedSchema, DataLoader, type DeleteMany, type DeleteOne, type DistinctDocumentId, type DocumentWithId, ENCRYPTION_ALGORITHMS, type EstimatedDocumentCount, type Find, type FindCursor, type FindOne, type FindOneAndUpdate, type FindOneAndUpdateUpdateOptions, type InferIdType, type InferSchemaTypeWithId, type InitItem, type InsertAndFind, type InsertMany, type InsertManyOptions, type InsertOne, type InsertOptions, type ModelClassBase, type ModelToMongoSelector, MongoCollection, type MongoFilter, type MongoSelector, type OptionalId, Repository, type SchemaWithRequiredId, type TypedId, type UpdateAndFind, type UpdateItem, type UpdateMany, type UpdateOne, type UpdateOptions, type Upsert, allConnectionPromises, collectionsRegistry, configureConnection, connections, createCollection, createIndexesPromises, deleteAllUnusedIndexes, getDBName, getMongoConnection, getOrCreateEncryptionKey, getRegisteredCollections, registerCollection, typedId };
|
|
391
|
+
export { BaseCollection, Collection, type CollectionIndex, type CountDocuments, type CreateCollectionOptions, type CreateCollectionOptionsWithSchemaType, type CreateCollectionOptionsWithTypedSchema, DataLoader, type DeleteMany, type DeleteOne, type DistinctDocumentId, type DocumentWithId, ENCRYPTION_ALGORITHMS, type EstimatedDocumentCount, type Find, type FindCursor, type FindOne, type FindOneAndUpdate, type FindOneAndUpdateUpdateOptions, type InferIdType, type InferSchemaTypeWithId, type InitItem, type InsertAndFind, type InsertMany, type InsertManyOptions, type InsertOne, type InsertOptions, type ModelClassBase, type ModelToMongoSelector, MongoCollection, type MongoFilter, type MongoSelector, type OptionalId, Repository, type SchemaWithRequiredId, type TypedId, type UpdateAndFind, type UpdateItem, type UpdateMany, type UpdateOne, type UpdateOptions, type Upsert, allConnectionPromises, collectionsRegistry, configureConnection, connections, createCollection, createIndexesPromises, deleteAllUnusedIndexes, getDBName, getMergedIndexes, getMongoConnection, getOrCreateEncryptionKey, getRegisteredCollections, registerCollection, typedId };
|
package/dist/index.d.ts
CHANGED
|
@@ -335,6 +335,14 @@ declare function registerCollection(connectionName: string, collection: Collecti
|
|
|
335
335
|
* @returns Array of registered collections for the connection
|
|
336
336
|
*/
|
|
337
337
|
declare function getRegisteredCollections(connectionName?: string): Array<Collection<ModelClassBase>>;
|
|
338
|
+
/**
|
|
339
|
+
* Gets the merged indexes for a specific collection from the registry.
|
|
340
|
+
* This includes all indexes from all createCollection() calls for the same collection name.
|
|
341
|
+
* @param connectionName - The name of the MongoDB connection
|
|
342
|
+
* @param collectionName - The name of the collection
|
|
343
|
+
* @returns Array of merged index definitions, or empty array if collection not registered
|
|
344
|
+
*/
|
|
345
|
+
declare function getMergedIndexes(connectionName: string, collectionName: string): CollectionIndex[];
|
|
338
346
|
/**
|
|
339
347
|
* Deletes unused indexes from all registered collections for a connection.
|
|
340
348
|
* Iterates over all collections registered via createCollection() and
|
|
@@ -380,4 +388,4 @@ declare const ENCRYPTION_ALGORITHMS: {
|
|
|
380
388
|
RANDOM: string;
|
|
381
389
|
};
|
|
382
390
|
|
|
383
|
-
export { BaseCollection, Collection, type CollectionIndex, type CountDocuments, type CreateCollectionOptions, type CreateCollectionOptionsWithSchemaType, type CreateCollectionOptionsWithTypedSchema, DataLoader, type DeleteMany, type DeleteOne, type DistinctDocumentId, type DocumentWithId, ENCRYPTION_ALGORITHMS, type EstimatedDocumentCount, type Find, type FindCursor, type FindOne, type FindOneAndUpdate, type FindOneAndUpdateUpdateOptions, type InferIdType, type InferSchemaTypeWithId, type InitItem, type InsertAndFind, type InsertMany, type InsertManyOptions, type InsertOne, type InsertOptions, type ModelClassBase, type ModelToMongoSelector, MongoCollection, type MongoFilter, type MongoSelector, type OptionalId, Repository, type SchemaWithRequiredId, type TypedId, type UpdateAndFind, type UpdateItem, type UpdateMany, type UpdateOne, type UpdateOptions, type Upsert, allConnectionPromises, collectionsRegistry, configureConnection, connections, createCollection, createIndexesPromises, deleteAllUnusedIndexes, getDBName, getMongoConnection, getOrCreateEncryptionKey, getRegisteredCollections, registerCollection, typedId };
|
|
391
|
+
export { BaseCollection, Collection, type CollectionIndex, type CountDocuments, type CreateCollectionOptions, type CreateCollectionOptionsWithSchemaType, type CreateCollectionOptionsWithTypedSchema, DataLoader, type DeleteMany, type DeleteOne, type DistinctDocumentId, type DocumentWithId, ENCRYPTION_ALGORITHMS, type EstimatedDocumentCount, type Find, type FindCursor, type FindOne, type FindOneAndUpdate, type FindOneAndUpdateUpdateOptions, type InferIdType, type InferSchemaTypeWithId, type InitItem, type InsertAndFind, type InsertMany, type InsertManyOptions, type InsertOne, type InsertOptions, type ModelClassBase, type ModelToMongoSelector, MongoCollection, type MongoFilter, type MongoSelector, type OptionalId, Repository, type SchemaWithRequiredId, type TypedId, type UpdateAndFind, type UpdateItem, type UpdateMany, type UpdateOne, type UpdateOptions, type Upsert, allConnectionPromises, collectionsRegistry, configureConnection, connections, createCollection, createIndexesPromises, deleteAllUnusedIndexes, getDBName, getMergedIndexes, getMongoConnection, getOrCreateEncryptionKey, getRegisteredCollections, registerCollection, typedId };
|
package/dist/index.js
CHANGED
|
@@ -74,9 +74,6 @@ var OrionMongoDatabaseWrapper = class {
|
|
|
74
74
|
configTimeout;
|
|
75
75
|
constructor(connectionName) {
|
|
76
76
|
this.connectionName = connectionName;
|
|
77
|
-
logger.info("New connection requested", {
|
|
78
|
-
connectionName
|
|
79
|
-
});
|
|
80
77
|
this.connectionEvent.setMaxListeners(Number.POSITIVE_INFINITY);
|
|
81
78
|
this.connectionPromise = new Promise((resolve, reject) => {
|
|
82
79
|
if (this.state === "connected") {
|
|
@@ -122,11 +119,8 @@ var OrionMongoDatabaseWrapper = class {
|
|
|
122
119
|
return this;
|
|
123
120
|
}
|
|
124
121
|
this.state = "connecting";
|
|
125
|
-
const censoredURI = this.uri.replace(/\/\/.*:.*@/, "//");
|
|
126
|
-
logger.info(
|
|
127
|
-
uri: censoredURI,
|
|
128
|
-
connectionName: this.connectionName
|
|
129
|
-
});
|
|
122
|
+
const censoredURI = this.uri.replace(/\/\/.*:.*@/, "//").replace(/^mongodb(\+srv)?:\/\//, "");
|
|
123
|
+
logger.info(`Starting MongoDB connection "${this.connectionName}" [${censoredURI}]`);
|
|
130
124
|
if (this.encrypted.client) {
|
|
131
125
|
await this.connectWithRetry(this.encrypted.client);
|
|
132
126
|
logger.info("Successfully connected to encrypted mongo", {
|
|
@@ -137,10 +131,6 @@ var OrionMongoDatabaseWrapper = class {
|
|
|
137
131
|
await this.connectWithRetry(this.client);
|
|
138
132
|
this.state = "connected";
|
|
139
133
|
this.connectionEvent.emit("connected", this.client);
|
|
140
|
-
logger.info("Successfully connected to mongo", {
|
|
141
|
-
uri: censoredURI,
|
|
142
|
-
connectionName: this.connectionName
|
|
143
|
-
});
|
|
144
134
|
nextTick(() => {
|
|
145
135
|
this.connectionEvent.removeAllListeners();
|
|
146
136
|
this.connectionEvent = null;
|
|
@@ -1146,7 +1136,7 @@ var generateId_default = getIdGenerator;
|
|
|
1146
1136
|
|
|
1147
1137
|
// src/createCollection/createIndexes.ts
|
|
1148
1138
|
import { MongoExpiredSessionError, MongoNotConnectedError } from "mongodb";
|
|
1149
|
-
import { logger as
|
|
1139
|
+
import { logger as logger4 } from "@orion-js/logger";
|
|
1150
1140
|
|
|
1151
1141
|
// src/createCollection/deleteUnusedIndexes.ts
|
|
1152
1142
|
import { logger as logger2 } from "@orion-js/logger";
|
|
@@ -1168,6 +1158,15 @@ function getIndexName(indexDef) {
|
|
|
1168
1158
|
}
|
|
1169
1159
|
|
|
1170
1160
|
// src/createCollection/deleteUnusedIndexes.ts
|
|
1161
|
+
function isTextIndexDefinition(keys) {
|
|
1162
|
+
return Object.values(keys).some((value) => value === "text");
|
|
1163
|
+
}
|
|
1164
|
+
function isMongoDBTextIndex(key) {
|
|
1165
|
+
return "_fts" in key && "_ftsx" in key;
|
|
1166
|
+
}
|
|
1167
|
+
function generateIndexName(keys) {
|
|
1168
|
+
return Object.entries(keys).map(([field, value]) => `${field}_${value}`).join("_");
|
|
1169
|
+
}
|
|
1171
1170
|
function keysMatch(definitionKeys, currentIndexKey) {
|
|
1172
1171
|
const defEntries = Object.entries(definitionKeys);
|
|
1173
1172
|
const curEntries = Object.entries(currentIndexKey);
|
|
@@ -1183,7 +1182,12 @@ function isIndexDefined(definedIndexes, currentIndex) {
|
|
|
1183
1182
|
return definedIndexes.some((defIndex) => {
|
|
1184
1183
|
const customName = getIndexName(defIndex);
|
|
1185
1184
|
if (customName && customName === currentIndex.name) return true;
|
|
1186
|
-
|
|
1185
|
+
const defKeys = defIndex.keys;
|
|
1186
|
+
if (isTextIndexDefinition(defKeys) && isMongoDBTextIndex(currentIndex.key)) {
|
|
1187
|
+
const expectedName = generateIndexName(defKeys);
|
|
1188
|
+
return currentIndex.name === expectedName;
|
|
1189
|
+
}
|
|
1190
|
+
return keysMatch(defKeys, currentIndex.key);
|
|
1187
1191
|
});
|
|
1188
1192
|
}
|
|
1189
1193
|
async function deleteUnusedIndexes(collection) {
|
|
@@ -1221,67 +1225,8 @@ async function deleteUnusedIndexes(collection) {
|
|
|
1221
1225
|
return result;
|
|
1222
1226
|
}
|
|
1223
1227
|
|
|
1224
|
-
// src/createCollection/createIndexes.ts
|
|
1225
|
-
async function checkIndexes(collection) {
|
|
1226
|
-
await collection.connectionPromise;
|
|
1227
|
-
let currentIndexes = [];
|
|
1228
|
-
try {
|
|
1229
|
-
currentIndexes = await collection.rawCollection.indexes();
|
|
1230
|
-
} catch (error) {
|
|
1231
|
-
if (error.codeName !== "NamespaceNotFound") throw error;
|
|
1232
|
-
return;
|
|
1233
|
-
}
|
|
1234
|
-
if (!collection.indexes || collection.indexes.length === 0) {
|
|
1235
|
-
return;
|
|
1236
|
-
}
|
|
1237
|
-
const unexpectedIndexes = currentIndexes.filter(
|
|
1238
|
-
(index) => index.name !== "_id_" && !isIndexDefined(collection.indexes, index)
|
|
1239
|
-
);
|
|
1240
|
-
if (unexpectedIndexes.length > 0) {
|
|
1241
|
-
logger3.warn(
|
|
1242
|
-
`${unexpectedIndexes.length} unexpected indexes found in collection "${collection.name}": ${unexpectedIndexes.map((i) => i.name).join(", ")} | Delete the index or fix the collection definition`
|
|
1243
|
-
);
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
async function loadIndexes(collection) {
|
|
1247
|
-
if (!collection.indexes) return;
|
|
1248
|
-
if (!collection.indexes.length) return;
|
|
1249
|
-
await collection.connectionPromise;
|
|
1250
|
-
const results = Promise.all(
|
|
1251
|
-
collection.indexes.map(async (indexDef) => {
|
|
1252
|
-
const { keys } = indexDef;
|
|
1253
|
-
const options = getIndexOptions(indexDef);
|
|
1254
|
-
try {
|
|
1255
|
-
return await collection.rawCollection.createIndex(keys, options);
|
|
1256
|
-
} catch (error) {
|
|
1257
|
-
if (error.code === 85 || error.code === 86) {
|
|
1258
|
-
console.info("Will delete index to create the new version");
|
|
1259
|
-
const indexName = (() => {
|
|
1260
|
-
const message = error.errorResponse.errmsg;
|
|
1261
|
-
const indexName2 = message.split('name: "')[1].split('"')[0];
|
|
1262
|
-
return indexName2;
|
|
1263
|
-
})();
|
|
1264
|
-
await collection.rawCollection.dropIndex(indexName);
|
|
1265
|
-
console.info("Index was deleted, creating new index");
|
|
1266
|
-
const result = await collection.rawCollection.createIndex(keys, options);
|
|
1267
|
-
console.info("Index updated correctly");
|
|
1268
|
-
return result;
|
|
1269
|
-
}
|
|
1270
|
-
if (error instanceof MongoExpiredSessionError || error instanceof MongoNotConnectedError) {
|
|
1271
|
-
} else {
|
|
1272
|
-
console.error(`Error creating index for collection ${collection.name}: ${error.message}`);
|
|
1273
|
-
console.error(error);
|
|
1274
|
-
return error.message;
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
})
|
|
1278
|
-
);
|
|
1279
|
-
await checkIndexes(collection);
|
|
1280
|
-
return results;
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
1228
|
// src/createCollection/collectionsRegistry.ts
|
|
1284
|
-
import { logger as
|
|
1229
|
+
import { logger as logger3 } from "@orion-js/logger";
|
|
1285
1230
|
var collectionsRegistry = /* @__PURE__ */ new Map();
|
|
1286
1231
|
function indexesAreEqual(indexA, indexB) {
|
|
1287
1232
|
const nameA = getIndexName(indexA);
|
|
@@ -1323,17 +1268,28 @@ function getRegisteredCollections(connectionName = "main") {
|
|
|
1323
1268
|
}
|
|
1324
1269
|
return Array.from(connectionCollections.values());
|
|
1325
1270
|
}
|
|
1271
|
+
function getMergedIndexes(connectionName, collectionName) {
|
|
1272
|
+
const connectionCollections = collectionsRegistry.get(connectionName);
|
|
1273
|
+
if (!connectionCollections) {
|
|
1274
|
+
return [];
|
|
1275
|
+
}
|
|
1276
|
+
const collection = connectionCollections.get(collectionName);
|
|
1277
|
+
if (!collection) {
|
|
1278
|
+
return [];
|
|
1279
|
+
}
|
|
1280
|
+
return collection.indexes || [];
|
|
1281
|
+
}
|
|
1326
1282
|
async function deleteAllUnusedIndexes(connectionName = "main") {
|
|
1327
1283
|
const collections = getRegisteredCollections(connectionName);
|
|
1328
1284
|
if (collections.length === 0) {
|
|
1329
|
-
|
|
1285
|
+
logger3.warn(`No collections registered for connection "${connectionName}"`);
|
|
1330
1286
|
return [];
|
|
1331
1287
|
}
|
|
1332
1288
|
if (createIndexesPromises.length > 0) {
|
|
1333
|
-
|
|
1289
|
+
logger3.info("Waiting for pending index creation to complete before deleting unused indexes...");
|
|
1334
1290
|
await Promise.all(createIndexesPromises);
|
|
1335
1291
|
}
|
|
1336
|
-
|
|
1292
|
+
logger3.info(
|
|
1337
1293
|
`Deleting unused indexes from ${collections.length} collections on connection "${connectionName}"`
|
|
1338
1294
|
);
|
|
1339
1295
|
const results = [];
|
|
@@ -1344,7 +1300,67 @@ async function deleteAllUnusedIndexes(connectionName = "main") {
|
|
|
1344
1300
|
}
|
|
1345
1301
|
}
|
|
1346
1302
|
const totalDeleted = results.reduce((sum, r) => sum + r.deletedIndexes.length, 0);
|
|
1347
|
-
|
|
1303
|
+
logger3.info(`Deleted ${totalDeleted} unused indexes from ${results.length} collections`);
|
|
1304
|
+
return results;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// src/createCollection/createIndexes.ts
|
|
1308
|
+
async function checkIndexes(collection) {
|
|
1309
|
+
await collection.connectionPromise;
|
|
1310
|
+
let currentIndexes = [];
|
|
1311
|
+
try {
|
|
1312
|
+
currentIndexes = await collection.rawCollection.indexes();
|
|
1313
|
+
} catch (error) {
|
|
1314
|
+
if (error.codeName !== "NamespaceNotFound") throw error;
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
const mergedIndexes = getMergedIndexes(collection.connectionName, collection.name);
|
|
1318
|
+
if (mergedIndexes.length === 0) {
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
const unexpectedIndexes = currentIndexes.filter(
|
|
1322
|
+
(index) => index.name !== "_id_" && !isIndexDefined(mergedIndexes, index)
|
|
1323
|
+
);
|
|
1324
|
+
if (unexpectedIndexes.length > 0) {
|
|
1325
|
+
logger4.warn(
|
|
1326
|
+
`${unexpectedIndexes.length} unexpected indexes found in collection "${collection.name}": ${unexpectedIndexes.map((i) => i.name).join(", ")} | Delete the index or fix the collection definition`
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
async function loadIndexes(collection) {
|
|
1331
|
+
if (!collection.indexes) return;
|
|
1332
|
+
if (!collection.indexes.length) return;
|
|
1333
|
+
await collection.connectionPromise;
|
|
1334
|
+
const results = Promise.all(
|
|
1335
|
+
collection.indexes.map(async (indexDef) => {
|
|
1336
|
+
const { keys } = indexDef;
|
|
1337
|
+
const options = getIndexOptions(indexDef);
|
|
1338
|
+
try {
|
|
1339
|
+
return await collection.rawCollection.createIndex(keys, options);
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
if (error.code === 85 || error.code === 86) {
|
|
1342
|
+
console.info("Will delete index to create the new version");
|
|
1343
|
+
const indexName = (() => {
|
|
1344
|
+
const message = error.errorResponse.errmsg;
|
|
1345
|
+
const indexName2 = message.split('name: "')[1].split('"')[0];
|
|
1346
|
+
return indexName2;
|
|
1347
|
+
})();
|
|
1348
|
+
await collection.rawCollection.dropIndex(indexName);
|
|
1349
|
+
console.info("Index was deleted, creating new index");
|
|
1350
|
+
const result = await collection.rawCollection.createIndex(keys, options);
|
|
1351
|
+
console.info("Index updated correctly");
|
|
1352
|
+
return result;
|
|
1353
|
+
}
|
|
1354
|
+
if (error instanceof MongoExpiredSessionError || error instanceof MongoNotConnectedError) {
|
|
1355
|
+
} else {
|
|
1356
|
+
console.error(`Error creating index for collection ${collection.name}: ${error.message}`);
|
|
1357
|
+
console.error(error);
|
|
1358
|
+
return error.message;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
})
|
|
1362
|
+
);
|
|
1363
|
+
await checkIndexes(collection);
|
|
1348
1364
|
return results;
|
|
1349
1365
|
}
|
|
1350
1366
|
|
|
@@ -1628,6 +1644,7 @@ export {
|
|
|
1628
1644
|
createIndexesPromises,
|
|
1629
1645
|
deleteAllUnusedIndexes,
|
|
1630
1646
|
getDBName,
|
|
1647
|
+
getMergedIndexes,
|
|
1631
1648
|
getMongoConnection,
|
|
1632
1649
|
getOrCreateEncryptionKey,
|
|
1633
1650
|
getRegisteredCollections,
|