@orion-js/mongodb 4.2.1 → 4.2.4
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 +101 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +100 -42
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -317,11 +317,14 @@ interface DeleteUnusedIndexesResult {
|
|
|
317
317
|
/**
|
|
318
318
|
* Registry that tracks all collections created via createCollection().
|
|
319
319
|
* Maps connection name to a map of collection name to collection instance.
|
|
320
|
+
* When the same collection is registered multiple times, indexes are merged.
|
|
320
321
|
*/
|
|
321
322
|
declare const collectionsRegistry: Map<string, Map<string, Collection<ModelClassBase>>>;
|
|
322
323
|
/**
|
|
323
324
|
* Registers a collection in the registry.
|
|
324
325
|
* Called automatically when a collection is created via createCollection().
|
|
326
|
+
* If the same collection name is registered multiple times, indexes are merged
|
|
327
|
+
* to support multiple createCollection() calls for the same collection.
|
|
325
328
|
* @param connectionName - The name of the MongoDB connection
|
|
326
329
|
* @param collection - The collection instance to register
|
|
327
330
|
*/
|
|
@@ -332,11 +335,23 @@ declare function registerCollection(connectionName: string, collection: Collecti
|
|
|
332
335
|
* @returns Array of registered collections for the connection
|
|
333
336
|
*/
|
|
334
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[];
|
|
335
346
|
/**
|
|
336
347
|
* Deletes unused indexes from all registered collections for a connection.
|
|
337
348
|
* Iterates over all collections registered via createCollection() and
|
|
338
349
|
* removes indexes that exist in MongoDB but are not defined in the collection configuration.
|
|
339
350
|
*
|
|
351
|
+
* **Important**: This function waits for all pending index creation to complete before
|
|
352
|
+
* deleting any indexes, to avoid race conditions where an index being created might
|
|
353
|
+
* be incorrectly identified as unused.
|
|
354
|
+
*
|
|
340
355
|
* @param connectionName - The name of the MongoDB connection (defaults to 'main')
|
|
341
356
|
* @returns Array of results for each collection that had indexes deleted
|
|
342
357
|
*
|
|
@@ -373,4 +388,4 @@ declare const ENCRYPTION_ALGORITHMS: {
|
|
|
373
388
|
RANDOM: string;
|
|
374
389
|
};
|
|
375
390
|
|
|
376
|
-
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
|
@@ -317,11 +317,14 @@ interface DeleteUnusedIndexesResult {
|
|
|
317
317
|
/**
|
|
318
318
|
* Registry that tracks all collections created via createCollection().
|
|
319
319
|
* Maps connection name to a map of collection name to collection instance.
|
|
320
|
+
* When the same collection is registered multiple times, indexes are merged.
|
|
320
321
|
*/
|
|
321
322
|
declare const collectionsRegistry: Map<string, Map<string, Collection<ModelClassBase>>>;
|
|
322
323
|
/**
|
|
323
324
|
* Registers a collection in the registry.
|
|
324
325
|
* Called automatically when a collection is created via createCollection().
|
|
326
|
+
* If the same collection name is registered multiple times, indexes are merged
|
|
327
|
+
* to support multiple createCollection() calls for the same collection.
|
|
325
328
|
* @param connectionName - The name of the MongoDB connection
|
|
326
329
|
* @param collection - The collection instance to register
|
|
327
330
|
*/
|
|
@@ -332,11 +335,23 @@ declare function registerCollection(connectionName: string, collection: Collecti
|
|
|
332
335
|
* @returns Array of registered collections for the connection
|
|
333
336
|
*/
|
|
334
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[];
|
|
335
346
|
/**
|
|
336
347
|
* Deletes unused indexes from all registered collections for a connection.
|
|
337
348
|
* Iterates over all collections registered via createCollection() and
|
|
338
349
|
* removes indexes that exist in MongoDB but are not defined in the collection configuration.
|
|
339
350
|
*
|
|
351
|
+
* **Important**: This function waits for all pending index creation to complete before
|
|
352
|
+
* deleting any indexes, to avoid race conditions where an index being created might
|
|
353
|
+
* be incorrectly identified as unused.
|
|
354
|
+
*
|
|
340
355
|
* @param connectionName - The name of the MongoDB connection (defaults to 'main')
|
|
341
356
|
* @returns Array of results for each collection that had indexes deleted
|
|
342
357
|
*
|
|
@@ -373,4 +388,4 @@ declare const ENCRYPTION_ALGORITHMS: {
|
|
|
373
388
|
RANDOM: string;
|
|
374
389
|
};
|
|
375
390
|
|
|
376
|
-
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
|
@@ -1146,7 +1146,7 @@ var generateId_default = getIdGenerator;
|
|
|
1146
1146
|
|
|
1147
1147
|
// src/createCollection/createIndexes.ts
|
|
1148
1148
|
import { MongoExpiredSessionError, MongoNotConnectedError } from "mongodb";
|
|
1149
|
-
import { logger as
|
|
1149
|
+
import { logger as logger4 } from "@orion-js/logger";
|
|
1150
1150
|
|
|
1151
1151
|
// src/createCollection/deleteUnusedIndexes.ts
|
|
1152
1152
|
import { logger as logger2 } from "@orion-js/logger";
|
|
@@ -1168,6 +1168,15 @@ function getIndexName(indexDef) {
|
|
|
1168
1168
|
}
|
|
1169
1169
|
|
|
1170
1170
|
// src/createCollection/deleteUnusedIndexes.ts
|
|
1171
|
+
function isTextIndexDefinition(keys) {
|
|
1172
|
+
return Object.values(keys).some((value) => value === "text");
|
|
1173
|
+
}
|
|
1174
|
+
function isMongoDBTextIndex(key) {
|
|
1175
|
+
return "_fts" in key && "_ftsx" in key;
|
|
1176
|
+
}
|
|
1177
|
+
function generateIndexName(keys) {
|
|
1178
|
+
return Object.entries(keys).map(([field, value]) => `${field}_${value}`).join("_");
|
|
1179
|
+
}
|
|
1171
1180
|
function keysMatch(definitionKeys, currentIndexKey) {
|
|
1172
1181
|
const defEntries = Object.entries(definitionKeys);
|
|
1173
1182
|
const curEntries = Object.entries(currentIndexKey);
|
|
@@ -1183,7 +1192,12 @@ function isIndexDefined(definedIndexes, currentIndex) {
|
|
|
1183
1192
|
return definedIndexes.some((defIndex) => {
|
|
1184
1193
|
const customName = getIndexName(defIndex);
|
|
1185
1194
|
if (customName && customName === currentIndex.name) return true;
|
|
1186
|
-
|
|
1195
|
+
const defKeys = defIndex.keys;
|
|
1196
|
+
if (isTextIndexDefinition(defKeys) && isMongoDBTextIndex(currentIndex.key)) {
|
|
1197
|
+
const expectedName = generateIndexName(defKeys);
|
|
1198
|
+
return currentIndex.name === expectedName;
|
|
1199
|
+
}
|
|
1200
|
+
return keysMatch(defKeys, currentIndex.key);
|
|
1187
1201
|
});
|
|
1188
1202
|
}
|
|
1189
1203
|
async function deleteUnusedIndexes(collection) {
|
|
@@ -1221,6 +1235,85 @@ async function deleteUnusedIndexes(collection) {
|
|
|
1221
1235
|
return result;
|
|
1222
1236
|
}
|
|
1223
1237
|
|
|
1238
|
+
// src/createCollection/collectionsRegistry.ts
|
|
1239
|
+
import { logger as logger3 } from "@orion-js/logger";
|
|
1240
|
+
var collectionsRegistry = /* @__PURE__ */ new Map();
|
|
1241
|
+
function indexesAreEqual(indexA, indexB) {
|
|
1242
|
+
const nameA = getIndexName(indexA);
|
|
1243
|
+
const nameB = getIndexName(indexB);
|
|
1244
|
+
if (nameA && nameB) {
|
|
1245
|
+
return nameA === nameB;
|
|
1246
|
+
}
|
|
1247
|
+
return keysMatch(
|
|
1248
|
+
indexA.keys,
|
|
1249
|
+
indexB.keys
|
|
1250
|
+
);
|
|
1251
|
+
}
|
|
1252
|
+
function mergeIndexes(existingIndexes, newIndexes) {
|
|
1253
|
+
const merged = [...existingIndexes];
|
|
1254
|
+
for (const newIndex of newIndexes) {
|
|
1255
|
+
const isDuplicate = existingIndexes.some((existing) => indexesAreEqual(existing, newIndex));
|
|
1256
|
+
if (!isDuplicate) {
|
|
1257
|
+
merged.push(newIndex);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
return merged;
|
|
1261
|
+
}
|
|
1262
|
+
function registerCollection(connectionName, collection) {
|
|
1263
|
+
if (!collectionsRegistry.has(connectionName)) {
|
|
1264
|
+
collectionsRegistry.set(connectionName, /* @__PURE__ */ new Map());
|
|
1265
|
+
}
|
|
1266
|
+
const connectionMap = collectionsRegistry.get(connectionName);
|
|
1267
|
+
const existingCollection = connectionMap.get(collection.name);
|
|
1268
|
+
if (existingCollection) {
|
|
1269
|
+
existingCollection.indexes = mergeIndexes(existingCollection.indexes, collection.indexes);
|
|
1270
|
+
} else {
|
|
1271
|
+
connectionMap.set(collection.name, collection);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
function getRegisteredCollections(connectionName = "main") {
|
|
1275
|
+
const connectionCollections = collectionsRegistry.get(connectionName);
|
|
1276
|
+
if (!connectionCollections) {
|
|
1277
|
+
return [];
|
|
1278
|
+
}
|
|
1279
|
+
return Array.from(connectionCollections.values());
|
|
1280
|
+
}
|
|
1281
|
+
function getMergedIndexes(connectionName, collectionName) {
|
|
1282
|
+
const connectionCollections = collectionsRegistry.get(connectionName);
|
|
1283
|
+
if (!connectionCollections) {
|
|
1284
|
+
return [];
|
|
1285
|
+
}
|
|
1286
|
+
const collection = connectionCollections.get(collectionName);
|
|
1287
|
+
if (!collection) {
|
|
1288
|
+
return [];
|
|
1289
|
+
}
|
|
1290
|
+
return collection.indexes || [];
|
|
1291
|
+
}
|
|
1292
|
+
async function deleteAllUnusedIndexes(connectionName = "main") {
|
|
1293
|
+
const collections = getRegisteredCollections(connectionName);
|
|
1294
|
+
if (collections.length === 0) {
|
|
1295
|
+
logger3.warn(`No collections registered for connection "${connectionName}"`);
|
|
1296
|
+
return [];
|
|
1297
|
+
}
|
|
1298
|
+
if (createIndexesPromises.length > 0) {
|
|
1299
|
+
logger3.info("Waiting for pending index creation to complete before deleting unused indexes...");
|
|
1300
|
+
await Promise.all(createIndexesPromises);
|
|
1301
|
+
}
|
|
1302
|
+
logger3.info(
|
|
1303
|
+
`Deleting unused indexes from ${collections.length} collections on connection "${connectionName}"`
|
|
1304
|
+
);
|
|
1305
|
+
const results = [];
|
|
1306
|
+
for (const collection of collections) {
|
|
1307
|
+
const result = await collection.deleteUnusedIndexes();
|
|
1308
|
+
if (result.deletedIndexes.length > 0) {
|
|
1309
|
+
results.push(result);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
const totalDeleted = results.reduce((sum, r) => sum + r.deletedIndexes.length, 0);
|
|
1313
|
+
logger3.info(`Deleted ${totalDeleted} unused indexes from ${results.length} collections`);
|
|
1314
|
+
return results;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1224
1317
|
// src/createCollection/createIndexes.ts
|
|
1225
1318
|
async function checkIndexes(collection) {
|
|
1226
1319
|
await collection.connectionPromise;
|
|
@@ -1231,14 +1324,15 @@ async function checkIndexes(collection) {
|
|
|
1231
1324
|
if (error.codeName !== "NamespaceNotFound") throw error;
|
|
1232
1325
|
return;
|
|
1233
1326
|
}
|
|
1234
|
-
|
|
1327
|
+
const mergedIndexes = getMergedIndexes(collection.connectionName, collection.name);
|
|
1328
|
+
if (mergedIndexes.length === 0) {
|
|
1235
1329
|
return;
|
|
1236
1330
|
}
|
|
1237
1331
|
const unexpectedIndexes = currentIndexes.filter(
|
|
1238
|
-
(index) => index.name !== "_id_" && !isIndexDefined(
|
|
1332
|
+
(index) => index.name !== "_id_" && !isIndexDefined(mergedIndexes, index)
|
|
1239
1333
|
);
|
|
1240
1334
|
if (unexpectedIndexes.length > 0) {
|
|
1241
|
-
|
|
1335
|
+
logger4.warn(
|
|
1242
1336
|
`${unexpectedIndexes.length} unexpected indexes found in collection "${collection.name}": ${unexpectedIndexes.map((i) => i.name).join(", ")} | Delete the index or fix the collection definition`
|
|
1243
1337
|
);
|
|
1244
1338
|
}
|
|
@@ -1280,43 +1374,6 @@ async function loadIndexes(collection) {
|
|
|
1280
1374
|
return results;
|
|
1281
1375
|
}
|
|
1282
1376
|
|
|
1283
|
-
// src/createCollection/collectionsRegistry.ts
|
|
1284
|
-
import { logger as logger4 } from "@orion-js/logger";
|
|
1285
|
-
var collectionsRegistry = /* @__PURE__ */ new Map();
|
|
1286
|
-
function registerCollection(connectionName, collection) {
|
|
1287
|
-
if (!collectionsRegistry.has(connectionName)) {
|
|
1288
|
-
collectionsRegistry.set(connectionName, /* @__PURE__ */ new Map());
|
|
1289
|
-
}
|
|
1290
|
-
collectionsRegistry.get(connectionName).set(collection.name, collection);
|
|
1291
|
-
}
|
|
1292
|
-
function getRegisteredCollections(connectionName = "main") {
|
|
1293
|
-
const connectionCollections = collectionsRegistry.get(connectionName);
|
|
1294
|
-
if (!connectionCollections) {
|
|
1295
|
-
return [];
|
|
1296
|
-
}
|
|
1297
|
-
return Array.from(connectionCollections.values());
|
|
1298
|
-
}
|
|
1299
|
-
async function deleteAllUnusedIndexes(connectionName = "main") {
|
|
1300
|
-
const collections = getRegisteredCollections(connectionName);
|
|
1301
|
-
if (collections.length === 0) {
|
|
1302
|
-
logger4.warn(`No collections registered for connection "${connectionName}"`);
|
|
1303
|
-
return [];
|
|
1304
|
-
}
|
|
1305
|
-
logger4.info(
|
|
1306
|
-
`Deleting unused indexes from ${collections.length} collections on connection "${connectionName}"`
|
|
1307
|
-
);
|
|
1308
|
-
const results = [];
|
|
1309
|
-
for (const collection of collections) {
|
|
1310
|
-
const result = await collection.deleteUnusedIndexes();
|
|
1311
|
-
if (result.deletedIndexes.length > 0) {
|
|
1312
|
-
results.push(result);
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
const totalDeleted = results.reduce((sum, r) => sum + r.deletedIndexes.length, 0);
|
|
1316
|
-
logger4.info(`Deleted ${totalDeleted} unused indexes from ${results.length} collections`);
|
|
1317
|
-
return results;
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
1377
|
// src/createCollection/getSchemaAndModel.ts
|
|
1321
1378
|
import { clone as clone3 } from "@orion-js/helpers";
|
|
1322
1379
|
Symbol.metadata ?? (Symbol.metadata = Symbol("Symbol.metadata"));
|
|
@@ -1597,6 +1654,7 @@ export {
|
|
|
1597
1654
|
createIndexesPromises,
|
|
1598
1655
|
deleteAllUnusedIndexes,
|
|
1599
1656
|
getDBName,
|
|
1657
|
+
getMergedIndexes,
|
|
1600
1658
|
getMongoConnection,
|
|
1601
1659
|
getOrCreateEncryptionKey,
|
|
1602
1660
|
getRegisteredCollections,
|