Skip to content

Commit 103a130

Browse files
committed
feat: Support Mastodon 4.3.0
wip Bump docker image for testing Add support notification group Move NotificationPolicy to v2 Add NotificationsMerged event Add link timeline Add test todo Fix tests fix settings
1 parent 884b83d commit 103a130

30 files changed

+939
-57
lines changed

cspell.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{
22
"version": "0.2",
33
"language": "en,en-GB",
4-
"ignorePaths": ["**/node_modules/**", "**/dist/**"],
4+
"ignorePaths": [
5+
"**/node_modules/**",
6+
"**/dist/**"
7+
],
58
"words": [
69
"AGPL",
710
"asynckit",
@@ -32,10 +35,12 @@
3235
"reblog",
3336
"reblogged",
3437
"reblogs",
38+
"sadams",
3539
"serializers",
3640
"shortcode",
3741
"subprotocol",
3842
"subresource",
43+
"timeframe",
3944
"tootctl",
4045
"trendable",
4146
"typedoc",

docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ services:
2323

2424
mastodon:
2525
restart: always
26-
image: neetshin/mastodon-dev:4.2.13
26+
image: neetshin/mastodon-dev:4.3.0
2727
ports:
2828
- "3000:3000"
2929
- "4000:4000"

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@rollup/plugin-commonjs": "^26.0.1",
4444
"@rollup/plugin-json": "^6.1.0",
4545
"@rollup/plugin-typescript": "^11.1.6",
46+
"@sadams/wait-for-expect": "^1.1.0",
4647
"@size-limit/preset-small-lib": "^11.1.2",
4748
"@types/jest": "^29.5.12",
4849
"@types/node": "^20.12.8",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { type Account } from "./account";
2+
import { type Appeal } from "./appeal";
3+
4+
/**
5+
* Moderation warning against a particular account.
6+
*/
7+
export interface AccountWarning {
8+
/** The ID of the account warning in the database. */
9+
id: string;
10+
/** Action taken against the account. */
11+
action: AccountWarningAction;
12+
/** Message from the moderator to the target account. */
13+
text: string;
14+
/** List of status IDs that are relevant to the warning. When action is mark_statuses_as_sensitive or delete_statuses, those are the affected statuses. */
15+
statusIds: string[];
16+
/** Account against which a moderation decision has been taken. */
17+
targetAccount: Account;
18+
/** Appeal submitted by the target account, if any. */
19+
appeal?: Appeal | null;
20+
/** When the event took place. */
21+
createdAt: string;
22+
}
23+
24+
export type AccountWarningAction =
25+
| "none"
26+
| "disable"
27+
| "mark_statuses_as_sensitive"
28+
| "delete_statuses"
29+
| "sensitive"
30+
| "silence"
31+
| "suspend";

src/mastodon/entities/v1/appeal.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Appeal against a moderation action.
3+
*/
4+
export interface Appeal {
5+
/** Text of the appeal from the moderated account to the moderators. */
6+
text: string;
7+
/** State of the appeal. */
8+
state: AppealState;
9+
}
10+
11+
export type AppealState = "approved" | "rejected" | "pending";
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { type Account } from "./account";
2+
import { type AccountWarning } from "./account-warning";
3+
import { type RelationshipSeveranceEvent } from "./relationship-severance-event";
4+
import { type Report } from "./report";
5+
import { type Status } from "./status";
6+
7+
export interface GroupedNotificationsResults {
8+
/** Accounts referenced by grouped notifications. */
9+
accounts: Account[];
10+
/** Partial accounts referenced by grouped notifications. Those are only returned when requesting grouped notifications with `expand_accounts=partial_avatars`. */
11+
partialAccounts?: PartialAccountWithAvatar[];
12+
/** Statuses referenced by grouped notifications. */
13+
statuses: Status[];
14+
/** The grouped notifications themselves. */
15+
notificationGroups: NotificationGroup[];
16+
}
17+
18+
/** These are stripped-down versions of {@link Account} that only contain what is necessary to display a list of avatars, as well as a few other useful properties. The aim is to cut back on expensive server-side serialization and reduce the network payload size of notification groups. */
19+
export type PartialAccountWithAvatar = Pick<
20+
Account,
21+
"id" | "acct" | "url" | "avatar" | "avatarStatic" | "locked" | "bot"
22+
>;
23+
24+
interface BaseNotificationGroup<T> {
25+
/** Group key identifying the grouped notifications. Should be treated as an opaque value. */
26+
groupKey: string;
27+
/** Total number of individual notifications that are part of this notification group. */
28+
notificationsCount: number;
29+
/** The type of event that resulted in the notifications in this group. */
30+
type: T;
31+
/** ID of the most recent notification in the group. */
32+
mostRecentNotificationId: string;
33+
/** ID of the oldest notification from this group represented within the current page. This is only returned when paginating through notification groups. Useful when polling new notifications. */
34+
pageMinId?: string;
35+
/** ID of the newest notification from this group represented within the current page. This is only returned when paginating through notification groups. Useful when polling new notifications. */
36+
pageMaxId?: string;
37+
/** Date at which the most recent notification from this group within the current page has been created. This is only returned when paginating through notification groups. */
38+
latestPageNotificationAt?: string;
39+
/** IDs of some of the accounts who most recently triggered notifications in this group. */
40+
sampleAccountIds: string;
41+
/** ID of the Status that was the object of the notification. Attached when type of the notification is favourite, reblog, status, mention, poll, or update. */
42+
statusId?: undefined | null;
43+
/** Report that was the object of the notification. Attached when type of the notification is admin.report. */
44+
report?: undefined | null;
45+
/** Summary of the event that caused follow relationships to be severed. Attached when type of the notification is severed_relationships. */
46+
event?: undefined | null;
47+
/** Moderation warning that caused the notification. Attached when type of the notification is moderation_warning. */
48+
moderationWarning?: undefined | null;
49+
}
50+
51+
type NotificationGroupPlain<T> = BaseNotificationGroup<T>;
52+
53+
type NotificationGroupWithStatusId<T> = BaseNotificationGroup<T> & {
54+
/** ID of the Status that was the object of the notification. Attached when type of the notification is favourite, reblog, status, mention, poll, or update. */
55+
statusId: string;
56+
};
57+
58+
type NotificationGroupWithReport<T> = BaseNotificationGroup<T> & {
59+
/** Report that was the object of the notification. Attached when type of the notification is admin.report. */
60+
report: Report;
61+
};
62+
63+
type NotificationGroupWithEvent<T> = BaseNotificationGroup<T> & {
64+
/** Summary of the event that caused follow relationships to be severed. Attached when type of the notification is severed_relationships. */
65+
event: RelationshipSeveranceEvent;
66+
};
67+
68+
type NotificationGroupWithModerationWarning<T> = BaseNotificationGroup<T> & {
69+
/** Moderation warning that caused the notification. Attached when type of the notification is moderation_warning. */
70+
moderationWarning: AccountWarning;
71+
};
72+
73+
/** Someone mentioned you in their status */
74+
export type MentionNotificationGroup = NotificationGroupWithStatusId<"mention">;
75+
76+
/** Someone you enabled notifications for has posted a status */
77+
export type StatusNotificationGroup = NotificationGroupWithStatusId<"status">;
78+
79+
/** Someone boosted one of your statuses */
80+
export type ReblogNotificationGroup = NotificationGroupWithStatusId<"reblog">;
81+
82+
/** Someone followed you */
83+
export type FollowNotificationGroup = NotificationGroupPlain<"follow">;
84+
85+
/** Someone requested to follow you */
86+
export type FollowRequestNotificationGroup =
87+
NotificationGroupPlain<"follow_request">;
88+
89+
/** Someone favourited one of your statuses */
90+
export type FavouriteNotificationGroup =
91+
NotificationGroupWithStatusId<"favourite">;
92+
93+
/** A poll you have voted in or created has ended */
94+
export type PollNotificationGroup = NotificationGroupWithStatusId<"poll">;
95+
96+
/** A status you interacted with has been edited */
97+
export type UpdateNotificationGroup = NotificationGroupWithStatusId<"update">;
98+
99+
/** Someone signed up (optionally sent to admins) */
100+
export type AdminSignUpNotificationGroup =
101+
NotificationGroupPlain<"admin.sign_up">;
102+
103+
/** A new report has been filed */
104+
export type AdminReportNotificationGroup =
105+
NotificationGroupWithReport<"admin.report">;
106+
107+
/** Some of your follow relationships have been severed as a result of a moderation or block event */
108+
export type SeveredRelationshipsNotificationGroup =
109+
NotificationGroupWithEvent<"severed_relationships">;
110+
111+
/** A moderator has taken action against your account or has sent you a warning */
112+
export type ModerationWarningNotificationGroup =
113+
NotificationGroupWithModerationWarning<"moderation_warning">;
114+
115+
/** Group key identifying the grouped notifications. Should be treated as an opaque value. */
116+
export type NotificationGroup =
117+
| MentionNotificationGroup
118+
| StatusNotificationGroup
119+
| ReblogNotificationGroup
120+
| FollowNotificationGroup
121+
| FollowRequestNotificationGroup
122+
| FavouriteNotificationGroup
123+
| PollNotificationGroup
124+
| UpdateNotificationGroup
125+
| AdminSignUpNotificationGroup
126+
| AdminReportNotificationGroup
127+
| SeveredRelationshipsNotificationGroup
128+
| ModerationWarningNotificationGroup;
129+
130+
export type NotificationGroupType = NotificationGroup["type"];

src/mastodon/entities/v1/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ export * from "./filter";
1414
export * from "./filter-keyword";
1515
export * from "./filter-result";
1616
export * from "./filter-status";
17+
export * from "./grouped-notifications";
1718
export * from "./identity-proof";
1819
export * from "./instance";
1920
export * from "./list";
2021
export * from "./marker";
2122
export * from "./media-attachment";
2223
export * from "./notification";
24+
export * from "./notification-request";
2325
export * from "./poll";
2426
export * from "./preference";
2527
export * from "./preview-card";
2628
export * from "./reaction";
2729
export * from "./relationship";
30+
export * from "./relationship-severance-event";
2831
export * from "./report";
2932
export * from "./role";
3033
export * from "./rule";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { type Account } from "./account";
2+
import { type Status } from "./status";
3+
4+
export interface NotificationRequest {
5+
/** The id of the notification request in the database. */
6+
id: string;
7+
/** The timestamp of the notification request, i.e. when the first filtered notification from that user was created. */
8+
createdAt: string;
9+
/** The timestamp of when the notification request was last updated. */
10+
updatedAt: string;
11+
/** The account that performed the action that generated the filtered notifications. */
12+
account: Account;
13+
/** How many of this account’s notifications were filtered. */
14+
notificationsCount: number;
15+
/** Most recent status associated with a filtered notification from that account. */
16+
lastStatus?: Status | null;
17+
}

src/mastodon/entities/v1/notification.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { type Account } from "./account";
2+
import { type AccountWarning } from "./account-warning";
3+
import { type RelationshipSeveranceEvent } from "./relationship-severance-event";
24
import { type Report } from "./report";
35
import { type Status } from "./status";
46

@@ -11,6 +13,8 @@ interface BaseNotification<T> {
1113
createdAt: string;
1214
/** The account that performed the action that generated the notification. */
1315
account: Account;
16+
/** Group key shared by similar notifications, to be used in the grouped notifications feature. Should be considered opaque, but ungrouped notifications can be assumed to have a group_key of the form ungrouped-{notification_id} */
17+
groupKey: string;
1418
}
1519

1620
type BaseNotificationPlain<T> = BaseNotification<T> & {
@@ -82,6 +86,22 @@ export type AdminSignUpNotification = BaseNotificationPlain<"admin.sign_up">;
8286
export type AdminReportNotification =
8387
BaseNotificationWithReport<"admin.report">;
8488

89+
/**
90+
* Some of your follow relationships have been severed as a result of a moderation or block event
91+
*/
92+
export type SeveredRelationshipsNotification =
93+
BaseNotificationPlain<"severed_relationships"> & {
94+
relationshipSeveranceEvent: RelationshipSeveranceEvent;
95+
};
96+
97+
/**
98+
* A moderator has taken action against your account or has sent you a warning
99+
*/
100+
export type ModerationWarningNotification =
101+
BaseNotificationPlain<"moderation_warning"> & {
102+
moderationWarning: AccountWarning;
103+
};
104+
85105
/**
86106
* Represents a notification of an event relevant to the user.
87107
* @see https://docs.joinmastodon.org/entities/notification
@@ -96,6 +116,8 @@ export type Notification =
96116
| PollNotification
97117
| UpdateNotification
98118
| AdminSignUpNotification
99-
| AdminReportNotification;
119+
| AdminReportNotification
120+
| SeveredRelationshipsNotification
121+
| ModerationWarningNotification;
100122

101123
export type NotificationType = Notification["type"];

0 commit comments

Comments
 (0)