refactor(federation): ♻️ Rewrite federation SDK

This commit is contained in:
Jesse Wierzbinski 2025-04-08 16:01:10 +02:00
parent ad1dc13a51
commit d638610361
No known key found for this signature in database
72 changed files with 2137 additions and 738 deletions

View file

@ -0,0 +1,29 @@
import type { z } from "zod";
import {
CollectionSchema,
URICollectionSchema,
} from "../schemas/collection.ts";
import type { JSONObject } from "../types.ts";
import { Entity } from "./entity.ts";
export class Collection extends Entity {
public constructor(public data: z.infer<typeof CollectionSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Collection> {
return CollectionSchema.parseAsync(json).then((u) => new Collection(u));
}
}
export class URICollection extends Entity {
public constructor(public data: z.infer<typeof URICollectionSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<URICollection> {
return URICollectionSchema.parseAsync(json).then(
(u) => new URICollection(u),
);
}
}

View file

@ -0,0 +1,82 @@
import type { z } from "zod";
import {
AudioContentFormatSchema,
ContentFormatSchema,
ImageContentFormatSchema,
NonTextContentFormatSchema,
TextContentFormatSchema,
VideoContentFormatSchema,
} from "../schemas/contentformat.ts";
import type { JSONObject } from "../types.ts";
export class ContentFormat {
public static fromJSON(data: JSONObject): Promise<ContentFormat> {
return ContentFormatSchema.parseAsync(data).then(
(d) => new ContentFormat(d),
);
}
public constructor(public data: z.infer<typeof ContentFormatSchema>) {}
}
export class TextContentFormat extends ContentFormat {
public static fromJSON(data: JSONObject): Promise<TextContentFormat> {
return TextContentFormatSchema.parseAsync(data).then(
(d) => new TextContentFormat(d),
);
}
public constructor(public data: z.infer<typeof TextContentFormatSchema>) {
super(data);
}
}
export class NonTextContentFormat extends ContentFormat {
public static fromJSON(data: JSONObject): Promise<NonTextContentFormat> {
return NonTextContentFormatSchema.parseAsync(data).then(
(d) => new NonTextContentFormat(d),
);
}
public constructor(
public data: z.infer<typeof NonTextContentFormatSchema>,
) {
super(data);
}
}
export class ImageContentFormat extends ContentFormat {
public static fromJSON(data: JSONObject): Promise<ImageContentFormat> {
return ImageContentFormatSchema.parseAsync(data).then(
(d) => new ImageContentFormat(d),
);
}
public constructor(public data: z.infer<typeof ImageContentFormatSchema>) {
super(data);
}
}
export class VideoContentFormat extends ContentFormat {
public static fromJSON(data: JSONObject): Promise<VideoContentFormat> {
return VideoContentFormatSchema.parseAsync(data).then(
(d) => new VideoContentFormat(d),
);
}
public constructor(public data: z.infer<typeof VideoContentFormatSchema>) {
super(data);
}
}
export class AudioContentFormat extends ContentFormat {
public static fromJSON(data: JSONObject): Promise<AudioContentFormat> {
return AudioContentFormatSchema.parseAsync(data).then(
(d) => new AudioContentFormat(d),
);
}
public constructor(public data: z.infer<typeof AudioContentFormatSchema>) {
super(data);
}
}

View file

@ -0,0 +1,16 @@
import type { z } from "zod";
import { DeleteSchema } from "../schemas/delete.ts";
import type { JSONObject } from "../types.ts";
import { Entity } from "./entity.ts";
export class Delete extends Entity {
public static name = "Delete";
public constructor(public data: z.infer<typeof DeleteSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Delete> {
return DeleteSchema.parseAsync(json).then((u) => new Delete(u));
}
}

View file

@ -0,0 +1,17 @@
import { EntitySchema } from "../schemas/entity.ts";
import type { JSONObject } from "../types.ts";
export class Entity {
public static name = "Entity";
// biome-ignore lint/suspicious/noExplicitAny: This is a base class that is never instanciated directly
public constructor(public data: any) {}
public static fromJSON(json: JSONObject): Promise<Entity> {
return EntitySchema.parseAsync(json).then((u) => new Entity(u));
}
public toJSON(): JSONObject {
return this.data;
}
}

View file

@ -0,0 +1,28 @@
import type { z } from "zod";
import { DislikeSchema, LikeSchema } from "../../schemas/extensions/likes.ts";
import type { JSONObject } from "../../types.ts";
import { Entity } from "../entity.ts";
export class Like extends Entity {
public static name = "pub.versia:likes/Like";
public constructor(public data: z.infer<typeof LikeSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Like> {
return LikeSchema.parseAsync(json).then((u) => new Like(u));
}
}
export class Dislike extends Entity {
public static name = "pub.versia:likes/Dislike";
public constructor(public data: z.infer<typeof DislikeSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Dislike> {
return DislikeSchema.parseAsync(json).then((u) => new Dislike(u));
}
}

View file

@ -0,0 +1,16 @@
import type { z } from "zod";
import { VoteSchema } from "../../schemas/extensions/polls.ts";
import type { JSONObject } from "../../types.ts";
import { Entity } from "../entity.ts";
export class Vote extends Entity {
public static name = "pub.versia:polls/Vote";
public constructor(public data: z.infer<typeof VoteSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Vote> {
return VoteSchema.parseAsync(json).then((u) => new Vote(u));
}
}

View file

@ -0,0 +1,16 @@
import type { z } from "zod";
import { ReactionSchema } from "../../schemas/extensions/reactions.ts";
import type { JSONObject } from "../../types.ts";
import { Entity } from "../entity.ts";
export class Reaction extends Entity {
public static name = "pub.versia:reactions/Reaction";
public constructor(public data: z.infer<typeof ReactionSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Reaction> {
return ReactionSchema.parseAsync(json).then((u) => new Reaction(u));
}
}

View file

@ -0,0 +1,16 @@
import type { z } from "zod";
import { ReportSchema } from "../../schemas/extensions/reports.ts";
import type { JSONObject } from "../../types.ts";
import { Entity } from "../entity.ts";
export class Report extends Entity {
public static name = "pub.versia:reports/Report";
public constructor(public data: z.infer<typeof ReportSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Report> {
return ReportSchema.parseAsync(json).then((u) => new Report(u));
}
}

View file

@ -0,0 +1,16 @@
import type { z } from "zod";
import { ShareSchema } from "../../schemas/extensions/share.ts";
import type { JSONObject } from "../../types.ts";
import { Entity } from "../entity.ts";
export class Share extends Entity {
public static name = "pub.versia:share/Share";
public constructor(public data: z.infer<typeof ShareSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Share> {
return ShareSchema.parseAsync(json).then((u) => new Share(u));
}
}

View file

@ -0,0 +1,61 @@
import type { z } from "zod";
import {
FollowAcceptSchema,
FollowRejectSchema,
FollowSchema,
UnfollowSchema,
} from "../schemas/follow.ts";
import type { JSONObject } from "../types.ts";
import { Entity } from "./entity.ts";
export class Follow extends Entity {
public static name = "Follow";
public constructor(public data: z.infer<typeof FollowSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Follow> {
return FollowSchema.parseAsync(json).then((u) => new Follow(u));
}
}
export class FollowAccept extends Entity {
public static name = "FollowAccept";
public constructor(public data: z.infer<typeof FollowAcceptSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<FollowAccept> {
return FollowAcceptSchema.parseAsync(json).then(
(u) => new FollowAccept(u),
);
}
}
export class FollowReject extends Entity {
public static name = "FollowReject";
public constructor(public data: z.infer<typeof FollowRejectSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<FollowReject> {
return FollowRejectSchema.parseAsync(json).then(
(u) => new FollowReject(u),
);
}
}
export class Unfollow extends Entity {
public static name = "Unfollow";
public constructor(public data: z.infer<typeof UnfollowSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Unfollow> {
return UnfollowSchema.parseAsync(json).then((u) => new Unfollow(u));
}
}

View file

@ -0,0 +1,21 @@
// biome-ignore lint/performance/noBarrelFile: <explanation>
export { User } from "./user.ts";
export { Note } from "./note.ts";
export { Entity } from "./entity.ts";
export { Delete } from "./delete.ts";
export { InstanceMetadata } from "./instancemetadata.ts";
export {
ImageContentFormat,
AudioContentFormat,
NonTextContentFormat,
TextContentFormat,
ContentFormat,
VideoContentFormat,
} from "./contentformat.ts";
export { Follow, FollowAccept, FollowReject, Unfollow } from "./follow.ts";
export { Collection, URICollection } from "./collection.ts";
export { Like, Dislike } from "./extensions/likes.ts";
export { Vote } from "./extensions/polls.ts";
export { Reaction } from "./extensions/reactions.ts";
export { Report } from "./extensions/reports.ts";
export { Share } from "./extensions/share.ts";

View file

@ -0,0 +1,31 @@
import type { z } from "zod";
import { InstanceMetadataSchema } from "../schemas/instance.ts";
import type { JSONObject } from "../types.ts";
import { ImageContentFormat } from "./contentformat.ts";
import { Entity } from "./entity.ts";
export class InstanceMetadata extends Entity {
public static name = "InstanceMetadata";
public constructor(public data: z.infer<typeof InstanceMetadataSchema>) {
super(data);
}
public get logo(): ImageContentFormat | undefined {
return this.data.logo
? new ImageContentFormat(this.data.logo)
: undefined;
}
public get banner(): ImageContentFormat | undefined {
return this.data.banner
? new ImageContentFormat(this.data.banner)
: undefined;
}
public static fromJSON(json: JSONObject): Promise<InstanceMetadata> {
return InstanceMetadataSchema.parseAsync(json).then(
(u) => new InstanceMetadata(u),
);
}
}

View file

@ -0,0 +1,29 @@
import type { z } from "zod";
import { NoteSchema } from "../schemas/note.ts";
import type { JSONObject } from "../types.ts";
import { NonTextContentFormat, TextContentFormat } from "./contentformat.ts";
import { Entity } from "./entity.ts";
export class Note extends Entity {
public static name = "Note";
public constructor(public data: z.infer<typeof NoteSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<Note> {
return NoteSchema.parseAsync(json).then((n) => new Note(n));
}
public get attachments(): NonTextContentFormat[] {
return (
this.data.attachments?.map((a) => new NonTextContentFormat(a)) ?? []
);
}
public get content(): TextContentFormat | undefined {
return this.data.content
? new TextContentFormat(this.data.content)
: undefined;
}
}

View file

@ -0,0 +1,33 @@
import type { z } from "zod";
import { UserSchema } from "../schemas/user.ts";
import type { JSONObject } from "../types.ts";
import { ImageContentFormat, TextContentFormat } from "./contentformat.ts";
import { Entity } from "./entity.ts";
export class User extends Entity {
public static name = "User";
public constructor(public data: z.infer<typeof UserSchema>) {
super(data);
}
public static fromJSON(json: JSONObject): Promise<User> {
return UserSchema.parseAsync(json).then((u) => new User(u));
}
public get avatar(): ImageContentFormat | undefined {
return this.data.avatar
? new ImageContentFormat(this.data.avatar)
: undefined;
}
public get header(): ImageContentFormat | undefined {
return this.data.header
? new ImageContentFormat(this.data.header)
: undefined;
}
public get bio(): TextContentFormat | undefined {
return this.data.bio ? new TextContentFormat(this.data.bio) : undefined;
}
}