@shadowob/shared 0.3.4 → 0.4.1
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-6H4LIJZC.js +0 -0
- package/dist/chunk-EMLX23LF.js +59 -0
- package/dist/chunk-PXKHJSTK.js +328 -0
- package/dist/constants/index.cjs +87 -0
- package/dist/constants/index.d.cts +55 -0
- package/dist/constants/index.d.ts +55 -0
- package/dist/constants/index.js +10 -0
- package/dist/index.cjs +424 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +35 -0
- package/dist/types/index.cjs +18 -0
- package/dist/types/index.d.cts +278 -0
- package/dist/types/index.d.ts +278 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/index.cjs +362 -0
- package/dist/utils/index.d.cts +41 -0
- package/dist/utils/index.d.ts +41 -0
- package/dist/utils/index.js +26 -0
- package/package.json +45 -7
- package/__tests__/constants.test.ts +0 -69
- package/__tests__/utils.test.ts +0 -80
- package/src/constants/events.ts +0 -28
- package/src/constants/index.ts +0 -2
- package/src/constants/limits.ts +0 -30
- package/src/index.ts +0 -3
- package/src/types/agent.types.ts +0 -44
- package/src/types/channel.types.ts +0 -36
- package/src/types/friendship.types.ts +0 -27
- package/src/types/index.ts +0 -6
- package/src/types/message.types.ts +0 -126
- package/src/types/server.types.ts +0 -38
- package/src/types/user.types.ts +0 -40
- package/src/utils/avatar-generator.ts +0 -231
- package/src/utils/index.ts +0 -24
- package/src/utils/pixel-cats.ts +0 -139
- package/tsconfig.json +0 -8
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/constants/events.ts
|
|
2
|
+
var CLIENT_EVENTS = {
|
|
3
|
+
CHANNEL_JOIN: "channel:join",
|
|
4
|
+
CHANNEL_LEAVE: "channel:leave",
|
|
5
|
+
MESSAGE_SEND: "message:send",
|
|
6
|
+
MESSAGE_TYPING: "message:typing",
|
|
7
|
+
PRESENCE_UPDATE: "presence:update"
|
|
8
|
+
};
|
|
9
|
+
var SERVER_EVENTS = {
|
|
10
|
+
MESSAGE_NEW: "message:new",
|
|
11
|
+
MESSAGE_UPDATE: "message:update",
|
|
12
|
+
MESSAGE_DELETE: "message:delete",
|
|
13
|
+
MEMBER_TYPING: "member:typing",
|
|
14
|
+
MEMBER_JOIN: "member:join",
|
|
15
|
+
MEMBER_LEAVE: "member:leave",
|
|
16
|
+
PRESENCE_CHANGE: "presence:change",
|
|
17
|
+
REACTION_ADD: "reaction:add",
|
|
18
|
+
REACTION_REMOVE: "reaction:remove",
|
|
19
|
+
NOTIFICATION_NEW: "notification:new",
|
|
20
|
+
DM_MESSAGE_NEW: "dm:message:new"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/constants/limits.ts
|
|
24
|
+
var LIMITS = {
|
|
25
|
+
/** Max message content length */
|
|
26
|
+
MESSAGE_CONTENT_MAX: 4e3,
|
|
27
|
+
/** Max username length */
|
|
28
|
+
USERNAME_MAX: 32,
|
|
29
|
+
/** Min username length */
|
|
30
|
+
USERNAME_MIN: 3,
|
|
31
|
+
/** Max display name length */
|
|
32
|
+
DISPLAY_NAME_MAX: 64,
|
|
33
|
+
/** Max server name length */
|
|
34
|
+
SERVER_NAME_MAX: 100,
|
|
35
|
+
/** Max channel name length */
|
|
36
|
+
CHANNEL_NAME_MAX: 100,
|
|
37
|
+
/** Max thread name length */
|
|
38
|
+
THREAD_NAME_MAX: 100,
|
|
39
|
+
/** Max file upload size (10MB) */
|
|
40
|
+
FILE_UPLOAD_MAX_SIZE: 10 * 1024 * 1024,
|
|
41
|
+
/** Messages per page (cursor pagination) */
|
|
42
|
+
MESSAGES_PER_PAGE: 50,
|
|
43
|
+
/** Max servers per user */
|
|
44
|
+
SERVERS_PER_USER_MAX: 100,
|
|
45
|
+
/** Max channels per server */
|
|
46
|
+
CHANNELS_PER_SERVER_MAX: 200,
|
|
47
|
+
/** Invite code length */
|
|
48
|
+
INVITE_CODE_LENGTH: 8,
|
|
49
|
+
/** Password min length */
|
|
50
|
+
PASSWORD_MIN: 8,
|
|
51
|
+
/** Max reactions per message per user */
|
|
52
|
+
REACTIONS_PER_MESSAGE_MAX: 20
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
CLIENT_EVENTS,
|
|
57
|
+
SERVER_EVENTS,
|
|
58
|
+
LIMITS
|
|
59
|
+
};
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
// src/utils/index.ts
|
|
2
|
+
import { customAlphabet } from "nanoid";
|
|
3
|
+
|
|
4
|
+
// src/utils/avatar-generator.ts
|
|
5
|
+
var COLORS = {
|
|
6
|
+
bg: [
|
|
7
|
+
"transparent",
|
|
8
|
+
"#1e1f22",
|
|
9
|
+
"#313338",
|
|
10
|
+
"#5865F2",
|
|
11
|
+
"#23a559",
|
|
12
|
+
"#da373c",
|
|
13
|
+
"#f472b6",
|
|
14
|
+
"#3b82f6",
|
|
15
|
+
"#fbbf24",
|
|
16
|
+
"#a855f7",
|
|
17
|
+
"#1abc9c",
|
|
18
|
+
"#f39c12",
|
|
19
|
+
"#e74c3c"
|
|
20
|
+
],
|
|
21
|
+
body: [
|
|
22
|
+
"#2d2d30",
|
|
23
|
+
"#e8842c",
|
|
24
|
+
"#e8e8e8",
|
|
25
|
+
"#7a7a80",
|
|
26
|
+
"#d4a574",
|
|
27
|
+
"#6b8094",
|
|
28
|
+
"#f472b6",
|
|
29
|
+
"#c8d6e5",
|
|
30
|
+
"#3e2723",
|
|
31
|
+
"#bdc3c7",
|
|
32
|
+
"#ffb8b8"
|
|
33
|
+
],
|
|
34
|
+
eyes: [
|
|
35
|
+
"#f8e71c",
|
|
36
|
+
"#00f3ff",
|
|
37
|
+
"#4ade80",
|
|
38
|
+
"#60a5fa",
|
|
39
|
+
"#a855f7",
|
|
40
|
+
"#fbbf24",
|
|
41
|
+
"#f87171",
|
|
42
|
+
"#ffc0cb",
|
|
43
|
+
"#1dd1a1",
|
|
44
|
+
"#e056fd"
|
|
45
|
+
],
|
|
46
|
+
pattern: ["#1a1a1c", "#ffffff", "#5a4a46", "#3d3d40", "#9a9aa0", "#d1ccc0", "#2d3436"]
|
|
47
|
+
};
|
|
48
|
+
function getRandomElement(arr) {
|
|
49
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
50
|
+
}
|
|
51
|
+
function generateRandomCatConfig() {
|
|
52
|
+
return {
|
|
53
|
+
bg: getRandomElement(COLORS.bg),
|
|
54
|
+
bgPattern: getRandomElement(["none", "dots", "stripes", "grid", "stars"]),
|
|
55
|
+
body: getRandomElement(COLORS.body),
|
|
56
|
+
pattern: getRandomElement([
|
|
57
|
+
"none",
|
|
58
|
+
"tabby",
|
|
59
|
+
"tuxedo",
|
|
60
|
+
"siamese",
|
|
61
|
+
"calico",
|
|
62
|
+
"bicolor"
|
|
63
|
+
]),
|
|
64
|
+
patternColor: getRandomElement(COLORS.pattern),
|
|
65
|
+
eyeColor: getRandomElement(COLORS.eyes),
|
|
66
|
+
expression: getRandomElement([
|
|
67
|
+
"smile",
|
|
68
|
+
"open",
|
|
69
|
+
"flat",
|
|
70
|
+
"sad",
|
|
71
|
+
"surprised",
|
|
72
|
+
"kawaii",
|
|
73
|
+
"winking",
|
|
74
|
+
"smirk"
|
|
75
|
+
]),
|
|
76
|
+
decoration: getRandomElement([
|
|
77
|
+
"none",
|
|
78
|
+
"glasses",
|
|
79
|
+
"blush",
|
|
80
|
+
"scar",
|
|
81
|
+
"flower",
|
|
82
|
+
"fish",
|
|
83
|
+
"headband"
|
|
84
|
+
])
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function renderCatSvg(config) {
|
|
88
|
+
const { bg, bgPattern, body, pattern, patternColor, eyeColor, expression, decoration } = config;
|
|
89
|
+
const stroke = "#1a1a1c";
|
|
90
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">`;
|
|
91
|
+
if (bg && bg !== "transparent") {
|
|
92
|
+
svg += `<rect width="100" height="100" fill="${bg}" rx="20" />`;
|
|
93
|
+
const pColor = `rgba(255,255,255,0.15)`;
|
|
94
|
+
const cleanBg = bg.replace("#", "");
|
|
95
|
+
if (bgPattern === "dots") {
|
|
96
|
+
svg += `<pattern id="p-${cleanBg}-dots" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="2" fill="${pColor}"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-dots)" rx="20" />`;
|
|
97
|
+
} else if (bgPattern === "stripes") {
|
|
98
|
+
svg += `<pattern id="p-${cleanBg}-str" x="0" y="0" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="${pColor}" stroke-width="4"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-str)" rx="20" />`;
|
|
99
|
+
} else if (bgPattern === "grid") {
|
|
100
|
+
svg += `<pattern id="p-${cleanBg}-grid" width="16" height="16" patternUnits="userSpaceOnUse"><path d="M 16 0 L 0 0 0 16" fill="none" stroke="${pColor}" stroke-width="1"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-grid)" rx="20" />`;
|
|
101
|
+
} else if (bgPattern === "stars") {
|
|
102
|
+
svg += `<pattern id="p-${cleanBg}-star" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M10,2 L12,8 L18,8 L13,12 L15,18 L10,14 L5,18 L7,12 L2,8 L8,8 Z" fill="${pColor}" transform="scale(0.5) translate(5,5)"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-star)" rx="20" />`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
svg += `<ellipse cx="50" cy="85" rx="30" ry="6" fill="rgba(0,0,0,0.2)"/>`;
|
|
106
|
+
svg += `<path d="M22,45 C15,22 28,18 34,22 C38,25 40,38 40,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
107
|
+
svg += `<path d="M78,45 C85,22 72,18 66,22 C62,25 60,38 60,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
108
|
+
svg += `<path d="M26,38 C22,26 29,24 33,26 C35,28 36,34 36,34" fill="#ffb8b8" opacity="0.8"/>`;
|
|
109
|
+
svg += `<path d="M74,38 C78,26 71,24 67,26 C65,28 64,34 64,34" fill="#ffb8b8" opacity="0.8"/>`;
|
|
110
|
+
svg += `<ellipse cx="50" cy="58" rx="38" ry="30" fill="${body}" stroke="${stroke}" stroke-width="2.5"/>`;
|
|
111
|
+
if (pattern === "tabby") {
|
|
112
|
+
svg += `<path d="M50,30 L50,40 M42,32 L46,39 M58,32 L54,39" stroke="${patternColor}" stroke-width="3" stroke-linecap="round" opacity="0.7"/>`;
|
|
113
|
+
svg += `<path d="M18,55 L26,57 M20,62 L27,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`;
|
|
114
|
+
svg += `<path d="M82,55 L74,57 M80,62 L73,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`;
|
|
115
|
+
} else if (pattern === "tuxedo") {
|
|
116
|
+
svg += `<path d="M50,56 C30,68 28,88 50,88 C72,88 70,68 50,56" fill="${patternColor}" opacity="0.95"/>`;
|
|
117
|
+
svg += `<ellipse cx="50" cy="65" rx="16" ry="12" fill="${patternColor}" opacity="0.95"/>`;
|
|
118
|
+
} else if (pattern === "siamese") {
|
|
119
|
+
svg += `<ellipse cx="50" cy="62" rx="20" ry="16" fill="${patternColor}" opacity="0.6"/>`;
|
|
120
|
+
} else if (pattern === "calico") {
|
|
121
|
+
svg += `<path d="M25,40 Q35,30 45,45 Q35,55 25,40" fill="${patternColor}" opacity="0.8"/>`;
|
|
122
|
+
svg += `<path d="M75,45 Q65,60 55,50 Q65,35 75,45" fill="#e8842c" opacity="0.8"/>`;
|
|
123
|
+
} else if (pattern === "bicolor") {
|
|
124
|
+
svg += `<path d="M12,58 Q30,30 50,40 Q60,70 50,88 Q12,88 12,58 Z" fill="${patternColor}" opacity="0.8"/>`;
|
|
125
|
+
}
|
|
126
|
+
if (decoration === "blush") {
|
|
127
|
+
svg += `<ellipse cx="28" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`;
|
|
128
|
+
svg += `<ellipse cx="72" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`;
|
|
129
|
+
}
|
|
130
|
+
if (decoration === "scar") {
|
|
131
|
+
svg += `<path d="M28,42 L40,52 M30,48 L35,43 M34,51 L39,46 M32,53 L37,48" stroke="#d63031" stroke-width="1.5" stroke-linecap="round"/>`;
|
|
132
|
+
}
|
|
133
|
+
const drawEye = (cx, cy, lookDir = 0) => {
|
|
134
|
+
if (expression === "kawaii") {
|
|
135
|
+
return `<path d="M${cx - 8},${cy} Q${cx},${cy - 8} ${cx + 8},${cy} Q${cx},${cy - 3} ${cx - 8},${cy}" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx + lookDir}" cy="${cy - 2}" r="3" fill="white"/><circle cx="${cx - 3 + lookDir}" cy="${cy}" r="1" fill="white"/>`;
|
|
136
|
+
} else if (expression === "winking" && cx > 50) {
|
|
137
|
+
return `<path d="M${cx - 7},${cy + 2} Q${cx},${cy - 4} ${cx + 7},${cy + 2}" fill="none" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
138
|
+
} else if (expression === "surprised") {
|
|
139
|
+
return `<circle cx="${cx}" cy="${cy}" r="8" fill="white" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx}" cy="${cy}" r="3" fill="${eyeColor}"/>`;
|
|
140
|
+
} else {
|
|
141
|
+
return `<circle cx="${cx}" cy="${cy}" r="7.5" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx - 2 + lookDir}" cy="${cy - 2}" r="2.5" fill="white"/><circle cx="${cx + 2 + lookDir}" cy="${cy + 1}" r="1" fill="white"/>`;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
if (expression === "smirk") {
|
|
145
|
+
svg += `<path d="M26,50 L42,50" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
146
|
+
svg += drawEye(66, 52, 2);
|
|
147
|
+
} else {
|
|
148
|
+
svg += drawEye(34, 52, 0);
|
|
149
|
+
svg += drawEye(66, 52, 0);
|
|
150
|
+
}
|
|
151
|
+
if (decoration === "glasses") {
|
|
152
|
+
svg += `<circle cx="34" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`;
|
|
153
|
+
svg += `<circle cx="66" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`;
|
|
154
|
+
svg += `<path d="M45,50 Q50,48 55,50" fill="none" stroke="#2d3436" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
155
|
+
}
|
|
156
|
+
svg += `<path d="M47,62 L53,62 L50,65 Z" fill="#ff9ff3" stroke="${stroke}" stroke-width="1" stroke-linejoin="round"/>`;
|
|
157
|
+
if (expression === "smile" || expression === "kawaii" || expression === "winking") {
|
|
158
|
+
svg += `<path d="M42,67 Q46,72 50,67 M50,67 Q54,72 58,67" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
159
|
+
} else if (expression === "open") {
|
|
160
|
+
svg += `<path d="M46,67 Q50,75 54,67 Z" fill="#ff7675" stroke="${stroke}" stroke-width="1.5" stroke-linejoin="round"/>`;
|
|
161
|
+
} else if (expression === "flat") {
|
|
162
|
+
svg += `<path d="M47,68 L53,68" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
163
|
+
} else if (expression === "sad") {
|
|
164
|
+
svg += `<path d="M43,70 Q50,64 57,70" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
165
|
+
} else if (expression === "surprised") {
|
|
166
|
+
svg += `<circle cx="50" cy="70" r="3" fill="#1a1a1c"/>`;
|
|
167
|
+
} else if (expression === "smirk") {
|
|
168
|
+
svg += `<path d="M46,67 Q52,69 56,64" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
169
|
+
}
|
|
170
|
+
svg += `<path d="M28,62 L15,60 M28,65 L14,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`;
|
|
171
|
+
svg += `<path d="M72,62 L85,60 M72,65 L86,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`;
|
|
172
|
+
if (decoration === "headband") {
|
|
173
|
+
svg += `<path d="M16,35 Q50,20 84,35" fill="none" stroke="#e17055" stroke-width="6" stroke-linecap="round"/>`;
|
|
174
|
+
svg += `<path d="M50,15 L60,25 L50,28 L40,25 Z" fill="#fab1a0" stroke="#e17055" stroke-width="2"/>`;
|
|
175
|
+
} else if (decoration === "flower") {
|
|
176
|
+
svg += `<path d="M75,30 Q80,20 85,30 Q95,25 85,35 Q90,45 80,40 Q70,45 75,35 Q65,25 75,30 Z" fill="#ffeaa7" stroke="#fdcb6e" stroke-width="1.5"/>`;
|
|
177
|
+
svg += `<circle cx="80" cy="33" r="3" fill="#d63031"/>`;
|
|
178
|
+
} else if (decoration === "fish") {
|
|
179
|
+
svg += `<path d="M40,82 Q50,75 60,82 L65,78 L65,86 L60,82 Q50,89 40,82 Z" fill="#81ecec" stroke="${stroke}" stroke-width="1.5"/>`;
|
|
180
|
+
svg += `<circle cx="45" cy="81" r="1" fill="${stroke}"/>`;
|
|
181
|
+
}
|
|
182
|
+
svg += `</svg>`;
|
|
183
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/utils/pixel-cats.ts
|
|
187
|
+
var variants = [
|
|
188
|
+
// 0: Shadow — Black cat (logo style)
|
|
189
|
+
{
|
|
190
|
+
body: "#2d2d30",
|
|
191
|
+
stroke: "#1a1a1c",
|
|
192
|
+
earInner: "#3d3d40",
|
|
193
|
+
eyeL: "#f8e71c",
|
|
194
|
+
eyeR: "#00f3ff",
|
|
195
|
+
nose: "#3a2a26"
|
|
196
|
+
},
|
|
197
|
+
// 1: Mikan — Orange tabby
|
|
198
|
+
{
|
|
199
|
+
body: "#e8842c",
|
|
200
|
+
stroke: "#1a1a1c",
|
|
201
|
+
earInner: "#f5a623",
|
|
202
|
+
eyeL: "#4ade80",
|
|
203
|
+
eyeR: "#4ade80",
|
|
204
|
+
nose: "#d46b1a"
|
|
205
|
+
},
|
|
206
|
+
// 2: Yuki — White cat
|
|
207
|
+
{
|
|
208
|
+
body: "#e8e8e8",
|
|
209
|
+
stroke: "#a0a0a0",
|
|
210
|
+
earInner: "#ffc0cb",
|
|
211
|
+
eyeL: "#60a5fa",
|
|
212
|
+
eyeR: "#60a5fa",
|
|
213
|
+
nose: "#f5a0b0"
|
|
214
|
+
},
|
|
215
|
+
// 3: Haiiro — Gray cat
|
|
216
|
+
{
|
|
217
|
+
body: "#7a7a80",
|
|
218
|
+
stroke: "#4a4a50",
|
|
219
|
+
earInner: "#9a9aa0",
|
|
220
|
+
eyeL: "#fbbf24",
|
|
221
|
+
eyeR: "#fbbf24",
|
|
222
|
+
nose: "#5a4a46"
|
|
223
|
+
},
|
|
224
|
+
// 4: Tuxedo — Black & white accents
|
|
225
|
+
{
|
|
226
|
+
body: "#2d2d30",
|
|
227
|
+
stroke: "#1a1a1c",
|
|
228
|
+
earInner: "#e0e0e0",
|
|
229
|
+
eyeL: "#22c55e",
|
|
230
|
+
eyeR: "#22c55e",
|
|
231
|
+
nose: "#3a2a26"
|
|
232
|
+
},
|
|
233
|
+
// 5: Mocha — Cream/beige
|
|
234
|
+
{
|
|
235
|
+
body: "#d4a574",
|
|
236
|
+
stroke: "#8b6914",
|
|
237
|
+
earInner: "#e8c9a0",
|
|
238
|
+
eyeL: "#d97706",
|
|
239
|
+
eyeR: "#d97706",
|
|
240
|
+
nose: "#a0705a"
|
|
241
|
+
},
|
|
242
|
+
// 6: Blue — Russian blue
|
|
243
|
+
{
|
|
244
|
+
body: "#6b8094",
|
|
245
|
+
stroke: "#3d5060",
|
|
246
|
+
earInner: "#8ba0b4",
|
|
247
|
+
eyeL: "#22c55e",
|
|
248
|
+
eyeR: "#22c55e",
|
|
249
|
+
nose: "#5a6a76"
|
|
250
|
+
},
|
|
251
|
+
// 7: Sakura — Fantasy pink
|
|
252
|
+
{
|
|
253
|
+
body: "#f472b6",
|
|
254
|
+
stroke: "#be185d",
|
|
255
|
+
earInner: "#f9a8d4",
|
|
256
|
+
eyeL: "#a855f7",
|
|
257
|
+
eyeR: "#c084fc",
|
|
258
|
+
nose: "#d44a8c"
|
|
259
|
+
}
|
|
260
|
+
];
|
|
261
|
+
function makeCatSvg(c) {
|
|
262
|
+
return [
|
|
263
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">',
|
|
264
|
+
`<path d="M22,45 Q15,22 28,22 Q34,22 40,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`,
|
|
265
|
+
`<path d="M78,45 Q85,22 72,22 Q66,22 60,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`,
|
|
266
|
+
`<path d="M26,38 Q22,26 29,26 Q33,26 36,34" fill="${c.earInner}" opacity="0.5"/>`,
|
|
267
|
+
`<path d="M74,38 Q78,26 71,26 Q67,26 64,34" fill="${c.earInner}" opacity="0.5"/>`,
|
|
268
|
+
`<ellipse cx="50" cy="58" rx="36" ry="28" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5"/>`,
|
|
269
|
+
`<circle cx="35" cy="52" r="7" fill="${c.eyeL}" stroke="${c.stroke}" stroke-width="1.5"/>`,
|
|
270
|
+
`<circle cx="33" cy="49" r="2.5" fill="white"/>`,
|
|
271
|
+
`<circle cx="65" cy="52" r="7" fill="${c.eyeR}" stroke="${c.stroke}" stroke-width="1.5"/>`,
|
|
272
|
+
`<circle cx="63" cy="49" r="2.5" fill="white"/>`,
|
|
273
|
+
`<ellipse cx="50" cy="62" rx="3.5" ry="2.2" fill="${c.nose}"/>`,
|
|
274
|
+
`<path d="M42,67 Q46,72 50,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`,
|
|
275
|
+
`<path d="M50,67 Q54,72 58,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`,
|
|
276
|
+
"</svg>"
|
|
277
|
+
].join("");
|
|
278
|
+
}
|
|
279
|
+
var catDataUris = variants.map((v) => {
|
|
280
|
+
const svg = makeCatSvg(v);
|
|
281
|
+
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
282
|
+
});
|
|
283
|
+
function getCatAvatar(index) {
|
|
284
|
+
return catDataUris[index % catDataUris.length];
|
|
285
|
+
}
|
|
286
|
+
function getCatAvatarByUserId(userId) {
|
|
287
|
+
let hash = 0;
|
|
288
|
+
for (let i = 0; i < userId.length; i++) {
|
|
289
|
+
hash = (hash << 5) - hash + userId.charCodeAt(i) | 0;
|
|
290
|
+
}
|
|
291
|
+
return getCatAvatar(Math.abs(hash) % catDataUris.length);
|
|
292
|
+
}
|
|
293
|
+
function getAllCatAvatars() {
|
|
294
|
+
const names = ["\u5F71\u5B50", "\u871C\u67D1", "\u5C0F\u96EA", "\u7070\u7070", "\u71D5\u5C3E\u670D", "\u6469\u5361", "\u84DD\u84DD", "\u5C0F\u6A31"];
|
|
295
|
+
return catDataUris.map((uri, i) => ({ index: i, name: names[i], dataUri: uri }));
|
|
296
|
+
}
|
|
297
|
+
function getCatSvgString(index) {
|
|
298
|
+
return makeCatSvg(variants[index % variants.length]);
|
|
299
|
+
}
|
|
300
|
+
var CAT_AVATAR_COUNT = variants.length;
|
|
301
|
+
|
|
302
|
+
// src/utils/index.ts
|
|
303
|
+
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
304
|
+
var generateInviteCode = customAlphabet(alphabet, 8);
|
|
305
|
+
function formatDate(date) {
|
|
306
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
307
|
+
return d.toISOString();
|
|
308
|
+
}
|
|
309
|
+
function isValidEmail(email) {
|
|
310
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
311
|
+
}
|
|
312
|
+
function slugify(text) {
|
|
313
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export {
|
|
317
|
+
generateRandomCatConfig,
|
|
318
|
+
renderCatSvg,
|
|
319
|
+
getCatAvatar,
|
|
320
|
+
getCatAvatarByUserId,
|
|
321
|
+
getAllCatAvatars,
|
|
322
|
+
getCatSvgString,
|
|
323
|
+
CAT_AVATAR_COUNT,
|
|
324
|
+
generateInviteCode,
|
|
325
|
+
formatDate,
|
|
326
|
+
isValidEmail,
|
|
327
|
+
slugify
|
|
328
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/constants/index.ts
|
|
21
|
+
var constants_exports = {};
|
|
22
|
+
__export(constants_exports, {
|
|
23
|
+
CLIENT_EVENTS: () => CLIENT_EVENTS,
|
|
24
|
+
LIMITS: () => LIMITS,
|
|
25
|
+
SERVER_EVENTS: () => SERVER_EVENTS
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(constants_exports);
|
|
28
|
+
|
|
29
|
+
// src/constants/events.ts
|
|
30
|
+
var CLIENT_EVENTS = {
|
|
31
|
+
CHANNEL_JOIN: "channel:join",
|
|
32
|
+
CHANNEL_LEAVE: "channel:leave",
|
|
33
|
+
MESSAGE_SEND: "message:send",
|
|
34
|
+
MESSAGE_TYPING: "message:typing",
|
|
35
|
+
PRESENCE_UPDATE: "presence:update"
|
|
36
|
+
};
|
|
37
|
+
var SERVER_EVENTS = {
|
|
38
|
+
MESSAGE_NEW: "message:new",
|
|
39
|
+
MESSAGE_UPDATE: "message:update",
|
|
40
|
+
MESSAGE_DELETE: "message:delete",
|
|
41
|
+
MEMBER_TYPING: "member:typing",
|
|
42
|
+
MEMBER_JOIN: "member:join",
|
|
43
|
+
MEMBER_LEAVE: "member:leave",
|
|
44
|
+
PRESENCE_CHANGE: "presence:change",
|
|
45
|
+
REACTION_ADD: "reaction:add",
|
|
46
|
+
REACTION_REMOVE: "reaction:remove",
|
|
47
|
+
NOTIFICATION_NEW: "notification:new",
|
|
48
|
+
DM_MESSAGE_NEW: "dm:message:new"
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/constants/limits.ts
|
|
52
|
+
var LIMITS = {
|
|
53
|
+
/** Max message content length */
|
|
54
|
+
MESSAGE_CONTENT_MAX: 4e3,
|
|
55
|
+
/** Max username length */
|
|
56
|
+
USERNAME_MAX: 32,
|
|
57
|
+
/** Min username length */
|
|
58
|
+
USERNAME_MIN: 3,
|
|
59
|
+
/** Max display name length */
|
|
60
|
+
DISPLAY_NAME_MAX: 64,
|
|
61
|
+
/** Max server name length */
|
|
62
|
+
SERVER_NAME_MAX: 100,
|
|
63
|
+
/** Max channel name length */
|
|
64
|
+
CHANNEL_NAME_MAX: 100,
|
|
65
|
+
/** Max thread name length */
|
|
66
|
+
THREAD_NAME_MAX: 100,
|
|
67
|
+
/** Max file upload size (10MB) */
|
|
68
|
+
FILE_UPLOAD_MAX_SIZE: 10 * 1024 * 1024,
|
|
69
|
+
/** Messages per page (cursor pagination) */
|
|
70
|
+
MESSAGES_PER_PAGE: 50,
|
|
71
|
+
/** Max servers per user */
|
|
72
|
+
SERVERS_PER_USER_MAX: 100,
|
|
73
|
+
/** Max channels per server */
|
|
74
|
+
CHANNELS_PER_SERVER_MAX: 200,
|
|
75
|
+
/** Invite code length */
|
|
76
|
+
INVITE_CODE_LENGTH: 8,
|
|
77
|
+
/** Password min length */
|
|
78
|
+
PASSWORD_MIN: 8,
|
|
79
|
+
/** Max reactions per message per user */
|
|
80
|
+
REACTIONS_PER_MESSAGE_MAX: 20
|
|
81
|
+
};
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
CLIENT_EVENTS,
|
|
85
|
+
LIMITS,
|
|
86
|
+
SERVER_EVENTS
|
|
87
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
declare const CLIENT_EVENTS: {
|
|
2
|
+
readonly CHANNEL_JOIN: "channel:join";
|
|
3
|
+
readonly CHANNEL_LEAVE: "channel:leave";
|
|
4
|
+
readonly MESSAGE_SEND: "message:send";
|
|
5
|
+
readonly MESSAGE_TYPING: "message:typing";
|
|
6
|
+
readonly PRESENCE_UPDATE: "presence:update";
|
|
7
|
+
};
|
|
8
|
+
declare const SERVER_EVENTS: {
|
|
9
|
+
readonly MESSAGE_NEW: "message:new";
|
|
10
|
+
readonly MESSAGE_UPDATE: "message:update";
|
|
11
|
+
readonly MESSAGE_DELETE: "message:delete";
|
|
12
|
+
readonly MEMBER_TYPING: "member:typing";
|
|
13
|
+
readonly MEMBER_JOIN: "member:join";
|
|
14
|
+
readonly MEMBER_LEAVE: "member:leave";
|
|
15
|
+
readonly PRESENCE_CHANGE: "presence:change";
|
|
16
|
+
readonly REACTION_ADD: "reaction:add";
|
|
17
|
+
readonly REACTION_REMOVE: "reaction:remove";
|
|
18
|
+
readonly NOTIFICATION_NEW: "notification:new";
|
|
19
|
+
readonly DM_MESSAGE_NEW: "dm:message:new";
|
|
20
|
+
};
|
|
21
|
+
type ClientEvent = (typeof CLIENT_EVENTS)[keyof typeof CLIENT_EVENTS];
|
|
22
|
+
type ServerEvent = (typeof SERVER_EVENTS)[keyof typeof SERVER_EVENTS];
|
|
23
|
+
|
|
24
|
+
declare const LIMITS: {
|
|
25
|
+
/** Max message content length */
|
|
26
|
+
readonly MESSAGE_CONTENT_MAX: 4000;
|
|
27
|
+
/** Max username length */
|
|
28
|
+
readonly USERNAME_MAX: 32;
|
|
29
|
+
/** Min username length */
|
|
30
|
+
readonly USERNAME_MIN: 3;
|
|
31
|
+
/** Max display name length */
|
|
32
|
+
readonly DISPLAY_NAME_MAX: 64;
|
|
33
|
+
/** Max server name length */
|
|
34
|
+
readonly SERVER_NAME_MAX: 100;
|
|
35
|
+
/** Max channel name length */
|
|
36
|
+
readonly CHANNEL_NAME_MAX: 100;
|
|
37
|
+
/** Max thread name length */
|
|
38
|
+
readonly THREAD_NAME_MAX: 100;
|
|
39
|
+
/** Max file upload size (10MB) */
|
|
40
|
+
readonly FILE_UPLOAD_MAX_SIZE: number;
|
|
41
|
+
/** Messages per page (cursor pagination) */
|
|
42
|
+
readonly MESSAGES_PER_PAGE: 50;
|
|
43
|
+
/** Max servers per user */
|
|
44
|
+
readonly SERVERS_PER_USER_MAX: 100;
|
|
45
|
+
/** Max channels per server */
|
|
46
|
+
readonly CHANNELS_PER_SERVER_MAX: 200;
|
|
47
|
+
/** Invite code length */
|
|
48
|
+
readonly INVITE_CODE_LENGTH: 8;
|
|
49
|
+
/** Password min length */
|
|
50
|
+
readonly PASSWORD_MIN: 8;
|
|
51
|
+
/** Max reactions per message per user */
|
|
52
|
+
readonly REACTIONS_PER_MESSAGE_MAX: 20;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { CLIENT_EVENTS, type ClientEvent, LIMITS, SERVER_EVENTS, type ServerEvent };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
declare const CLIENT_EVENTS: {
|
|
2
|
+
readonly CHANNEL_JOIN: "channel:join";
|
|
3
|
+
readonly CHANNEL_LEAVE: "channel:leave";
|
|
4
|
+
readonly MESSAGE_SEND: "message:send";
|
|
5
|
+
readonly MESSAGE_TYPING: "message:typing";
|
|
6
|
+
readonly PRESENCE_UPDATE: "presence:update";
|
|
7
|
+
};
|
|
8
|
+
declare const SERVER_EVENTS: {
|
|
9
|
+
readonly MESSAGE_NEW: "message:new";
|
|
10
|
+
readonly MESSAGE_UPDATE: "message:update";
|
|
11
|
+
readonly MESSAGE_DELETE: "message:delete";
|
|
12
|
+
readonly MEMBER_TYPING: "member:typing";
|
|
13
|
+
readonly MEMBER_JOIN: "member:join";
|
|
14
|
+
readonly MEMBER_LEAVE: "member:leave";
|
|
15
|
+
readonly PRESENCE_CHANGE: "presence:change";
|
|
16
|
+
readonly REACTION_ADD: "reaction:add";
|
|
17
|
+
readonly REACTION_REMOVE: "reaction:remove";
|
|
18
|
+
readonly NOTIFICATION_NEW: "notification:new";
|
|
19
|
+
readonly DM_MESSAGE_NEW: "dm:message:new";
|
|
20
|
+
};
|
|
21
|
+
type ClientEvent = (typeof CLIENT_EVENTS)[keyof typeof CLIENT_EVENTS];
|
|
22
|
+
type ServerEvent = (typeof SERVER_EVENTS)[keyof typeof SERVER_EVENTS];
|
|
23
|
+
|
|
24
|
+
declare const LIMITS: {
|
|
25
|
+
/** Max message content length */
|
|
26
|
+
readonly MESSAGE_CONTENT_MAX: 4000;
|
|
27
|
+
/** Max username length */
|
|
28
|
+
readonly USERNAME_MAX: 32;
|
|
29
|
+
/** Min username length */
|
|
30
|
+
readonly USERNAME_MIN: 3;
|
|
31
|
+
/** Max display name length */
|
|
32
|
+
readonly DISPLAY_NAME_MAX: 64;
|
|
33
|
+
/** Max server name length */
|
|
34
|
+
readonly SERVER_NAME_MAX: 100;
|
|
35
|
+
/** Max channel name length */
|
|
36
|
+
readonly CHANNEL_NAME_MAX: 100;
|
|
37
|
+
/** Max thread name length */
|
|
38
|
+
readonly THREAD_NAME_MAX: 100;
|
|
39
|
+
/** Max file upload size (10MB) */
|
|
40
|
+
readonly FILE_UPLOAD_MAX_SIZE: number;
|
|
41
|
+
/** Messages per page (cursor pagination) */
|
|
42
|
+
readonly MESSAGES_PER_PAGE: 50;
|
|
43
|
+
/** Max servers per user */
|
|
44
|
+
readonly SERVERS_PER_USER_MAX: 100;
|
|
45
|
+
/** Max channels per server */
|
|
46
|
+
readonly CHANNELS_PER_SERVER_MAX: 200;
|
|
47
|
+
/** Invite code length */
|
|
48
|
+
readonly INVITE_CODE_LENGTH: 8;
|
|
49
|
+
/** Password min length */
|
|
50
|
+
readonly PASSWORD_MIN: 8;
|
|
51
|
+
/** Max reactions per message per user */
|
|
52
|
+
readonly REACTIONS_PER_MESSAGE_MAX: 20;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { CLIENT_EVENTS, type ClientEvent, LIMITS, SERVER_EVENTS, type ServerEvent };
|