import pick from 'lodash.pick'; import { z } from 'zod'; import { accountSchema } from './account'; import { accountWarningSchema } from './account-warning'; import { chatMessageSchema } from './chat-message'; import { relationshipSeveranceEventSchema } from './relationship-severance-event'; import { reportSchema } from './report'; import { statusSchema } from './status'; import { dateSchema } from './utils'; const baseNotificationSchema = z.object({ account: accountSchema, created_at: dateSchema, id: z.string(), type: z.string(), is_muted: z.boolean().optional().catch(undefined), is_seen: z.boolean().optional().catch(undefined), }); const accountNotificationSchema = baseNotificationSchema.extend({ type: z.enum(['follow', 'follow_request', 'admin.sign_up', 'bite']), }); const statusNotificationSchema = baseNotificationSchema.extend({ type: z.enum(['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'event_reminder']), status: statusSchema, }); const reportNotificationSchema = baseNotificationSchema.extend({ type: z.literal('admin.report'), report: reportSchema, }); const severedRelationshipNotificationSchema = baseNotificationSchema.extend({ type: z.literal('severed_relationships'), relationship_severance_event: relationshipSeveranceEventSchema, }); const moderationWarningNotificationSchema = baseNotificationSchema.extend({ type: z.literal('moderation_warning'), moderation_warning: accountWarningSchema, }); const moveNotificationSchema = baseNotificationSchema.extend({ type: z.literal('move'), target: accountSchema, }); const emojiReactionNotificationSchema = baseNotificationSchema.extend({ type: z.literal('emoji_reaction'), emoji: z.string(), emoji_url: z.string().nullable().catch(null), status: statusSchema, }); const chatMentionNotificationSchema = baseNotificationSchema.extend({ type: z.literal('chat_mention'), chat_message: chatMessageSchema, }); const eventParticipationRequestNotificationSchema = baseNotificationSchema.extend({ type: z.enum(['participation_accepted', 'participation_request']), status: statusSchema, participation_message: z.string().nullable().catch(null), }); /** @see {@link https://docs.joinmastodon.org/entities/Notification/} */ const notificationSchema: z.ZodType = z.preprocess((notification: any) => ({ ...pick(notification.pleroma || {}, ['is_muted', 'is_seen']), ...notification, type: notification.type === 'pleroma:report' ? 'admin.report' : notification.type?.replace(/^pleroma:/, ''), }), z.discriminatedUnion('type', [ accountNotificationSchema, statusNotificationSchema, reportNotificationSchema, severedRelationshipNotificationSchema, moderationWarningNotificationSchema, moveNotificationSchema, emojiReactionNotificationSchema, chatMentionNotificationSchema, eventParticipationRequestNotificationSchema, ])) as any; type Notification = z.infer< | typeof accountNotificationSchema | typeof statusNotificationSchema | typeof reportNotificationSchema | typeof severedRelationshipNotificationSchema | typeof moderationWarningNotificationSchema | typeof moveNotificationSchema | typeof emojiReactionNotificationSchema | typeof chatMentionNotificationSchema | typeof eventParticipationRequestNotificationSchema >; export { notificationSchema, type Notification };