@openora/core 0.4.1-canary.49 → 0.4.1-canary.50
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/.tsbuildinfo +1 -1
- package/dist/admin-console/contract/index.d.ts +12 -0
- package/dist/admin-console/contract/index.d.ts.map +1 -1
- package/dist/admin-console/router/index.d.ts +6 -0
- package/dist/admin-console/router/index.d.ts.map +1 -1
- package/dist/audit/plugin.d.ts.map +1 -1
- package/dist/audit/plugin.js +19 -4
- package/dist/audit/plugin.js.map +1 -1
- package/dist/audit/service/audit.service.d.ts +1 -0
- package/dist/audit/service/audit.service.d.ts.map +1 -1
- package/dist/audit/service/audit.service.js +11 -6
- package/dist/audit/service/audit.service.js.map +1 -1
- package/dist/casino/gaming/__tests__/gaming.service.test.js +2 -2
- package/dist/casino/gaming/__tests__/gaming.service.test.js.map +1 -1
- package/dist/casino/gaming/admin-reporting.d.ts +2 -1
- package/dist/casino/gaming/admin-reporting.d.ts.map +1 -1
- package/dist/casino/gaming/admin-reporting.js +14 -0
- package/dist/casino/gaming/admin-reporting.js.map +1 -1
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js +3 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js.map +1 -1
- package/dist/compliance/drizzle/migrations/0004_military_silk_fever.sql +1 -1
- package/dist/contracts/adapters/admin-game-reporting.d.ts +5 -0
- package/dist/contracts/adapters/admin-game-reporting.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-game-reporting.js.map +1 -1
- package/dist/contracts/adapters/admin-user-directory.d.ts +6 -1
- package/dist/contracts/adapters/admin-user-directory.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-user-directory.js.map +1 -1
- package/dist/contracts/adapters/audit.d.ts +10 -0
- package/dist/contracts/adapters/audit.d.ts.map +1 -1
- package/dist/contracts/adapters/audit.js.map +1 -1
- package/dist/contracts/adapters/cache.d.ts +3 -0
- package/dist/contracts/adapters/cache.d.ts.map +1 -1
- package/dist/contracts/adapters/cache.js.map +1 -1
- package/dist/contracts/adapters/chat-block-writer.d.ts +8 -0
- package/dist/contracts/adapters/chat-block-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-block-writer.js +3 -0
- package/dist/contracts/adapters/chat-block-writer.js.map +1 -0
- package/dist/contracts/adapters/chat-room-access.d.ts +6 -0
- package/dist/contracts/adapters/chat-room-access.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-room-access.js +3 -0
- package/dist/contracts/adapters/chat-room-access.js.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts +12 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.js +3 -0
- package/dist/contracts/adapters/chat-system-writer.js.map +1 -0
- package/dist/contracts/adapters/index.d.ts +8 -2
- package/dist/contracts/adapters/index.d.ts.map +1 -1
- package/dist/contracts/adapters/index.js +4 -1
- package/dist/contracts/adapters/index.js.map +1 -1
- package/dist/contracts/adapters/realtime.d.ts +3 -0
- package/dist/contracts/adapters/realtime.d.ts.map +1 -1
- package/dist/contracts/adapters/realtime.js +14 -0
- package/dist/contracts/adapters/realtime.js.map +1 -1
- package/dist/contracts/adapters/wallet-commands.d.ts +2 -0
- package/dist/contracts/adapters/wallet-commands.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-commands.js.map +1 -1
- package/dist/contracts/schemas/chat-command-metadata.d.ts +47 -0
- package/dist/contracts/schemas/chat-command-metadata.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command-metadata.js +42 -0
- package/dist/contracts/schemas/chat-command-metadata.js.map +1 -0
- package/dist/contracts/schemas/chat-command.d.ts +87 -0
- package/dist/contracts/schemas/chat-command.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command.js +26 -0
- package/dist/contracts/schemas/chat-command.js.map +1 -0
- package/dist/contracts/schemas/events.d.ts +59 -0
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +52 -2
- package/dist/contracts/schemas/events.js.map +1 -1
- package/dist/contracts/schemas/index.d.ts +2 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -1
- package/dist/contracts/schemas/index.js +2 -0
- package/dist/contracts/schemas/index.js.map +1 -1
- package/dist/contracts/schemas/wallet-tx.d.ts +3 -1
- package/dist/contracts/schemas/wallet-tx.d.ts.map +1 -1
- package/dist/contracts/schemas/wallet-tx.js +2 -0
- package/dist/contracts/schemas/wallet-tx.js.map +1 -1
- package/dist/engagement/chat/__tests__/chat.service.test.js +138 -10
- package/dist/engagement/chat/__tests__/chat.service.test.js.map +1 -1
- package/dist/engagement/chat/contract/index.d.ts +285 -0
- package/dist/engagement/chat/contract/index.d.ts.map +1 -1
- package/dist/engagement/chat/contract/index.js +23 -1
- package/dist/engagement/chat/contract/index.js.map +1 -1
- package/dist/engagement/chat/drizzle/migrations/0002_steep_zodiak.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0003_stormy_king_bedlam.sql +9 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0002_snapshot.json +576 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0003_snapshot.json +652 -0
- package/dist/engagement/chat/drizzle/migrations/meta/_journal.json +14 -0
- package/dist/engagement/chat/plugin.d.ts.map +1 -1
- package/dist/engagement/chat/plugin.js +15 -3
- package/dist/engagement/chat/plugin.js.map +1 -1
- package/dist/engagement/chat/router/index.d.ts +242 -0
- package/dist/engagement/chat/router/index.d.ts.map +1 -1
- package/dist/engagement/chat/router/index.js +14 -2
- package/dist/engagement/chat/router/index.js.map +1 -1
- package/dist/engagement/chat/schema/index.d.ts +179 -0
- package/dist/engagement/chat/schema/index.d.ts.map +1 -1
- package/dist/engagement/chat/schema/index.js +17 -1
- package/dist/engagement/chat/schema/index.js.map +1 -1
- package/dist/engagement/chat/service/chat.service.d.ts +176 -8
- package/dist/engagement/chat/service/chat.service.d.ts.map +1 -1
- package/dist/engagement/chat/service/chat.service.js +129 -13
- package/dist/engagement/chat/service/chat.service.js.map +1 -1
- package/dist/engagement/chat-commands/contract/index.d.ts +252 -0
- package/dist/engagement/chat-commands/contract/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/contract/index.js +138 -0
- package/dist/engagement/chat-commands/contract/index.js.map +1 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0000_daffy_lady_bullseye.sql +24 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0000_snapshot.json +164 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/_journal.json +13 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts +4 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/chat-commands/drizzle.config.js +21 -0
- package/dist/engagement/chat-commands/drizzle.config.js.map +1 -0
- package/dist/engagement/chat-commands/migrate.d.ts +3 -0
- package/dist/engagement/chat-commands/migrate.d.ts.map +1 -0
- package/dist/engagement/chat-commands/migrate.js +15 -0
- package/dist/engagement/chat-commands/migrate.js.map +1 -0
- package/dist/engagement/chat-commands/plugin.d.ts +3 -0
- package/dist/engagement/chat-commands/plugin.d.ts.map +1 -0
- package/dist/engagement/chat-commands/plugin.js +15 -0
- package/dist/engagement/chat-commands/plugin.js.map +1 -0
- package/dist/engagement/chat-commands/router/index.d.ts +173 -0
- package/dist/engagement/chat-commands/router/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/router/index.js +61 -0
- package/dist/engagement/chat-commands/router/index.js.map +1 -0
- package/dist/engagement/chat-commands/schema/index.d.ts +337 -0
- package/dist/engagement/chat-commands/schema/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/schema/index.js +29 -0
- package/dist/engagement/chat-commands/schema/index.js.map +1 -0
- package/dist/engagement/chat-commands/seed/index.d.ts +3 -0
- package/dist/engagement/chat-commands/seed/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/seed/index.js +54 -0
- package/dist/engagement/chat-commands/seed/index.js.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts +2 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js +888 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts +90 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js +641 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js.map +1 -0
- package/dist/engagement/contracts.d.ts +1 -0
- package/dist/engagement/contracts.d.ts.map +1 -1
- package/dist/engagement/contracts.js +1 -0
- package/dist/engagement/contracts.js.map +1 -1
- package/dist/engagement/index.d.ts +1 -0
- package/dist/engagement/index.d.ts.map +1 -1
- package/dist/engagement/index.js +1 -0
- package/dist/engagement/index.js.map +1 -1
- package/dist/engagement/server.d.ts +1 -0
- package/dist/engagement/server.d.ts.map +1 -1
- package/dist/engagement/server.js +1 -0
- package/dist/engagement/server.js.map +1 -1
- package/dist/iam/service/iam.service.d.ts +1 -1
- package/dist/pam/identity/__tests__/admin-user-directory.test.js +24 -0
- package/dist/pam/identity/__tests__/admin-user-directory.test.js.map +1 -1
- package/dist/pam/identity/admin-user-directory.d.ts +16 -1
- package/dist/pam/identity/admin-user-directory.d.ts.map +1 -1
- package/dist/pam/identity/admin-user-directory.js +39 -6
- package/dist/pam/identity/admin-user-directory.js.map +1 -1
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts +2 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts.map +1 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js +153 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js.map +1 -0
- package/dist/react/hooks/use-event-stream.d.ts +3 -3
- package/dist/react/hooks/use-event-stream.d.ts.map +1 -1
- package/dist/react/hooks/use-event-stream.js +60 -28
- package/dist/react/hooks/use-event-stream.js.map +1 -1
- package/dist/server/kernel/__tests__/cache.test.js +1 -0
- package/dist/server/kernel/__tests__/cache.test.js.map +1 -1
- package/dist/server/kernel/__tests__/realtime-transport.test.js +11 -0
- package/dist/server/kernel/__tests__/realtime-transport.test.js.map +1 -1
- package/dist/server/kernel/realtime-transport.d.ts +2 -0
- package/dist/server/kernel/realtime-transport.d.ts.map +1 -1
- package/dist/server/kernel/realtime-transport.js +13 -1
- package/dist/server/kernel/realtime-transport.js.map +1 -1
- package/dist/server/kernel/redis-cache.d.ts +3 -0
- package/dist/server/kernel/redis-cache.d.ts.map +1 -1
- package/dist/server/kernel/redis-cache.js +10 -0
- package/dist/server/kernel/redis-cache.js.map +1 -1
- package/dist/server/runtime/create-app.d.ts.map +1 -1
- package/dist/server/runtime/create-app.js +2 -4
- package/dist/server/runtime/create-app.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock.d.ts +1 -0
- package/dist/testing/mock.d.ts.map +1 -1
- package/dist/testing/mock.js +7 -2
- package/dist/testing/mock.js.map +1 -1
- package/dist/testing/realtime-transport-conformance.d.ts +35 -0
- package/dist/testing/realtime-transport-conformance.d.ts.map +1 -0
- package/dist/testing/realtime-transport-conformance.js +77 -0
- package/dist/testing/realtime-transport-conformance.js.map +1 -0
- package/dist/wallet/__tests__/wallet-commands.service.test.js +36 -6
- package/dist/wallet/__tests__/wallet-commands.service.test.js.map +1 -1
- package/dist/wallet/admin-reporting.d.ts +2 -2
- package/dist/wallet/contract/index.d.ts +6 -0
- package/dist/wallet/contract/index.d.ts.map +1 -1
- package/dist/wallet/drizzle/migrations/0004_reflective_shriek.sql +2 -0
- package/dist/wallet/drizzle/migrations/meta/0004_snapshot.json +567 -0
- package/dist/wallet/drizzle/migrations/meta/_journal.json +7 -0
- package/dist/wallet/router/index.d.ts +4 -0
- package/dist/wallet/router/index.d.ts.map +1 -1
- package/dist/wallet/schema/index.d.ts +3 -3
- package/dist/wallet/schema/index.d.ts.map +1 -1
- package/dist/wallet/service/wallet-commands.service.d.ts +1 -1
- package/dist/wallet/service/wallet-commands.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet-commands.service.js +6 -3
- package/dist/wallet/service/wallet-commands.service.js.map +1 -1
- package/dist/wallet/service/wallet.service.d.ts +1 -1
- package/package.json +30 -7
- package/dist/engagement/chat/react/use-chat-stream.d.ts +0 -26
- package/dist/engagement/chat/react/use-chat-stream.d.ts.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.js +0 -54
- package/dist/engagement/chat/react/use-chat-stream.js.map +0 -1
- package/dist/engagement/chat/react/use-join-room.d.ts +0 -13
- package/dist/engagement/chat/react/use-join-room.d.ts.map +0 -1
- package/dist/engagement/chat/react/use-join-room.js +0 -25
- package/dist/engagement/chat/react/use-join-room.js.map +0 -1
- package/dist/engagement/react.d.ts +0 -3
- package/dist/engagement/react.d.ts.map +0 -1
- package/dist/engagement/react.js +0 -4
- package/dist/engagement/react.js.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { pgTable, pgEnum, uuid, text, boolean, timestamp, uniqueIndex, index, } from 'drizzle-orm/pg-core';
|
|
1
|
+
import { pgTable, pgEnum, uuid, text, boolean, jsonb, timestamp, uniqueIndex, index, } from 'drizzle-orm/pg-core';
|
|
2
2
|
import { CHAT_ROOM_CATEGORIES, CHAT_ROOM_ROLES } from '../contract/index.js';
|
|
3
|
+
import { CHAT_MESSAGE_TYPES } from '@openora/core/contracts';
|
|
3
4
|
export const chatRoomRole = pgEnum('chat_room_role', CHAT_ROOM_ROLES);
|
|
4
5
|
export const chatRoomCategory = pgEnum('chat_room_category', CHAT_ROOM_CATEGORIES);
|
|
6
|
+
export const chatMessageType = pgEnum('chat_message_type', CHAT_MESSAGE_TYPES);
|
|
5
7
|
export const chatRoom = pgTable('chat_room', {
|
|
6
8
|
id: uuid().primaryKey().defaultRandom(),
|
|
7
9
|
name: text().notNull(),
|
|
@@ -25,6 +27,8 @@ export const chatMessage = pgTable('chat_message', {
|
|
|
25
27
|
userId: uuid().notNull(),
|
|
26
28
|
username: text().notNull(),
|
|
27
29
|
content: text().notNull(),
|
|
30
|
+
type: chatMessageType().notNull().default('user'),
|
|
31
|
+
metadata: jsonb().$type(),
|
|
28
32
|
isDeleted: boolean().notNull().default(false),
|
|
29
33
|
createdAt: timestamp({ withTimezone: true }).notNull().defaultNow(),
|
|
30
34
|
}, (t) => [
|
|
@@ -42,6 +46,18 @@ export const chatUserBlock = pgTable('chat_user_block', {
|
|
|
42
46
|
uniqueIndex('chat_user_block_pair_key').on(t.blockerId, t.blockedId),
|
|
43
47
|
index('chat_user_block_blocker_idx').on(t.blockerId),
|
|
44
48
|
]);
|
|
49
|
+
// A directional soft-mute: `ignorerId` no longer sees messages from `ignoredId`.
|
|
50
|
+
// A separate relationship from chatUserBlock (not an alias) - same message-hiding
|
|
51
|
+
// effect for now, but block vs ignore may diverge further later.
|
|
52
|
+
export const chatUserIgnore = pgTable('chat_user_ignore', {
|
|
53
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
54
|
+
ignorerId: uuid().notNull(),
|
|
55
|
+
ignoredId: uuid().notNull(),
|
|
56
|
+
createdAt: timestamp({ withTimezone: true }).notNull().defaultNow(),
|
|
57
|
+
}, (t) => [
|
|
58
|
+
uniqueIndex('chat_user_ignore_pair_key').on(t.ignorerId, t.ignoredId),
|
|
59
|
+
index('chat_user_ignore_ignorer_idx').on(t.ignorerId),
|
|
60
|
+
]);
|
|
45
61
|
export const chatRoomMember = pgTable('chat_room_member', {
|
|
46
62
|
id: uuid().primaryKey().defaultRandom(),
|
|
47
63
|
roomId: uuid()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/engagement/chat/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,SAAS,EACT,WAAW,EACX,KAAK,GACN,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/engagement/chat/schema/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type EventBus, DrizzleService } from '@openora/core/server';
|
|
2
|
-
import type { ClientMeta, RealtimeTransport } from '@openora/core/contracts';
|
|
2
|
+
import type { ClientMeta, RealtimeTransport, CommandMetadata, ChatSystemMessage, AdminUserDirectory } from '@openora/core/contracts';
|
|
3
3
|
import type { User } from '@openora/core/pam/schema/identity';
|
|
4
4
|
import type { AdminRoomSortBy, ChatRoom, ChatMessage, ChatRoomCategory, SortOrder } from '../contract/index.js';
|
|
5
|
-
export declare function chatChannel(roomId: ChatRoom['id'] | null): string;
|
|
6
5
|
export declare const ChatRoomNotFoundError: new (id: string) => Error;
|
|
6
|
+
export declare const ChatRoomOwnershipError: new () => Error;
|
|
7
7
|
export declare const ChatMessageNotFoundError: new (id: string) => Error;
|
|
8
8
|
export declare const ChatMessageOwnershipError: new () => Error;
|
|
9
9
|
export declare const ChatMessageBlockedError: new () => Error;
|
|
10
10
|
export declare const ChatSelfBlockError: new () => Error;
|
|
11
|
+
export declare const ChatSelfIgnoreError: new () => Error;
|
|
11
12
|
export declare const ChatRoomSlugConflictError: new () => Error;
|
|
12
13
|
export declare const ChatRoomLimitReachedError: new () => Error;
|
|
13
14
|
export declare const ChatRoomLastModeratorError: new () => Error;
|
|
@@ -20,12 +21,15 @@ export declare class ChatService {
|
|
|
20
21
|
private readonly drizzle;
|
|
21
22
|
private readonly events;
|
|
22
23
|
private readonly transport;
|
|
23
|
-
|
|
24
|
+
private readonly directory;
|
|
25
|
+
constructor(drizzle: DrizzleService, events: EventBus, transport: RealtimeTransport, directory: AdminUserDirectory);
|
|
24
26
|
subscribeMessages(roomId: ChatRoom['id'] | null, listener: (message: ChatMessage) => void, viewerId?: User['id'], connectionId?: string): () => void;
|
|
25
27
|
getOnlineCount(roomId: ChatRoom['id'] | null): Promise<{
|
|
26
28
|
count: number;
|
|
27
29
|
}>;
|
|
28
30
|
private blockedIdsFor;
|
|
31
|
+
private ignoredIdsFor;
|
|
32
|
+
private excludedSenderIdsFor;
|
|
29
33
|
private resolveDisplayName;
|
|
30
34
|
/** Throws ChatRoomNotFoundError or ChatRoomNotMemberError; returns the room on success. */
|
|
31
35
|
verifyRoomAccess(roomId: ChatRoom['id'], viewerId?: User['id']): Promise<{
|
|
@@ -90,13 +94,48 @@ export declare class ChatService {
|
|
|
90
94
|
}): Promise<import("@openora/core/server").SerializedRow<{
|
|
91
95
|
id: string;
|
|
92
96
|
userId: string;
|
|
97
|
+
type: "system" | "user";
|
|
93
98
|
createdAt: Date;
|
|
99
|
+
metadata: {
|
|
100
|
+
command: "profile";
|
|
101
|
+
targetUserId: string;
|
|
102
|
+
displayName: string;
|
|
103
|
+
level: number;
|
|
104
|
+
} | {
|
|
105
|
+
command: "gift";
|
|
106
|
+
giftId: string;
|
|
107
|
+
senderId: string;
|
|
108
|
+
senderUsername: string;
|
|
109
|
+
amount: string;
|
|
110
|
+
currency: string;
|
|
111
|
+
} | {
|
|
112
|
+
command: "rain";
|
|
113
|
+
fromUserId: string;
|
|
114
|
+
amount: string;
|
|
115
|
+
currency: string;
|
|
116
|
+
recipientCount: number;
|
|
117
|
+
perRecipient: string;
|
|
118
|
+
} | {
|
|
119
|
+
command: "block";
|
|
120
|
+
targetUserId: string;
|
|
121
|
+
displayName: string;
|
|
122
|
+
} | {
|
|
123
|
+
command: "ignore";
|
|
124
|
+
targetUserId: string;
|
|
125
|
+
displayName: string;
|
|
126
|
+
} | {
|
|
127
|
+
command: "donate";
|
|
128
|
+
recipientId: string;
|
|
129
|
+
recipientUsername: string;
|
|
130
|
+
amount: string;
|
|
131
|
+
currency: string;
|
|
132
|
+
} | null;
|
|
94
133
|
roomId: string | null;
|
|
95
|
-
username: string;
|
|
96
134
|
content: string;
|
|
135
|
+
username: string;
|
|
97
136
|
isDeleted: boolean;
|
|
98
137
|
}, "createdAt">[]>;
|
|
99
|
-
private
|
|
138
|
+
private appendExcludedSendersFilter;
|
|
100
139
|
sendRoomMessage({ userId, username, roomId, content, }: {
|
|
101
140
|
userId: User['id'];
|
|
102
141
|
username: string;
|
|
@@ -105,10 +144,45 @@ export declare class ChatService {
|
|
|
105
144
|
}): Promise<import("@openora/core/server").SerializedRow<{
|
|
106
145
|
id: string;
|
|
107
146
|
userId: string;
|
|
147
|
+
type: "system" | "user";
|
|
108
148
|
createdAt: Date;
|
|
149
|
+
metadata: {
|
|
150
|
+
command: "profile";
|
|
151
|
+
targetUserId: string;
|
|
152
|
+
displayName: string;
|
|
153
|
+
level: number;
|
|
154
|
+
} | {
|
|
155
|
+
command: "gift";
|
|
156
|
+
giftId: string;
|
|
157
|
+
senderId: string;
|
|
158
|
+
senderUsername: string;
|
|
159
|
+
amount: string;
|
|
160
|
+
currency: string;
|
|
161
|
+
} | {
|
|
162
|
+
command: "rain";
|
|
163
|
+
fromUserId: string;
|
|
164
|
+
amount: string;
|
|
165
|
+
currency: string;
|
|
166
|
+
recipientCount: number;
|
|
167
|
+
perRecipient: string;
|
|
168
|
+
} | {
|
|
169
|
+
command: "block";
|
|
170
|
+
targetUserId: string;
|
|
171
|
+
displayName: string;
|
|
172
|
+
} | {
|
|
173
|
+
command: "ignore";
|
|
174
|
+
targetUserId: string;
|
|
175
|
+
displayName: string;
|
|
176
|
+
} | {
|
|
177
|
+
command: "donate";
|
|
178
|
+
recipientId: string;
|
|
179
|
+
recipientUsername: string;
|
|
180
|
+
amount: string;
|
|
181
|
+
currency: string;
|
|
182
|
+
} | null;
|
|
109
183
|
roomId: string | null;
|
|
110
|
-
username: string;
|
|
111
184
|
content: string;
|
|
185
|
+
username: string;
|
|
112
186
|
isDeleted: boolean;
|
|
113
187
|
}, "createdAt">>;
|
|
114
188
|
deleteMessage(id: ChatMessage['id'], userId: User['id']): Promise<{
|
|
@@ -117,19 +191,89 @@ export declare class ChatService {
|
|
|
117
191
|
getGlobalMessages(limit?: number, viewerId?: User['id']): Promise<import("@openora/core/server").SerializedRow<{
|
|
118
192
|
id: string;
|
|
119
193
|
userId: string;
|
|
194
|
+
type: "system" | "user";
|
|
120
195
|
createdAt: Date;
|
|
196
|
+
metadata: {
|
|
197
|
+
command: "profile";
|
|
198
|
+
targetUserId: string;
|
|
199
|
+
displayName: string;
|
|
200
|
+
level: number;
|
|
201
|
+
} | {
|
|
202
|
+
command: "gift";
|
|
203
|
+
giftId: string;
|
|
204
|
+
senderId: string;
|
|
205
|
+
senderUsername: string;
|
|
206
|
+
amount: string;
|
|
207
|
+
currency: string;
|
|
208
|
+
} | {
|
|
209
|
+
command: "rain";
|
|
210
|
+
fromUserId: string;
|
|
211
|
+
amount: string;
|
|
212
|
+
currency: string;
|
|
213
|
+
recipientCount: number;
|
|
214
|
+
perRecipient: string;
|
|
215
|
+
} | {
|
|
216
|
+
command: "block";
|
|
217
|
+
targetUserId: string;
|
|
218
|
+
displayName: string;
|
|
219
|
+
} | {
|
|
220
|
+
command: "ignore";
|
|
221
|
+
targetUserId: string;
|
|
222
|
+
displayName: string;
|
|
223
|
+
} | {
|
|
224
|
+
command: "donate";
|
|
225
|
+
recipientId: string;
|
|
226
|
+
recipientUsername: string;
|
|
227
|
+
amount: string;
|
|
228
|
+
currency: string;
|
|
229
|
+
} | null;
|
|
121
230
|
roomId: string | null;
|
|
122
|
-
username: string;
|
|
123
231
|
content: string;
|
|
232
|
+
username: string;
|
|
124
233
|
isDeleted: boolean;
|
|
125
234
|
}, "createdAt">[]>;
|
|
126
235
|
sendGlobalMessage(userId: User['id'], username: string, content: string): Promise<import("@openora/core/server").SerializedRow<{
|
|
127
236
|
id: string;
|
|
128
237
|
userId: string;
|
|
238
|
+
type: "system" | "user";
|
|
129
239
|
createdAt: Date;
|
|
240
|
+
metadata: {
|
|
241
|
+
command: "profile";
|
|
242
|
+
targetUserId: string;
|
|
243
|
+
displayName: string;
|
|
244
|
+
level: number;
|
|
245
|
+
} | {
|
|
246
|
+
command: "gift";
|
|
247
|
+
giftId: string;
|
|
248
|
+
senderId: string;
|
|
249
|
+
senderUsername: string;
|
|
250
|
+
amount: string;
|
|
251
|
+
currency: string;
|
|
252
|
+
} | {
|
|
253
|
+
command: "rain";
|
|
254
|
+
fromUserId: string;
|
|
255
|
+
amount: string;
|
|
256
|
+
currency: string;
|
|
257
|
+
recipientCount: number;
|
|
258
|
+
perRecipient: string;
|
|
259
|
+
} | {
|
|
260
|
+
command: "block";
|
|
261
|
+
targetUserId: string;
|
|
262
|
+
displayName: string;
|
|
263
|
+
} | {
|
|
264
|
+
command: "ignore";
|
|
265
|
+
targetUserId: string;
|
|
266
|
+
displayName: string;
|
|
267
|
+
} | {
|
|
268
|
+
command: "donate";
|
|
269
|
+
recipientId: string;
|
|
270
|
+
recipientUsername: string;
|
|
271
|
+
amount: string;
|
|
272
|
+
currency: string;
|
|
273
|
+
} | null;
|
|
130
274
|
roomId: string | null;
|
|
131
|
-
username: string;
|
|
132
275
|
content: string;
|
|
276
|
+
username: string;
|
|
133
277
|
isDeleted: boolean;
|
|
134
278
|
}, "createdAt">>;
|
|
135
279
|
listBlockedUsers(blockerId: User['id']): Promise<import("@openora/core/server").SerializedRow<{
|
|
@@ -142,6 +286,17 @@ export declare class ChatService {
|
|
|
142
286
|
unblockUser(blockerId: User['id'], blockedId: User['id'], meta?: ClientMeta): Promise<{
|
|
143
287
|
readonly success: true;
|
|
144
288
|
}>;
|
|
289
|
+
listIgnoredUsers(ignorerId: User['id']): Promise<import("@openora/core/server").SerializedRow<{
|
|
290
|
+
ignoredId: string;
|
|
291
|
+
createdAt: Date;
|
|
292
|
+
}, "createdAt">[]>;
|
|
293
|
+
ignoreUser(ignorerId: User['id'], ignoredId: User['id'], meta?: ClientMeta): Promise<{
|
|
294
|
+
readonly success: true;
|
|
295
|
+
}>;
|
|
296
|
+
unignoreUser(ignorerId: User['id'], ignoredId: User['id'], meta?: ClientMeta): Promise<{
|
|
297
|
+
readonly success: true;
|
|
298
|
+
}>;
|
|
299
|
+
getExcludedUserIds(viewerId: User['id']): Promise<string[]>;
|
|
145
300
|
createRoom({ name, slug, category, actorId, ip, userAgent, }: {
|
|
146
301
|
name: string;
|
|
147
302
|
slug: string;
|
|
@@ -173,6 +328,12 @@ export declare class ChatService {
|
|
|
173
328
|
isPublic: boolean;
|
|
174
329
|
joinCode: string | null;
|
|
175
330
|
}, "createdAt">>;
|
|
331
|
+
deletePrivateRoom({ roomId, userId, ip, userAgent, }: {
|
|
332
|
+
roomId: ChatRoom['id'];
|
|
333
|
+
userId: User['id'];
|
|
334
|
+
} & ClientMeta): Promise<{
|
|
335
|
+
readonly success: true;
|
|
336
|
+
}>;
|
|
176
337
|
deleteRoom(id: ChatRoom['id'], actorId?: User['id'], meta?: ClientMeta): Promise<{
|
|
177
338
|
readonly success: true;
|
|
178
339
|
}>;
|
|
@@ -222,10 +383,17 @@ export declare class ChatService {
|
|
|
222
383
|
} & ClientMeta): Promise<{
|
|
223
384
|
readonly success: true;
|
|
224
385
|
}>;
|
|
386
|
+
postSystemMessage(args: {
|
|
387
|
+
roomId: ChatRoom['id'] | null;
|
|
388
|
+
actorId: User['id'];
|
|
389
|
+
metadata: CommandMetadata;
|
|
390
|
+
tx?: unknown;
|
|
391
|
+
}): Promise<ChatSystemMessage>;
|
|
225
392
|
listRoomMembers({ roomId, viewerId }: {
|
|
226
393
|
roomId: ChatRoom['id'];
|
|
227
394
|
viewerId?: User['id'];
|
|
228
395
|
}): Promise<import("@openora/core/server").SerializedRow<{
|
|
396
|
+
username: string | null;
|
|
229
397
|
userId: string;
|
|
230
398
|
role: "member" | "moderator";
|
|
231
399
|
joinedAt: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.service.d.ts","sourceRoot":"","sources":["../../../../src/engagement/chat/service/chat.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,QAAQ,EAMb,cAAc,
|
|
1
|
+
{"version":3,"file":"chat.service.d.ts","sourceRoot":"","sources":["../../../../src/engagement/chat/service/chat.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { randomInt, randomUUID } from 'node:crypto';
|
|
2
2
|
import { makeNotFoundError, makeOwnershipError, makeConflictError, createDomainError, assertOwnership, findOneOrThrow, serializeRow, pageToOffset, withAdvisoryXactLock, } from '@openora/core/server';
|
|
3
|
+
import { chatChannel } from '@openora/core/contracts';
|
|
3
4
|
import { eq, and, isNull, lt, desc, asc, notInArray, inArray, count, ne } from 'drizzle-orm';
|
|
4
5
|
import { user } from '@openora/core/pam/schema/identity';
|
|
5
|
-
import { chatRoom, chatMessage, chatUserBlock, chatRoomMember, chatRoomBan, } from '../schema/index.js';
|
|
6
|
+
import { chatRoom, chatMessage, chatUserBlock, chatUserIgnore, chatRoomMember, chatRoomBan, } from '../schema/index.js';
|
|
6
7
|
import { DEFAULT_MESSAGE_LIMIT, JOIN_CODE_ALPHABET, JOIN_CODE_LENGTH, MAX_PRIVATE_ROOMS_PER_PLAYER, PRIVATE_ROOM_SLUG_PREFIX, } from '../contract/constants.js';
|
|
7
8
|
import { moderateContent } from '../moderation/index.js';
|
|
8
|
-
export function chatChannel(roomId) {
|
|
9
|
-
return roomId ? `chat:room:${roomId}` : 'chat:global';
|
|
10
|
-
}
|
|
11
9
|
export const ChatRoomNotFoundError = makeNotFoundError('ChatRoom');
|
|
10
|
+
export const ChatRoomOwnershipError = makeOwnershipError('ChatRoom');
|
|
12
11
|
export const ChatMessageNotFoundError = makeNotFoundError('ChatMessage');
|
|
13
12
|
export const ChatMessageOwnershipError = makeOwnershipError('ChatMessage');
|
|
14
13
|
export const ChatMessageBlockedError = createDomainError('ChatMessageBlockedError', () => 'Message blocked: it contains prohibited language');
|
|
15
14
|
export const ChatSelfBlockError = createDomainError('ChatSelfBlockError', () => 'You cannot block yourself');
|
|
15
|
+
export const ChatSelfIgnoreError = createDomainError('ChatSelfIgnoreError', () => 'You cannot ignore yourself');
|
|
16
16
|
export const ChatRoomSlugConflictError = makeConflictError('ChatRoomSlugConflictError', 'A room with this slug already exists');
|
|
17
17
|
export const ChatRoomLimitReachedError = makeConflictError('ChatRoomLimitReachedError', 'Private room limit reached');
|
|
18
18
|
export const ChatRoomLastModeratorError = makeConflictError('ChatRoomLastModeratorError', 'Cannot leave: you are the sole moderator of this room');
|
|
@@ -59,10 +59,12 @@ export class ChatService {
|
|
|
59
59
|
drizzle;
|
|
60
60
|
events;
|
|
61
61
|
transport;
|
|
62
|
-
|
|
62
|
+
directory;
|
|
63
|
+
constructor(drizzle, events, transport, directory) {
|
|
63
64
|
this.drizzle = drizzle;
|
|
64
65
|
this.events = events;
|
|
65
66
|
this.transport = transport;
|
|
67
|
+
this.directory = directory;
|
|
66
68
|
}
|
|
67
69
|
subscribeMessages(roomId, listener, viewerId, connectionId = randomUUID()) {
|
|
68
70
|
const channel = chatChannel(roomId);
|
|
@@ -77,7 +79,7 @@ export class ChatService {
|
|
|
77
79
|
}
|
|
78
80
|
};
|
|
79
81
|
if (viewerId) {
|
|
80
|
-
this.
|
|
82
|
+
this.excludedSenderIdsFor(viewerId)
|
|
81
83
|
.catch(() => new Set())
|
|
82
84
|
.then((ids) => {
|
|
83
85
|
blocked = ids;
|
|
@@ -111,6 +113,20 @@ export class ChatService {
|
|
|
111
113
|
.where(eq(chatUserBlock.blockerId, viewerId));
|
|
112
114
|
return new Set(rows.map((r) => r.blockedId));
|
|
113
115
|
}
|
|
116
|
+
async ignoredIdsFor(viewerId) {
|
|
117
|
+
const rows = await this.drizzle.db
|
|
118
|
+
.select({ ignoredId: chatUserIgnore.ignoredId })
|
|
119
|
+
.from(chatUserIgnore)
|
|
120
|
+
.where(eq(chatUserIgnore.ignorerId, viewerId));
|
|
121
|
+
return new Set(rows.map((r) => r.ignoredId));
|
|
122
|
+
}
|
|
123
|
+
async excludedSenderIdsFor(viewerId) {
|
|
124
|
+
const [blocked, ignored] = await Promise.all([
|
|
125
|
+
this.blockedIdsFor(viewerId),
|
|
126
|
+
this.ignoredIdsFor(viewerId),
|
|
127
|
+
]);
|
|
128
|
+
return new Set([...blocked, ...ignored]);
|
|
129
|
+
}
|
|
114
130
|
async resolveDisplayName(userId, fallback) {
|
|
115
131
|
const [row] = await this.drizzle.db
|
|
116
132
|
.select({ name: user.name })
|
|
@@ -193,7 +209,7 @@ export class ChatService {
|
|
|
193
209
|
if (before) {
|
|
194
210
|
conditions.push(lt(chatMessage.createdAt, new Date(before)));
|
|
195
211
|
}
|
|
196
|
-
await this.
|
|
212
|
+
await this.appendExcludedSendersFilter(conditions, viewerId);
|
|
197
213
|
const messages = await this.drizzle.db
|
|
198
214
|
.select()
|
|
199
215
|
.from(chatMessage)
|
|
@@ -202,13 +218,13 @@ export class ChatService {
|
|
|
202
218
|
.limit(limit);
|
|
203
219
|
return messages.map(toMessage);
|
|
204
220
|
}
|
|
205
|
-
async
|
|
221
|
+
async appendExcludedSendersFilter(conditions, viewerId) {
|
|
206
222
|
if (!viewerId) {
|
|
207
223
|
return;
|
|
208
224
|
}
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
211
|
-
conditions.push(notInArray(chatMessage.userId, [...
|
|
225
|
+
const excluded = await this.excludedSenderIdsFor(viewerId);
|
|
226
|
+
if (excluded.size > 0) {
|
|
227
|
+
conditions.push(notInArray(chatMessage.userId, [...excluded]));
|
|
212
228
|
}
|
|
213
229
|
}
|
|
214
230
|
async sendRoomMessage({ userId, username, roomId, content, }) {
|
|
@@ -245,7 +261,7 @@ export class ChatService {
|
|
|
245
261
|
}
|
|
246
262
|
async getGlobalMessages(limit = DEFAULT_MESSAGE_LIMIT, viewerId) {
|
|
247
263
|
const conditions = [isNull(chatMessage.roomId), eq(chatMessage.isDeleted, false)];
|
|
248
|
-
await this.
|
|
264
|
+
await this.appendExcludedSendersFilter(conditions, viewerId);
|
|
249
265
|
const messages = await this.drizzle.db
|
|
250
266
|
.select()
|
|
251
267
|
.from(chatMessage)
|
|
@@ -319,6 +335,52 @@ export class ChatService {
|
|
|
319
335
|
}
|
|
320
336
|
return { success: true };
|
|
321
337
|
}
|
|
338
|
+
async listIgnoredUsers(ignorerId) {
|
|
339
|
+
const rows = await this.drizzle.db
|
|
340
|
+
.select({ ignoredId: chatUserIgnore.ignoredId, createdAt: chatUserIgnore.createdAt })
|
|
341
|
+
.from(chatUserIgnore)
|
|
342
|
+
.where(eq(chatUserIgnore.ignorerId, ignorerId))
|
|
343
|
+
.orderBy(desc(chatUserIgnore.createdAt));
|
|
344
|
+
return rows.map((r) => serializeRow(r, { dateFields: ['createdAt'] }));
|
|
345
|
+
}
|
|
346
|
+
async ignoreUser(ignorerId, ignoredId, meta) {
|
|
347
|
+
if (ignorerId === ignoredId) {
|
|
348
|
+
throw new ChatSelfIgnoreError();
|
|
349
|
+
}
|
|
350
|
+
// Idempotent: re-ignoring is a no-op, so only the first ignore emits an event.
|
|
351
|
+
const inserted = await this.drizzle.db
|
|
352
|
+
.insert(chatUserIgnore)
|
|
353
|
+
.values({ ignorerId, ignoredId })
|
|
354
|
+
.onConflictDoNothing({ target: [chatUserIgnore.ignorerId, chatUserIgnore.ignoredId] })
|
|
355
|
+
.returning();
|
|
356
|
+
if (inserted.length > 0) {
|
|
357
|
+
this.events.emit('chat.user.ignored', {
|
|
358
|
+
ignorerId,
|
|
359
|
+
ignoredId,
|
|
360
|
+
ip: meta?.ip ?? null,
|
|
361
|
+
userAgent: meta?.userAgent ?? null,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return { success: true };
|
|
365
|
+
}
|
|
366
|
+
async unignoreUser(ignorerId, ignoredId, meta) {
|
|
367
|
+
const removed = await this.drizzle.db
|
|
368
|
+
.delete(chatUserIgnore)
|
|
369
|
+
.where(and(eq(chatUserIgnore.ignorerId, ignorerId), eq(chatUserIgnore.ignoredId, ignoredId)))
|
|
370
|
+
.returning();
|
|
371
|
+
if (removed.length > 0) {
|
|
372
|
+
this.events.emit('chat.user.unignored', {
|
|
373
|
+
ignorerId,
|
|
374
|
+
ignoredId,
|
|
375
|
+
ip: meta?.ip ?? null,
|
|
376
|
+
userAgent: meta?.userAgent ?? null,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
return { success: true };
|
|
380
|
+
}
|
|
381
|
+
async getExcludedUserIds(viewerId) {
|
|
382
|
+
return [...(await this.excludedSenderIdsFor(viewerId))];
|
|
383
|
+
}
|
|
322
384
|
async createRoom({ name, slug, category, actorId, ip, userAgent, }) {
|
|
323
385
|
const [existing] = await this.drizzle.db
|
|
324
386
|
.select({ id: chatRoom.id })
|
|
@@ -402,6 +464,28 @@ export class ChatService {
|
|
|
402
464
|
});
|
|
403
465
|
return toRoom(updated);
|
|
404
466
|
}
|
|
467
|
+
async deletePrivateRoom({ roomId, userId, ip, userAgent, }) {
|
|
468
|
+
const room = findOneOrThrow(await this.drizzle.db
|
|
469
|
+
.select()
|
|
470
|
+
.from(chatRoom)
|
|
471
|
+
.where(and(eq(chatRoom.id, roomId), eq(chatRoom.isPublic, false), isNull(chatRoom.deletedAt)))
|
|
472
|
+
.limit(1), new ChatRoomNotFoundError(roomId));
|
|
473
|
+
if (!room.creatorId) {
|
|
474
|
+
throw new ChatRoomOwnershipError();
|
|
475
|
+
}
|
|
476
|
+
assertOwnership(room.creatorId, userId, new ChatRoomOwnershipError());
|
|
477
|
+
await this.drizzle.db
|
|
478
|
+
.update(chatRoom)
|
|
479
|
+
.set({ deletedAt: new Date() })
|
|
480
|
+
.where(eq(chatRoom.id, roomId));
|
|
481
|
+
this.events.emit('chat.private_room.deleted', {
|
|
482
|
+
roomId,
|
|
483
|
+
creatorId: userId,
|
|
484
|
+
ip: ip ?? null,
|
|
485
|
+
userAgent: userAgent ?? null,
|
|
486
|
+
});
|
|
487
|
+
return { success: true };
|
|
488
|
+
}
|
|
405
489
|
async deleteRoom(id, actorId, meta) {
|
|
406
490
|
const deleted = findOneOrThrow(await this.drizzle.db
|
|
407
491
|
.update(chatRoom)
|
|
@@ -610,6 +694,36 @@ export class ChatService {
|
|
|
610
694
|
await this.transport.revokeClient?.(userId);
|
|
611
695
|
return { success: true };
|
|
612
696
|
}
|
|
697
|
+
async postSystemMessage(args) {
|
|
698
|
+
const db = args.tx ?? this.drizzle.db;
|
|
699
|
+
const [record] = await db
|
|
700
|
+
.insert(chatMessage)
|
|
701
|
+
.values({
|
|
702
|
+
roomId: args.roomId,
|
|
703
|
+
userId: args.actorId,
|
|
704
|
+
username: 'system',
|
|
705
|
+
content: '',
|
|
706
|
+
type: 'system',
|
|
707
|
+
metadata: args.metadata,
|
|
708
|
+
})
|
|
709
|
+
.returning();
|
|
710
|
+
const msg = {
|
|
711
|
+
id: record.id,
|
|
712
|
+
roomId: record.roomId ?? null,
|
|
713
|
+
actorId: args.actorId,
|
|
714
|
+
content: record.content,
|
|
715
|
+
metadata: args.metadata,
|
|
716
|
+
createdAt: record.createdAt.toISOString(),
|
|
717
|
+
};
|
|
718
|
+
// Only auto-publish when this call owns the write (no caller-managed transaction).
|
|
719
|
+
// When `tx` is passed, the caller's transaction hasn't committed yet - publishing
|
|
720
|
+
// here would leak a message to clients before (or even if) it actually commits.
|
|
721
|
+
// The caller must publish itself after its transaction resolves.
|
|
722
|
+
if (!args.tx) {
|
|
723
|
+
void this.transport.publish(chatChannel(args.roomId), msg);
|
|
724
|
+
}
|
|
725
|
+
return msg;
|
|
726
|
+
}
|
|
613
727
|
async listRoomMembers({ roomId, viewerId }) {
|
|
614
728
|
await this.verifyRoomAccess(roomId, viewerId);
|
|
615
729
|
const members = await this.drizzle.db
|
|
@@ -621,7 +735,9 @@ export class ChatService {
|
|
|
621
735
|
.from(chatRoomMember)
|
|
622
736
|
.where(eq(chatRoomMember.roomId, roomId))
|
|
623
737
|
.orderBy(asc(chatRoomMember.joinedAt));
|
|
624
|
-
|
|
738
|
+
const summaries = await this.directory.lookupPlayers(members.map((m) => m.userId));
|
|
739
|
+
const usernameByUserId = new Map(summaries.map((s) => [s.userId, s.username]));
|
|
740
|
+
return members.map((m) => serializeRow({ ...m, username: usernameByUserId.get(m.userId) ?? null }, { dateFields: ['joinedAt'] }));
|
|
625
741
|
}
|
|
626
742
|
}
|
|
627
743
|
//# sourceMappingURL=chat.service.js.map
|