2024-05-14 09:00:05 +02:00
import { z } from "zod" ;
2024-05-14 21:08:46 +02:00
import { ContentFormatSchema } from "./content_format" ;
2024-05-15 02:12:26 +02:00
import { ExtensionPropertySchema } from "./extensions" ;
2024-05-14 09:00:05 +02:00
import { CustomEmojiExtension } from "./extensions/custom_emojis" ;
2024-05-14 21:08:46 +02:00
import { VanityExtensionSchema } from "./extensions/vanity" ;
2024-05-14 09:00:05 +02:00
import { extensionTypeRegex } from "./regex" ;
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-05-15 02:12:26 +02:00
extensions : ExtensionPropertySchema.optional ( ) ,
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-05-14 21:08:46 +02:00
content : ContentFormatSchema.optional ( ) ,
attachments : z.array ( ContentFormatSchema ) . optional ( ) ,
2024-05-14 09:00:05 +02:00
replies_to : z.string ( ) . url ( ) . optional ( ) ,
quotes : z.string ( ) . url ( ) . optional ( ) ,
mentions : z.array ( z . string ( ) . url ( ) ) . optional ( ) ,
subject : z.string ( ) . optional ( ) ,
is_sensitive : z.boolean ( ) . optional ( ) ,
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 ( ) ,
} )
. optional ( ) ,
"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 ( ) ) ,
multiple_choice : z.boolean ( ) . optional ( ) ,
expires_at : z.string ( ) ,
} ) ,
} )
. optional ( ) ,
2024-05-15 02:12:26 +02:00
} ) . optional ( ) ,
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" ) ,
display_name : z.string ( ) . optional ( ) ,
username : z.string ( ) ,
2024-05-14 21:08:46 +02:00
avatar : ContentFormatSchema.optional ( ) ,
header : ContentFormatSchema.optional ( ) ,
2024-05-14 09:00:05 +02:00
indexable : z.boolean ( ) ,
2024-05-14 21:08:46 +02:00
public_key : ActorPublicKeyDataSchema ,
bio : ContentFormatSchema.optional ( ) ,
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
} ) ,
)
. optional ( ) ,
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-05-14 21:08:46 +02:00
"org.lysand:vanity" : VanityExtensionSchema . optional ( ) ,
2024-05-15 02:12:26 +02:00
} ) . optional ( ) ,
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 ( ) ,
comment : z.string ( ) . optional ( ) ,
} ) ;
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 ( ) ,
description : z.string ( ) . optional ( ) ,
website : z.string ( ) . optional ( ) ,
moderators : z.array ( z . string ( ) ) . optional ( ) ,
admins : z.array ( z . string ( ) ) . optional ( ) ,
2024-05-14 21:08:46 +02:00
logo : ContentFormatSchema.optional ( ) ,
banner : ContentFormatSchema.optional ( ) ,
2024-05-14 09:00:05 +02:00
supported_extensions : z.array ( z . string ( ) ) ,
extensions : z.record ( z . string ( ) , z . any ( ) ) . optional ( ) ,
} ) ;
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-05-14 09:00:05 +02:00
CustomEmojiExtension ,
2024-05-15 02:12:26 +02:00
ExtensionPropertySchema ,
2024-05-14 09:00:05 +02:00
} ;