Skip to content

Commit

Permalink
feat: Support Mastodon 4.3.0
Browse files Browse the repository at this point in the history
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
  • Loading branch information
neet committed Oct 14, 2024
1 parent 884b83d commit 103a130
Show file tree
Hide file tree
Showing 30 changed files with 939 additions and 57 deletions.
7 changes: 6 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"version": "0.2",
"language": "en,en-GB",
"ignorePaths": ["**/node_modules/**", "**/dist/**"],
"ignorePaths": [
"**/node_modules/**",
"**/dist/**"
],
"words": [
"AGPL",
"asynckit",
Expand Down Expand Up @@ -32,10 +35,12 @@
"reblog",
"reblogged",
"reblogs",
"sadams",
"serializers",
"shortcode",
"subprotocol",
"subresource",
"timeframe",
"tootctl",
"trendable",
"typedoc",
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:

mastodon:
restart: always
image: neetshin/mastodon-dev:4.2.13
image: neetshin/mastodon-dev:4.3.0
ports:
- "3000:3000"
- "4000:4000"
Expand Down
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-typescript": "^11.1.6",
"@sadams/wait-for-expect": "^1.1.0",
"@size-limit/preset-small-lib": "^11.1.2",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.8",
Expand Down
31 changes: 31 additions & 0 deletions src/mastodon/entities/v1/account-warning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { type Account } from "./account";
import { type Appeal } from "./appeal";

/**
* Moderation warning against a particular account.
*/
export interface AccountWarning {
/** The ID of the account warning in the database. */
id: string;
/** Action taken against the account. */
action: AccountWarningAction;
/** Message from the moderator to the target account. */
text: string;
/** 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. */
statusIds: string[];
/** Account against which a moderation decision has been taken. */
targetAccount: Account;
/** Appeal submitted by the target account, if any. */
appeal?: Appeal | null;
/** When the event took place. */
createdAt: string;
}

export type AccountWarningAction =
| "none"
| "disable"
| "mark_statuses_as_sensitive"
| "delete_statuses"
| "sensitive"
| "silence"
| "suspend";
11 changes: 11 additions & 0 deletions src/mastodon/entities/v1/appeal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Appeal against a moderation action.
*/
export interface Appeal {
/** Text of the appeal from the moderated account to the moderators. */
text: string;
/** State of the appeal. */
state: AppealState;
}

export type AppealState = "approved" | "rejected" | "pending";
130 changes: 130 additions & 0 deletions src/mastodon/entities/v1/grouped-notifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { type Account } from "./account";
import { type AccountWarning } from "./account-warning";
import { type RelationshipSeveranceEvent } from "./relationship-severance-event";
import { type Report } from "./report";
import { type Status } from "./status";

export interface GroupedNotificationsResults {
/** Accounts referenced by grouped notifications. */
accounts: Account[];
/** Partial accounts referenced by grouped notifications. Those are only returned when requesting grouped notifications with `expand_accounts=partial_avatars`. */
partialAccounts?: PartialAccountWithAvatar[];
/** Statuses referenced by grouped notifications. */
statuses: Status[];
/** The grouped notifications themselves. */
notificationGroups: NotificationGroup[];
}

/** 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. */
export type PartialAccountWithAvatar = Pick<
Account,
"id" | "acct" | "url" | "avatar" | "avatarStatic" | "locked" | "bot"
>;

interface BaseNotificationGroup<T> {
/** Group key identifying the grouped notifications. Should be treated as an opaque value. */
groupKey: string;
/** Total number of individual notifications that are part of this notification group. */
notificationsCount: number;
/** The type of event that resulted in the notifications in this group. */
type: T;
/** ID of the most recent notification in the group. */
mostRecentNotificationId: string;
/** 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. */
pageMinId?: string;
/** 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. */
pageMaxId?: string;
/** 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. */
latestPageNotificationAt?: string;
/** IDs of some of the accounts who most recently triggered notifications in this group. */
sampleAccountIds: string;
/** 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. */
statusId?: undefined | null;
/** Report that was the object of the notification. Attached when type of the notification is admin.report. */
report?: undefined | null;
/** Summary of the event that caused follow relationships to be severed. Attached when type of the notification is severed_relationships. */
event?: undefined | null;
/** Moderation warning that caused the notification. Attached when type of the notification is moderation_warning. */
moderationWarning?: undefined | null;
}

type NotificationGroupPlain<T> = BaseNotificationGroup<T>;

type NotificationGroupWithStatusId<T> = BaseNotificationGroup<T> & {
/** 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. */
statusId: string;
};

type NotificationGroupWithReport<T> = BaseNotificationGroup<T> & {
/** Report that was the object of the notification. Attached when type of the notification is admin.report. */
report: Report;
};

type NotificationGroupWithEvent<T> = BaseNotificationGroup<T> & {
/** Summary of the event that caused follow relationships to be severed. Attached when type of the notification is severed_relationships. */
event: RelationshipSeveranceEvent;
};

type NotificationGroupWithModerationWarning<T> = BaseNotificationGroup<T> & {
/** Moderation warning that caused the notification. Attached when type of the notification is moderation_warning. */
moderationWarning: AccountWarning;
};

/** Someone mentioned you in their status */
export type MentionNotificationGroup = NotificationGroupWithStatusId<"mention">;

/** Someone you enabled notifications for has posted a status */
export type StatusNotificationGroup = NotificationGroupWithStatusId<"status">;

/** Someone boosted one of your statuses */
export type ReblogNotificationGroup = NotificationGroupWithStatusId<"reblog">;

/** Someone followed you */
export type FollowNotificationGroup = NotificationGroupPlain<"follow">;

/** Someone requested to follow you */
export type FollowRequestNotificationGroup =
NotificationGroupPlain<"follow_request">;

/** Someone favourited one of your statuses */
export type FavouriteNotificationGroup =
NotificationGroupWithStatusId<"favourite">;

/** A poll you have voted in or created has ended */
export type PollNotificationGroup = NotificationGroupWithStatusId<"poll">;

/** A status you interacted with has been edited */
export type UpdateNotificationGroup = NotificationGroupWithStatusId<"update">;

/** Someone signed up (optionally sent to admins) */
export type AdminSignUpNotificationGroup =
NotificationGroupPlain<"admin.sign_up">;

/** A new report has been filed */
export type AdminReportNotificationGroup =
NotificationGroupWithReport<"admin.report">;

/** Some of your follow relationships have been severed as a result of a moderation or block event */
export type SeveredRelationshipsNotificationGroup =
NotificationGroupWithEvent<"severed_relationships">;

/** A moderator has taken action against your account or has sent you a warning */
export type ModerationWarningNotificationGroup =
NotificationGroupWithModerationWarning<"moderation_warning">;

/** Group key identifying the grouped notifications. Should be treated as an opaque value. */
export type NotificationGroup =
| MentionNotificationGroup
| StatusNotificationGroup
| ReblogNotificationGroup
| FollowNotificationGroup
| FollowRequestNotificationGroup
| FavouriteNotificationGroup
| PollNotificationGroup
| UpdateNotificationGroup
| AdminSignUpNotificationGroup
| AdminReportNotificationGroup
| SeveredRelationshipsNotificationGroup
| ModerationWarningNotificationGroup;

export type NotificationGroupType = NotificationGroup["type"];
3 changes: 3 additions & 0 deletions src/mastodon/entities/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@ export * from "./filter";
export * from "./filter-keyword";
export * from "./filter-result";
export * from "./filter-status";
export * from "./grouped-notifications";
export * from "./identity-proof";
export * from "./instance";
export * from "./list";
export * from "./marker";
export * from "./media-attachment";
export * from "./notification";
export * from "./notification-request";
export * from "./poll";
export * from "./preference";
export * from "./preview-card";
export * from "./reaction";
export * from "./relationship";
export * from "./relationship-severance-event";
export * from "./report";
export * from "./role";
export * from "./rule";
Expand Down
17 changes: 17 additions & 0 deletions src/mastodon/entities/v1/notification-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type Account } from "./account";
import { type Status } from "./status";

