@shadowob/shared 1.1.0 → 1.1.3
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/{chunk-EMLX23LF.js → chunk-DMUZB4WV.js} +3 -4
- package/dist/{chunk-PXKHJSTK.js → chunk-E3UBH4AI.js} +193 -0
- package/dist/chunk-EXZEQO5X.js +429 -0
- package/dist/constants/index.cjs +3 -4
- package/dist/constants/index.d.cts +2 -3
- package/dist/constants/index.d.ts +2 -3
- package/dist/constants/index.js +1 -1
- package/dist/index.cjs +637 -4
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +32 -2
- package/dist/message.types-lG4qBSus.d.cts +182 -0
- package/dist/message.types-lG4qBSus.d.ts +182 -0
- package/dist/play-catalog/index.cjs +457 -0
- package/dist/play-catalog/index.d.cts +77 -0
- package/dist/play-catalog/index.d.ts +77 -0
- package/dist/play-catalog/index.js +14 -0
- package/dist/types/index.d.cts +23 -120
- package/dist/types/index.d.ts +23 -120
- package/dist/utils/index.cjs +202 -0
- package/dist/utils/index.d.cts +40 -1
- package/dist/utils/index.d.ts +40 -1
- package/dist/utils/index.js +19 -1
- package/package.json +15 -2
package/dist/types/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, M as MentionSuggestion, c as MentionSuggestionTrigger, d as Message, e as MessageMention, f as MessageMentionKind, g as MessageMentionRange, h as MessageMetadata, N as Notification, i as NotificationType, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, T as Thread, U as UpdateMessageRequest } from '../message.types-lG4qBSus.cjs';
|
|
2
|
+
|
|
1
3
|
type AgentStatus = 'running' | 'stopped' | 'error';
|
|
2
4
|
type AgentKernelType = 'claude-code' | 'cursor' | 'mcp-server' | 'custom';
|
|
3
5
|
type AgentCapability = 'chat' | 'code-gen' | 'code-review' | 'research' | 'tools' | 'file-access';
|
|
@@ -72,7 +74,7 @@ interface Friendship {
|
|
|
72
74
|
createdAt: string;
|
|
73
75
|
updatedAt: string;
|
|
74
76
|
}
|
|
75
|
-
type FriendSource = 'friend' | '
|
|
77
|
+
type FriendSource = 'friend' | 'owned_agent' | 'rented_agent';
|
|
76
78
|
interface FriendEntry {
|
|
77
79
|
friendshipId: string;
|
|
78
80
|
/** Where this friend entry comes from */
|
|
@@ -88,122 +90,6 @@ interface FriendEntry {
|
|
|
88
90
|
createdAt: string;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
interface Message {
|
|
92
|
-
id: string;
|
|
93
|
-
content: string;
|
|
94
|
-
channelId: string;
|
|
95
|
-
authorId: string;
|
|
96
|
-
threadId: string | null;
|
|
97
|
-
replyToId: string | null;
|
|
98
|
-
isEdited: boolean;
|
|
99
|
-
isPinned: boolean;
|
|
100
|
-
createdAt: string;
|
|
101
|
-
updatedAt: string;
|
|
102
|
-
author?: {
|
|
103
|
-
id: string;
|
|
104
|
-
username: string;
|
|
105
|
-
displayName: string;
|
|
106
|
-
avatarUrl: string | null;
|
|
107
|
-
isBot: boolean;
|
|
108
|
-
};
|
|
109
|
-
attachments?: Attachment[];
|
|
110
|
-
reactions?: ReactionGroup[];
|
|
111
|
-
}
|
|
112
|
-
interface Attachment {
|
|
113
|
-
id: string;
|
|
114
|
-
messageId: string;
|
|
115
|
-
filename: string;
|
|
116
|
-
url: string;
|
|
117
|
-
contentType: string;
|
|
118
|
-
size: number;
|
|
119
|
-
width: number | null;
|
|
120
|
-
height: number | null;
|
|
121
|
-
createdAt: string;
|
|
122
|
-
}
|
|
123
|
-
interface ReactionGroup {
|
|
124
|
-
emoji: string;
|
|
125
|
-
count: number;
|
|
126
|
-
userIds: string[];
|
|
127
|
-
}
|
|
128
|
-
interface Thread {
|
|
129
|
-
id: string;
|
|
130
|
-
name: string;
|
|
131
|
-
channelId: string;
|
|
132
|
-
parentMessageId: string;
|
|
133
|
-
creatorId: string;
|
|
134
|
-
isArchived: boolean;
|
|
135
|
-
createdAt: string;
|
|
136
|
-
updatedAt: string;
|
|
137
|
-
}
|
|
138
|
-
interface SendMessageRequest {
|
|
139
|
-
content: string;
|
|
140
|
-
threadId?: string;
|
|
141
|
-
replyToId?: string;
|
|
142
|
-
}
|
|
143
|
-
interface UpdateMessageRequest {
|
|
144
|
-
content: string;
|
|
145
|
-
}
|
|
146
|
-
type NotificationType = 'mention' | 'reply' | 'dm' | 'system';
|
|
147
|
-
interface Notification {
|
|
148
|
-
id: string;
|
|
149
|
-
userId: string;
|
|
150
|
-
type: NotificationType;
|
|
151
|
-
title: string;
|
|
152
|
-
body: string | null;
|
|
153
|
-
referenceId: string | null;
|
|
154
|
-
referenceType: string | null;
|
|
155
|
-
isRead: boolean;
|
|
156
|
-
createdAt: string;
|
|
157
|
-
}
|
|
158
|
-
interface DmChannel {
|
|
159
|
-
id: string;
|
|
160
|
-
userAId: string;
|
|
161
|
-
userBId: string;
|
|
162
|
-
lastMessageAt: string | null;
|
|
163
|
-
createdAt: string;
|
|
164
|
-
otherUser?: {
|
|
165
|
-
id: string;
|
|
166
|
-
username: string;
|
|
167
|
-
displayName: string;
|
|
168
|
-
avatarUrl: string | null;
|
|
169
|
-
status: string;
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
/** DM message — mirrors channel Message but scoped to DM channels */
|
|
173
|
-
interface DmMessage {
|
|
174
|
-
id: string;
|
|
175
|
-
content: string;
|
|
176
|
-
dmChannelId: string;
|
|
177
|
-
authorId: string;
|
|
178
|
-
replyToId: string | null;
|
|
179
|
-
isEdited: boolean;
|
|
180
|
-
createdAt: string;
|
|
181
|
-
updatedAt: string;
|
|
182
|
-
author?: {
|
|
183
|
-
id: string;
|
|
184
|
-
username: string;
|
|
185
|
-
displayName: string;
|
|
186
|
-
avatarUrl: string | null;
|
|
187
|
-
isBot: boolean;
|
|
188
|
-
};
|
|
189
|
-
attachments?: DmAttachment[];
|
|
190
|
-
reactions?: ReactionGroup[];
|
|
191
|
-
}
|
|
192
|
-
interface DmAttachment {
|
|
193
|
-
id: string;
|
|
194
|
-
dmMessageId: string;
|
|
195
|
-
filename: string;
|
|
196
|
-
url: string;
|
|
197
|
-
contentType: string;
|
|
198
|
-
size: number;
|
|
199
|
-
width: number | null;
|
|
200
|
-
height: number | null;
|
|
201
|
-
createdAt: string;
|
|
202
|
-
}
|
|
203
|
-
interface UpdateDmMessageRequest {
|
|
204
|
-
content: string;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
93
|
interface Server {
|
|
208
94
|
id: string;
|
|
209
95
|
name: string;
|
|
@@ -248,6 +134,7 @@ interface User {
|
|
|
248
134
|
avatarUrl: string | null;
|
|
249
135
|
status: UserStatus;
|
|
250
136
|
isBot: boolean;
|
|
137
|
+
membership?: UserMembership;
|
|
251
138
|
createdAt: string;
|
|
252
139
|
updatedAt: string;
|
|
253
140
|
}
|
|
@@ -265,14 +152,30 @@ interface LoginRequest {
|
|
|
265
152
|
}
|
|
266
153
|
interface RegisterRequest {
|
|
267
154
|
email: string;
|
|
268
|
-
username
|
|
269
|
-
displayName
|
|
155
|
+
username?: string;
|
|
156
|
+
displayName?: string;
|
|
270
157
|
password: string;
|
|
158
|
+
inviteCode?: string;
|
|
271
159
|
}
|
|
272
160
|
interface AuthResponse {
|
|
273
161
|
user: User;
|
|
274
162
|
accessToken: string;
|
|
275
163
|
refreshToken: string;
|
|
276
164
|
}
|
|
165
|
+
interface UserMembershipTier {
|
|
166
|
+
id: string;
|
|
167
|
+
level: number;
|
|
168
|
+
label: string;
|
|
169
|
+
capabilities: string[];
|
|
170
|
+
}
|
|
171
|
+
interface UserMembership {
|
|
172
|
+
status: string;
|
|
173
|
+
tier: UserMembershipTier;
|
|
174
|
+
level: number;
|
|
175
|
+
isMember: boolean;
|
|
176
|
+
memberSince?: string | null;
|
|
177
|
+
inviteCodeId?: string | null;
|
|
178
|
+
capabilities: string[];
|
|
179
|
+
}
|
|
277
180
|
|
|
278
|
-
export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus,
|
|
181
|
+
export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, RegisterRequest, Server, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { A as Attachment, C as CommerceMessageCard, a as CommerceOfferCardInput, b as CommerceProductCard, M as MentionSuggestion, c as MentionSuggestionTrigger, d as Message, e as MessageMention, f as MessageMentionKind, g as MessageMentionRange, h as MessageMetadata, N as Notification, i as NotificationType, P as PaidFileCard, R as ReactionGroup, S as SendMessageRequest, T as Thread, U as UpdateMessageRequest } from '../message.types-lG4qBSus.js';
|
|
2
|
+
|
|
1
3
|
type AgentStatus = 'running' | 'stopped' | 'error';
|
|
2
4
|
type AgentKernelType = 'claude-code' | 'cursor' | 'mcp-server' | 'custom';
|
|
3
5
|
type AgentCapability = 'chat' | 'code-gen' | 'code-review' | 'research' | 'tools' | 'file-access';
|
|
@@ -72,7 +74,7 @@ interface Friendship {
|
|
|
72
74
|
createdAt: string;
|
|
73
75
|
updatedAt: string;
|
|
74
76
|
}
|
|
75
|
-
type FriendSource = 'friend' | '
|
|
77
|
+
type FriendSource = 'friend' | 'owned_agent' | 'rented_agent';
|
|
76
78
|
interface FriendEntry {
|
|
77
79
|
friendshipId: string;
|
|
78
80
|
/** Where this friend entry comes from */
|
|
@@ -88,122 +90,6 @@ interface FriendEntry {
|
|
|
88
90
|
createdAt: string;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
interface Message {
|
|
92
|
-
id: string;
|
|
93
|
-
content: string;
|
|
94
|
-
channelId: string;
|
|
95
|
-
authorId: string;
|
|
96
|
-
threadId: string | null;
|
|
97
|
-
replyToId: string | null;
|
|
98
|
-
isEdited: boolean;
|
|
99
|
-
isPinned: boolean;
|
|
100
|
-
createdAt: string;
|
|
101
|
-
updatedAt: string;
|
|
102
|
-
author?: {
|
|
103
|
-
id: string;
|
|
104
|
-
username: string;
|
|
105
|
-
displayName: string;
|
|
106
|
-
avatarUrl: string | null;
|
|
107
|
-
isBot: boolean;
|
|
108
|
-
};
|
|
109
|
-
attachments?: Attachment[];
|
|
110
|
-
reactions?: ReactionGroup[];
|
|
111
|
-
}
|
|
112
|
-
interface Attachment {
|
|
113
|
-
id: string;
|
|
114
|
-
messageId: string;
|
|
115
|
-
filename: string;
|
|
116
|
-
url: string;
|
|
117
|
-
contentType: string;
|
|
118
|
-
size: number;
|
|
119
|
-
width: number | null;
|
|
120
|
-
height: number | null;
|
|
121
|
-
createdAt: string;
|
|
122
|
-
}
|
|
123
|
-
interface ReactionGroup {
|
|
124
|
-
emoji: string;
|
|
125
|
-
count: number;
|
|
126
|
-
userIds: string[];
|
|
127
|
-
}
|
|
128
|
-
interface Thread {
|
|
129
|
-
id: string;
|
|
130
|
-
name: string;
|
|
131
|
-
channelId: string;
|
|
132
|
-
parentMessageId: string;
|
|
133
|
-
creatorId: string;
|
|
134
|
-
isArchived: boolean;
|
|
135
|
-
createdAt: string;
|
|
136
|
-
updatedAt: string;
|
|
137
|
-
}
|
|
138
|
-
interface SendMessageRequest {
|
|
139
|
-
content: string;
|
|
140
|
-
threadId?: string;
|
|
141
|
-
replyToId?: string;
|
|
142
|
-
}
|
|
143
|
-
interface UpdateMessageRequest {
|
|
144
|
-
content: string;
|
|
145
|
-
}
|
|
146
|
-
type NotificationType = 'mention' | 'reply' | 'dm' | 'system';
|
|
147
|
-
interface Notification {
|
|
148
|
-
id: string;
|
|
149
|
-
userId: string;
|
|
150
|
-
type: NotificationType;
|
|
151
|
-
title: string;
|
|
152
|
-
body: string | null;
|
|
153
|
-
referenceId: string | null;
|
|
154
|
-
referenceType: string | null;
|
|
155
|
-
isRead: boolean;
|
|
156
|
-
createdAt: string;
|
|
157
|
-
}
|
|
158
|
-
interface DmChannel {
|
|
159
|
-
id: string;
|
|
160
|
-
userAId: string;
|
|
161
|
-
userBId: string;
|
|
162
|
-
lastMessageAt: string | null;
|
|
163
|
-
createdAt: string;
|
|
164
|
-
otherUser?: {
|
|
165
|
-
id: string;
|
|
166
|
-
username: string;
|
|
167
|
-
displayName: string;
|
|
168
|
-
avatarUrl: string | null;
|
|
169
|
-
status: string;
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
/** DM message — mirrors channel Message but scoped to DM channels */
|
|
173
|
-
interface DmMessage {
|
|
174
|
-
id: string;
|
|
175
|
-
content: string;
|
|
176
|
-
dmChannelId: string;
|
|
177
|
-
authorId: string;
|
|
178
|
-
replyToId: string | null;
|
|
179
|
-
isEdited: boolean;
|
|
180
|
-
createdAt: string;
|
|
181
|
-
updatedAt: string;
|
|
182
|
-
author?: {
|
|
183
|
-
id: string;
|
|
184
|
-
username: string;
|
|
185
|
-
displayName: string;
|
|
186
|
-
avatarUrl: string | null;
|
|
187
|
-
isBot: boolean;
|
|
188
|
-
};
|
|
189
|
-
attachments?: DmAttachment[];
|
|
190
|
-
reactions?: ReactionGroup[];
|
|
191
|
-
}
|
|
192
|
-
interface DmAttachment {
|
|
193
|
-
id: string;
|
|
194
|
-
dmMessageId: string;
|
|
195
|
-
filename: string;
|
|
196
|
-
url: string;
|
|
197
|
-
contentType: string;
|
|
198
|
-
size: number;
|
|
199
|
-
width: number | null;
|
|
200
|
-
height: number | null;
|
|
201
|
-
createdAt: string;
|
|
202
|
-
}
|
|
203
|
-
interface UpdateDmMessageRequest {
|
|
204
|
-
content: string;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
93
|
interface Server {
|
|
208
94
|
id: string;
|
|
209
95
|
name: string;
|
|
@@ -248,6 +134,7 @@ interface User {
|
|
|
248
134
|
avatarUrl: string | null;
|
|
249
135
|
status: UserStatus;
|
|
250
136
|
isBot: boolean;
|
|
137
|
+
membership?: UserMembership;
|
|
251
138
|
createdAt: string;
|
|
252
139
|
updatedAt: string;
|
|
253
140
|
}
|
|
@@ -265,14 +152,30 @@ interface LoginRequest {
|
|
|
265
152
|
}
|
|
266
153
|
interface RegisterRequest {
|
|
267
154
|
email: string;
|
|
268
|
-
username
|
|
269
|
-
displayName
|
|
155
|
+
username?: string;
|
|
156
|
+
displayName?: string;
|
|
270
157
|
password: string;
|
|
158
|
+
inviteCode?: string;
|
|
271
159
|
}
|
|
272
160
|
interface AuthResponse {
|
|
273
161
|
user: User;
|
|
274
162
|
accessToken: string;
|
|
275
163
|
refreshToken: string;
|
|
276
164
|
}
|
|
165
|
+
interface UserMembershipTier {
|
|
166
|
+
id: string;
|
|
167
|
+
level: number;
|
|
168
|
+
label: string;
|
|
169
|
+
capabilities: string[];
|
|
170
|
+
}
|
|
171
|
+
interface UserMembership {
|
|
172
|
+
status: string;
|
|
173
|
+
tier: UserMembershipTier;
|
|
174
|
+
level: number;
|
|
175
|
+
isMember: boolean;
|
|
176
|
+
memberSince?: string | null;
|
|
177
|
+
inviteCodeId?: string | null;
|
|
178
|
+
capabilities: string[];
|
|
179
|
+
}
|
|
277
180
|
|
|
278
|
-
export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus,
|
|
181
|
+
export type { Agent, AgentCapability, AgentInfo, AgentKernelType, AgentStatus, AuthResponse, Channel, ChannelSortBy, ChannelSortDirection, ChannelSortOptions, ChannelType, CreateAgentRequest, CreateChannelRequest, CreateServerRequest, FriendEntry, FriendSource, Friendship, FriendshipStatus, LoginRequest, Member, MemberRole, RegisterRequest, Server, UpdateChannelRequest, UpdateServerRequest, User, UserMembership, UserMembershipTier, UserProfile, UserStatus };
|
package/dist/utils/index.cjs
CHANGED
|
@@ -21,6 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var utils_exports = {};
|
|
22
22
|
__export(utils_exports, {
|
|
23
23
|
CAT_AVATAR_COUNT: () => CAT_AVATAR_COUNT,
|
|
24
|
+
assignMentionRanges: () => assignMentionRanges,
|
|
25
|
+
buildMentionMarkdownLinks: () => buildMentionMarkdownLinks,
|
|
26
|
+
canonicalMentionToken: () => canonicalMentionToken,
|
|
27
|
+
canonicalizeMentionContent: () => canonicalizeMentionContent,
|
|
28
|
+
escapeMarkdownLinkLabel: () => escapeMarkdownLinkLabel,
|
|
24
29
|
formatDate: () => formatDate,
|
|
25
30
|
generateInviteCode: () => generateInviteCode,
|
|
26
31
|
generateRandomCatConfig: () => generateRandomCatConfig,
|
|
@@ -28,8 +33,12 @@ __export(utils_exports, {
|
|
|
28
33
|
getCatAvatar: () => getCatAvatar,
|
|
29
34
|
getCatAvatarByUserId: () => getCatAvatarByUserId,
|
|
30
35
|
getCatSvgString: () => getCatSvgString,
|
|
36
|
+
isCanonicalMentionToken: () => isCanonicalMentionToken,
|
|
31
37
|
isValidEmail: () => isValidEmail,
|
|
38
|
+
mentionDisplayText: () => mentionDisplayText,
|
|
39
|
+
parseCanonicalMentionToken: () => parseCanonicalMentionToken,
|
|
32
40
|
renderCatSvg: () => renderCatSvg,
|
|
41
|
+
segmentTextByMentions: () => segmentTextByMentions,
|
|
33
42
|
slugify: () => slugify
|
|
34
43
|
});
|
|
35
44
|
module.exports = __toCommonJS(utils_exports);
|
|
@@ -217,6 +226,190 @@ function renderCatSvg(config) {
|
|
|
217
226
|
return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`;
|
|
218
227
|
}
|
|
219
228
|
|
|
229
|
+
// src/utils/message-mentions.ts
|
|
230
|
+
function uniqueValues(values) {
|
|
231
|
+
return Array.from(new Set(values.filter((value) => !!value)));
|
|
232
|
+
}
|
|
233
|
+
function canonicalMentionToken(mention) {
|
|
234
|
+
if (mention.kind === "channel") return `<#${mention.channelId ?? mention.targetId}>`;
|
|
235
|
+
if (mention.kind === "server") return `<@server:${mention.serverId ?? mention.targetId}>`;
|
|
236
|
+
if (mention.kind === "here" || mention.kind === "everyone") {
|
|
237
|
+
const scope = mention.serverId ?? mention.targetId;
|
|
238
|
+
return scope ? `<!${mention.kind}:${scope}>` : `<!${mention.kind}>`;
|
|
239
|
+
}
|
|
240
|
+
return `<@${mention.userId ?? mention.targetId}>`;
|
|
241
|
+
}
|
|
242
|
+
function parseCanonicalMentionToken(token) {
|
|
243
|
+
const user = token.match(/^<@([^>:]+)>$/u);
|
|
244
|
+
if (user?.[1]) return { kind: "user", targetId: user[1] };
|
|
245
|
+
const server = token.match(/^<@server:([^>]+)>$/u);
|
|
246
|
+
if (server?.[1]) return { kind: "server", targetId: server[1] };
|
|
247
|
+
const channel = token.match(/^<#([^>]+)>$/u);
|
|
248
|
+
if (channel?.[1]) return { kind: "channel", targetId: channel[1] };
|
|
249
|
+
const broadcast = token.match(/^<!(here|everyone)(?::([^>]+))?>$/u);
|
|
250
|
+
if (broadcast?.[1] === "here" || broadcast?.[1] === "everyone") {
|
|
251
|
+
return {
|
|
252
|
+
kind: broadcast[1],
|
|
253
|
+
...broadcast[2] ? { targetId: broadcast[2] } : {}
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
function isCanonicalMentionToken(token) {
|
|
259
|
+
return parseCanonicalMentionToken(token) !== null;
|
|
260
|
+
}
|
|
261
|
+
function matchTextsForMention(mention) {
|
|
262
|
+
return uniqueValues([mention.token, mention.sourceToken, canonicalMentionToken(mention)]);
|
|
263
|
+
}
|
|
264
|
+
function isValidRange(content, mention, range) {
|
|
265
|
+
if (!range) return false;
|
|
266
|
+
if (!Number.isInteger(range.start) || !Number.isInteger(range.end)) return false;
|
|
267
|
+
if (range.start < 0 || range.end <= range.start || range.end > content.length) return false;
|
|
268
|
+
const sourceText = content.slice(range.start, range.end);
|
|
269
|
+
return matchTextsForMention(mention).includes(sourceText);
|
|
270
|
+
}
|
|
271
|
+
function overlaps(a, b) {
|
|
272
|
+
return a.start < b.end && b.start < a.end;
|
|
273
|
+
}
|
|
274
|
+
function canUseRange(range, used) {
|
|
275
|
+
return !used.some((candidate) => overlaps(candidate, range));
|
|
276
|
+
}
|
|
277
|
+
function findOccurrences(content, token, used) {
|
|
278
|
+
const occurrences = [];
|
|
279
|
+
let index = content.indexOf(token);
|
|
280
|
+
while (index >= 0) {
|
|
281
|
+
const range = { start: index, end: index + token.length };
|
|
282
|
+
if (canUseRange(range, used)) occurrences.push(range);
|
|
283
|
+
index = content.indexOf(token, index + token.length);
|
|
284
|
+
}
|
|
285
|
+
return occurrences;
|
|
286
|
+
}
|
|
287
|
+
function addCandidate(candidates, used, mention, range, order, sourceText) {
|
|
288
|
+
if (!canUseRange(range, used)) return;
|
|
289
|
+
const matchedText = sourceText ?? mention.sourceToken ?? mention.token;
|
|
290
|
+
used.push(range);
|
|
291
|
+
candidates.push({
|
|
292
|
+
start: range.start,
|
|
293
|
+
end: range.end,
|
|
294
|
+
order,
|
|
295
|
+
sourceText: matchedText,
|
|
296
|
+
mention: { ...mention, range }
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
function segmentTextByMentions(content, mentions) {
|
|
300
|
+
if (!content) return [];
|
|
301
|
+
const usableMentions = (mentions ?? []).filter((mention) => mention.token);
|
|
302
|
+
if (usableMentions.length === 0) return [{ type: "text", text: content }];
|
|
303
|
+
const candidates = [];
|
|
304
|
+
const usedRanges = [];
|
|
305
|
+
const pendingByText = /* @__PURE__ */ new Map();
|
|
306
|
+
usableMentions.forEach((mention, order) => {
|
|
307
|
+
if (isValidRange(content, mention, mention.range)) {
|
|
308
|
+
addCandidate(
|
|
309
|
+
candidates,
|
|
310
|
+
usedRanges,
|
|
311
|
+
mention,
|
|
312
|
+
mention.range,
|
|
313
|
+
order,
|
|
314
|
+
content.slice(mention.range.start, mention.range.end)
|
|
315
|
+
);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
for (const text of matchTextsForMention(mention)) {
|
|
319
|
+
const pending = pendingByText.get(text) ?? [];
|
|
320
|
+
pending.push({ mention, order });
|
|
321
|
+
pendingByText.set(text, pending);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
const pendingGroups = Array.from(pendingByText.entries()).sort((a, b) => {
|
|
325
|
+
const lengthDelta = b[0].length - a[0].length;
|
|
326
|
+
if (lengthDelta !== 0) return lengthDelta;
|
|
327
|
+
return a[1][0].order - b[1][0].order;
|
|
328
|
+
});
|
|
329
|
+
for (const [token, pending] of pendingGroups) {
|
|
330
|
+
const occurrences = findOccurrences(content, token, usedRanges);
|
|
331
|
+
if (occurrences.length === 0) continue;
|
|
332
|
+
if (pending.length === 1) {
|
|
333
|
+
const { mention, order } = pending[0];
|
|
334
|
+
for (const range of occurrences) {
|
|
335
|
+
addCandidate(candidates, usedRanges, mention, range, order, token);
|
|
336
|
+
}
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
pending.forEach(({ mention, order }, index) => {
|
|
340
|
+
const range = occurrences[index];
|
|
341
|
+
if (range) addCandidate(candidates, usedRanges, mention, range, order, token);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
candidates.sort((a, b) => a.start - b.start || b.end - a.end || a.order - b.order);
|
|
345
|
+
const segments = [];
|
|
346
|
+
let cursor = 0;
|
|
347
|
+
for (const candidate of candidates) {
|
|
348
|
+
if (candidate.start < cursor) continue;
|
|
349
|
+
if (candidate.start > cursor) {
|
|
350
|
+
segments.push({ type: "text", text: content.slice(cursor, candidate.start) });
|
|
351
|
+
}
|
|
352
|
+
const text = content.slice(candidate.start, candidate.end);
|
|
353
|
+
segments.push({
|
|
354
|
+
type: "mention",
|
|
355
|
+
text,
|
|
356
|
+
range: { start: candidate.start, end: candidate.end },
|
|
357
|
+
mention: { ...candidate.mention, sourceToken: candidate.sourceText }
|
|
358
|
+
});
|
|
359
|
+
cursor = candidate.end;
|
|
360
|
+
}
|
|
361
|
+
if (cursor < content.length) {
|
|
362
|
+
segments.push({ type: "text", text: content.slice(cursor) });
|
|
363
|
+
}
|
|
364
|
+
return segments.length > 0 ? segments : [{ type: "text", text: content }];
|
|
365
|
+
}
|
|
366
|
+
function assignMentionRanges(content, mentions) {
|
|
367
|
+
return segmentTextByMentions(content, mentions).filter((segment) => {
|
|
368
|
+
return segment.type === "mention";
|
|
369
|
+
}).map((segment) => ({
|
|
370
|
+
...segment.mention,
|
|
371
|
+
token: segment.mention.token || segment.text,
|
|
372
|
+
range: segment.range
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
function canonicalizeMentionContent(content, mentions) {
|
|
376
|
+
const canonicalMentions = [];
|
|
377
|
+
let nextContent = "";
|
|
378
|
+
for (const segment of segmentTextByMentions(content, mentions)) {
|
|
379
|
+
if (segment.type === "text") {
|
|
380
|
+
nextContent += segment.text;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
const token = canonicalMentionToken(segment.mention);
|
|
384
|
+
const start = nextContent.length;
|
|
385
|
+
nextContent += token;
|
|
386
|
+
canonicalMentions.push({
|
|
387
|
+
...segment.mention,
|
|
388
|
+
token,
|
|
389
|
+
sourceToken: segment.text === token ? segment.mention.sourceToken : segment.text,
|
|
390
|
+
range: { start, end: start + token.length }
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return { content: nextContent, mentions: canonicalMentions };
|
|
394
|
+
}
|
|
395
|
+
function mentionDisplayText(mention) {
|
|
396
|
+
return mention.label || mention.token;
|
|
397
|
+
}
|
|
398
|
+
function escapeMarkdownLinkLabel(label) {
|
|
399
|
+
return label.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
|
|
400
|
+
}
|
|
401
|
+
function buildMentionMarkdownLinks(content, mentions, hrefForMention) {
|
|
402
|
+
const linkedMentions = [];
|
|
403
|
+
const markdown = segmentTextByMentions(content, mentions).map((segment) => {
|
|
404
|
+
if (segment.type === "text") return segment.text;
|
|
405
|
+
const href = hrefForMention(segment.mention, linkedMentions.length);
|
|
406
|
+
if (!href) return segment.text;
|
|
407
|
+
linkedMentions.push(segment.mention);
|
|
408
|
+
return `[${escapeMarkdownLinkLabel(mentionDisplayText(segment.mention))}](${href})`;
|
|
409
|
+
}).join("");
|
|
410
|
+
return { markdown, mentions: linkedMentions };
|
|
411
|
+
}
|
|
412
|
+
|
|
220
413
|
// src/utils/pixel-cats.ts
|
|
221
414
|
var variants = [
|
|
222
415
|
// 0: Shadow — Black cat (logo style)
|
|
@@ -349,6 +542,11 @@ function slugify(text) {
|
|
|
349
542
|
// Annotate the CommonJS export names for ESM import in node:
|
|
350
543
|
0 && (module.exports = {
|
|
351
544
|
CAT_AVATAR_COUNT,
|
|
545
|
+
assignMentionRanges,
|
|
546
|
+
buildMentionMarkdownLinks,
|
|
547
|
+
canonicalMentionToken,
|
|
548
|
+
canonicalizeMentionContent,
|
|
549
|
+
escapeMarkdownLinkLabel,
|
|
352
550
|
formatDate,
|
|
353
551
|
generateInviteCode,
|
|
354
552
|
generateRandomCatConfig,
|
|
@@ -356,7 +554,11 @@ function slugify(text) {
|
|
|
356
554
|
getCatAvatar,
|
|
357
555
|
getCatAvatarByUserId,
|
|
358
556
|
getCatSvgString,
|
|
557
|
+
isCanonicalMentionToken,
|
|
359
558
|
isValidEmail,
|
|
559
|
+
mentionDisplayText,
|
|
560
|
+
parseCanonicalMentionToken,
|
|
360
561
|
renderCatSvg,
|
|
562
|
+
segmentTextByMentions,
|
|
361
563
|
slugify
|
|
362
564
|
});
|
package/dist/utils/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { g as MessageMentionRange, e as MessageMention } from '../message.types-lG4qBSus.cjs';
|
|
2
|
+
|
|
1
3
|
type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor';
|
|
2
4
|
type CatExpression = 'smile' | 'open' | 'flat' | 'sad' | 'surprised' | 'kawaii' | 'winking' | 'smirk';
|
|
3
5
|
type CatDecoration = 'none' | 'glasses' | 'blush' | 'scar' | 'flower' | 'fish' | 'headband';
|
|
@@ -15,6 +17,43 @@ interface CatConfig {
|
|
|
15
17
|
declare function generateRandomCatConfig(): CatConfig;
|
|
16
18
|
declare function renderCatSvg(config: CatConfig): string;
|
|
17
19
|
|
|
20
|
+
type MessageMentionTextSegment = {
|
|
21
|
+
type: 'text';
|
|
22
|
+
text: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'mention';
|
|
25
|
+
text: string;
|
|
26
|
+
range: MessageMentionRange;
|
|
27
|
+
mention: MessageMention;
|
|
28
|
+
};
|
|
29
|
+
declare function canonicalMentionToken(mention: Pick<MessageMention, 'kind' | 'targetId'> & Partial<MessageMention>): string;
|
|
30
|
+
declare function parseCanonicalMentionToken(token: string): {
|
|
31
|
+
kind: 'user';
|
|
32
|
+
targetId: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'channel';
|
|
35
|
+
targetId: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'server';
|
|
38
|
+
targetId: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'here' | 'everyone';
|
|
41
|
+
targetId?: string;
|
|
42
|
+
} | null;
|
|
43
|
+
declare function isCanonicalMentionToken(token: string): boolean;
|
|
44
|
+
declare function segmentTextByMentions(content: string, mentions: readonly MessageMention[] | null | undefined): MessageMentionTextSegment[];
|
|
45
|
+
declare function assignMentionRanges(content: string, mentions: readonly MessageMention[] | null | undefined): MessageMention[];
|
|
46
|
+
declare function canonicalizeMentionContent(content: string, mentions: readonly MessageMention[] | null | undefined): {
|
|
47
|
+
content: string;
|
|
48
|
+
mentions: MessageMention[];
|
|
49
|
+
};
|
|
50
|
+
declare function mentionDisplayText(mention: Pick<MessageMention, 'label' | 'token'>): string;
|
|
51
|
+
declare function escapeMarkdownLinkLabel(label: string): string;
|
|
52
|
+
declare function buildMentionMarkdownLinks(content: string, mentions: readonly MessageMention[] | null | undefined, hrefForMention: (mention: MessageMention, index: number) => string | null | undefined): {
|
|
53
|
+
markdown: string;
|
|
54
|
+
mentions: MessageMention[];
|
|
55
|
+
};
|
|
56
|
+
|
|
18
57
|
/**
|
|
19
58
|
* Pixel Art Cat Avatar System
|
|
20
59
|
* 8 unique cat variants with distinct color schemes inspired by the Shadow logo
|
|
@@ -38,4 +77,4 @@ declare function formatDate(date: string | Date): string;
|
|
|
38
77
|
declare function isValidEmail(email: string): boolean;
|
|
39
78
|
declare function slugify(text: string): string;
|
|
40
79
|
|
|
41
|
-
export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isValidEmail, renderCatSvg, slugify };
|
|
80
|
+
export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, type MessageMentionTextSegment, assignMentionRanges, buildMentionMarkdownLinks, canonicalMentionToken, canonicalizeMentionContent, escapeMarkdownLinkLabel, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isCanonicalMentionToken, isValidEmail, mentionDisplayText, parseCanonicalMentionToken, renderCatSvg, segmentTextByMentions, slugify };
|