@builder6/rooms 3.0.5 → 3.0.6

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 (54) hide show
  1. package/package.json +10 -7
  2. package/.prettierrc +0 -4
  3. package/src/emails/UnreadMention.tsx +0 -37
  4. package/src/emails/UnreadReplies.tsx +0 -49
  5. package/src/emails/_components/comment.tsx +0 -70
  6. package/src/emails/_components/header.tsx +0 -26
  7. package/src/emails/_components/headline.tsx +0 -20
  8. package/src/emails/_components/layout.tsx +0 -45
  9. package/src/emails/_lib/types.ts +0 -10
  10. package/src/emails/_styles/colors.ts +0 -7
  11. package/src/emails/_utils/cn.ts +0 -6
  12. package/src/emails/_utils/comments.ts +0 -61
  13. package/src/emails/_utils/getProps.ts +0 -7
  14. package/src/plugin.module.ts +0 -3
  15. package/src/rooms/app.controller.ts +0 -89
  16. package/src/rooms/dtos/inbox_notifications.dto.ts +0 -13
  17. package/src/rooms/dtos/notifications.dto.ts +0 -14
  18. package/src/rooms/dtos/room_members.dto.ts +0 -32
  19. package/src/rooms/dtos/rooms.dto.ts +0 -51
  20. package/src/rooms/emailNotification.service.tsx +0 -126
  21. package/src/rooms/emails/comment-body.tsx +0 -342
  22. package/src/rooms/emails/comment-with-body.ts +0 -24
  23. package/src/rooms/emails/index.ts +0 -25
  24. package/src/rooms/emails/lib/batch-users-resolver.ts +0 -120
  25. package/src/rooms/emails/lib/css-properties.ts +0 -123
  26. package/src/rooms/emails/lib/warning.ts +0 -25
  27. package/src/rooms/emails/thread-notification.tsx +0 -583
  28. package/src/rooms/globals/augmentation.ts +0 -89
  29. package/src/rooms/index.ts +0 -5
  30. package/src/rooms/lib/DateToString.ts +0 -9
  31. package/src/rooms/lib/Json.ts +0 -34
  32. package/src/rooms/lib/utils.ts +0 -240
  33. package/src/rooms/liveblocks.service.ts +0 -25
  34. package/src/rooms/notifications.service.ts +0 -235
  35. package/src/rooms/protocol/AuthToken.ts +0 -126
  36. package/src/rooms/protocol/Authentication.ts +0 -18
  37. package/src/rooms/protocol/BaseActivitiesData.ts +0 -5
  38. package/src/rooms/protocol/BaseRoomInfo.ts +0 -15
  39. package/src/rooms/protocol/BaseUserMeta.ts +0 -28
  40. package/src/rooms/protocol/ClientMsg.ts +0 -94
  41. package/src/rooms/protocol/Comments.ts +0 -202
  42. package/src/rooms/protocol/InboxNotifications.ts +0 -75
  43. package/src/rooms/protocol/Op.ts +0 -143
  44. package/src/rooms/protocol/SerializedCrdt.ts +0 -61
  45. package/src/rooms/protocol/ServerMsg.ts +0 -307
  46. package/src/rooms/protocol/VersionHistory.ts +0 -9
  47. package/src/rooms/rooms.controller.ts +0 -587
  48. package/src/rooms/rooms.gateway.ts +0 -267
  49. package/src/rooms/rooms.guard.ts +0 -52
  50. package/src/rooms/rooms.module.ts +0 -38
  51. package/src/rooms/rooms.moleculer.ts +0 -80
  52. package/src/rooms/rooms.service.ts +0 -723
  53. package/tsconfig.json +0 -10
  54. package/yarn-error.log +0 -17218
