mongodb-dynamic-api 4.7.0 → 4.9.0

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.
Files changed (123) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -0
  3. package/package.json +2 -1
  4. package/src/guards/base-policies.guard.d.ts +3 -1
  5. package/src/guards/base-policies.guard.js +2 -2
  6. package/src/guards/base-policies.guard.js.map +1 -1
  7. package/src/helpers/mixin-data.helper.d.ts +3 -2
  8. package/src/helpers/mixin-data.helper.js +2 -1
  9. package/src/helpers/mixin-data.helper.js.map +1 -1
  10. package/src/index.d.ts +2 -0
  11. package/src/index.js +2 -0
  12. package/src/index.js.map +1 -1
  13. package/src/interfaces/dynamic-api-ability.interface.d.ts +2 -1
  14. package/src/interfaces/dynamic-api-cascade-config.interface.d.ts +9 -0
  15. package/src/interfaces/dynamic-api-cascade-config.interface.js +3 -0
  16. package/src/interfaces/dynamic-api-cascade-config.interface.js.map +1 -0
  17. package/src/interfaces/dynamic-api-presence.interface.d.ts +22 -0
  18. package/src/interfaces/dynamic-api-presence.interface.js +6 -0
  19. package/src/interfaces/dynamic-api-presence.interface.js.map +1 -0
  20. package/src/interfaces/dynamic-api-route-config.interface.d.ts +6 -2
  21. package/src/interfaces/dynamic-api-service-before-save-callback.interface.d.ts +4 -1
  22. package/src/interfaces/dynamic-api-service-callback.interface.d.ts +26 -1
  23. package/src/interfaces/index.d.ts +2 -0
  24. package/src/interfaces/index.js +2 -0
  25. package/src/interfaces/index.js.map +1 -1
  26. package/src/mixins/policies-guard.mixin.d.ts +9 -3
  27. package/src/mixins/policies-guard.mixin.js +5 -2
  28. package/src/mixins/policies-guard.mixin.js.map +1 -1
  29. package/src/modules/presence/adapters/in-memory-presence.adapter.d.ts +10 -0
  30. package/src/modules/presence/adapters/in-memory-presence.adapter.js +64 -0
  31. package/src/modules/presence/adapters/in-memory-presence.adapter.js.map +1 -0
  32. package/src/modules/presence/adapters/redis-presence.adapter.d.ts +17 -0
  33. package/src/modules/presence/adapters/redis-presence.adapter.js +80 -0
  34. package/src/modules/presence/adapters/redis-presence.adapter.js.map +1 -0
  35. package/src/modules/presence/index.d.ts +5 -0
  36. package/src/modules/presence/index.js +22 -0
  37. package/src/modules/presence/index.js.map +1 -0
  38. package/src/modules/presence/presence.controller.d.ts +6 -0
  39. package/src/modules/presence/presence.controller.js +55 -0
  40. package/src/modules/presence/presence.controller.js.map +1 -0
  41. package/src/modules/presence/presence.gateway.d.ts +13 -0
  42. package/src/modules/presence/presence.gateway.js +79 -0
  43. package/src/modules/presence/presence.gateway.js.map +1 -0
  44. package/src/modules/presence/presence.module.d.ts +5 -0
  45. package/src/modules/presence/presence.module.js +50 -0
  46. package/src/modules/presence/presence.module.js.map +1 -0
  47. package/src/routes/aggregate/aggregate-controller.mixin.js +2 -2
  48. package/src/routes/aggregate/aggregate-controller.mixin.js.map +1 -1
  49. package/src/routes/aggregate/aggregate-gateway.mixin.js +2 -2
  50. package/src/routes/aggregate/aggregate-gateway.mixin.js.map +1 -1
  51. package/src/routes/aggregate/aggregate.helper.d.ts +2 -2
  52. package/src/routes/aggregate/aggregate.helper.js +3 -1
  53. package/src/routes/aggregate/aggregate.helper.js.map +1 -1
  54. package/src/routes/aggregate/aggregate.module.js +1 -1
  55. package/src/routes/aggregate/aggregate.module.js.map +1 -1
  56. package/src/routes/aggregate/base-aggregate.service.d.ts +3 -1
  57. package/src/routes/aggregate/base-aggregate.service.js +6 -1
  58. package/src/routes/aggregate/base-aggregate.service.js.map +1 -1
  59. package/src/routes/create-many/create-many-gateway.mixin.js +1 -1
  60. package/src/routes/create-many/create-many-gateway.mixin.js.map +1 -1
  61. package/src/routes/create-one/create-one-gateway.mixin.js +1 -1
  62. package/src/routes/create-one/create-one-gateway.mixin.js.map +1 -1
  63. package/src/routes/delete-many/base-delete-many.service.d.ts +3 -1
  64. package/src/routes/delete-many/base-delete-many.service.js +22 -9
  65. package/src/routes/delete-many/base-delete-many.service.js.map +1 -1
  66. package/src/routes/delete-many/delete-many-gateway.mixin.js +1 -1
  67. package/src/routes/delete-many/delete-many-gateway.mixin.js.map +1 -1
  68. package/src/routes/delete-many/delete-many.helper.d.ts +2 -2
  69. package/src/routes/delete-many/delete-many.helper.js +3 -1
  70. package/src/routes/delete-many/delete-many.helper.js.map +1 -1
  71. package/src/routes/delete-many/delete-many.module.js +1 -1
  72. package/src/routes/delete-many/delete-many.module.js.map +1 -1
  73. package/src/routes/delete-one/base-delete-one.service.d.ts +4 -1
  74. package/src/routes/delete-one/base-delete-one.service.js +30 -9
  75. package/src/routes/delete-one/base-delete-one.service.js.map +1 -1
  76. package/src/routes/delete-one/delete-one-gateway.mixin.js +1 -1
  77. package/src/routes/delete-one/delete-one-gateway.mixin.js.map +1 -1
  78. package/src/routes/delete-one/delete-one.helper.d.ts +2 -2
  79. package/src/routes/delete-one/delete-one.helper.js +3 -1
  80. package/src/routes/delete-one/delete-one.helper.js.map +1 -1
  81. package/src/routes/delete-one/delete-one.module.js +1 -1
  82. package/src/routes/delete-one/delete-one.module.js.map +1 -1
  83. package/src/routes/duplicate-many/duplicate-many-gateway.mixin.js +1 -1
  84. package/src/routes/duplicate-many/duplicate-many-gateway.mixin.js.map +1 -1
  85. package/src/routes/duplicate-one/duplicate-one-gateway.mixin.js +1 -1
  86. package/src/routes/duplicate-one/duplicate-one-gateway.mixin.js.map +1 -1
  87. package/src/routes/get-many/base-get-many.service.d.ts +3 -1
  88. package/src/routes/get-many/base-get-many.service.js +5 -1
  89. package/src/routes/get-many/base-get-many.service.js.map +1 -1
  90. package/src/routes/get-many/get-many-controller.mixin.js +2 -2
  91. package/src/routes/get-many/get-many-controller.mixin.js.map +1 -1
  92. package/src/routes/get-many/get-many-gateway.mixin.js +2 -2
  93. package/src/routes/get-many/get-many-gateway.mixin.js.map +1 -1
  94. package/src/routes/get-many/get-many.helper.d.ts +2 -2
  95. package/src/routes/get-many/get-many.helper.js +3 -1
  96. package/src/routes/get-many/get-many.helper.js.map +1 -1
  97. package/src/routes/get-many/get-many.module.js +1 -1
  98. package/src/routes/get-many/get-many.module.js.map +1 -1
  99. package/src/routes/get-one/get-one-gateway.mixin.js +1 -1
  100. package/src/routes/get-one/get-one-gateway.mixin.js.map +1 -1
  101. package/src/routes/replace-one/replace-one-gateway.mixin.js +1 -1
  102. package/src/routes/replace-one/replace-one-gateway.mixin.js.map +1 -1
  103. package/src/routes/update-many/update-many-gateway.mixin.js +1 -1
  104. package/src/routes/update-many/update-many-gateway.mixin.js.map +1 -1
  105. package/src/routes/update-one/update-one-gateway.mixin.js +1 -1
  106. package/src/routes/update-one/update-one-gateway.mixin.js.map +1 -1
  107. package/src/services/base/base.service.d.ts +5 -1
  108. package/src/services/base/base.service.js +36 -0
  109. package/src/services/base/base.service.js.map +1 -1
  110. package/src/version.json +1 -1
  111. package/test/for-feature/ability-predicate-filter.e2e-spec.d.ts +1 -0
  112. package/test/for-feature/ability-predicate-filter.e2e-spec.js +106 -0
  113. package/test/for-feature/ability-predicate-filter.e2e-spec.js.map +1 -0
  114. package/test/for-feature/cascade-and-before-delete.e2e-spec.d.ts +1 -0
  115. package/test/for-feature/cascade-and-before-delete.e2e-spec.js +304 -0
  116. package/test/for-feature/cascade-and-before-delete.e2e-spec.js.map +1 -0
  117. package/test/for-feature/presence.e2e-spec.d.ts +1 -0
  118. package/test/for-feature/presence.e2e-spec.js +169 -0
  119. package/test/for-feature/presence.e2e-spec.js.map +1 -0
  120. package/test/for-feature/raw-update-callback-methods.e2e-spec.d.ts +1 -0
  121. package/test/for-feature/raw-update-callback-methods.e2e-spec.js +263 -0
  122. package/test/for-feature/raw-update-callback-methods.e2e-spec.js.map +1 -0
  123. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const common_1 = require("@nestjs/common");
13
+ const mongoose_1 = require("@nestjs/mongoose");
14
+ const mongoose_2 = require("mongoose");
15
+ const src_1 = require("../../src");
16
+ const e2e_setup_1 = require("../e2e.setup");
17
+ const shared_1 = require("../shared");
18
+ const utils_1 = require("../utils");
19
+ require("dotenv/config");
20
+ let PostEntity = class PostEntity extends src_1.BaseEntity {
21
+ };
22
+ __decorate([
23
+ (0, mongoose_1.Prop)({ type: String, required: true }),
24
+ __metadata("design:type", String)
25
+ ], PostEntity.prototype, "title", void 0);
26
+ PostEntity = __decorate([
27
+ (0, mongoose_1.Schema)({ collection: 'e2e-posts' })
28
+ ], PostEntity);
29
+ let SoftPostEntity = class SoftPostEntity extends src_1.SoftDeletableEntity {
30
+ };
31
+ __decorate([
32
+ (0, mongoose_1.Prop)({ type: String, required: true }),
33
+ __metadata("design:type", String)
34
+ ], SoftPostEntity.prototype, "title", void 0);
35
+ SoftPostEntity = __decorate([
36
+ (0, mongoose_1.Schema)({ collection: 'e2e-soft-posts' })
37
+ ], SoftPostEntity);
38
+ let CommentEntity = class CommentEntity extends src_1.BaseEntity {
39
+ };
40
+ __decorate([
41
+ (0, mongoose_1.Prop)({ type: String, required: true }),
42
+ __metadata("design:type", String)
43
+ ], CommentEntity.prototype, "postId", void 0);
44
+ __decorate([
45
+ (0, mongoose_1.Prop)({ type: String, required: true }),
46
+ __metadata("design:type", String)
47
+ ], CommentEntity.prototype, "body", void 0);
48
+ CommentEntity = __decorate([
49
+ (0, mongoose_1.Schema)({ collection: 'e2e-comments' })
50
+ ], CommentEntity);
51
+ let SoftCommentEntity = class SoftCommentEntity extends src_1.SoftDeletableEntity {
52
+ };
53
+ __decorate([
54
+ (0, mongoose_1.Prop)({ type: String, required: true }),
55
+ __metadata("design:type", String)
56
+ ], SoftCommentEntity.prototype, "postId", void 0);
57
+ __decorate([
58
+ (0, mongoose_1.Prop)({ type: String, required: true }),
59
+ __metadata("design:type", String)
60
+ ], SoftCommentEntity.prototype, "body", void 0);
61
+ SoftCommentEntity = __decorate([
62
+ (0, mongoose_1.Schema)({ collection: 'e2e-soft-comments' })
63
+ ], SoftCommentEntity);
64
+ describe('DynamicApiModule forFeature - cascade & beforeDeleteCallback (e2e)', () => {
65
+ beforeEach(() => {
66
+ src_1.DynamicApiModule.state['resetState']();
67
+ });
68
+ afterEach(async () => {
69
+ await (0, e2e_setup_1.closeTestingApp)(mongoose_2.default.connections);
70
+ });
71
+ describe('beforeDeleteCallback on DeleteOne — throws => HTTP 4xx, parent preserved', () => {
72
+ let postId;
73
+ const blockingBeforeDelete = async (_entity, _context, _methods) => {
74
+ throw new common_1.BadRequestException('deletion blocked by beforeDeleteCallback');
75
+ };
76
+ beforeEach(async () => {
77
+ await (0, shared_1.initApp)({
78
+ entity: PostEntity,
79
+ controllerOptions: { path: 'posts' },
80
+ routes: [
81
+ { type: 'CreateOne' },
82
+ { type: 'GetMany' },
83
+ { type: 'DeleteOne', beforeDeleteCallback: blockingBeforeDelete },
84
+ ],
85
+ }, {}, async (_) => {
86
+ const model = await (0, utils_1.getModelFromEntity)(PostEntity);
87
+ const [inserted] = await model.insertMany([{ title: 'post-1' }]);
88
+ postId = inserted._id.toString();
89
+ });
90
+ });
91
+ it('should return 400 and leave the document in the database', async () => {
92
+ const { status } = await e2e_setup_1.server.delete(`/posts/${postId}`);
93
+ expect(status).toBe(400);
94
+ const { body, status: getStatus } = await e2e_setup_1.server.get('/posts');
95
+ expect(getStatus).toBe(200);
96
+ expect(body).toHaveLength(1);
97
+ });
98
+ });
99
+ describe('beforeDeleteCallback on DeleteMany — throws => HTTP 4xx, parents preserved', () => {
100
+ let ids;
101
+ const blockingBeforeDeleteMany = async (_entities, _context, _methods) => {
102
+ throw new common_1.BadRequestException('bulk deletion blocked');
103
+ };
104
+ beforeEach(async () => {
105
+ await (0, shared_1.initApp)({
106
+ entity: PostEntity,
107
+ controllerOptions: { path: 'posts' },
108
+ routes: [
109
+ { type: 'CreateOne' },
110
+ { type: 'GetMany' },
111
+ { type: 'DeleteMany', beforeDeleteCallback: blockingBeforeDeleteMany },
112
+ ],
113
+ }, {}, async (_) => {
114
+ const model = await (0, utils_1.getModelFromEntity)(PostEntity);
115
+ const docs = await model.insertMany([{ title: 'a' }, { title: 'b' }]);
116
+ ids = docs.map((d) => d._id.toString());
117
+ });
118
+ });
119
+ it('should return 400 and leave all documents in the database', async () => {
120
+ const { status } = await e2e_setup_1.server.delete('/posts', { query: { ids } });
121
+ expect(status).toBe(400);
122
+ const { body } = await e2e_setup_1.server.get('/posts');
123
+ expect(body).toHaveLength(2);
124
+ });
125
+ });
126
+ describe('beforeSaveCallback on DeleteOne — throws => HTTP 4xx (fix: no longer swallowed)', () => {
127
+ let postId;
128
+ const blockingBeforeSave = async (_entity, _context, _methods) => {
129
+ throw new common_1.BadRequestException('blocked by beforeSaveCallback');
130
+ };
131
+ beforeEach(async () => {
132
+ await (0, shared_1.initApp)({
133
+ entity: PostEntity,
134
+ controllerOptions: { path: 'posts' },
135
+ routes: [
136
+ { type: 'GetMany' },
137
+ { type: 'DeleteOne', beforeSaveCallback: blockingBeforeSave },
138
+ ],
139
+ }, {}, async (_) => {
140
+ const model = await (0, utils_1.getModelFromEntity)(PostEntity);
141
+ const [inserted] = await model.insertMany([{ title: 'to-survive' }]);
142
+ postId = inserted._id.toString();
143
+ });
144
+ });
145
+ it('should return 400 and not delete the document', async () => {
146
+ const { status } = await e2e_setup_1.server.delete(`/posts/${postId}`);
147
+ expect(status).toBe(400);
148
+ const { body } = await e2e_setup_1.server.get('/posts');
149
+ expect(body).toHaveLength(1);
150
+ });
151
+ });
152
+ describe('cascade on DeleteOne — hard-deletes child documents', () => {
153
+ let postId;
154
+ const cascade = [
155
+ { entity: CommentEntity, foreignKey: 'postId', on: 'delete' },
156
+ ];
157
+ beforeEach(async () => {
158
+ await (0, shared_1.initApp)({
159
+ entity: PostEntity,
160
+ controllerOptions: { path: 'posts' },
161
+ routes: [
162
+ { type: 'GetMany' },
163
+ { type: 'DeleteOne', cascade },
164
+ ],
165
+ extraImports: [
166
+ src_1.DynamicApiModule.forFeature({ entity: CommentEntity, controllerOptions: { path: 'comments' }, routes: [] }),
167
+ ],
168
+ }, {}, async (_) => {
169
+ const postModel = await (0, utils_1.getModelFromEntity)(PostEntity);
170
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
171
+ const [post] = await postModel.insertMany([{ title: 'parent' }]);
172
+ postId = post._id.toString();
173
+ await commentModel.insertMany([
174
+ { postId, body: 'comment-1' },
175
+ { postId, body: 'comment-2' },
176
+ ]);
177
+ });
178
+ });
179
+ it('should delete the post and cascade-delete its comments', async () => {
180
+ const { status, body } = await e2e_setup_1.server.delete(`/posts/${postId}`);
181
+ expect(status).toBe(200);
182
+ expect(body).toMatchObject({ deletedCount: 1 });
183
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
184
+ const remaining = await commentModel.find({ postId }).lean().exec();
185
+ expect(remaining).toHaveLength(0);
186
+ });
187
+ it('should NOT cascade if the parent was not found (deletedCount = 0)', async () => {
188
+ const nonExistentId = new mongoose_2.default.Types.ObjectId().toString();
189
+ const { status } = await e2e_setup_1.server.delete(`/posts/${nonExistentId}`);
190
+ expect(status).toBe(200);
191
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
192
+ const remaining = await commentModel.find({ postId }).lean().exec();
193
+ expect(remaining).toHaveLength(2);
194
+ });
195
+ });
196
+ describe('cascade on DeleteMany — hard-deletes children for all parents', () => {
197
+ let postIds;
198
+ const cascade = [
199
+ { entity: CommentEntity, foreignKey: 'postId', on: 'delete' },
200
+ ];
201
+ beforeEach(async () => {
202
+ await (0, shared_1.initApp)({
203
+ entity: PostEntity,
204
+ controllerOptions: { path: 'posts' },
205
+ routes: [
206
+ { type: 'GetMany' },
207
+ { type: 'DeleteMany', cascade },
208
+ ],
209
+ extraImports: [
210
+ src_1.DynamicApiModule.forFeature({ entity: CommentEntity, controllerOptions: { path: 'comments' }, routes: [] }),
211
+ ],
212
+ }, {}, async (_) => {
213
+ const postModel = await (0, utils_1.getModelFromEntity)(PostEntity);
214
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
215
+ const posts = await postModel.insertMany([{ title: 'p1' }, { title: 'p2' }]);
216
+ postIds = posts.map((p) => p._id.toString());
217
+ await commentModel.insertMany([
218
+ { postId: postIds[0], body: 'c1' },
219
+ { postId: postIds[0], body: 'c2' },
220
+ { postId: postIds[1], body: 'c3' },
221
+ ]);
222
+ });
223
+ });
224
+ it('should delete all posts and cascade-delete their comments', async () => {
225
+ const { status, body } = await e2e_setup_1.server.delete('/posts', { query: { ids: postIds } });
226
+ expect(status).toBe(200);
227
+ expect(body).toMatchObject({ deletedCount: 2 });
228
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
229
+ const remaining = await commentModel.find({ postId: { $in: postIds } }).lean().exec();
230
+ expect(remaining).toHaveLength(0);
231
+ });
232
+ });
233
+ describe('cascade on DeleteOne soft-deletable — soft-deletes child documents', () => {
234
+ let postId;
235
+ const cascade = [
236
+ { entity: SoftCommentEntity, foreignKey: 'postId', on: 'softDelete' },
237
+ ];
238
+ beforeEach(async () => {
239
+ await (0, shared_1.initApp)({
240
+ entity: SoftPostEntity,
241
+ controllerOptions: { path: 'soft-posts' },
242
+ routes: [
243
+ { type: 'GetMany' },
244
+ { type: 'DeleteOne', cascade },
245
+ ],
246
+ extraImports: [
247
+ src_1.DynamicApiModule.forFeature({ entity: SoftCommentEntity, controllerOptions: { path: 'soft-comments' }, routes: [] }),
248
+ ],
249
+ }, {}, async (_) => {
250
+ const postModel = await (0, utils_1.getModelFromEntity)(SoftPostEntity);
251
+ const commentModel = await (0, utils_1.getModelFromEntity)(SoftCommentEntity);
252
+ const [post] = await postModel.insertMany([{ title: 'soft-parent' }]);
253
+ postId = post._id.toString();
254
+ await commentModel.insertMany([
255
+ { postId, body: 'sc1' },
256
+ { postId, body: 'sc2' },
257
+ ]);
258
+ });
259
+ });
260
+ it('should soft-delete the post and soft-delete its comments via cascade', async () => {
261
+ const { status, body } = await e2e_setup_1.server.delete(`/soft-posts/${postId}`);
262
+ expect(status).toBe(200);
263
+ expect(body).toMatchObject({ deletedCount: 1 });
264
+ const commentModel = await (0, utils_1.getModelFromEntity)(SoftCommentEntity);
265
+ const remaining = await commentModel.find({ postId, isDeleted: false }).lean().exec();
266
+ expect(remaining).toHaveLength(0);
267
+ const softDeleted = await commentModel.find({ postId, isDeleted: true }).lean().exec();
268
+ expect(softDeleted).toHaveLength(2);
269
+ });
270
+ });
271
+ describe('cascade on: delete NOT triggered when parent is soft-deletable', () => {
272
+ let postId;
273
+ const cascade = [
274
+ { entity: CommentEntity, foreignKey: 'postId', on: 'delete' },
275
+ ];
276
+ beforeEach(async () => {
277
+ await (0, shared_1.initApp)({
278
+ entity: SoftPostEntity,
279
+ controllerOptions: { path: 'soft-posts' },
280
+ routes: [
281
+ { type: 'GetMany' },
282
+ { type: 'DeleteOne', cascade },
283
+ ],
284
+ extraImports: [
285
+ src_1.DynamicApiModule.forFeature({ entity: CommentEntity, controllerOptions: { path: 'comments' }, routes: [] }),
286
+ ],
287
+ }, {}, async (_) => {
288
+ const postModel = await (0, utils_1.getModelFromEntity)(SoftPostEntity);
289
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
290
+ const [post] = await postModel.insertMany([{ title: 'soft-parent' }]);
291
+ postId = post._id.toString();
292
+ await commentModel.insertMany([{ postId, body: 'should-survive' }]);
293
+ });
294
+ });
295
+ it('should soft-delete the post but leave comments untouched', async () => {
296
+ const { status } = await e2e_setup_1.server.delete(`/soft-posts/${postId}`);
297
+ expect(status).toBe(200);
298
+ const commentModel = await (0, utils_1.getModelFromEntity)(CommentEntity);
299
+ const remaining = await commentModel.find({ postId }).lean().exec();
300
+ expect(remaining).toHaveLength(1);
301
+ });
302
+ });
303
+ });
304
+ //# sourceMappingURL=cascade-and-before-delete.e2e-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-and-before-delete.e2e-spec.js","sourceRoot":"","sources":["../../../libs/dynamic-api/test/for-feature/cascade-and-before-delete.e2e-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const mongoose_1 = require("@nestjs/mongoose");
13
+ const testing_1 = require("@nestjs/testing");
14
+ const socket_io_client_1 = require("socket.io-client");
15
+ const mongoose_2 = require("mongoose");
16
+ require("dotenv/config");
17
+ const src_1 = require("../../src");
18
+ const e2e_setup_1 = require("../e2e.setup");
19
+ let PresenceUserEntity = class PresenceUserEntity extends src_1.BaseEntity {
20
+ };
21
+ __decorate([
22
+ (0, mongoose_1.Prop)({ type: String, required: true }),
23
+ __metadata("design:type", String)
24
+ ], PresenceUserEntity.prototype, "email", void 0);
25
+ __decorate([
26
+ (0, mongoose_1.Prop)({ type: String, required: true }),
27
+ __metadata("design:type", String)
28
+ ], PresenceUserEntity.prototype, "password", void 0);
29
+ PresenceUserEntity = __decorate([
30
+ (0, mongoose_1.Schema)({ collection: 'presence-users' })
31
+ ], PresenceUserEntity);
32
+ const DEFAULT_TIMEOUT_MS = 6000;
33
+ async function connectSocket(baseUrl, accessToken) {
34
+ return new Promise((resolve, reject) => {
35
+ const socket = (0, socket_io_client_1.io)(baseUrl, {
36
+ query: accessToken ? { accessToken } : {},
37
+ reconnection: false,
38
+ });
39
+ const timeout = setTimeout(() => {
40
+ socket.close();
41
+ reject(new Error('Socket connection timed out'));
42
+ }, DEFAULT_TIMEOUT_MS);
43
+ socket.once('connect', () => {
44
+ clearTimeout(timeout);
45
+ resolve(socket);
46
+ });
47
+ socket.once('connect_error', (err) => {
48
+ clearTimeout(timeout);
49
+ reject(err);
50
+ });
51
+ });
52
+ }
53
+ function waitForEvent(socket, event, timeoutMs = DEFAULT_TIMEOUT_MS) {
54
+ return new Promise((resolve, reject) => {
55
+ const timeout = setTimeout(() => reject(new Error(`Timeout waiting for "${event}" after ${timeoutMs}ms`)), timeoutMs);
56
+ socket.once(event, (data) => {
57
+ clearTimeout(timeout);
58
+ resolve(data);
59
+ });
60
+ });
61
+ }
62
+ const delay = (ms) => new Promise((r) => setTimeout(r, ms));
63
+ describe('DynamicApiPresenceModule (e2e)', () => {
64
+ jest.setTimeout(20000);
65
+ let accessToken;
66
+ beforeEach(() => {
67
+ src_1.DynamicApiModule.state['resetState']();
68
+ });
69
+ afterEach(async () => {
70
+ await (0, e2e_setup_1.closeTestingApp)(mongoose_2.default.connections);
71
+ });
72
+ async function initPresenceApp(enableController = false) {
73
+ const uri = process.env.MONGO_DB_URL;
74
+ const moduleRef = await testing_1.Test.createTestingModule({
75
+ imports: [
76
+ src_1.DynamicApiModule.forRoot(uri, {
77
+ useAuth: {
78
+ userEntity: PresenceUserEntity,
79
+ jwt: { secret: 'presence-e2e-secret', expiresIn: '1h' },
80
+ login: {},
81
+ webSocket: true,
82
+ },
83
+ }),
84
+ src_1.DynamicApiPresenceModule.register({
85
+ adapter: 'memory',
86
+ enableController,
87
+ }),
88
+ ],
89
+ }).compile();
90
+ return (0, e2e_setup_1.createTestingApp)(moduleRef, undefined, async (app) => {
91
+ (0, src_1.enableDynamicAPIWebSockets)(app);
92
+ });
93
+ }
94
+ async function registerAndLogin(email = 'presence@test.co', password = 'P@ssw0rd!') {
95
+ await e2e_setup_1.server.post('/auth/register', { email, password });
96
+ const { body } = await e2e_setup_1.server.post('/auth/login', { email, password });
97
+ return body.accessToken;
98
+ }
99
+ it('should emit user:online when an authenticated socket connects', async () => {
100
+ await initPresenceApp();
101
+ accessToken = await registerAndLogin();
102
+ const observer = await connectSocket(global.appBaseUrl);
103
+ const onlinePromise = waitForEvent(observer, 'user:online');
104
+ const authenticated = await connectSocket(global.appBaseUrl, accessToken);
105
+ const payload = await onlinePromise;
106
+ expect(payload).toMatchObject({ userId: expect.any(String) });
107
+ authenticated.disconnect();
108
+ observer.disconnect();
109
+ });
110
+ it('should emit user:offline when the last authenticated socket disconnects', async () => {
111
+ await initPresenceApp();
112
+ accessToken = await registerAndLogin();
113
+ const observer = await connectSocket(global.appBaseUrl);
114
+ const onlinePromise = waitForEvent(observer, 'user:online', 5000);
115
+ const authenticated = await connectSocket(global.appBaseUrl, accessToken);
116
+ await onlinePromise;
117
+ const offlinePromise = waitForEvent(observer, 'user:offline', 5000);
118
+ authenticated.disconnect();
119
+ const payload = await offlinePromise;
120
+ expect(payload).toMatchObject({ userId: expect.any(String) });
121
+ observer.disconnect();
122
+ });
123
+ it('should NOT emit user:offline while the user has another active socket (multi-tab)', async () => {
124
+ await initPresenceApp();
125
+ accessToken = await registerAndLogin();
126
+ const observer = await connectSocket(global.appBaseUrl);
127
+ const tab1 = await connectSocket(global.appBaseUrl, accessToken);
128
+ const tab2 = await connectSocket(global.appBaseUrl, accessToken);
129
+ await delay(300);
130
+ let offlineReceived = false;
131
+ observer.on('user:offline', () => { offlineReceived = true; });
132
+ tab1.disconnect();
133
+ await delay(500);
134
+ expect(offlineReceived).toBe(false);
135
+ tab2.disconnect();
136
+ observer.disconnect();
137
+ });
138
+ it('should NOT emit user:online for anonymous (unauthenticated) connections', async () => {
139
+ await initPresenceApp();
140
+ const observer = await connectSocket(global.appBaseUrl);
141
+ let onlineReceived = false;
142
+ observer.on('user:online', () => { onlineReceived = true; });
143
+ const anon = await connectSocket(global.appBaseUrl);
144
+ await delay(300);
145
+ expect(onlineReceived).toBe(false);
146
+ anon.disconnect();
147
+ observer.disconnect();
148
+ });
149
+ it('GET /presence should return online user IDs when enableController is true', async () => {
150
+ await initPresenceApp(true);
151
+ accessToken = await registerAndLogin();
152
+ const observer = await connectSocket(global.appBaseUrl);
153
+ const onlinePromise = waitForEvent(observer, 'user:online', 5000);
154
+ const authenticated = await connectSocket(global.appBaseUrl, accessToken);
155
+ await onlinePromise;
156
+ const res = await e2e_setup_1.server.get('/presence');
157
+ const onlineIds = res.body?.onlineUserIds ?? [];
158
+ expect(onlineIds.length).toBeGreaterThan(0);
159
+ authenticated.disconnect();
160
+ observer.disconnect();
161
+ });
162
+ it('GET /presence?room=nonexistent should return empty array', async () => {
163
+ await initPresenceApp(true);
164
+ const res = await e2e_setup_1.server.get('/presence', { query: { room: 'nonexistent-room' } });
165
+ const onlineIds = res.body?.onlineUserIds ?? [];
166
+ expect(onlineIds).toEqual([]);
167
+ });
168
+ });
169
+ //# sourceMappingURL=presence.e2e-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence.e2e-spec.js","sourceRoot":"","sources":["../../../libs/dynamic-api/test/for-feature/presence.e2e-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import 'dotenv/config';