2024-07-23 00:02:39 +02:00
import { ContentFormatSchema } from "@/federation/schemas/content_format" ;
import { ExtensionPropertySchema } from "@/federation/schemas/extensions" ;
import { CustomEmojiExtensionSchema } from "@/federation/schemas/extensions/custom_emojis" ;
import { VanityExtensionSchema } from "@/federation/schemas/extensions/vanity" ;
import { extensionTypeRegex } from "@/federation/schemas/regex" ;
2024-05-14 09:00:05 +02:00
import { z } from "zod" ;
2024-05-14 21:08:46 +02:00
const EntitySchema = z . object ( {
2024-05-14 09:00:05 +02:00
id : z.string ( ) . uuid ( ) ,
created_at : z.string ( ) ,
uri : z.string ( ) . url ( ) ,
type : z . string ( ) ,
2024-07-16 20:01:07 +02:00
extensions : ExtensionPropertySchema.optional ( ) . nullable ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
} ) ;
2024-05-14 21:08:46 +02:00
const VisibilitySchema = z . enum ( [ "public" , "unlisted" , "private" , "direct" ] ) ;
2024-05-14 09:00:05 +02:00
2024-05-14 21:08:46 +02:00
const PublicationSchema = EntitySchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . enum ( [ "Note" , "Patch" ] ) ,
author : z.string ( ) . url ( ) ,
2024-07-16 20:01:07 +02:00
content : ContentFormatSchema.optional ( ) . nullable ( ) ,
attachments : z.array ( ContentFormatSchema ) . optional ( ) . nullable ( ) ,
replies_to : z.string ( ) . url ( ) . optional ( ) . nullable ( ) ,
quotes : z.string ( ) . url ( ) . optional ( ) . nullable ( ) ,
mentions : z.array ( z . string ( ) . url ( ) ) . optional ( ) . nullable ( ) ,
subject : z.string ( ) . optional ( ) . nullable ( ) ,
is_sensitive : z.boolean ( ) . optional ( ) . nullable ( ) ,
2024-05-14 21:08:46 +02:00
visibility : VisibilitySchema ,
2024-05-15 02:12:26 +02:00
extensions : ExtensionPropertySchema.extend ( {
2024-05-14 09:00:05 +02:00
"org.lysand:reactions" : z
. object ( {
reactions : z.string ( ) ,
} )
2024-07-16 20:01:07 +02:00
. optional ( )
. nullable ( ) ,
2024-05-14 09:00:05 +02:00
"org.lysand:polls" : z
. object ( {
poll : z.object ( {
2024-05-14 21:08:46 +02:00
options : z.array ( ContentFormatSchema ) ,
2024-05-14 09:00:05 +02:00
votes : z.array ( z . number ( ) . int ( ) . nonnegative ( ) ) ,
2024-07-16 20:01:07 +02:00
multiple_choice : z.boolean ( ) . optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
expires_at : z.string ( ) ,
} ) ,
} )
2024-07-16 20:01:07 +02:00
. optional ( )
. nullable ( ) ,
} )
. optional ( )
. nullable ( ) ,
2024-05-14 09:00:05 +02:00
} ) ;
2024-05-14 21:08:46 +02:00
const NoteSchema = PublicationSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Note" ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const PatchSchema = PublicationSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Patch" ) ,
patched_id : z.string ( ) . uuid ( ) ,
patched_at : z.string ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const ActorPublicKeyDataSchema = z . object ( {
2024-05-14 09:00:05 +02:00
public_key : z.string ( ) ,
actor : z.string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const UserSchema = EntitySchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "User" ) ,
2024-07-16 20:01:07 +02:00
display_name : z.string ( ) . optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
username : z.string ( ) ,
2024-07-16 20:01:07 +02:00
avatar : ContentFormatSchema.optional ( ) . nullable ( ) ,
header : ContentFormatSchema.optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
indexable : z.boolean ( ) ,
2024-05-14 21:08:46 +02:00
public_key : ActorPublicKeyDataSchema ,
2024-07-16 20:01:07 +02:00
bio : ContentFormatSchema.optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
fields : z
. array (
z . object ( {
2024-05-17 19:30:10 +02:00
key : ContentFormatSchema ,
2024-05-14 21:08:46 +02:00
value : ContentFormatSchema ,
2024-05-14 09:00:05 +02:00
} ) ,
)
2024-07-16 20:01:07 +02:00
. optional ( )
. nullable ( ) ,
2024-05-14 09:00:05 +02:00
featured : z.string ( ) . url ( ) ,
followers : z.string ( ) . url ( ) ,
following : z.string ( ) . url ( ) ,
likes : z.string ( ) . url ( ) ,
dislikes : z.string ( ) . url ( ) ,
inbox : z.string ( ) . url ( ) ,
outbox : z.string ( ) . url ( ) ,
2024-05-15 02:12:26 +02:00
extensions : ExtensionPropertySchema.extend ( {
2024-07-16 20:01:07 +02:00
"org.lysand:vanity" : VanityExtensionSchema . optional ( ) . nullable ( ) ,
} )
. optional ( )
. nullable ( ) ,
2024-05-14 09:00:05 +02:00
} ) ;
2024-05-14 21:08:46 +02:00
const ActionSchema = EntitySchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . union ( [
z . literal ( "Like" ) ,
z . literal ( "Dislike" ) ,
z . literal ( "Follow" ) ,
z . literal ( "FollowAccept" ) ,
z . literal ( "FollowReject" ) ,
z . literal ( "Announce" ) ,
z . literal ( "Undo" ) ,
] ) ,
author : z.string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const LikeSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Like" ) ,
object : z . string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const UndoSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Undo" ) ,
object : z . string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const DislikeSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Dislike" ) ,
object : z . string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const FollowSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Follow" ) ,
followee : z.string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const FollowAcceptSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "FollowAccept" ) ,
follower : z.string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const FollowRejectSchema = ActionSchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "FollowReject" ) ,
follower : z.string ( ) . url ( ) ,
} ) ;
2024-05-14 21:08:46 +02:00
const ExtensionSchema = EntitySchema . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "Extension" ) ,
extension_type : z
. string ( )
. regex (
extensionTypeRegex ,
"extension_type must be in the format 'namespaced_url:extension_name/ExtensionType', e.g. 'org.lysand:reactions/Reaction'. Notably, only the type can have uppercase letters." ,
) ,
} ) ;
2024-05-14 21:08:46 +02:00
const ReportSchema = ExtensionSchema . extend ( {
2024-05-14 09:00:05 +02:00
extension_type : z.literal ( "org.lysand:reports/Report" ) ,
objects : z.array ( z . string ( ) . url ( ) ) ,
reason : z.string ( ) ,
2024-07-16 20:01:07 +02:00
comment : z.string ( ) . optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
} ) ;
2024-05-15 02:28:27 +02:00
const ServerMetadataSchema = EntitySchema . omit ( {
created_at : true ,
id : true ,
uri : true ,
} ) . extend ( {
2024-05-14 09:00:05 +02:00
type : z . literal ( "ServerMetadata" ) ,
name : z.string ( ) ,
version : z.string ( ) ,
2024-07-16 20:01:07 +02:00
description : z.string ( ) . optional ( ) . nullable ( ) ,
website : z.string ( ) . optional ( ) . nullable ( ) ,
moderators : z.array ( z . string ( ) ) . optional ( ) . nullable ( ) ,
admins : z.array ( z . string ( ) ) . optional ( ) . nullable ( ) ,
logo : ContentFormatSchema.optional ( ) . nullable ( ) ,
banner : ContentFormatSchema.optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
supported_extensions : z.array ( z . string ( ) ) ,
2024-07-16 20:01:07 +02:00
extensions : z.record ( z . string ( ) , z . any ( ) ) . optional ( ) . nullable ( ) ,
2024-05-14 09:00:05 +02:00
} ) ;
export {
2024-05-14 21:08:46 +02:00
EntitySchema ,
VisibilitySchema ,
PublicationSchema ,
NoteSchema ,
PatchSchema ,
ActorPublicKeyDataSchema ,
VanityExtensionSchema ,
UserSchema ,
ActionSchema ,
LikeSchema ,
UndoSchema ,
DislikeSchema ,
FollowSchema ,
FollowAcceptSchema ,
FollowRejectSchema ,
ExtensionSchema ,
ReportSchema ,
ServerMetadataSchema ,
ContentFormatSchema ,
2024-06-20 00:21:34 +02:00
CustomEmojiExtensionSchema ,
2024-05-15 02:12:26 +02:00
ExtensionPropertySchema ,
2024-05-14 09:00:05 +02:00
} ;