export interface NotificationRequest {
/** The id of the notification request in the database. */
id: string;
/** The timestamp of the notification request, i.e. when the first filtered notification from that user was created. */
createdAt: string;
/** The timestamp of when the notification request was last updated. */
updatedAt: string;
/** The account that performed the action that generated the filtered notifications. */
account: Account;
/** How many of this account’s notifications were filtered. */
notificationsCount: number;
/** Most recent status associated with a filtered notification from that account. */
lastStatus?: Status | null;
}
24 changes: 23 additions & 1 deletion src/mastodon/entities/v1/notification.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { type Account } from "./account";
import { type AccountWarning } from "./account-warning";
import { type RelationshipSeveranceEvent } from "./relationship-severance-event";
import { type Report } from "./report";
import { type Status } from "./status";

Expand All @@ -11,6 +13,8 @@ interface BaseNotification<T> {
createdAt: string;
/** The account that performed the action that generated the notification. */
account: Account;
/** 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} */
groupKey: string;
}

type BaseNotificationPlain<T> = BaseNotification<T> & {
Expand Down Expand Up @@ -82,6 +86,22 @@ export type AdminSignUpNotification = BaseNotificationPlain<"admin.sign_up">;
export type AdminReportNotification =
BaseNotificationWithReport<"admin.report">;

/**
* Some of your follow relationships have been severed as a result of a moderation or block event
*/
export type SeveredRelationshipsNotification =
BaseNotificationPlain<"severed_relationships"> & {
relationshipSeveranceEvent: RelationshipSeveranceEvent;
};

/**
* A moderator has taken action against your account or has sent you a warning
*/
export type ModerationWarningNotification =
BaseNotificationPlain<"moderation_warning"> & {
moderationWarning: AccountWarning;
};

/**
* Represents a notification of an event relevant to the user.
* @see https://docs.joinmastodon.org/entities/notification
Expand All @@ -96,6 +116,8 @@ export type Notification =
| PollNotification
| UpdateNotification
| AdminSignUpNotification
| AdminReportNotification;
| AdminReportNotification
| SeveredRelationshipsNotification
| ModerationWarningNotification;

export type NotificationType = Notification["type"];
22 changes: 22 additions & 0 deletions src/mastodon/entities/v1/relationship-severance-event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Summary of a moderation or block event that caused follow relationships to be severed.
*/
export interface RelationshipSeveranceEvent {
/** The ID of the relationship severance event in the database. */
id: string;
/** Type of event. */
type: RelationshipSeveranceEventType;
/** Whether the list of severed relationships is unavailable because the underlying issue has been purged. */
purged: boolean;
/** Name of the target of the moderation/block event. This is either a domain name or a user handle, depending on the event type. */
targetName: string;
/** Number of follow relationships (in either direction) that were severed. */
relationshipsCount?: number | null;
/** When the event took place. */
createdAt: string;
}

export type RelationshipSeveranceEventType =
| "domain_block"
| "user_domain_block"
| "account_suspension";
4 changes: 4 additions & 0 deletions src/mastodon/entities/v1/rule.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export interface Rule {
/** An identifier for the rule. */
id: string;
/** The rule to be followed. */
text: string;
/** Longer-form description of the rule. */
hint: string;
}
Loading

0 comments on commit 103a130

Please sign in to comment.