@rapidrest/service-core 1.0.0-beta.6 → 1.0.0-rc.2
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/lib/database/MongoRepository.js +22 -24
- package/dist/lib/database/MongoRepository.js.map +1 -1
- package/dist/lib/database/MongoSchemaSync.js +80 -21
- package/dist/lib/database/MongoSchemaSync.js.map +1 -1
- package/dist/lib/database/NamingUtils.js +4 -4
- package/dist/lib/database/NamingUtils.js.map +1 -1
- package/dist/lib/decorators/PersistenceDecorators.js +17 -17
- package/dist/lib/decorators/PersistenceDecorators.js.map +1 -1
- package/dist/lib/models/BaseMongoEntity.js +10 -3
- package/dist/lib/models/BaseMongoEntity.js.map +1 -1
- package/dist/lib/models/ModelUtils.js +31 -34
- package/dist/lib/models/ModelUtils.js.map +1 -1
- package/dist/lib/models/RecoverableBaseMongoEntity.js +11 -3
- package/dist/lib/models/RecoverableBaseMongoEntity.js.map +1 -1
- package/dist/lib/models/RepoUtils.js +37 -45
- package/dist/lib/models/RepoUtils.js.map +1 -1
- package/dist/lib/models/SimpleEntity.js +1 -1
- package/dist/lib/models/SimpleEntity.js.map +1 -1
- package/dist/lib/routes/ModelRoute.js +1 -11
- package/dist/lib/routes/ModelRoute.js.map +1 -1
- package/dist/types/database/MongoRepository.d.ts +17 -11
- package/dist/types/database/MongoSchemaSync.d.ts +25 -3
- package/dist/types/database/NamingUtils.d.ts +1 -1
- package/dist/types/decorators/PersistenceDecorators.d.ts +29 -3
- package/dist/types/models/ModelUtils.d.ts +3 -6
- package/dist/types/models/RepoUtils.d.ts +1 -7
- package/dist/types/routes/ModelRoute.d.ts +0 -4
- package/docs/reference/@rapidrest/namespaces/DatabaseDecorators/functions/MongoRepository.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DatabaseDecorators/functions/RedisConnection.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DatabaseDecorators/functions/Repository.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Default.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Description.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Document.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Example.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Format.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Returns.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Summary.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/Tags.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/functions/TypeInfo.md +1 -1
- package/docs/reference/@rapidrest/namespaces/DocDecorators/interfaces/DocumentsData.md +7 -7
- package/docs/reference/@rapidrest/namespaces/EventDecorators/functions/EventListener.md +1 -1
- package/docs/reference/@rapidrest/namespaces/EventDecorators/functions/OnEvent.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/Cache.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/ChildEntity.md +2 -2
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/DataStore.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/Identifier.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/Protect.md +5 -5
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/Reference.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/Shard.md +1 -1
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/functions/TrackChanges.md +2 -2
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/interfaces/PendingTypeOrmColumn.md +7 -7
- package/docs/reference/@rapidrest/namespaces/ModelDecorators/variables/pendingTypeOrmColumns.md +2 -2
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/README.md +2 -0
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/Column.md +1 -1
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/Entity.md +5 -6
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/Index.md +3 -3
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/PrimaryColumn.md +1 -1
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/Unique.md +3 -3
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/getColumnMetadata.md +1 -1
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/getEntityName.md +1 -1
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/functions/getIndexMetadata.md +1 -1
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/CollationOptions.md +79 -0
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/ColumnInfo.md +4 -4
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/ColumnOptions.md +5 -5
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/EntityOptions.md +32 -0
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/IndexInfo.md +4 -4
- package/docs/reference/@rapidrest/namespaces/PersistenceDecorators/interfaces/IndexOptions.md +15 -5
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/After.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Auth.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/AuthResult.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Before.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/ContentType.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Delete.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Get.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Head.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Header.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Method.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Model.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Options.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Param.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Patch.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Post.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Protect.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Put.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Query.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Request.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/RequiresRole.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Response.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Route.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Socket.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/User.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/Validate.md +1 -1
- package/docs/reference/@rapidrest/namespaces/RouteDecorators/functions/WebSocket.md +1 -1
- package/docs/reference/classes/ACLUtils.md +10 -10
- package/docs/reference/classes/AdminRoute.md +3 -3
- package/docs/reference/classes/AuthMiddleware.md +6 -6
- package/docs/reference/classes/BackgroundService.md +8 -8
- package/docs/reference/classes/BackgroundServiceManager.md +7 -7
- package/docs/reference/classes/BaseEntity.md +6 -6
- package/docs/reference/classes/BaseMongoEntity.md +7 -7
- package/docs/reference/classes/BasicStrategy.md +5 -5
- package/docs/reference/classes/BasicStrategyOptions.md +7 -7
- package/docs/reference/classes/BulkError.md +3 -3
- package/docs/reference/classes/ConnectionManager.md +4 -4
- package/docs/reference/classes/EventListenerManager.md +5 -5
- package/docs/reference/classes/HttpRouter.md +16 -16
- package/docs/reference/classes/JWTStrategy.md +5 -5
- package/docs/reference/classes/JWTStrategyOptions.md +8 -8
- package/docs/reference/classes/MetricsRoute.md +2 -2
- package/docs/reference/classes/ModelRoute.md +46 -46
- package/docs/reference/classes/ModelUtils.md +13 -31
- package/docs/reference/classes/MongoConnection.md +12 -12
- package/docs/reference/classes/MongoRepository.md +73 -37
- package/docs/reference/classes/MongoSchemaSync.md +37 -7
- package/docs/reference/classes/NetUtils.md +3 -3
- package/docs/reference/classes/NotificationUtils.md +3 -3
- package/docs/reference/classes/ObjectFactory.md +3 -3
- package/docs/reference/classes/OpenAPIRoute.md +5 -5
- package/docs/reference/classes/OpenApiSpec.md +45 -45
- package/docs/reference/classes/RecoverableBaseEntity.md +7 -7
- package/docs/reference/classes/RecoverableBaseMongoEntity.md +8 -8
- package/docs/reference/classes/RedisTransport.md +4 -4
- package/docs/reference/classes/RepoUtils.md +36 -40
- package/docs/reference/classes/RouteUtils.md +7 -7
- package/docs/reference/classes/Server.md +26 -26
- package/docs/reference/classes/SimpleEntity.md +3 -3
- package/docs/reference/classes/SimpleMongoEntity.md +4 -4
- package/docs/reference/classes/StatusExtraData.md +4 -4
- package/docs/reference/classes/StatusRoute.md +1 -1
- package/docs/reference/classes/UWSRequest.md +16 -16
- package/docs/reference/classes/UWSResponse.md +13 -13
- package/docs/reference/classes/UWSWebSocketShim.md +5 -5
- package/docs/reference/enumerations/ACLAction.md +7 -7
- package/docs/reference/enumerations/ApiErrorMessages.md +15 -15
- package/docs/reference/enumerations/ApiErrors.md +15 -15
- package/docs/reference/functions/createWebSocketStream.md +1 -1
- package/docs/reference/functions/isSqlDataSource.md +1 -1
- package/docs/reference/functions/readBody.md +1 -1
- package/docs/reference/functions/resolveCollectionName.md +2 -2
- package/docs/reference/functions/runChain.md +1 -1
- package/docs/reference/functions/snakeCase.md +1 -1
- package/docs/reference/interfaces/ACLRecord.md +8 -8
- package/docs/reference/interfaces/AccessControlList.md +5 -5
- package/docs/reference/interfaces/AuthResult.md +5 -5
- package/docs/reference/interfaces/AuthStrategy.md +4 -4
- package/docs/reference/interfaces/CreateRequestOptions.md +9 -9
- package/docs/reference/interfaces/DeleteRequestOptions.md +10 -20
- package/docs/reference/interfaces/FindRequestOptions.md +10 -10
- package/docs/reference/interfaces/HttpRequest.md +15 -15
- package/docs/reference/interfaces/HttpResponse.md +11 -11
- package/docs/reference/interfaces/JWTAuthResult.md +6 -6
- package/docs/reference/interfaces/RepoCreateOptions.md +7 -7
- package/docs/reference/interfaces/RepoDeleteOptions.md +8 -18
- package/docs/reference/interfaces/RepoFindOptions.md +10 -20
- package/docs/reference/interfaces/RepoOperationOptions.md +6 -6
- package/docs/reference/interfaces/RepoUpdateOptions.md +7 -17
- package/docs/reference/interfaces/RequestOptions.md +8 -8
- package/docs/reference/interfaces/RequestWS.md +17 -17
- package/docs/reference/interfaces/TruncateRequestOptions.md +12 -26
- package/docs/reference/interfaces/UpdateRequestOptions.md +10 -20
- package/docs/reference/type-aliases/ErrorHandler.md +1 -1
- package/docs/reference/type-aliases/NextFunction.md +1 -1
- package/docs/reference/type-aliases/OneOrMany.md +1 -1
- package/docs/reference/type-aliases/OneOrNull.md +1 -1
- package/docs/reference/type-aliases/PartialBaseEntity.md +1 -1
- package/docs/reference/type-aliases/PartialSimpleEntity.md +1 -1
- package/docs/reference/type-aliases/RequestHandler.md +1 -1
- package/docs/reference/type-aliases/UpdateObject.md +1 -1
- package/docs/reference/type-aliases/WsUpgradeAuth.md +1 -1
- package/docs/reference/type-aliases/WsUpgradeAuthResult.md +5 -5
- package/package.json +1 -1
|
@@ -30,39 +30,34 @@ export class MongoRepository {
|
|
|
30
30
|
* collection does not exist.
|
|
31
31
|
*/
|
|
32
32
|
async clear() {
|
|
33
|
-
|
|
34
|
-
await this.collection.drop();
|
|
35
|
-
}
|
|
36
|
-
catch (err) {
|
|
37
|
-
// Ignore "ns not found" errors for collections that don't exist yet
|
|
38
|
-
if (err.codeName !== "NamespaceNotFound" && !String(err.message).includes("ns not found")) {
|
|
39
|
-
throw err;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
33
|
+
await this.collection.deleteMany({});
|
|
42
34
|
}
|
|
43
35
|
/**
|
|
44
36
|
* Returns the number of documents matching the given filter.
|
|
45
37
|
*
|
|
46
|
-
* @param filter The
|
|
38
|
+
* @param filter - The filter for the count
|
|
39
|
+
* @param options - Optional settings for the command
|
|
47
40
|
*/
|
|
48
|
-
|
|
49
|
-
return this.collection.countDocuments(filter ?? {});
|
|
41
|
+
count(filter, options) {
|
|
42
|
+
return this.collection.countDocuments(filter ?? {}, options);
|
|
50
43
|
}
|
|
51
44
|
/**
|
|
52
45
|
* Deletes all documents matching the given filter.
|
|
53
46
|
*
|
|
54
47
|
* @param filter The query filter to match documents against.
|
|
48
|
+
* @param options - Optional settings for the command
|
|
55
49
|
*/
|
|
56
|
-
|
|
57
|
-
return this.collection.deleteMany(filter);
|
|
50
|
+
deleteMany(filter, options) {
|
|
51
|
+
return this.collection.deleteMany(filter, options);
|
|
58
52
|
}
|
|
59
53
|
/**
|
|
60
54
|
* Deletes the first document matching the given filter.
|
|
61
55
|
*
|
|
62
56
|
* @param filter The query filter to match documents against.
|
|
57
|
+
* @param options - Optional settings for the command
|
|
63
58
|
*/
|
|
64
|
-
|
|
65
|
-
return this.collection.deleteOne(filter);
|
|
59
|
+
deleteOne(filter, options) {
|
|
60
|
+
return this.collection.deleteOne(filter, options);
|
|
66
61
|
}
|
|
67
62
|
/**
|
|
68
63
|
* Returns the list of distinct values of the given field for all documents matching the given filter.
|
|
@@ -70,23 +65,24 @@ export class MongoRepository {
|
|
|
70
65
|
* @param field The name of the document field to return distinct values of.
|
|
71
66
|
* @param filter The query filter to match documents against.
|
|
72
67
|
*/
|
|
73
|
-
|
|
68
|
+
distinct(field, filter) {
|
|
74
69
|
return this.collection.distinct(field, filter ?? {});
|
|
75
70
|
}
|
|
76
71
|
/**
|
|
77
72
|
* Returns all documents matching the given filter.
|
|
78
73
|
*
|
|
79
74
|
* @param filter The query filter to match documents against.
|
|
75
|
+
* @param options - Optional settings for the command
|
|
80
76
|
*/
|
|
81
|
-
|
|
82
|
-
return this.collection.find(filter ?? {})
|
|
77
|
+
find(filter, options) {
|
|
78
|
+
return this.collection.find(filter ?? {}, options);
|
|
83
79
|
}
|
|
84
80
|
/**
|
|
85
81
|
* Returns the first document matching the given filter.
|
|
86
82
|
*
|
|
87
83
|
* @param filter The query filter to match documents against.
|
|
88
84
|
*/
|
|
89
|
-
|
|
85
|
+
findOne(filter) {
|
|
90
86
|
return this.collection.findOne(filter);
|
|
91
87
|
}
|
|
92
88
|
/**
|
|
@@ -119,18 +115,20 @@ export class MongoRepository {
|
|
|
119
115
|
*
|
|
120
116
|
* @param filter The query filter to match documents against.
|
|
121
117
|
* @param update The update operations (e.g. `$set`) to apply.
|
|
118
|
+
* @param options - Optional settings for the command
|
|
122
119
|
*/
|
|
123
|
-
|
|
124
|
-
return this.collection.updateMany(filter, update);
|
|
120
|
+
updateMany(filter, update, options) {
|
|
121
|
+
return this.collection.updateMany(filter, update, options);
|
|
125
122
|
}
|
|
126
123
|
/**
|
|
127
124
|
* Updates the first document matching the given filter with the provided update operations.
|
|
128
125
|
*
|
|
129
126
|
* @param filter The query filter to match documents against.
|
|
130
127
|
* @param update The update operations (e.g. `$set`) to apply.
|
|
128
|
+
* @param options - Optional settings for the command
|
|
131
129
|
*/
|
|
132
|
-
|
|
133
|
-
return this.collection.updateOne(filter, update);
|
|
130
|
+
updateOne(filter, update, options) {
|
|
131
|
+
return this.collection.updateOne(filter, update, options);
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
134
|
//# sourceMappingURL=MongoRepository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MongoRepository.js","sourceRoot":"","sources":["../../../src/database/MongoRepository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MongoRepository.js","sourceRoot":"","sources":["../../../src/database/MongoRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getIndexMetadata } from "../decorators/PersistenceDecorators.js";
|
|
2
|
-
import {
|
|
2
|
+
import { snakeCase } from "./NamingUtils.js";
|
|
3
3
|
/**
|
|
4
4
|
* Performs structure synchronization of MongoDB collections based on the persistence metadata of model classes.
|
|
5
5
|
*
|
|
@@ -18,6 +18,47 @@ export class MongoSchemaSync {
|
|
|
18
18
|
this.db = db;
|
|
19
19
|
this.logger = logger;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolves the entity info of the database collection (or table) that records of the given model class are stored in.
|
|
23
|
+
*
|
|
24
|
+
* The entity info is resolved using the following rules:
|
|
25
|
+
* 1. The nearest class in the inheritance chain (starting with `clazz` itself) that specifies an explicit
|
|
26
|
+
* entity info via the `@Entity(info)` decorator.
|
|
27
|
+
* 2. Otherwise, the most ancestral class in the inheritance chain that declares its own `@DataStore` binding.
|
|
28
|
+
* This ensures that `@ChildEntity` subclasses are stored in the same collection as their parent entity
|
|
29
|
+
* (single collection inheritance).
|
|
30
|
+
* 3. Otherwise, a new info object containing the snake_case form of the class name.
|
|
31
|
+
*
|
|
32
|
+
* @param clazz The model class to resolve the collection name for.
|
|
33
|
+
*/
|
|
34
|
+
resolveCollectionInfo(clazz) {
|
|
35
|
+
// Rule 1: nearest explicit entity options
|
|
36
|
+
for (let c = clazz; c && c !== Function.prototype; c = Object.getPrototypeOf(c)) {
|
|
37
|
+
const entityOptions = Reflect.getOwnMetadata("rrst:entityOptions", c);
|
|
38
|
+
if (entityOptions) {
|
|
39
|
+
const info = {
|
|
40
|
+
name: entityOptions.name,
|
|
41
|
+
classes: [],
|
|
42
|
+
};
|
|
43
|
+
if (entityOptions.collation) {
|
|
44
|
+
info.options = { collation: entityOptions.collation };
|
|
45
|
+
}
|
|
46
|
+
return info;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Rule 2: most ancestral class owning a datastore binding
|
|
50
|
+
let owner = undefined;
|
|
51
|
+
for (let c = clazz; c && c !== Function.prototype; c = Object.getPrototypeOf(c)) {
|
|
52
|
+
if (Reflect.getOwnMetadata("rrst:datastore", c)) {
|
|
53
|
+
owner = c;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Rule 3: fall back to the class itself
|
|
57
|
+
return {
|
|
58
|
+
name: snakeCase((owner ?? clazz).name),
|
|
59
|
+
classes: [],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
21
62
|
/**
|
|
22
63
|
* Synchronizes the structure of all collections associated with the given model classes.
|
|
23
64
|
*
|
|
@@ -28,28 +69,26 @@ export class MongoSchemaSync {
|
|
|
28
69
|
// collection (e.g. @ChildEntity subclasses) contribute their indexes to a single specification.
|
|
29
70
|
const collections = new Map();
|
|
30
71
|
for (const clazz of entities) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
collections.set(name, group);
|
|
72
|
+
const info = this.resolveCollectionInfo(clazz);
|
|
73
|
+
info.classes.push(clazz);
|
|
74
|
+
collections.set(info.name, info);
|
|
35
75
|
}
|
|
36
|
-
for (const [name,
|
|
37
|
-
await this.syncCollection(
|
|
76
|
+
for (const [name, info] of collections.entries()) {
|
|
77
|
+
await this.syncCollection(info);
|
|
38
78
|
}
|
|
39
79
|
}
|
|
40
80
|
/**
|
|
41
81
|
* Synchronizes the structure of a single collection.
|
|
42
82
|
*
|
|
43
|
-
* @param
|
|
44
|
-
* @param classes The list of model classes whose records are stored in the collection.
|
|
83
|
+
* @param info The information about the collection to synchronize.
|
|
45
84
|
*/
|
|
46
|
-
async syncCollection(
|
|
85
|
+
async syncCollection(info) {
|
|
47
86
|
// Create the collection if it doesn't already exist
|
|
48
|
-
const existing = await this.db.listCollections({ name }, { nameOnly: true }).toArray();
|
|
87
|
+
const existing = await this.db.listCollections({ name: info.name }, { nameOnly: true }).toArray();
|
|
49
88
|
if (existing.length === 0) {
|
|
50
89
|
try {
|
|
51
|
-
await this.db.createCollection(name);
|
|
52
|
-
this.logger?.debug(`Created collection: ${name}`);
|
|
90
|
+
await this.db.createCollection(info.name, info.options);
|
|
91
|
+
this.logger?.debug(`Created collection: ${info.name}`);
|
|
53
92
|
}
|
|
54
93
|
catch (err) {
|
|
55
94
|
// Tolerate concurrent creation races
|
|
@@ -59,15 +98,21 @@ export class MongoSchemaSync {
|
|
|
59
98
|
}
|
|
60
99
|
}
|
|
61
100
|
// Build the merged set of desired indexes from all classes stored in this collection
|
|
101
|
+
const entityCollation = info.options?.collation;
|
|
62
102
|
const desired = new Map();
|
|
63
|
-
for (const clazz of classes) {
|
|
103
|
+
for (const clazz of info.classes) {
|
|
64
104
|
for (const index of getIndexMetadata(clazz)) {
|
|
65
105
|
const spec = this.toDesiredIndex(index);
|
|
106
|
+
// Indexes inherit the collection's collation when none is declared on the index itself.
|
|
107
|
+
// This means @Entity({ collation }) is the single source of truth for case-sensitivity.
|
|
108
|
+
if (!spec.collation && entityCollation) {
|
|
109
|
+
spec.collation = entityCollation;
|
|
110
|
+
}
|
|
66
111
|
desired.set(JSON.stringify(spec.key), spec);
|
|
67
112
|
}
|
|
68
113
|
}
|
|
69
114
|
// Retrieve the collection's current indexes
|
|
70
|
-
const collection = this.db.collection(name);
|
|
115
|
+
const collection = this.db.collection(info.name);
|
|
71
116
|
let currentIndexes = [];
|
|
72
117
|
try {
|
|
73
118
|
currentIndexes = await collection.listIndexes().toArray();
|
|
@@ -85,25 +130,30 @@ export class MongoSchemaSync {
|
|
|
85
130
|
continue;
|
|
86
131
|
}
|
|
87
132
|
// The index definition has changed. Drop and re-create it.
|
|
88
|
-
this.logger?.debug(`Re-creating index ${current.name} on collection ${name} due to changed definition.`);
|
|
133
|
+
this.logger?.debug(`Re-creating index ${current.name} on collection ${info.name} due to changed definition.`);
|
|
89
134
|
await collection.dropIndex(current.name);
|
|
90
135
|
}
|
|
91
136
|
else {
|
|
92
137
|
// If an unrelated index already uses the desired name it must be dropped first to avoid a conflict
|
|
93
138
|
const conflict = currentIndexes.find((idx) => idx.name === spec.name);
|
|
94
139
|
if (conflict) {
|
|
95
|
-
this.logger?.debug(`Dropping index ${spec.name} on collection ${name} due to changed key.`);
|
|
140
|
+
this.logger?.debug(`Dropping index ${spec.name} on collection ${info.name} due to changed key.`);
|
|
96
141
|
await collection.dropIndex(spec.name);
|
|
97
142
|
}
|
|
98
|
-
this.logger?.debug(`Creating index ${spec.name} on collection ${name}.`);
|
|
143
|
+
this.logger?.debug(`Creating index ${spec.name} on collection ${info.name}.`);
|
|
99
144
|
}
|
|
100
|
-
|
|
145
|
+
const options = {
|
|
101
146
|
name: spec.name,
|
|
102
147
|
unique: spec.unique,
|
|
103
148
|
sparse: spec.sparse,
|
|
104
149
|
...(spec.background !== undefined ? { background: spec.background } : {}),
|
|
105
150
|
...(spec.expireAfterSeconds !== undefined ? { expireAfterSeconds: spec.expireAfterSeconds } : {}),
|
|
106
|
-
}
|
|
151
|
+
};
|
|
152
|
+
// HAX For some reason MongoDB chokes if you pass in `collation` with a value of `undefined`
|
|
153
|
+
if (spec.collation) {
|
|
154
|
+
options.collation = spec.collation;
|
|
155
|
+
}
|
|
156
|
+
await collection.createIndex(spec.key, options);
|
|
107
157
|
}
|
|
108
158
|
}
|
|
109
159
|
/**
|
|
@@ -121,16 +171,25 @@ export class MongoSchemaSync {
|
|
|
121
171
|
sparse: index.options.sparse ?? false,
|
|
122
172
|
background: index.options.background,
|
|
123
173
|
expireAfterSeconds: index.options.expireAfterSeconds,
|
|
174
|
+
collation: index.options.collation,
|
|
124
175
|
};
|
|
125
176
|
}
|
|
126
177
|
/**
|
|
127
178
|
* Determines whether an existing index satisfies the desired index specification. The `background` option is
|
|
128
179
|
* a build-time hint and is intentionally excluded from the comparison.
|
|
180
|
+
*
|
|
181
|
+
* Collation is compared by `locale` and `strength` only — MongoDB adds default values for all other fields
|
|
182
|
+
* when storing the index, which would cause spurious mismatches if we compared the full object.
|
|
129
183
|
*/
|
|
130
184
|
optionsMatch(spec, current) {
|
|
185
|
+
const collationMatches = spec.collation
|
|
186
|
+
? spec.collation.locale === current.collation?.locale &&
|
|
187
|
+
(spec.collation.strength ?? 3) === (current.collation?.strength ?? 3)
|
|
188
|
+
: !current.collation;
|
|
131
189
|
return (spec.unique === (current.unique ?? false) &&
|
|
132
190
|
spec.sparse === (current.sparse ?? false) &&
|
|
133
|
-
spec.expireAfterSeconds === (current.expireAfterSeconds ?? undefined)
|
|
191
|
+
spec.expireAfterSeconds === (current.expireAfterSeconds ?? undefined) &&
|
|
192
|
+
collationMatches);
|
|
134
193
|
}
|
|
135
194
|
}
|
|
136
195
|
//# sourceMappingURL=MongoSchemaSync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MongoSchemaSync.js","sourceRoot":"","sources":["../../../src/database/MongoSchemaSync.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"MongoSchemaSync.js","sourceRoot":"","sources":["../../../src/database/MongoSchemaSync.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ export function snakeCase(str) {
|
|
|
23
23
|
*
|
|
24
24
|
* The name is resolved using the following rules:
|
|
25
25
|
* 1. The nearest class in the inheritance chain (starting with `clazz` itself) that specifies an explicit
|
|
26
|
-
* entity name via the `@Entity(
|
|
26
|
+
* entity name via the `@Entity(options)` decorator.
|
|
27
27
|
* 2. Otherwise, the most ancestral class in the inheritance chain that declares its own `@DataStore` binding.
|
|
28
28
|
* This ensures that `@ChildEntity` subclasses are stored in the same collection as their parent entity
|
|
29
29
|
* (single collection inheritance).
|
|
@@ -34,9 +34,9 @@ export function snakeCase(str) {
|
|
|
34
34
|
export function resolveCollectionName(clazz) {
|
|
35
35
|
// Rule 1: nearest explicit entity name
|
|
36
36
|
for (let c = clazz; c && c !== Function.prototype; c = Object.getPrototypeOf(c)) {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
return
|
|
37
|
+
const options = Reflect.getOwnMetadata("rrst:entityOptions", c);
|
|
38
|
+
if (options && options.name) {
|
|
39
|
+
return options.name;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
// Rule 2: most ancestral class owning a datastore binding
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NamingUtils.js","sourceRoot":"","sources":["../../../src/database/NamingUtils.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"NamingUtils.js","sourceRoot":"","sources":["../../../src/database/NamingUtils.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,OAAO,kBAAkB,CAAC;AAG1B;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACjC,OAAO,CACH,GAAG;QACC,cAAc;SACb,OAAO,CAAC,wBAAwB,EAAE,SAAS,CAAC;QAC7C,YAAY;SACX,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,WAAW,EAAE,CACrB,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAU;IAC5C,uCAAuC;IACvC,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,OAAO,GAA8B,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;QAC3F,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,IAAI,CAAC;QACxB,CAAC;IACL,CAAC;IAED,0DAA0D;IAC1D,IAAI,KAAK,GAAQ,SAAS,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAI,OAAO,CAAC,cAAc,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC;YAC9C,KAAK,GAAG,CAAC,CAAC;QACd,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,OAAO,SAAS,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -102,18 +102,14 @@ export function Unique(nameOrFields, maybeFields) {
|
|
|
102
102
|
/**
|
|
103
103
|
* Indicates that the class describes an entity that is persisted to a datastore.
|
|
104
104
|
*
|
|
105
|
-
* @param
|
|
106
|
-
* form of the class name.
|
|
105
|
+
* @param options The options to set.
|
|
107
106
|
*/
|
|
108
|
-
export function Entity(
|
|
107
|
+
export function Entity(options) {
|
|
109
108
|
return function (target) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
writable: true,
|
|
115
|
-
value: entityName,
|
|
116
|
-
});
|
|
109
|
+
options = options ?? {};
|
|
110
|
+
options.name = options.name ?? snakeCase(target.name);
|
|
111
|
+
Reflect.defineMetadata("rrst:entityOptions", options, target);
|
|
112
|
+
Reflect.defineMetadata("rrst:entityName", options.name, target);
|
|
117
113
|
};
|
|
118
114
|
}
|
|
119
115
|
/**
|
|
@@ -144,18 +140,22 @@ export function getColumnMetadata(clazz) {
|
|
|
144
140
|
export function getIndexMetadata(clazz) {
|
|
145
141
|
const merged = new Map();
|
|
146
142
|
const identity = (idx) => idx.name ?? `cols:${idx.columns.join(",")}`;
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
143
|
+
// Walk from most-derived to most-ancestral. At each class level, process class-level indexes
|
|
144
|
+
// (CLASS_INDEXES_KEY) before property-level indexes (INDEXES_KEY) so that a subclass can
|
|
145
|
+
// shadow an ancestor's property-level index via a class-level @Index declaration.
|
|
146
|
+
let ctor = clazz;
|
|
147
|
+
let proto = clazz.prototype ?? clazz;
|
|
148
|
+
while (ctor && ctor !== Function.prototype && ctor !== Object.prototype) {
|
|
149
|
+
const classIdxs = Reflect.getOwnMetadata(CLASS_INDEXES_KEY, ctor) ?? [];
|
|
150
|
+
const propIdxs = Reflect.getOwnMetadata(INDEXES_KEY, proto) ?? [];
|
|
151
|
+
for (const index of [...classIdxs, ...propIdxs]) {
|
|
154
152
|
const key = identity(index);
|
|
155
153
|
if (!merged.has(key)) {
|
|
156
154
|
merged.set(key, index);
|
|
157
155
|
}
|
|
158
156
|
}
|
|
157
|
+
ctor = Object.getPrototypeOf(ctor);
|
|
158
|
+
proto = Object.getPrototypeOf(proto);
|
|
159
159
|
}
|
|
160
160
|
return Array.from(merged.values());
|
|
161
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersistenceDecorators.js","sourceRoot":"","sources":["../../../src/decorators/PersistenceDecorators.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"PersistenceDecorators.js","sourceRoot":"","sources":["../../../src/decorators/PersistenceDecorators.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
///////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
// Copyright (C) 2020-2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
12
12
|
///////////////////////////////////////////////////////////////////////////////
|
|
13
|
-
import { Column } from "../decorators/PersistenceDecorators.js";
|
|
13
|
+
import { Column, Index } from "../decorators/PersistenceDecorators.js";
|
|
14
14
|
import { BaseEntity } from "./BaseEntity.js";
|
|
15
15
|
import { ObjectId } from "mongodb";
|
|
16
16
|
import { ObjectDecorators } from "@rapidrest/core";
|
|
@@ -20,7 +20,9 @@ const { Nullable } = ObjectDecorators;
|
|
|
20
20
|
*
|
|
21
21
|
* @author Jean-Philippe Steinmetz <rapidrests@gmail.com>
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
// Shadow BaseEntity's unique uid index — MongoDB entities store version history (multiple docs per uid),
|
|
24
|
+
// so uniqueness is enforced at the application layer (optimistic locking) rather than via a unique index.
|
|
25
|
+
let BaseMongoEntity = class BaseMongoEntity extends BaseEntity {
|
|
24
26
|
constructor(other) {
|
|
25
27
|
super(other);
|
|
26
28
|
if (other) {
|
|
@@ -31,10 +33,15 @@ export class BaseMongoEntity extends BaseEntity {
|
|
|
31
33
|
: this._id;
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
|
-
}
|
|
36
|
+
};
|
|
35
37
|
__decorate([
|
|
36
38
|
Column({ isObjectId: true }),
|
|
37
39
|
Nullable,
|
|
38
40
|
__metadata("design:type", Object)
|
|
39
41
|
], BaseMongoEntity.prototype, "_id", void 0);
|
|
42
|
+
BaseMongoEntity = __decorate([
|
|
43
|
+
Index("uid", ["uid"]),
|
|
44
|
+
__metadata("design:paramtypes", [Object])
|
|
45
|
+
], BaseMongoEntity);
|
|
46
|
+
export { BaseMongoEntity };
|
|
40
47
|
//# sourceMappingURL=BaseMongoEntity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseMongoEntity.js","sourceRoot":"","sources":["../../../src/models/BaseMongoEntity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseMongoEntity.js","sourceRoot":"","sources":["../../../src/models/BaseMongoEntity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CAAC;AAEtC;;;;GAIG;AACH,yGAAyG;AACzG,0GAA0G;AAEnG,IAAe,eAAe,GAA9B,MAAe,eAAgB,SAAQ,UAAU;IAQpD,YAAY,KAAgC;QACxC,KAAK,CAAC,KAAK,CAAC,CAAC;QAEb,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG;gBAChB,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;oBAC5D,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACjC,CAAC,CAAC,KAAK,CAAC,GAAG;gBACf,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACnB,CAAC;IACL,CAAC;CACJ,CAAA;AAbU;IAFN,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC5B,QAAQ;;4CACQ;AANC,eAAe;IADpC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;;GACA,eAAe,CAmBpC"}
|
|
@@ -64,15 +64,14 @@ export class ModelUtils {
|
|
|
64
64
|
* @param modelClass The class definition of the data model to build a search query for.
|
|
65
65
|
* @param id The unique identifier to search for.
|
|
66
66
|
* @param version The version number of the document to search for.
|
|
67
|
-
* @param productUid The optional product uid that is associated with the uid (when a compound key is used).
|
|
68
67
|
* @returns An object that can be passed to a TypeORM `find` function.
|
|
69
68
|
*/
|
|
70
|
-
static buildIdSearchQuery(repo, modelClass, id, version
|
|
69
|
+
static buildIdSearchQuery(repo, modelClass, id, version) {
|
|
71
70
|
if (repo instanceof MongoRepository) {
|
|
72
|
-
return ModelUtils.buildIdSearchQueryMongo(modelClass, id, version
|
|
71
|
+
return ModelUtils.buildIdSearchQueryMongo(modelClass, id, version);
|
|
73
72
|
}
|
|
74
73
|
else {
|
|
75
|
-
return ModelUtils.buildIdSearchQuerySQL(modelClass, id, version
|
|
74
|
+
return ModelUtils.buildIdSearchQuerySQL(modelClass, id, version);
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
/**
|
|
@@ -82,22 +81,15 @@ export class ModelUtils {
|
|
|
82
81
|
* @param modelClass The class definition of the data model to build a search query for.
|
|
83
82
|
* @param id The unique identifier to search for.
|
|
84
83
|
* @param version The version number of the document to search for.
|
|
85
|
-
* @param productUid The optional product uid that is associated with the uid (when a compound key is used).
|
|
86
84
|
* @returns An object that can be passed to a TypeORM `find` function.
|
|
87
85
|
*/
|
|
88
|
-
static buildIdSearchQuerySQL(modelClass, id, version
|
|
86
|
+
static buildIdSearchQuerySQL(modelClass, id, version) {
|
|
89
87
|
const props = ModelUtils.getIdPropertyNames(modelClass);
|
|
90
88
|
// Create the where in SQL syntax. We only care about one of the identifier field's matching.
|
|
91
89
|
// e.g. WHERE idField1 = :idField1 OR idField2 = :idField2 ...
|
|
92
90
|
const where = [];
|
|
93
91
|
for (const prop of props) {
|
|
94
|
-
// If productUid is an id, skip it because it's used as a compound key
|
|
95
|
-
if (prop === "productUid")
|
|
96
|
-
continue;
|
|
97
92
|
const q = { [prop]: Array.isArray(id) ? ModelUtils.orm.In(id) : id };
|
|
98
|
-
if (props.includes("productUid")) {
|
|
99
|
-
q.productUid = productUid;
|
|
100
|
-
}
|
|
101
93
|
if (version !== undefined) {
|
|
102
94
|
q.version = version;
|
|
103
95
|
}
|
|
@@ -112,33 +104,28 @@ export class ModelUtils {
|
|
|
112
104
|
* @param modelClass The class definition of the data model to build a search query for.
|
|
113
105
|
* @param id The unique identifier to search for.
|
|
114
106
|
* @param version The version number of the document to search for.
|
|
115
|
-
* @param productUid The optional product uid that is associated with the uid (when a compound key is used).
|
|
116
107
|
* @returns An object that can be passed to a MongoDB `find` function.
|
|
117
108
|
*/
|
|
118
|
-
static buildIdSearchQueryMongo(modelClass, id, version
|
|
109
|
+
static buildIdSearchQueryMongo(modelClass, id, version) {
|
|
119
110
|
const props = ModelUtils.getIdPropertyNames(modelClass);
|
|
120
|
-
// We want to performa case-insensitive search.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
//
|
|
132
|
-
//
|
|
111
|
+
// We want to performa case-insensitive search. We used to convert strings to RegEx but this is _very_
|
|
112
|
+
// slow. Instead, we use case-insenstive indexes that are configured using the `collation` option. Now
|
|
113
|
+
// we only need to pass in the raw string. So we skip this section but we retain the code for historical
|
|
114
|
+
// reasons.
|
|
115
|
+
// See: https://www.mongodb.com/docs/v7.0/core/index-case-insensitive/
|
|
116
|
+
// if (Array.isArray(id)) {
|
|
117
|
+
// for (let i = 0; i < id.length; i++) {
|
|
118
|
+
// if (typeof id[i] === "string") {
|
|
119
|
+
// id[i] = new RegExp("^" + id[i].replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "$", "i");
|
|
120
|
+
// }
|
|
121
|
+
// }
|
|
122
|
+
// } else if (typeof id === "string") {
|
|
123
|
+
// id = new RegExp("^" + id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "$", "i");
|
|
124
|
+
// }
|
|
125
|
+
// Create the where in Mongo filter syntax. We only care about one of the identifier field's matching.
|
|
133
126
|
const query = [];
|
|
134
127
|
for (const prop of props) {
|
|
135
|
-
// If productUid is an id, skip it because it's used as a compound key
|
|
136
|
-
if (prop === "productUid")
|
|
137
|
-
continue;
|
|
138
128
|
const q = { [prop]: Array.isArray(id) ? { $in: id } : id };
|
|
139
|
-
if (productUid && props.includes("productUid")) {
|
|
140
|
-
q.productUid = productUid;
|
|
141
|
-
}
|
|
142
129
|
if (version !== undefined) {
|
|
143
130
|
q.version = version;
|
|
144
131
|
}
|
|
@@ -573,7 +560,9 @@ export class ModelUtils {
|
|
|
573
560
|
let orResults = [];
|
|
574
561
|
for (const query of queryParams[key]) {
|
|
575
562
|
const subQueryOrResult = this.buildSearchQueryMongo(modelClass, undefined, query, exactMatch, user);
|
|
576
|
-
const validSubQueryResult = subQueryOrResult && subQueryOrResult.length > 0
|
|
563
|
+
const validSubQueryResult = Array.isArray(subQueryOrResult) && subQueryOrResult.length > 0
|
|
564
|
+
? subQueryOrResult[0]["$match"]
|
|
565
|
+
: subQueryOrResult["$match"];
|
|
577
566
|
validSubQueryResult && orResults.push(validSubQueryResult);
|
|
578
567
|
}
|
|
579
568
|
queries[0] = { $or: orResults };
|
|
@@ -614,6 +603,14 @@ export class ModelUtils {
|
|
|
614
603
|
if (sort && !isEmpty(sort)) {
|
|
615
604
|
result.push({ $sort: sort });
|
|
616
605
|
}
|
|
606
|
+
// If this is a simple query (e.g. only $match and $sort) then we want to extract this query so that
|
|
607
|
+
// we don't run it as an aggregate pipeline.
|
|
608
|
+
if (result.length < 3) {
|
|
609
|
+
return {
|
|
610
|
+
...result[0],
|
|
611
|
+
...result[1],
|
|
612
|
+
};
|
|
613
|
+
}
|
|
617
614
|
return result;
|
|
618
615
|
}
|
|
619
616
|
/**
|