@notidotbot/noti-api-client 1.9.86 → 1.9.88

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.
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FEEDBACK_NOTIFICATION_KINDS = exports.FEEDBACK_REACTION_KINDS = exports.FEEDBACK_REFUSALS = exports.FEEDBACK_STATUSES = exports.FEEDBACK_AUDIENCES = exports.APIFeedback = void 0;
4
+ // Data.
5
+ /**
6
+ * The feedback board - ideas and private requests, votes, follows (replaces Fider at feedback.noti.bot).
7
+ *
8
+ * ── WHO SEES WHAT ──────────────────────────────────────────────────────────
9
+ * Reads work logged out: pass `auth` ONLY when the user is logged in. With a session the server answers for
10
+ * that user (premium-only boards, their own hidden posts, staff view) and marks the response `private,
11
+ * no-store`; without one it answers the public view and lets it be cached. Never cache a logged-in response
12
+ * on the page side as if it were public.
13
+ *
14
+ * Behind the `feedback` launch flag: while it is hidden for the caller every method 404s. A post the viewer
15
+ * may not see is 404 too, never 403 - do not show "forbidden", show "not found".
16
+ *
17
+ * ── REFUSALS ───────────────────────────────────────────────────────────────
18
+ * A refused write is `{ status, error: { code } }`, `code` from `FeedbackErrorCode`. `voteRefusal` /
19
+ * `commentRefusal` on a post's `viewer` tell you up front why the buttons are off (banned, new account,
20
+ * archived board, locked post), so the page can say so instead of letting the click fail.
21
+ *
22
+ * ── TEXT ───────────────────────────────────────────────────────────────────
23
+ * `title` is plain text. `body` is MARKDOWN, stored raw: render it with an allowlist (no raw HTML, images
24
+ * only from Noti's own host, links `rel="nofollow ugc noopener"`). The server does not sanitise HTML for you.
25
+ */
26
+ class APIFeedback {
27
+ web;
28
+ constructor(web) {
29
+ this.web = web;
30
+ }
31
+ /** Boards the viewer may see, with visible-post counts per status. */
32
+ async getFeedbackBoards({ auth } = {}) {
33
+ return await this.web.request({
34
+ method: 'GET', auth,
35
+ endpoint: this.web.qp('/public/feedback/boards'),
36
+ });
37
+ }
38
+ async getFeedbackTags({ auth } = {}) {
39
+ return await this.web.request({
40
+ method: 'GET', auth,
41
+ endpoint: this.web.qp('/public/feedback/tags'),
42
+ });
43
+ }
44
+ /**
45
+ * The list. `board` / `tag` take a slug or id; `sort` is `top` (default, pinned first inside a board),
46
+ * `new` or `trending` (votes in the last 14 days). `limit` up to 50. Searching logged out is rate limited.
47
+ */
48
+ async getFeedbackPosts({ auth, ...query } = {}) {
49
+ return await this.web.request({
50
+ method: 'GET', auth,
51
+ endpoint: this.web.qp('/public/feedback/posts', query),
52
+ });
53
+ }
54
+ /** Up to 5 visible posts whose titles look like `q` - the "is this already asked?" hint while typing a title. */
55
+ async getSimilarFeedbackPosts({ auth, q }) {
56
+ return await this.web.request({
57
+ method: 'GET', auth,
58
+ endpoint: this.web.qp('/public/feedback/posts/similar', { q }),
59
+ });
60
+ }
61
+ /**
62
+ * One post. A merged post answers `{ post: null, viewer: null, mergedInto }`: send the user to
63
+ * `mergedInto` (its old number keeps working this way).
64
+ */
65
+ async getFeedbackPost({ auth, number }) {
66
+ return await this.web.request({
67
+ method: 'GET', auth,
68
+ endpoint: this.web.qp('/public/feedback/posts/' + number),
69
+ });
70
+ }
71
+ /** Post an idea / request. The author votes and follows it automatically. 5 per hour. `uploadIds` from createFeedbackUpload. */
72
+ async createFeedbackPost({ auth, post }) {
73
+ return await this.web.request({
74
+ method: 'POST', auth,
75
+ endpoint: this.web.qp('/public/feedback/posts'),
76
+ body: post,
77
+ });
78
+ }
79
+ /** Edit your own post. Only while it is open / under review and has 10 or fewer votes (`viewer.canEdit`). */
80
+ async updateFeedbackPost({ auth, number, post }) {
81
+ return await this.web.request({
82
+ method: 'PATCH', auth,
83
+ endpoint: this.web.qp('/public/feedback/posts/' + number),
84
+ body: post,
85
+ });
86
+ }
87
+ /** Delete your own post - only while nobody else has voted on it (`ask_staff` otherwise). */
88
+ async deleteFeedbackPost({ auth, number }) {
89
+ return await this.web.request({
90
+ method: 'DELETE', auth,
91
+ endpoint: this.web.qp('/public/feedback/posts/' + number),
92
+ });
93
+ }
94
+ /** Vote. Voting also follows the post, unless the user unfollowed it before. 30 per minute. */
95
+ async createFeedbackVote({ auth, number }) {
96
+ return await this.web.request({
97
+ method: 'PUT', auth,
98
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/votes/@me'),
99
+ });
100
+ }
101
+ async deleteFeedbackVote({ auth, number }) {
102
+ return await this.web.request({
103
+ method: 'DELETE', auth,
104
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/votes/@me'),
105
+ });
106
+ }
107
+ /** Follow: get notified when it changes status, ships, or gets an official answer. */
108
+ async createFeedbackFollow({ auth, number }) {
109
+ return await this.web.request({
110
+ method: 'PUT', auth,
111
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/follows/@me'),
112
+ });
113
+ }
114
+ /** Unfollow. Sticks: voting again later does not re-follow. */
115
+ async deleteFeedbackFollow({ auth, number }) {
116
+ return await this.web.request({
117
+ method: 'DELETE', auth,
118
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/follows/@me'),
119
+ });
120
+ }
121
+ /**
122
+ * The thread: the official staff answer first, then comments oldest first with their replies (one level).
123
+ * Staff notes (`internal`) only reach staff. A deleted comment shows as `deleted: true` with no body while it
124
+ * still has replies.
125
+ */
126
+ async getFeedbackComments({ auth, number }) {
127
+ return await this.web.request({
128
+ method: 'GET', auth,
129
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/comments'),
130
+ });
131
+ }
132
+ /** Comment, or reply with `parentId` (a top-level comment only). `uploadIds` from createFeedbackUpload. 10/minute. Returns the thread. */
133
+ async createFeedbackComment({ auth, number, comment }) {
134
+ return await this.web.request({
135
+ method: 'POST', auth,
136
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/comments'),
137
+ body: comment,
138
+ });
139
+ }
140
+ /** Edit your own comment. Returns the thread. */
141
+ async updateFeedbackComment({ auth, commentId, body }) {
142
+ return await this.web.request({
143
+ method: 'PATCH', auth,
144
+ endpoint: this.web.qp('/public/feedback/comments/' + commentId),
145
+ body: { body },
146
+ });
147
+ }
148
+ /** Delete your own comment (its replies stay). Returns the thread. */
149
+ async deleteFeedbackComment({ auth, commentId }) {
150
+ return await this.web.request({
151
+ method: 'DELETE', auth,
152
+ endpoint: this.web.qp('/public/feedback/comments/' + commentId),
153
+ });
154
+ }
155
+ /** React to a post. Answers the post's reactions. `reactions_off` (404) when the switch is off. */
156
+ async createFeedbackPostReaction({ auth, number, kind }) {
157
+ return await this.web.request({
158
+ method: 'PUT', auth,
159
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/reactions/' + kind),
160
+ });
161
+ }
162
+ async deleteFeedbackPostReaction({ auth, number, kind }) {
163
+ return await this.web.request({
164
+ method: 'DELETE', auth,
165
+ endpoint: this.web.qp('/public/feedback/posts/' + number + '/reactions/' + kind),
166
+ });
167
+ }
168
+ async createFeedbackCommentReaction({ auth, commentId, kind }) {
169
+ return await this.web.request({
170
+ method: 'PUT', auth,
171
+ endpoint: this.web.qp('/public/feedback/comments/' + commentId + '/reactions/' + kind),
172
+ });
173
+ }
174
+ async deleteFeedbackCommentReaction({ auth, commentId, kind }) {
175
+ return await this.web.request({
176
+ method: 'DELETE', auth,
177
+ endpoint: this.web.qp('/public/feedback/comments/' + commentId + '/reactions/' + kind),
178
+ });
179
+ }
180
+ /**
181
+ * Upload one image (field `image`: png, jpeg, webp or gif, up to 8 MB). It comes back as webp, at most
182
+ * 2000px, with its metadata (GPS, camera) removed. Put `url` in the markdown as `![alt](url)` and send
183
+ * `uploadId` in `uploadIds` when saving the post or comment; unattached uploads are deleted after 24h.
184
+ * 20 per day. Refusals: `uploads_off`, `image_too_large`, `unsupported_image`, `invalid_image`, `upload_quota`.
185
+ */
186
+ async createFeedbackUpload({ auth, formData }) {
187
+ return await this.web.request({
188
+ method: 'POST', auth,
189
+ endpoint: this.web.qp('/public/feedback/uploads'),
190
+ body: formData,
191
+ });
192
+ }
193
+ /** The roadmap: planned, in progress, and shipped in the last 30 days (older ones are on the timeline). */
194
+ async getFeedbackRoadmap({ auth } = {}) {
195
+ return await this.web.request({
196
+ method: 'GET', auth,
197
+ endpoint: this.web.qp('/public/feedback/roadmap'),
198
+ });
199
+ }
200
+ /** Shipped posts, newest first, each with the public changelog entry it shipped in (if staff linked one). */
201
+ async getFeedbackTimeline({ auth, ...query } = {}) {
202
+ return await this.web.request({
203
+ method: 'GET', auth,
204
+ endpoint: this.web.qp('/public/feedback/timeline', query),
205
+ });
206
+ }
207
+ /** Posts staff featured for the top of the feedback page (up to 10, in their order). */
208
+ async getFeedbackFeatured({ auth } = {}) {
209
+ return await this.web.request({
210
+ method: 'GET', auth,
211
+ endpoint: this.web.qp('/public/feedback/featured'),
212
+ });
213
+ }
214
+ /**
215
+ * The inbox (the bell): newest first. Visibility is checked when you read it, so a post that has gone
216
+ * private is simply not there. Page with `before` = the previous page's `next`.
217
+ */
218
+ async getFeedbackNotifications({ auth, ...query }) {
219
+ return await this.web.request({
220
+ method: 'GET', auth,
221
+ endpoint: this.web.qp('/public/feedback/users/@me/notifications', query),
222
+ });
223
+ }
224
+ /** The bell's number. Counts up to 100 (`capped` then true - show "99+"). */
225
+ async getFeedbackNotificationCount({ auth }) {
226
+ return await this.web.request({
227
+ method: 'GET', auth,
228
+ endpoint: this.web.qp('/public/feedback/users/@me/notifications/unread'),
229
+ });
230
+ }
231
+ /** Mark notifications read: the given `ids`, or all of them when omitted. */
232
+ async createFeedbackNotificationReads({ auth, ids }) {
233
+ return await this.web.request({
234
+ method: 'POST', auth,
235
+ endpoint: this.web.qp('/public/feedback/users/@me/notifications/reads'),
236
+ body: ids ? { ids } : {},
237
+ });
238
+ }
239
+ /** DM settings. `dmBlocked`: Discord refused a DM (closed DMs) - switching DMs on again clears it. `dmsAvailable` false = DMs are off for everyone. */
240
+ async getFeedbackSettings({ auth }) {
241
+ return await this.web.request({
242
+ method: 'GET', auth,
243
+ endpoint: this.web.qp('/public/feedback/users/@me/settings'),
244
+ });
245
+ }
246
+ /** Turn the update digest DM on or off (off by default; at most one DM per 15 minutes, 10 a day). */
247
+ async updateFeedbackSettings({ auth, dmEnabled }) {
248
+ return await this.web.request({
249
+ method: 'PATCH', auth,
250
+ endpoint: this.web.qp('/public/feedback/users/@me/settings'),
251
+ body: { dmEnabled },
252
+ });
253
+ }
254
+ /** The "my feedback" page: my posts, what I voted on, what I follow (100 each, newest first). */
255
+ async getMyFeedback({ auth }) {
256
+ return await this.web.request({
257
+ method: 'GET', auth,
258
+ endpoint: this.web.qp('/public/feedback/users/@me'),
259
+ });
260
+ }
261
+ }
262
+ exports.APIFeedback = APIFeedback;
263
+ /** Mirrors `FeedbackAudienceEnum` in Noti-v3. A post's audience is the narrower of its board's and its own. */
264
+ exports.FEEDBACK_AUDIENCES = ['public', 'premium', 'beta', 'staff', 'authorAndStaff'];
265
+ /** Mirrors `FeedbackStatusEnum`. The roadmap columns are planned / inProgress / done. */
266
+ exports.FEEDBACK_STATUSES = ['open', 'underReview', 'planned', 'inProgress', 'done', 'declined'];
267
+ /** Why an action was refused. Mirrors `FEEDBACK_REFUSALS` in Noti-v3's `src/modules/feedback/visibility.ts`. */
268
+ exports.FEEDBACK_REFUSALS = [
269
+ 'login_required', 'not_visible', 'banned', 'account_too_new', 'board_archived', 'posting_closed', 'voting_locked', 'comments_locked',
270
+ ];
271
+ /** Mirrors `FEEDBACK_REACTION_KINDS` in Noti-v3. */
272
+ exports.FEEDBACK_REACTION_KINDS = ['heart', 'thumbsUp', 'thumbsDown', 'fire'];
273
+ /** Mirrors `FEEDBACK_NOTIFICATION_KINDS` in Noti-v3. `merged`: the post you followed was merged into `post`. */
274
+ exports.FEEDBACK_NOTIFICATION_KINDS = ['statusChanged', 'shipped', 'officialAnswer', 'reply', 'merged', 'pollStarted'];
@@ -0,0 +1,120 @@
1
+ import { WebDataManager } from '../core/manager';
2
+ import { CancelOutWebResponses, WebResponse } from '../types';
3
+ /**
4
+ * Reposition Emojis - reorder a server's emojis in Discord's emoji picker.
5
+ *
6
+ * Discord has no reorder API: the picker lists a server's emojis oldest upload first. So Noti re-uploads the emojis
7
+ * that have to move, in the new order, and deletes the originals. **Every re-uploaded emoji gets a new id**: Noti
8
+ * updates its own settings (role panels, starboards, message buttons, `<:name:id>` in message text) and re-renders
9
+ * posted role panels, but emojis in old chat messages and other bots' settings may show as broken.
10
+ *
11
+ * Only what must move is re-uploaded: emojis at the start of the new order that are already in age order keep their
12
+ * place. Integration emojis (`managed`) and greyed-out ones (`available: false`) can never move - pin them.
13
+ *
14
+ * Free servers: one reposition per 7 days (`nextFreeAt`). Premium: unlimited (`unlimited`). Starting one needs a top.gg
15
+ * vote (403 `vote_required`, Premium skips it) and Manage Expressions for both the caller and Noti. Behind the
16
+ * `repositionEmojis` launch flag: every method answers 403 `not_available` until it is beta/public for the caller.
17
+ */
18
+ export declare class APIGuildEmojis {
19
+ private web;
20
+ constructor(web: WebDataManager);
21
+ /** The server's emojis in picker order, its slot limits, the weekly cap, permissions, and the current / last job. */
22
+ getGuildEmojis({ auth, guildId }: GuildEmojisFunctionsInput['getGuildEmojis']): Promise<WebResponse<GuildEmojisData>>;
23
+ /**
24
+ * Start a reposition. `order` is EVERY emoji id in the server, in the new order. Runs in the background - poll
25
+ * `getEmojiReposition` for progress (large servers can take hours: Discord limits emoji uploads).
26
+ *
27
+ * Errors (`error.code`): 400 `invalid_body` / `mismatch` (the list changed - reload) / `noop` / `managed_locked` /
28
+ * `unavailable_locked` (`error.ids`) / `over_limit`; 403 `not_available` / `vote_required` / `not_manager` /
29
+ * `missing_permissions`; 409 `running`; 429 `weekly_limit` (`error.resetsAt`, `error.premiumUrl`); 503
30
+ * `guild_unavailable`.
31
+ */
32
+ createEmojiReposition({ auth, guildId, order }: GuildEmojisFunctionsInput['createEmojiReposition']): Promise<WebResponse<{
33
+ job: EmojiRepositionJob;
34
+ }>>;
35
+ /** The current or last job (kept 7 days after it ends), or null. */
36
+ getEmojiReposition({ auth, guildId }: GuildEmojisFunctionsInput['getEmojiReposition']): Promise<WebResponse<{
37
+ job: EmojiRepositionJob | null;
38
+ }>>;
39
+ }
40
+ export type GuildEmoji = {
41
+ id: string;
42
+ name: string;
43
+ animated: boolean;
44
+ /** Integration (Twitch / YouTube) emoji: cannot be moved. */
45
+ managed: boolean;
46
+ /** False when greyed out (over the limit after a boost-level drop): cannot be moved. */
47
+ available: boolean;
48
+ /** Restricted to roles; the re-upload keeps the restriction. */
49
+ roleLocked: boolean;
50
+ url: string;
51
+ };
52
+ export type GuildEmojisData = {
53
+ /** Picker order: oldest upload first. */
54
+ emojis: GuildEmoji[];
55
+ /** Static and animated each have `max` slots. */
56
+ limits: {
57
+ static: number;
58
+ animated: number;
59
+ max: number;
60
+ };
61
+ canManage: {
62
+ bot: boolean;
63
+ member: boolean;
64
+ };
65
+ /** Premium: no weekly cap. */
66
+ unlimited: boolean;
67
+ /** Free servers: when the next reposition is allowed (ms), or null when one is free now. */
68
+ nextFreeAt: number | null;
69
+ job: EmojiRepositionJob | null;
70
+ };
71
+ /** One emoji's progress. `skipped` = someone deleted it during the job; `failed` carries `error`. */
72
+ export type EmojiRepositionStep = 'pending' | 'backedUp' | 'creating' | 'created' | 'deleting' | 'done' | 'failed' | 'skipped';
73
+ export type EmojiRepositionJob = {
74
+ jobId: string;
75
+ guildId: string;
76
+ startedBy: string;
77
+ startedAt: number;
78
+ status: 'backing-up' | 'moving' | 'repointing' | 'done' | 'failed';
79
+ /** Emojis that kept their place. */
80
+ keep: string[];
81
+ /** Emojis being re-uploaded, in order. `newId` once its copy exists. */
82
+ emojis: Array<{
83
+ id: string;
84
+ name: string;
85
+ animated: boolean;
86
+ roles: string[];
87
+ step: EmojiRepositionStep;
88
+ newId?: string;
89
+ deletedFirst?: boolean;
90
+ backupKey?: string;
91
+ error?: string;
92
+ }>;
93
+ movedAny: boolean;
94
+ /** Why it failed, e.g. `backup_too_large:<id>`, `emoji_down:<id>`, `repoint_failed`. */
95
+ failure?: string;
96
+ finishedAt?: number;
97
+ };
98
+ export type GuildEmojisFunctionsInput = {
99
+ 'getGuildEmojis': {
100
+ auth: string;
101
+ guildId: string;
102
+ };
103
+ 'createEmojiReposition': {
104
+ auth: string;
105
+ guildId: string;
106
+ order: string[];
107
+ };
108
+ 'getEmojiReposition': {
109
+ auth: string;
110
+ guildId: string;
111
+ };
112
+ };
113
+ export type GuildEmojisReturnTypes = {
114
+ 'getGuildEmojisRaw': Awaited<ReturnType<APIGuildEmojis['getGuildEmojis']>>;
115
+ 'getGuildEmojisSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildEmojis['getGuildEmojis']>>>;
116
+ 'createEmojiRepositionRaw': Awaited<ReturnType<APIGuildEmojis['createEmojiReposition']>>;
117
+ 'createEmojiRepositionSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildEmojis['createEmojiReposition']>>>;
118
+ 'getEmojiRepositionRaw': Awaited<ReturnType<APIGuildEmojis['getEmojiReposition']>>;
119
+ 'getEmojiRepositionSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildEmojis['getEmojiReposition']>>>;
120
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.APIGuildEmojis = void 0;
4
+ /**
5
+ * Reposition Emojis - reorder a server's emojis in Discord's emoji picker.
6
+ *
7
+ * Discord has no reorder API: the picker lists a server's emojis oldest upload first. So Noti re-uploads the emojis
8
+ * that have to move, in the new order, and deletes the originals. **Every re-uploaded emoji gets a new id**: Noti
9
+ * updates its own settings (role panels, starboards, message buttons, `<:name:id>` in message text) and re-renders
10
+ * posted role panels, but emojis in old chat messages and other bots' settings may show as broken.
11
+ *
12
+ * Only what must move is re-uploaded: emojis at the start of the new order that are already in age order keep their
13
+ * place. Integration emojis (`managed`) and greyed-out ones (`available: false`) can never move - pin them.
14
+ *
15
+ * Free servers: one reposition per 7 days (`nextFreeAt`). Premium: unlimited (`unlimited`). Starting one needs a top.gg
16
+ * vote (403 `vote_required`, Premium skips it) and Manage Expressions for both the caller and Noti. Behind the
17
+ * `repositionEmojis` launch flag: every method answers 403 `not_available` until it is beta/public for the caller.
18
+ */
19
+ class APIGuildEmojis {
20
+ web;
21
+ constructor(web) {
22
+ this.web = web;
23
+ }
24
+ /** The server's emojis in picker order, its slot limits, the weekly cap, permissions, and the current / last job. */
25
+ async getGuildEmojis({ auth, guildId }) {
26
+ return await this.web.request({
27
+ method: 'GET', auth,
28
+ endpoint: this.web.qp(`/data/guild/${guildId}/emojis`),
29
+ });
30
+ }
31
+ /**
32
+ * Start a reposition. `order` is EVERY emoji id in the server, in the new order. Runs in the background - poll
33
+ * `getEmojiReposition` for progress (large servers can take hours: Discord limits emoji uploads).
34
+ *
35
+ * Errors (`error.code`): 400 `invalid_body` / `mismatch` (the list changed - reload) / `noop` / `managed_locked` /
36
+ * `unavailable_locked` (`error.ids`) / `over_limit`; 403 `not_available` / `vote_required` / `not_manager` /
37
+ * `missing_permissions`; 409 `running`; 429 `weekly_limit` (`error.resetsAt`, `error.premiumUrl`); 503
38
+ * `guild_unavailable`.
39
+ */
40
+ async createEmojiReposition({ auth, guildId, order }) {
41
+ return await this.web.request({
42
+ method: 'POST', auth,
43
+ endpoint: this.web.qp(`/data/guild/${guildId}/emojis/repositions`),
44
+ body: { order },
45
+ });
46
+ }
47
+ /** The current or last job (kept 7 days after it ends), or null. */
48
+ async getEmojiReposition({ auth, guildId }) {
49
+ return await this.web.request({
50
+ method: 'GET', auth,
51
+ endpoint: this.web.qp(`/data/guild/${guildId}/emojis/repositions/current`),
52
+ });
53
+ }
54
+ }
55
+ exports.APIGuildEmojis = APIGuildEmojis;
@@ -86,6 +86,8 @@ export type SitePollOption = {
86
86
  optionId: string;
87
87
  label: string;
88
88
  description: string | null;
89
+ /** The feedback post this option stands for - link to it. Null when none, or while that post is not public. */
90
+ postNumber: number | null;
89
91
  };
90
92
  export type SitePollResults = {
91
93
  /** In display order. */
@@ -15,6 +15,7 @@ import { APIGuildBounties } from '../classes/guildBounties';
15
15
  import { APIGuildAssistant } from '../classes/guildAssistant';
16
16
  import { APIGuildAutoRoles } from '../classes/guildAutoRoles';
17
17
  import { APIGuildBoosts } from '../classes/guildBoosts';
18
+ import { APIGuildEmojis } from '../classes/guildEmojis';
18
19
  import { APIGuildMembers } from '../classes/guildMembers';
19
20
  import { APIGuildHealth } from '../classes/guildHealth';
20
21
  import { APIGuildInfluencerPanel } from '../classes/guildInfluencerPanel';
@@ -40,6 +41,8 @@ import { APIPublicDrops } from '../classes/publicDrops';
40
41
  import { APIPolls } from '../classes/polls';
41
42
  import { APIAnnouncements } from '../classes/announcements';
42
43
  import { APIAdminPolls } from '../classes/adminPolls';
44
+ import { APIFeedback } from '../classes/feedback';
45
+ import { APIAdminFeedback } from '../classes/adminFeedback';
43
46
  import { APIAdminAnnouncements } from '../classes/adminAnnouncements';
44
47
  import { APIGuildFishing } from '../classes/guildFishing';
45
48
  import { APIAdminFishing } from '../classes/adminFishing';
@@ -70,6 +73,8 @@ export declare class WebDataManager {
70
73
  readonly announcements: APIAnnouncements;
71
74
  readonly adminPolls: APIAdminPolls;
72
75
  readonly adminAnnouncements: APIAdminAnnouncements;
76
+ readonly feedback: APIFeedback;
77
+ readonly adminFeedback: APIAdminFeedback;
73
78
  readonly other: APIOther;
74
79
  readonly guild: APIGuild;
75
80
  readonly teams: APITeams;
@@ -86,6 +91,7 @@ export declare class WebDataManager {
86
91
  readonly guildAssistant: APIGuildAssistant;
87
92
  readonly guildAutoRoles: APIGuildAutoRoles;
88
93
  readonly guildBoosts: APIGuildBoosts;
94
+ readonly guildEmojis: APIGuildEmojis;
89
95
  readonly guildMembers: APIGuildMembers;
90
96
  readonly guildHealth: APIGuildHealth;
91
97
  readonly guildInfluencerPanel: APIGuildInfluencerPanel;
@@ -21,6 +21,7 @@ const guildBounties_1 = require("../classes/guildBounties");
21
21
  const guildAssistant_1 = require("../classes/guildAssistant");
22
22
  const guildAutoRoles_1 = require("../classes/guildAutoRoles");
23
23
  const guildBoosts_1 = require("../classes/guildBoosts");
24
+ const guildEmojis_1 = require("../classes/guildEmojis");
24
25
  const guildMembers_1 = require("../classes/guildMembers");
25
26
  const guildHealth_1 = require("../classes/guildHealth");
26
27
  const guildInfluencerPanel_1 = require("../classes/guildInfluencerPanel");
@@ -45,6 +46,8 @@ const publicDrops_1 = require("../classes/publicDrops");
45
46
  const polls_1 = require("../classes/polls");
46
47
  const announcements_1 = require("../classes/announcements");
47
48
  const adminPolls_1 = require("../classes/adminPolls");
49
+ const feedback_1 = require("../classes/feedback");
50
+ const adminFeedback_1 = require("../classes/adminFeedback");
48
51
  const adminAnnouncements_1 = require("../classes/adminAnnouncements");
49
52
  const guildFishing_1 = require("../classes/guildFishing");
50
53
  const adminFishing_1 = require("../classes/adminFishing");
@@ -74,6 +77,8 @@ class WebDataManager {
74
77
  announcements = new announcements_1.APIAnnouncements(this);
75
78
  adminPolls = new adminPolls_1.APIAdminPolls(this);
76
79
  adminAnnouncements = new adminAnnouncements_1.APIAdminAnnouncements(this);
80
+ feedback = new feedback_1.APIFeedback(this);
81
+ adminFeedback = new adminFeedback_1.APIAdminFeedback(this);
77
82
  other = new other_1.APIOther(this);
78
83
  guild = new guild_1.APIGuild(this);
79
84
  teams = new teams_1.APITeams(this);
@@ -90,6 +95,7 @@ class WebDataManager {
90
95
  guildAssistant = new guildAssistant_1.APIGuildAssistant(this);
91
96
  guildAutoRoles = new guildAutoRoles_1.APIGuildAutoRoles(this);
92
97
  guildBoosts = new guildBoosts_1.APIGuildBoosts(this);
98
+ guildEmojis = new guildEmojis_1.APIGuildEmojis(this);
93
99
  guildMembers = new guildMembers_1.APIGuildMembers(this);
94
100
  guildHealth = new guildHealth_1.APIGuildHealth(this);
95
101
  guildInfluencerPanel = new guildInfluencerPanel_1.APIGuildInfluencerPanel(this);
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export * from './classes/publicDrops';
13
13
  export * from './classes/polls';
14
14
  export * from './classes/announcements';
15
15
  export * from './classes/adminPolls';
16
+ export * from './classes/feedback';
17
+ export * from './classes/adminFeedback';
16
18
  export * from './classes/adminAnnouncements';
17
19
  export * from './classes/emotes';
18
20
  export * from './classes/files';
@@ -33,6 +35,7 @@ export * from './classes/guildBounties';
33
35
  export * from './classes/guildAssistant';
34
36
  export * from './classes/guildAutoRoles';
35
37
  export * from './classes/guildBoosts';
38
+ export * from './classes/guildEmojis';
36
39
  export * from './classes/guildMembers';
37
40
  export * from './classes/guildHealth';
38
41
  export * from './classes/guildInfluencerPanel';
package/dist/index.js CHANGED
@@ -30,6 +30,8 @@ __exportStar(require("./classes/publicDrops"), exports);
30
30
  __exportStar(require("./classes/polls"), exports);
31
31
  __exportStar(require("./classes/announcements"), exports);
32
32
  __exportStar(require("./classes/adminPolls"), exports);
33
+ __exportStar(require("./classes/feedback"), exports);
34
+ __exportStar(require("./classes/adminFeedback"), exports);
33
35
  __exportStar(require("./classes/adminAnnouncements"), exports);
34
36
  __exportStar(require("./classes/emotes"), exports);
35
37
  __exportStar(require("./classes/files"), exports);
@@ -50,6 +52,7 @@ __exportStar(require("./classes/guildBounties"), exports);
50
52
  __exportStar(require("./classes/guildAssistant"), exports);
51
53
  __exportStar(require("./classes/guildAutoRoles"), exports);
52
54
  __exportStar(require("./classes/guildBoosts"), exports);
55
+ __exportStar(require("./classes/guildEmojis"), exports);
53
56
  __exportStar(require("./classes/guildMembers"), exports);
54
57
  __exportStar(require("./classes/guildHealth"), exports);
55
58
  __exportStar(require("./classes/guildInfluencerPanel"), exports);
@@ -134,6 +134,7 @@ export declare const GuildFeatures: {
134
134
  BoostNotifications: bigint;
135
135
  BoostLogsAndStreaks: bigint;
136
136
  BoostBoard: bigint;
137
+ UnlimitedEmojiRepositions: bigint;
137
138
  };
138
139
  export declare const GuildFeaturesText: Record<keyof typeof GuildFeatures, string>;
139
140
  export declare const UserFeatures: {
@@ -256,8 +257,9 @@ export declare class GuildFeaturesManager extends BitFieldManager<typeof GuildFe
256
257
  BoostNotifications: bigint;
257
258
  BoostLogsAndStreaks: bigint;
258
259
  BoostBoard: bigint;
260
+ UnlimitedEmojiRepositions: bigint;
259
261
  };
260
- t: Record<"BaseSyncableRoles" | "FullSyncableRoles" | "LiveRole" | "StatCounters" | "VoteSkipping" | "KickAuditLogs" | "LeaderboardCommand" | "RefreshingLeaderboard" | "LeaderBoardSyncRoles" | "BetaAccess" | "PriorityNotifications" | "KickClips" | "KickNotifications" | "TwitchNotifications" | "ImportEmojis" | "ImportEmojisWithSub" | "CustomWebhooks" | "AnyMessageEditor" | "SyncSocialUsernames" | "AutoDeleteNotifications" | "TestNotificationCommand" | "CustomCooldowns" | "WelcomeAndLeaveNotifications" | "NotificationPingRoleId" | "SwitchStreamerAndGuildEmbeds" | "BirthdayNotifications" | "AllowNotSendingOfflineNotifications" | "AutoStatusLiveRoles" | "RumbleNotifications" | "AllowAutoPublishNotifications" | "NotificationOverrides" | "UseCustomButtons" | "AllowVodFeatures" | "TikTokNotifications" | "StatusRoles" | "ManageBranding" | "StickyMessages" | "Starboards" | "CustomStarboards" | "AutoThreadOnStarboard" | "StarboardRewardRole" | "Giveaways" | "GiveawayLogs" | "ModifyGiveawayWhileRunning" | "ScheduleGiveaways" | "GiveawayRequirements" | "GiveawayBonusEntries" | "GiveawayEntryLimit" | "DisableDoubleVoteEntry" | "YouTubeNotifications" | "LinkedRoles" | "RandomMessages" | "WeeklyBirthdayPanel" | "GameNotifications" | "GameCategoryRouting" | "GameAllTimeLowAlerts" | "GameChangelogs" | "GameRobloxTracking" | "FixUrlWebhook" | "FixUrlCustomRules" | "KickClipperSubscribe" | "WhatnotNotifications" | "ScheduledEventMessages" | "ScheduledMessageWebhooks" | "ReactionRoles" | "AdvancedRolePanels" | "KickClipForwarding" | "TwitchClipForwarding" | "ClubNotifications" | "RolePanelWebhooks" | "Fishing" | "FishingCustomization" | "FishingWebhooks" | "StreamRoles" | "RoleFilters" | "TwitterNotifications" | "TwitterLiveNotifications" | "BadgeAllGames" | "AutoRoles" | "AutoRoleTimers" | "AutoRoleInvites" | "StickyMessageRoleFilters" | "GiveawayClaims" | "GiveawayWinnerRole" | "InfluencerPanel" | "InfluencerPanelPremium" | "InfluencerPanelPlus" | "StatusRoleKeepOnOffline" | "YouTubeReplayChannel" | "LivePostUpdates" | "MultiDestination" | "InGameRewards" | "BoostNotifications" | "BoostLogsAndStreaks" | "BoostBoard", string>;
262
+ t: Record<"BaseSyncableRoles" | "FullSyncableRoles" | "LiveRole" | "StatCounters" | "VoteSkipping" | "KickAuditLogs" | "LeaderboardCommand" | "RefreshingLeaderboard" | "LeaderBoardSyncRoles" | "BetaAccess" | "PriorityNotifications" | "KickClips" | "KickNotifications" | "TwitchNotifications" | "ImportEmojis" | "ImportEmojisWithSub" | "CustomWebhooks" | "AnyMessageEditor" | "SyncSocialUsernames" | "AutoDeleteNotifications" | "TestNotificationCommand" | "CustomCooldowns" | "WelcomeAndLeaveNotifications" | "NotificationPingRoleId" | "SwitchStreamerAndGuildEmbeds" | "BirthdayNotifications" | "AllowNotSendingOfflineNotifications" | "AutoStatusLiveRoles" | "RumbleNotifications" | "AllowAutoPublishNotifications" | "NotificationOverrides" | "UseCustomButtons" | "AllowVodFeatures" | "TikTokNotifications" | "StatusRoles" | "ManageBranding" | "StickyMessages" | "Starboards" | "CustomStarboards" | "AutoThreadOnStarboard" | "StarboardRewardRole" | "Giveaways" | "GiveawayLogs" | "ModifyGiveawayWhileRunning" | "ScheduleGiveaways" | "GiveawayRequirements" | "GiveawayBonusEntries" | "GiveawayEntryLimit" | "DisableDoubleVoteEntry" | "YouTubeNotifications" | "LinkedRoles" | "RandomMessages" | "WeeklyBirthdayPanel" | "GameNotifications" | "GameCategoryRouting" | "GameAllTimeLowAlerts" | "GameChangelogs" | "GameRobloxTracking" | "FixUrlWebhook" | "FixUrlCustomRules" | "KickClipperSubscribe" | "WhatnotNotifications" | "ScheduledEventMessages" | "ScheduledMessageWebhooks" | "ReactionRoles" | "AdvancedRolePanels" | "KickClipForwarding" | "TwitchClipForwarding" | "ClubNotifications" | "RolePanelWebhooks" | "Fishing" | "FishingCustomization" | "FishingWebhooks" | "StreamRoles" | "RoleFilters" | "TwitterNotifications" | "TwitterLiveNotifications" | "BadgeAllGames" | "AutoRoles" | "AutoRoleTimers" | "AutoRoleInvites" | "StickyMessageRoleFilters" | "GiveawayClaims" | "GiveawayWinnerRole" | "InfluencerPanel" | "InfluencerPanelPremium" | "InfluencerPanelPlus" | "StatusRoleKeepOnOffline" | "YouTubeReplayChannel" | "LivePostUpdates" | "MultiDestination" | "InGameRewards" | "BoostNotifications" | "BoostLogsAndStreaks" | "BoostBoard" | "UnlimitedEmojiRepositions", string>;
261
263
  all: bigint;
262
264
  static b: {
263
265
  BaseSyncableRoles: bigint;
@@ -355,8 +357,9 @@ export declare class GuildFeaturesManager extends BitFieldManager<typeof GuildFe
355
357
  BoostNotifications: bigint;
356
358
  BoostLogsAndStreaks: bigint;
357
359
  BoostBoard: bigint;
360
+ UnlimitedEmojiRepositions: bigint;
358
361
  };
359
- static t: Record<"BaseSyncableRoles" | "FullSyncableRoles" | "LiveRole" | "StatCounters" | "VoteSkipping" | "KickAuditLogs" | "LeaderboardCommand" | "RefreshingLeaderboard" | "LeaderBoardSyncRoles" | "BetaAccess" | "PriorityNotifications" | "KickClips" | "KickNotifications" | "TwitchNotifications" | "ImportEmojis" | "ImportEmojisWithSub" | "CustomWebhooks" | "AnyMessageEditor" | "SyncSocialUsernames" | "AutoDeleteNotifications" | "TestNotificationCommand" | "CustomCooldowns" | "WelcomeAndLeaveNotifications" | "NotificationPingRoleId" | "SwitchStreamerAndGuildEmbeds" | "BirthdayNotifications" | "AllowNotSendingOfflineNotifications" | "AutoStatusLiveRoles" | "RumbleNotifications" | "AllowAutoPublishNotifications" | "NotificationOverrides" | "UseCustomButtons" | "AllowVodFeatures" | "TikTokNotifications" | "StatusRoles" | "ManageBranding" | "StickyMessages" | "Starboards" | "CustomStarboards" | "AutoThreadOnStarboard" | "StarboardRewardRole" | "Giveaways" | "GiveawayLogs" | "ModifyGiveawayWhileRunning" | "ScheduleGiveaways" | "GiveawayRequirements" | "GiveawayBonusEntries" | "GiveawayEntryLimit" | "DisableDoubleVoteEntry" | "YouTubeNotifications" | "LinkedRoles" | "RandomMessages" | "WeeklyBirthdayPanel" | "GameNotifications" | "GameCategoryRouting" | "GameAllTimeLowAlerts" | "GameChangelogs" | "GameRobloxTracking" | "FixUrlWebhook" | "FixUrlCustomRules" | "KickClipperSubscribe" | "WhatnotNotifications" | "ScheduledEventMessages" | "ScheduledMessageWebhooks" | "ReactionRoles" | "AdvancedRolePanels" | "KickClipForwarding" | "TwitchClipForwarding" | "ClubNotifications" | "RolePanelWebhooks" | "Fishing" | "FishingCustomization" | "FishingWebhooks" | "StreamRoles" | "RoleFilters" | "TwitterNotifications" | "TwitterLiveNotifications" | "BadgeAllGames" | "AutoRoles" | "AutoRoleTimers" | "AutoRoleInvites" | "StickyMessageRoleFilters" | "GiveawayClaims" | "GiveawayWinnerRole" | "InfluencerPanel" | "InfluencerPanelPremium" | "InfluencerPanelPlus" | "StatusRoleKeepOnOffline" | "YouTubeReplayChannel" | "LivePostUpdates" | "MultiDestination" | "InGameRewards" | "BoostNotifications" | "BoostLogsAndStreaks" | "BoostBoard", string>;
362
+ static t: Record<"BaseSyncableRoles" | "FullSyncableRoles" | "LiveRole" | "StatCounters" | "VoteSkipping" | "KickAuditLogs" | "LeaderboardCommand" | "RefreshingLeaderboard" | "LeaderBoardSyncRoles" | "BetaAccess" | "PriorityNotifications" | "KickClips" | "KickNotifications" | "TwitchNotifications" | "ImportEmojis" | "ImportEmojisWithSub" | "CustomWebhooks" | "AnyMessageEditor" | "SyncSocialUsernames" | "AutoDeleteNotifications" | "TestNotificationCommand" | "CustomCooldowns" | "WelcomeAndLeaveNotifications" | "NotificationPingRoleId" | "SwitchStreamerAndGuildEmbeds" | "BirthdayNotifications" | "AllowNotSendingOfflineNotifications" | "AutoStatusLiveRoles" | "RumbleNotifications" | "AllowAutoPublishNotifications" | "NotificationOverrides" | "UseCustomButtons" | "AllowVodFeatures" | "TikTokNotifications" | "StatusRoles" | "ManageBranding" | "StickyMessages" | "Starboards" | "CustomStarboards" | "AutoThreadOnStarboard" | "StarboardRewardRole" | "Giveaways" | "GiveawayLogs" | "ModifyGiveawayWhileRunning" | "ScheduleGiveaways" | "GiveawayRequirements" | "GiveawayBonusEntries" | "GiveawayEntryLimit" | "DisableDoubleVoteEntry" | "YouTubeNotifications" | "LinkedRoles" | "RandomMessages" | "WeeklyBirthdayPanel" | "GameNotifications" | "GameCategoryRouting" | "GameAllTimeLowAlerts" | "GameChangelogs" | "GameRobloxTracking" | "FixUrlWebhook" | "FixUrlCustomRules" | "KickClipperSubscribe" | "WhatnotNotifications" | "ScheduledEventMessages" | "ScheduledMessageWebhooks" | "ReactionRoles" | "AdvancedRolePanels" | "KickClipForwarding" | "TwitchClipForwarding" | "ClubNotifications" | "RolePanelWebhooks" | "Fishing" | "FishingCustomization" | "FishingWebhooks" | "StreamRoles" | "RoleFilters" | "TwitterNotifications" | "TwitterLiveNotifications" | "BadgeAllGames" | "AutoRoles" | "AutoRoleTimers" | "AutoRoleInvites" | "StickyMessageRoleFilters" | "GiveawayClaims" | "GiveawayWinnerRole" | "InfluencerPanel" | "InfluencerPanelPremium" | "InfluencerPanelPlus" | "StatusRoleKeepOnOffline" | "YouTubeReplayChannel" | "LivePostUpdates" | "MultiDestination" | "InGameRewards" | "BoostNotifications" | "BoostLogsAndStreaks" | "BoostBoard" | "UnlimitedEmojiRepositions", string>;
360
363
  static all: bigint;
361
364
  convertBitToField<T extends EnumValues<typeof GuildFeatures>>(bit: T): string | null;
362
365
  }
@@ -245,6 +245,8 @@ exports.GuildFeatures = {
245
245
  BoostLogsAndStreaks: 1n << 94n,
246
246
  // Boost notifications: the self-updating booster board. Premium Plus.
247
247
  BoostBoard: 1n << 95n,
248
+ // Reposition Emojis: lifts the free 1-per-7-days cap. Premium.
249
+ UnlimitedEmojiRepositions: 1n << 96n,
248
250
  };
249
251
  exports.GuildFeaturesText = {
250
252
  BaseSyncableRoles: 'Basic Syncable Roles',
@@ -344,6 +346,7 @@ exports.GuildFeaturesText = {
344
346
  BoostNotifications: 'Boost Notifications',
345
347
  BoostLogsAndStreaks: 'Boost Log & Boost Roles',
346
348
  BoostBoard: 'Booster Board',
349
+ UnlimitedEmojiRepositions: 'Unlimited Emoji Repositions',
347
350
  };
348
351
  exports.UserFeatures = {
349
352
  HasOneServerPremium: 1n << 0n,
@@ -1,4 +1,4 @@
1
- export declare const FEATURE_NAMES: readonly ["freeGames", "gameChangelogs", "robloxNotifications", "fixLinks", "clipperNotifications", "scheduledMessages", "linkedRoles", "reactionRoles", "clipForwarding", "club", "whatnot", "fishing", "giveaways", "starboards", "syncedRoles", "birthdays", "statusRoles", "autoStatusLiveRoles", "streamRoles", "badgeNotifications", "kickBounties", "autoRoles", "giveawayClaims", "influencerPanel", "publicGiveaways", "publicDrops", "sitePolls", "siteAnnouncements", "offlineGracePeriod", "vodNotifications", "youtubeReplays", "livePostUpdates", "multiDestination", "inGame", "boostNotifications", "twitter", "voteToTest", "voteToAddSocial", "aiAssistant", "voteToUseAssistant", "assistantShareChat", "latest", "latestYoutube", "emotes", "liveRoles", "stickyMessages", "welcomeLeave", "statCounters", "voteSkipping"];
1
+ export declare const FEATURE_NAMES: readonly ["freeGames", "gameChangelogs", "robloxNotifications", "fixLinks", "clipperNotifications", "scheduledMessages", "linkedRoles", "reactionRoles", "clipForwarding", "club", "whatnot", "fishing", "giveaways", "starboards", "syncedRoles", "birthdays", "statusRoles", "autoStatusLiveRoles", "streamRoles", "badgeNotifications", "kickBounties", "autoRoles", "giveawayClaims", "influencerPanel", "publicGiveaways", "publicDrops", "sitePolls", "siteAnnouncements", "feedback", "offlineGracePeriod", "vodNotifications", "youtubeReplays", "livePostUpdates", "multiDestination", "inGame", "boostNotifications", "twitter", "voteToTest", "voteToAddSocial", "aiAssistant", "voteToUseAssistant", "assistantShareChat", "latest", "latestYoutube", "repositionEmojis", "voteToRepositionEmojis", "emotes", "liveRoles", "stickyMessages", "welcomeLeave", "statCounters", "voteSkipping"];
2
2
  export type FeatureName = (typeof FEATURE_NAMES)[number];
3
3
  export type FeatureStatus = 'off' | 'beta' | 'public';
4
4
  export type ResolvedFeature = 'public' | 'beta' | 'hidden';