@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.
@@ -1,80 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { formatDate, generateInviteCode, isValidEmail, slugify } from '../src/utils'
3
-
4
- describe('generateInviteCode', () => {
5
- it('should generate a string of length 8', () => {
6
- const code = generateInviteCode()
7
- expect(code).toHaveLength(8)
8
- })
9
-
10
- it('should only contain alphanumeric characters', () => {
11
- const code = generateInviteCode()
12
- expect(code).toMatch(/^[A-Za-z0-9]+$/)
13
- })
14
-
15
- it('should generate unique codes', () => {
16
- const codes = new Set(Array.from({ length: 100 }, () => generateInviteCode()))
17
- expect(codes.size).toBe(100)
18
- })
19
- })
20
-
21
- describe('formatDate', () => {
22
- it('should format a Date object to ISO string', () => {
23
- const date = new Date('2024-01-15T12:30:00Z')
24
- expect(formatDate(date)).toBe('2024-01-15T12:30:00.000Z')
25
- })
26
-
27
- it('should format a date string to ISO string', () => {
28
- const result = formatDate('2024-01-15T12:30:00Z')
29
- expect(result).toBe('2024-01-15T12:30:00.000Z')
30
- })
31
-
32
- it('should handle various date string formats', () => {
33
- const result = formatDate('2024-01-15')
34
- expect(result).toContain('2024-01-15')
35
- })
36
- })
37
-
38
- describe('isValidEmail', () => {
39
- it('should return true for valid emails', () => {
40
- expect(isValidEmail('user@shadowob.com')).toBe(true)
41
- expect(isValidEmail('first.last@domain.org')).toBe(true)
42
- expect(isValidEmail('user+tag@sub.domain.com')).toBe(true)
43
- })
44
-
45
- it('should return false for invalid emails', () => {
46
- expect(isValidEmail('')).toBe(false)
47
- expect(isValidEmail('user')).toBe(false)
48
- expect(isValidEmail('user@')).toBe(false)
49
- expect(isValidEmail('@domain.com')).toBe(false)
50
- expect(isValidEmail('user @domain.com')).toBe(false)
51
- expect(isValidEmail('user@domain')).toBe(false)
52
- })
53
- })
54
-
55
- describe('slugify', () => {
56
- it('should convert text to lowercase slug', () => {
57
- expect(slugify('Hello World')).toBe('hello-world')
58
- })
59
-
60
- it('should replace special characters with hyphens', () => {
61
- expect(slugify('Hello, World!')).toBe('hello-world')
62
- })
63
-
64
- it('should trim leading/trailing hyphens', () => {
65
- expect(slugify(' Hello World ')).toBe('hello-world')
66
- expect(slugify('---hello---')).toBe('hello')
67
- })
68
-
69
- it('should handle multiple consecutive special characters', () => {
70
- expect(slugify('hello...world')).toBe('hello-world')
71
- })
72
-
73
- it('should keep numbers', () => {
74
- expect(slugify('Version 2.0')).toBe('version-2-0')
75
- })
76
-
77
- it('should handle empty string', () => {
78
- expect(slugify('')).toBe('')
79
- })
80
- })
@@ -1,28 +0,0 @@
1
- // ─── Client → Server ───
2
-
3
- export const CLIENT_EVENTS = {
4
- CHANNEL_JOIN: 'channel:join',
5
- CHANNEL_LEAVE: 'channel:leave',
6
- MESSAGE_SEND: 'message:send',
7
- MESSAGE_TYPING: 'message:typing',
8
- PRESENCE_UPDATE: 'presence:update',
9
- } as const
10
-
11
- // ─── Server → Client ───
12
-
13
- export const SERVER_EVENTS = {
14
- MESSAGE_NEW: 'message:new',
15
- MESSAGE_UPDATE: 'message:update',
16
- MESSAGE_DELETE: 'message:delete',
17
- MEMBER_TYPING: 'member:typing',
18
- MEMBER_JOIN: 'member:join',
19
- MEMBER_LEAVE: 'member:leave',
20
- PRESENCE_CHANGE: 'presence:change',
21
- REACTION_ADD: 'reaction:add',
22
- REACTION_REMOVE: 'reaction:remove',
23
- NOTIFICATION_NEW: 'notification:new',
24
- DM_MESSAGE_NEW: 'dm:message:new',
25
- } as const
26
-
27
- export type ClientEvent = (typeof CLIENT_EVENTS)[keyof typeof CLIENT_EVENTS]
28
- export type ServerEvent = (typeof SERVER_EVENTS)[keyof typeof SERVER_EVENTS]
@@ -1,2 +0,0 @@
1
- export * from './events'
2
- export * from './limits'
@@ -1,30 +0,0 @@
1
- export const LIMITS = {
2
- /** Max message content length */
3
- MESSAGE_CONTENT_MAX: 4000,
4
- /** Max username length */
5
- USERNAME_MAX: 32,
6
- /** Min username length */
7
- USERNAME_MIN: 3,
8
- /** Max display name length */
9
- DISPLAY_NAME_MAX: 64,
10
- /** Max server name length */
11
- SERVER_NAME_MAX: 100,
12
- /** Max channel name length */
13
- CHANNEL_NAME_MAX: 100,
14
- /** Max thread name length */
15
- THREAD_NAME_MAX: 100,
16
- /** Max file upload size (10MB) */
17
- FILE_UPLOAD_MAX_SIZE: 10 * 1024 * 1024,
18
- /** Messages per page (cursor pagination) */
19
- MESSAGES_PER_PAGE: 50,
20
- /** Max servers per user */
21
- SERVERS_PER_USER_MAX: 100,
22
- /** Max channels per server */
23
- CHANNELS_PER_SERVER_MAX: 200,
24
- /** Invite code length */
25
- INVITE_CODE_LENGTH: 8,
26
- /** Password min length */
27
- PASSWORD_MIN: 8,
28
- /** Max reactions per message per user */
29
- REACTIONS_PER_MESSAGE_MAX: 20,
30
- } as const
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './constants'
2
- export * from './types'
3
- export * from './utils'
@@ -1,44 +0,0 @@
1
- export type AgentStatus = 'running' | 'stopped' | 'error'
2
-
3
- export type AgentKernelType = 'claude-code' | 'cursor' | 'mcp-server' | 'custom'
4
-
5
- export type AgentCapability =
6
- | 'chat'
7
- | 'code-gen'
8
- | 'code-review'
9
- | 'research'
10
- | 'tools'
11
- | 'file-access'
12
-
13
- export interface Agent {
14
- id: string
15
- userId: string
16
- kernelType: AgentKernelType
17
- config: Record<string, unknown>
18
- containerId: string | null
19
- status: AgentStatus
20
- ownerId: string
21
- createdAt: string
22
- updatedAt: string
23
- user?: {
24
- id: string
25
- username: string
26
- displayName: string
27
- avatarUrl: string | null
28
- }
29
- capabilities?: AgentCapability[]
30
- }
31
-
32
- export interface CreateAgentRequest {
33
- name: string
34
- kernelType: AgentKernelType
35
- config?: Record<string, unknown>
36
- }
37
-
38
- export interface AgentInfo {
39
- id: string
40
- name: string
41
- kernelType: AgentKernelType
42
- status: AgentStatus
43
- capabilities: AgentCapability[]
44
- }
@@ -1,36 +0,0 @@
1
- export type ChannelType = 'text' | 'voice' | 'announcement'
2
-
3
- export interface Channel {
4
- id: string
5
- name: string
6
- type: ChannelType
7
- serverId: string
8
- topic: string | null
9
- position: number
10
- createdAt: string
11
- updatedAt: string
12
- /** Last message timestamp for sorting by activity */
13
- lastMessageAt?: string | null
14
- }
15
-
16
- export interface CreateChannelRequest {
17
- name: string
18
- type?: ChannelType
19
- topic?: string
20
- }
21
-
22
- export interface UpdateChannelRequest {
23
- name?: string
24
- topic?: string
25
- position?: number
26
- }
27
-
28
- /** Channel sorting options */
29
- export type ChannelSortBy = 'createdAt' | 'updatedAt' | 'lastMessageAt' | 'lastAccessedAt'
30
-
31
- export type ChannelSortDirection = 'asc' | 'desc'
32
-
33
- export interface ChannelSortOptions {
34
- by: ChannelSortBy
35
- direction: ChannelSortDirection
36
- }
@@ -1,27 +0,0 @@
1
- export type FriendshipStatus = 'pending' | 'accepted' | 'blocked'
2
-
3
- export interface Friendship {
4
- id: string
5
- requesterId: string
6
- addresseeId: string
7
- status: FriendshipStatus
8
- createdAt: string
9
- updatedAt: string
10
- }
11
-
12
- export type FriendSource = 'friend' | 'owned_claw' | 'rented_claw'
13
-
14
- export interface FriendEntry {
15
- friendshipId: string
16
- /** Where this friend entry comes from */
17
- source: FriendSource
18
- user: {
19
- id: string
20
- username: string
21
- displayName: string | null
22
- avatarUrl: string | null
23
- status: string
24
- isBot: boolean
25
- }
26
- createdAt: string
27
- }
@@ -1,6 +0,0 @@
1
- export * from './agent.types'
2
- export * from './channel.types'
3
- export * from './friendship.types'
4
- export * from './message.types'
5
- export * from './server.types'
6
- export * from './user.types'
@@ -1,126 +0,0 @@
1
- export interface Message {
2
- id: string
3
- content: string
4
- channelId: string
5
- authorId: string
6
- threadId: string | null
7
- replyToId: string | null
8
- isEdited: boolean
9
- isPinned: boolean
10
- createdAt: string
11
- updatedAt: string
12
- author?: {
13
- id: string
14
- username: string
15
- displayName: string
16
- avatarUrl: string | null
17
- isBot: boolean
18
- }
19
- attachments?: Attachment[]
20
- reactions?: ReactionGroup[]
21
- }
22
-
23
- export interface Attachment {
24
- id: string
25
- messageId: string
26
- filename: string
27
- url: string
28
- contentType: string
29
- size: number
30
- width: number | null
31
- height: number | null
32
- createdAt: string
33
- }
34
-
35
- export interface ReactionGroup {
36
- emoji: string
37
- count: number
38
- userIds: string[]
39
- }
40
-
41
- export interface Thread {
42
- id: string
43
- name: string
44
- channelId: string
45
- parentMessageId: string
46
- creatorId: string
47
- isArchived: boolean
48
- createdAt: string
49
- updatedAt: string
50
- }
51
-
52
- export interface SendMessageRequest {
53
- content: string
54
- threadId?: string
55
- replyToId?: string
56
- }
57
-
58
- export interface UpdateMessageRequest {
59
- content: string
60
- }
61
-
62
- export type NotificationType = 'mention' | 'reply' | 'dm' | 'system'
63
-
64
- export interface Notification {
65
- id: string
66
- userId: string
67
- type: NotificationType
68
- title: string
69
- body: string | null
70
- referenceId: string | null
71
- referenceType: string | null
72
- isRead: boolean
73
- createdAt: string
74
- }
75
-
76
- export interface DmChannel {
77
- id: string
78
- userAId: string
79
- userBId: string
80
- lastMessageAt: string | null
81
- createdAt: string
82
- otherUser?: {
83
- id: string
84
- username: string
85
- displayName: string
86
- avatarUrl: string | null
87
- status: string
88
- }
89
- }
90
-
91
- /** DM message — mirrors channel Message but scoped to DM channels */
92
- export interface DmMessage {
93
- id: string
94
- content: string
95
- dmChannelId: string
96
- authorId: string
97
- replyToId: string | null
98
- isEdited: boolean
99
- createdAt: string
100
- updatedAt: string
101
- author?: {
102
- id: string
103
- username: string
104
- displayName: string
105
- avatarUrl: string | null
106
- isBot: boolean
107
- }
108
- attachments?: DmAttachment[]
109
- reactions?: ReactionGroup[]
110
- }
111
-
112
- export interface DmAttachment {
113
- id: string
114
- dmMessageId: 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
-
124
- export interface UpdateDmMessageRequest {
125
- content: string
126
- }
@@ -1,38 +0,0 @@
1
- export interface Server {
2
- id: string
3
- name: string
4
- iconUrl: string | null
5
- ownerId: string
6
- inviteCode: string
7
- createdAt: string
8
- updatedAt: string
9
- }
10
-
11
- export interface CreateServerRequest {
12
- name: string
13
- iconUrl?: string
14
- }
15
-
16
- export interface UpdateServerRequest {
17
- name?: string
18
- iconUrl?: string
19
- }
20
-
21
- export type MemberRole = 'owner' | 'admin' | 'member'
22
-
23
- export interface Member {
24
- id: string
25
- userId: string
26
- serverId: string
27
- role: MemberRole
28
- nickname: string | null
29
- joinedAt: string
30
- user?: {
31
- id: string
32
- username: string
33
- displayName: string
34
- avatarUrl: string | null
35
- status: string
36
- isBot: boolean
37
- }
38
- }
@@ -1,40 +0,0 @@
1
- export type UserStatus = 'online' | 'idle' | 'dnd' | 'offline'
2
-
3
- export interface User {
4
- id: string
5
- email: string
6
- username: string
7
- displayName: string
8
- avatarUrl: string | null
9
- status: UserStatus
10
- isBot: boolean
11
- createdAt: string
12
- updatedAt: string
13
- }
14
-
15
- export interface UserProfile {
16
- id: string
17
- username: string
18
- displayName: string
19
- avatarUrl: string | null
20
- status: UserStatus
21
- isBot: boolean
22
- }
23
-
24
- export interface LoginRequest {
25
- email: string
26
- password: string
27
- }
28
-
29
- export interface RegisterRequest {
30
- email: string
31
- username: string
32
- displayName: string
33
- password: string
34
- }
35
-
36
- export interface AuthResponse {
37
- user: User
38
- accessToken: string
39
- refreshToken: string
40
- }