@@ -1,587 +0,0 @@
1
- import { AuthGuard } from '@builder6/core';
2
- import { FilesService } from '@builder6/files';
3
- import { RoomsService } from './rooms.service';
4
- import { omit, uniqBy } from 'lodash';
5
- import { ApiBearerAuth, ApiBody, ApiTags } from '@nestjs/swagger';
6
-
7
- import {
8
- Controller,
9
- Get,
10
- Post,
11
- Delete,
12
- Body,
13
- Param,
14
- Query,
15
- Req,
16
- UseGuards,
17
- Put,
18
- HttpException,
19
- HttpStatus,
20
- } from '@nestjs/common';
21
- import { JwtService } from '@nestjs/jwt';
22
- import { RoomsGuard } from './rooms.guard';
23
- import rawBody from 'raw-body';
24
- import { Request } from 'express';
25
- import { RoomsGateway } from './rooms.gateway';
26
- import { ServerMsgCode } from './protocol/ServerMsg';
27
- import { NotificationsService } from './notifications.service';
28
- import { EmailNotificationService } from './emailNotification.service';
29
-
30
- @Controller('v2/c/')
31
- @ApiTags('Rooms')
32
- @ApiBearerAuth()
33
- export class RoomsController {
34
- constructor(
35
- private roomsService: RoomsService,
36
- private filesService: FilesService,
37
- private jwtService: JwtService,
38
- private roomsGateway: RoomsGateway,
39
- private notificationsService: NotificationsService,
40
- private emailNotificationService: EmailNotificationService,
41
- ) {}
42
-
43
- @UseGuards(AuthGuard)
44
- @Post('auth')
45
- async getToken(
46
- @Body() body: { room: string; permission: string },
47
- @Req() req: Request,
48
- ) {
49
- const user = req['user'];
50
- const { room = 'test', permission = 'read' } = body;
51
- return await this.roomsService.getRoomToken({
52
- spaceId: user.space,
53
- userId: user.user,
54
- roomId: room,
55
- readonly: permission === 'read',
56
- });
57
- }
58
-
59
- @UseGuards(RoomsGuard)
60
- @Get('users')
61
- async getUsers(@Query('userIds') userIds: string | string[]) {
62
- if (typeof userIds === 'string') {
63
- userIds = [userIds];
64
- }
65
- const users = await this.roomsService.resolveUsers({ userIds });
66
- return users;
67
- }
68
-
69
- @UseGuards(RoomsGuard)
70
- @Get('users/search')
71
- async searchUsers(@Req() req: Request, @Query('keyword') keyword: string) {
72
- const spaceId = req['jwt'].sid;
73
- const users = await this.roomsService.searchUsers(spaceId, keyword);
74
- return users;
75
- }
76
-
77
- @UseGuards(RoomsGuard)
78
- @Get('rooms')
79
- async getRooms(@Query('roomIds') roomIds: string | string[]) {
80
- if (typeof roomIds === 'string') {
81
- roomIds = [roomIds];
82
- }
83
- const rooms = await this.roomsService.resolveRoomsInfo({ roomIds });
84
- return rooms;
85
- }
86
-
87
- @UseGuards(RoomsGuard)
88
- @Get('rooms/:roomId/threads')
89
- async getThreads(@Req() req: Request, @Param('roomId') roomId: string) {
90
- const threads = await this.roomsService.getThreads(roomId);
91
- const inboxNotifications =
92
- await this.notificationsService.findNotifications({
93
- userId: req['jwt'].uid,
94
- roomId,
95
- unread: true,
96
- });
97
- return {
98
- data: threads,
99
- inboxNotifications: inboxNotifications.map((inboxNotification) =>
100
- omit(inboxNotification, ['userId', '_id']),
101
- ),
102
- meta: {
103
- nextCursor: null,
104
- requestedAt: new Date().toISOString() as string,
105
- permissionHints: {
106
- [roomId]: ['room:write'],
107
- },
108
- },
109
- deletedThreads: [],
110
- deletedInboxNotifications: [],
111
- };
112
- }
113
-
114
- @UseGuards(RoomsGuard)
115
- @Get('rooms/:roomId/threads/delta')
116
- async getThreadsDelta(
117
- @Req() req: Request,
118
- @Param('roomId') roomId: string,
119
- @Query('since') since: string,
120
- ) {
121
- const sinceDate = new Date(since);
122
- const threads = await this.roomsService.getThreads(roomId, sinceDate);
123
- const inboxNotifications =
124
- await this.notificationsService.findNotifications({
125
- userId: req['jwt'].uid,
126
- roomId,
127
- sinceDate,
128
- });
129
- return {
130
- data: threads,
131
- inboxNotifications: inboxNotifications.map((inboxNotification) =>
132
- omit(inboxNotification, ['userId', '_id']),
133
- ),
134
- meta: {
135
- nextCursor: null,
136
- requestedAt: new Date().toISOString() as string,
137
- permissionHints: {
138
- [roomId]: ['room:write'],
139
- },
140
- },
141
- deletedThreads: [],
142
- deletedInboxNotifications: [],
143
- };
144
- }
145
-
146
- @UseGuards(RoomsGuard)
147
- @ApiBody({
148
- schema: {
149
- type: 'object',
150
- properties: {
151
- id: { type: 'string' },
152
- comment: {
153
- type: 'object',
154
- properties: {
155
- id: { type: 'string' },
156
- body: {
157
- type: 'object',
158
- example: {
159
- version: 1,
160
- content: [
161
- {
162
- type: 'paragraph',
163
- children: [
164
- {
165
- text: 'Hello World.',
166
- },
167
- ],
168
- },
169
- ],
170
- },
171
- },
172
- attachmentIds: { type: 'array', items: { type: 'string' } },
173
- },
174
- },
175
- },
176
- },
177
- })
178
- @Post('rooms/:roomId/threads')
179
- async createThread(
180
- @Req() req: Request,
181
- @Param('roomId') roomId: string,
182
- @Body() record: Record<string, any>,
183
- ) {
184
- const userId = req['jwt'].uid;
185
- const space = req['jwt'].sid;
186
- const newThread = await this.roomsService.createThread({
187
- id: record.id,
188
- comment: record.comment,
189
- roomId,
190
- userId,
191
- metadata: record.metadata || {},
192
- resolved: false,
193
- space,
194
- });
195
-
196
- this.roomsGateway.broadcastToRoom(roomId, {
197
- type: ServerMsgCode.THREAD_CREATED, // 使用 ServerMsgCode 枚举
198
- threadId: newThread.id,
199
- });
200
-
201
- this.roomsGateway.broadcastToRoom(roomId, {
202
- type: ServerMsgCode.COMMENT_CREATED, // 使用 ServerMsgCode 枚举
203
- threadId: newThread.id,
204
- commentId: newThread.comments[0].id,
205
- });
206
- return newThread;
207
- }
208
-
209
- @UseGuards(RoomsGuard)
210
- @Get('rooms/:roomId/thread-with-notification/:threadId')
211
- async threadWithNotification(
212
- @Req() req: Request,
213
- @Param('roomId') roomId: string,
214
- @Param('threadId') threadId: string,
215
- ) {
216
- const thread = await this.roomsService.getThread({ roomId, threadId });
217
- const inboxNotifications =
218
- await this.notificationsService.findNotifications({
219
- userId: req['jwt'].uid,
220
- roomId,
221
- threadId,
222
- });
223
- return {
224
- thread,
225
- inboxNotification: inboxNotifications[0]
226
- ? omit(inboxNotifications[0], ['userId', '_id'])
227
- : undefined,
228
- };
229
- }
230
-
231
- @UseGuards(RoomsGuard)
232
- @Post('rooms/:roomId/threads/:threadId/mark-as-resolved')
233
- async threadMarkasResolved(
234
- @Req() req: Request,
235
- @Param('roomId') roomId: string,
236
- @Param('threadId') threadId: string,
237
- ) {
238
- const newThread = await this.roomsService.updateThread(threadId, {
239
- resolved: true,
240
- });
241
-
242
- this.roomsGateway.broadcastToRoom(roomId, {
243
- type: ServerMsgCode.THREAD_UPDATED, // 使用 ServerMsgCode 枚举
244
- threadId: threadId,
245
- });
246
- return newThread;
247
- }
248
-
249
- @UseGuards(RoomsGuard)
250
- @Post('rooms/:roomId/threads/:threadId/mark-as-unresolved')
251
- async threadMarkasUnResolved(
252
- @Req() req: Request,
253
- @Param('roomId') roomId: string,
254
- @Param('threadId') threadId: string,
255
- ) {
256
- const newThread = await this.roomsService.updateThread(threadId, {
257
- resolved: false,
258
- });
259
-
260
- this.roomsGateway.broadcastToRoom(roomId, {
261
- type: ServerMsgCode.THREAD_UPDATED, // 使用 ServerMsgCode 枚举
262
- threadId: threadId,
263
- });
264
- return newThread;
265
- }
266
-
267
- // 创建回复
268
- @UseGuards(RoomsGuard)
269
- @Post('rooms/:roomId/threads/:threadId/comments')
270
- async createComment(
271
- @Req() req: Request,
272
- @Param('roomId') roomId: string,
273
- @Param('threadId') threadId: string,
274
- @Body() record: Record<string, any>,
275
- ) {
276
- const userId = req['jwt'].uid;
277
- const space = req['jwt'].sid;
278
- const newComment = await this.roomsService.createComment({
279
- id: record.id,
280
- attachmentIds: record.attachmentIds,
281
- body: record.body,
282
- roomId,
283
- threadId: threadId,
284
- userId: userId,
285
- space,
286
- });
287
-
288
- this.roomsGateway.broadcastToRoom(roomId, {
289
- type: ServerMsgCode.COMMENT_CREATED, // 使用 ServerMsgCode 枚举
290
- threadId: threadId,
291
- commentId: record.id,
292
- });
293
- return newComment;
294
- }
295
-
296
- // 编辑回复
297
- @UseGuards(RoomsGuard)
298
- @Post('rooms/:roomId/threads/:threadId/comments/:commentId')
299
- async updateComment(
300
- @Req() req: Request,
301
- @Param('roomId') roomId: string,
302
- @Param('threadId') threadId: string,
303
- @Param('commentId') commentId: string,
304
- @Body() record: Record<string, any>,
305
- ) {
306
- const userId = req['jwt'].uid;
307
- const newComment = await this.roomsService.updateComment(commentId, {
308
- attachmentIds: record.attachmentIds,
309
- body: record.body,
310
- userId,
311
- });
312
-
313
- await this.roomsService.updateThread(threadId);
314
- this.roomsGateway.broadcastToRoom(roomId, {
315
- type: ServerMsgCode.COMMENT_EDITED, // 使用 ServerMsgCode 枚举
316
- threadId: threadId,
317
- commentId: commentId,
318
- });
319
- return newComment;
320
- }
321
-
322
- // 删除回复
323
- @UseGuards(RoomsGuard)
324
- @Delete('rooms/:roomId/threads/:threadId/comments/:commentId')
325
- async deleteComment(
326
- @Req() req: Request,
327
- @Param('roomId') roomId: string,
328
- @Param('threadId') threadId: string,
329
- @Param('commentId') commentId: string,
330
- ) {
331
- await this.roomsService.deleteComment(commentId);
332
-
333
- await this.roomsService.updateThread(threadId);
334
- this.roomsGateway.broadcastToRoom(roomId, {
335
- type: ServerMsgCode.COMMENT_DELETED, // 使用 ServerMsgCode 枚举
336
- threadId: threadId,
337
- commentId: commentId,
338
- });
339
- return {};
340
- }
341
-
342
- // 获取增量通知
343
- @UseGuards(RoomsGuard)
344
- @Get('inbox-notifications/delta')
345
- async getInboxNotificationsSince(
346
- @Req() req: Request,
347
- @Query('since') since: string,
348
- ) {
349
- const userId = req['jwt'].uid;
350
- const sinceDate = new Date(since);
351
- const requestedAt = new Date();
352
- const notifications = await this.notificationsService.findNotifications({
353
- userId,
354
- sinceDate,
355
- });
356
- const threads = await this.roomsService.getThreadsByIds(
357
- uniqBy(
358
- notifications,
359
- (notification) => `${notification.roomId}-${notification.threadId}`,
360
- ),
361
- );
362
- return {
363
- inboxNotifications: notifications.map((notification) =>
364
- omit(notification, ['userId', '_id']),
365
- ),
366
- threads,
367
- meta: { requestedAt },
368
- deletedThreads: [],
369
- deletedInboxNotifications: [],
370
- };
371
- }
372
-
373
- // 获取通知
374
- @UseGuards(RoomsGuard)
375
- @Get('inbox-notifications')
376
- async getInboxNotifications(
377
- @Req() req: Request,
378
- @Query('unread') unread: string,
379
- @Query('limit') limit: string,
380
- ) {
381
- const userId = req['jwt'].uid;
382
- const requestedAt = new Date();
383
- const notifications = await this.notificationsService.findNotifications({
384
- userId,
385
- unread: unread === 'true',
386
- limit: Number(limit),
387
- });
388
- const threads = await this.roomsService.getThreadsByIds(
389
- uniqBy(
390
- notifications,
391
- (notification) => `${notification.roomId}-${notification.threadId}`,
392
- ),
393
- );
394
- return {
395
- inboxNotifications: notifications.map((notification) =>
396
- omit(notification, ['userId', '_id']),
397
- ),
398
- threads,
399
- meta: {
400
- nextCursor: null,
401
- requestedAt,
402
- },
403
- deletedThreads: [],
404
- deletedInboxNotifications: [],
405
- };
406
- }
407
-
408
- // 获取通知
409
- @UseGuards(RoomsGuard)
410
- @Delete('inbox-notifications')
411
- async deleteInboxNotifications(@Req() req: Request) {
412
- const userId = req['jwt'].uid;
413
- await this.notificationsService.deleteNotifications({
414
- userId,
415
- });
416
- return;
417
- }
418
-
419
- // room read
420
- @UseGuards(RoomsGuard)
421
- @Post('inbox-notifications/read')
422
- async read(
423
- @Req() req: Request,
424
- @Body('inboxNotificationIds') inboxNotificationIds: string[],
425
- ) {
426
- const userId = req['jwt'].uid;
427
- const notifications = await this.notificationsService.markAsRead({
428
- userId,
429
- inboxNotificationIds,
430
- });
431
- return {
432
- data:
433
- notifications?.length > 0
434
- ? notifications.map((notification) =>
435
- omit(notification, ['userId', '_id']),
436
- )
437
- : undefined,
438
- };
439
- }
440
-
441
- // room read
442
- @UseGuards(RoomsGuard)
443
- @Post('rooms/:roomId/inbox-notifications/read')
444
- async roomRead(
445
- @Req() req: Request,
446
- @Param('roomId') roomId: string,
447
- @Body('inboxNotificationIds') inboxNotificationIds: string[] | 'all',
448
- ) {
449
- const userId = req['jwt'].uid;
450
- const notifications = await this.notificationsService.markAsRead({
451
- roomId,
452
- userId,
453
- inboxNotificationIds,
454
- });
455
- return {
456
- data:
457
- notifications?.length > 0
458
- ? notifications.map((notification) =>
459
- omit(notification, ['userId', '_id']),
460
- )
461
- : undefined,
462
- };
463
- }
464
-
465
- // 获取下载Url
466
- @UseGuards(RoomsGuard)
467
- @Post('rooms/:roomId/attachments/presigned-urls')
468
- async presignedUrls(@Body('attachmentIds') attachmentIds: string[]) {
469
- const urls = await Promise.all(
470
- attachmentIds.map(async (attachmentId) => {
471
- return this.filesService.getPreSignedUrl(
472
- 'cfs.files.filerecord',
473
- attachmentId,
474
- );
475
- }),
476
- );
477
- return { urls };
478
- }
479
-
480
- // 上传文件
481
- @UseGuards(RoomsGuard)
482
- @Put('rooms/:roomId/attachments/:attachmentId/upload/:fileName')
483
- async uploadFile(
484
- @Param('roomId') roomId: string,
485
- @Param('attachmentId') attachmentId: string,
486
- @Param('fileName') fileName: string,
487
- @Query('fileSize') fileSize: number,
488
- @Req() req: Request,
489
- ) {
490
- const userId = req['jwt'].uid;
491
- const spaceId = req['jwt'].sid;
492
- // 检查 content-type 是否为 application/octet-stream
493
- if (req.headers['content-type'] !== 'application/octet-stream') {
494
- throw new HttpException('Invalid content type', HttpStatus.BAD_REQUEST);
495
- }
496
- const decodedFileName = decodeURIComponent(fileName);
497
- const fileBuffer = await rawBody(req);
498
-
499
- // 构造类似 Express.Multer.File 的对象
500
- const file = {
501
- buffer: fileBuffer,
502
- originalname: decodedFileName,
503
- size: fileSize,
504
- isUTF8: true,
505
- };
506
- console.log(fileName);
507
-
508
- const metadata = {
509
- _id: attachmentId,
510
- object_name: 'b6_rooms',
511
- record_id: roomId,
512
- owner: userId,
513
- space: spaceId,
514
- };
515
-
516
- if (!file) {
517
- throw new Error('未找到上传的文件');
518
- }
519
- const fileRecord = await this.filesService.uploadFile(
520
- 'cfs.files.filerecord',
521
- file,
522
- metadata,
523
- );
524
- return fileRecord;
525
- }
526
-
527
- // 创建Reaction
528
- @UseGuards(RoomsGuard)
529
- @Post('rooms/:roomId/threads/:threadId/comments/:commentId/reactions')
530
- async createReaction(
531
- @Req() req: Request,
532
- @Param('roomId') roomId: string,
533
- @Param('threadId') threadId: string,
534
- @Param('commentId') commentId: string,
535
- @Body('emoji') emoji: string,
536
- ) {
537
- const userId = req['jwt'].uid;
538
- const newComment = await this.roomsService.createReaction(commentId, {
539
- userId: userId,
540
- emoji: emoji,
541
- });
542
-
543
- await this.roomsService.updateThread(threadId);
544
- this.roomsGateway.broadcastToRoom(roomId, {
545
- type: ServerMsgCode.COMMENT_REACTION_ADDED, // 使用 ServerMsgCode 枚举
546
- threadId: threadId,
547
- commentId: commentId,
548
- emoji: emoji,
549
- });
550
- return newComment;
551
- }
552
-
553
- //删除Reaction
554
- @UseGuards(RoomsGuard)
555
- @Delete(
556
- 'rooms/:roomId/threads/:threadId/comments/:commentId/reactions/:emoji',
557
- )
558
- async deleteReaction(
559
- @Req() req: Request,
560
- @Param('roomId') roomId: string,
561
- @Param('threadId') threadId: string,
562
- @Param('commentId') commentId: string,
563
- @Param('emoji') emoji: string,
564
- ) {
565
- const userId = req['jwt'].uid;
566
- await this.roomsService.deleteReaction(commentId, { emoji, userId });
567
-
568
- await this.roomsService.updateThread(threadId);
569
- this.roomsGateway.broadcastToRoom(roomId, {
570
- type: ServerMsgCode.COMMENT_REACTION_REMOVED, // 使用 ServerMsgCode 枚举
571
- threadId: threadId,
572
- commentId: commentId,
573
- emoji: emoji,
574
- });
575
- return {};
576
- }
577
-
578
- @Post('email')
579
- @ApiBody({
580
- schema: {
581
- type: 'object',
582
- },
583
- })
584
- async sendEmail(@Body() body: object) {
585
- this.emailNotificationService.sendThreadNotificationEmail(body as any);
586
- }
587
- }