@rapidrest/service-core 1.0.0-beta.6 → 1.0.0-rc.10
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 +49 -42
- 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 +108 -59
- 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/AdminRoute.js +6 -0
- package/dist/lib/routes/AdminRoute.js.map +1 -1
- package/dist/lib/routes/ModelRoute.js +1 -11
- package/dist/lib/routes/ModelRoute.js.map +1 -1
- package/dist/lib/routes/StatusRoute.js +10 -6
- package/dist/lib/routes/StatusRoute.js.map +1 -1
- package/dist/lib/security/ACLUtils.js +3 -6
- package/dist/lib/security/ACLUtils.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 +5 -7
- package/dist/types/models/RepoUtils.d.ts +1 -7
- package/dist/types/routes/ModelRoute.d.ts +15 -19
- package/dist/types/routes/StatusRoute.d.ts +2 -1
- 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 +18 -18
- package/docs/reference/classes/AdminRoute.md +7 -7
- 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 +60 -60
- package/docs/reference/classes/ModelUtils.md +29 -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"}
|