• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

u-wave / core / 11980840475

22 Nov 2024 10:04PM UTC coverage: 78.492% (-1.7%) from 80.158%
11980840475

Pull #637

github

goto-bus-stop
ci: add node 22
Pull Request #637: Switch to a relational database

757 of 912 branches covered (83.0%)

Branch coverage included in aggregate %.

2001 of 2791 new or added lines in 52 files covered. (71.69%)

9 existing lines in 7 files now uncovered.

8666 of 11093 relevant lines covered (78.12%)

70.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.46
/src/plugins/chat.js
1
import { randomUUID } from 'node:crypto';
1✔
2
import routes from '../routes/chat.js';
1✔
3
import { now } from '../utils/sqlite.js';
1✔
4

1✔
5
/**
1✔
6
 * @typedef {import('../schema.js').UserID} UserID
1✔
7
 * @typedef {import('../schema.js').User} User
1✔
8
 * @typedef {object} ChatOptions
1✔
9
 * @prop {number} maxLength
1✔
10
 */
1✔
11

1✔
12
/** @type {ChatOptions} */
1✔
13
const defaultOptions = {
1✔
14
  maxLength: 300,
1✔
15
};
1✔
16

1✔
17
class Chat {
92✔
18
  #uw;
92✔
19

92✔
20
  /** @type {ChatOptions} */
92✔
21
  #options;
92✔
22

92✔
23
  /**
92✔
24
   * @param {import('../Uwave.js').default} uw
92✔
25
   * @param {Partial<ChatOptions>} [options]
92✔
26
   */
92✔
27
  constructor(uw, options = {}) {
92✔
28
    this.#uw = uw;
92✔
29

92✔
30
    this.#options = {
92✔
31
      ...defaultOptions,
92✔
32
      ...options,
92✔
33
    };
92✔
34
  }
92✔
35

92✔
36
  /**
92✔
37
   * @param {User} user
92✔
38
   * @param {number} duration - Duration in seconds
92✔
39
   * @param {{ moderator: User }} options
92✔
40
   */
92✔
41
  async mute(user, duration, options) {
92✔
NEW
42
    const { db } = this.#uw;
×
NEW
43

×
NEW
44
    const expiresAt = new Date(Date.now() + duration * 1000);
×
NEW
45
    await db.insertInto('mutes')
×
NEW
46
      .values({
×
NEW
47
        userID: user.id,
×
NEW
48
        moderatorID: options.moderator.id,
×
NEW
49
        expiresAt,
×
NEW
50
      })
×
NEW
51
      .execute();
×
52

×
53
    this.#uw.publish('chat:mute', {
×
54
      moderatorID: options.moderator.id,
×
55
      userID: user.id,
×
56
      duration,
×
57
    });
×
58
  }
×
59

92✔
60
  /**
92✔
61
   * @param {User} user
92✔
62
   * @param {{ moderator: User }} options
92✔
63
   */
92✔
64
  async unmute(user, options) {
92✔
NEW
65
    const { db } = this.#uw;
×
NEW
66

×
NEW
67
    await db.updateTable('mutes')
×
NEW
68
      .where('userID', '=', user.id)
×
NEW
69
      .where('expiresAt', '>', now)
×
NEW
70
      .set({ expiresAt: now, updatedAt: now })
×
NEW
71
      .execute();
×
72

×
73
    this.#uw.publish('chat:unmute', {
×
74
      moderatorID: options.moderator.id,
×
75
      userID: user.id,
×
76
    });
×
77
  }
×
78

92✔
79
  /**
92✔
80
   * @param {User} user
92✔
81
   * @private
92✔
82
   */
92✔
83
  async isMuted(user) {
92✔
NEW
84
    const { db } = this.#uw;
×
NEW
85

×
NEW
86
    const mute = await db.selectFrom('mutes')
×
NEW
87
      .where('userID', '=', user.id)
×
NEW
88
      .where('expiresAt', '>', now)
×
NEW
89
      .selectAll()
×
NEW
90
      .executeTakeFirst();
×
NEW
91

×
NEW
92
    return mute ?? null;
×
UNCOV
93
  }
×
94

92✔
95
  /**
92✔
96
   * @param {string} message
92✔
97
   * @private
92✔
98
   */
92✔
99
  truncate(message) {
92✔
100
    return message.slice(0, this.#options.maxLength);
×
101
  }
×
102

92✔
103
  /**
92✔
104
   * @param {User} user
92✔
105
   * @param {string} message
92✔
106
   */
92✔
107
  async send(user, message) {
92✔
108
    if (await this.isMuted(user)) {
×
109
      return;
×
110
    }
×
111

×
112
    this.#uw.publish('chat:message', {
×
113
      id: randomUUID(),
×
114
      userID: user.id,
×
115
      message: this.truncate(message),
×
116
      timestamp: Date.now(),
×
117
    });
×
118
  }
×
119

92✔
120
  /**
92✔
121
   * @param {{ id: string } | { userID: UserID } | {}} filter
92✔
122
   * @param {{ moderator: User }} options
92✔
123
   */
92✔
124
  delete(filter, options) {
92✔
125
    const deletion = {
×
126
      filter: typeof filter === 'string' ? { id: filter } : filter,
×
127
      moderatorID: options.moderator.id,
×
128
    };
×
129

×
130
    this.#uw.publish('chat:delete', deletion);
×
131
  }
×
132
}
92✔
133

1✔
134
/**
1✔
135
 * @param {import('../Uwave.js').default} uw
1✔
136
 * @param {Partial<ChatOptions>} [options]
1✔
137
 */
1✔
138
async function chat(uw, options = {}) {
92✔
139
  uw.chat = new Chat(uw, options);
92✔
140
  uw.httpApi.use('/chat', routes());
92✔
141
}
92✔
142

1✔
143
export default chat;
1✔
144
export { Chat };
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc