mirror of
https://github.com/versia-pub/api.git
synced 2025-12-06 08:28:19 +01:00
refactor(federation): 👽 Update rest of federation code to Working Draft 4
This commit is contained in:
parent
4a470f5f3c
commit
d422e28943
|
|
@ -79,7 +79,7 @@ describe("RequestParserHandler", () => {
|
||||||
expect(noteCallback).not.toHaveBeenCalled();
|
expect(noteCallback).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Throw on incorrect body type property", async () => {
|
test("Correctly handle unknown body type property", async () => {
|
||||||
const handler = new RequestParserHandler(
|
const handler = new RequestParserHandler(
|
||||||
{
|
{
|
||||||
type: "DoesntExist",
|
type: "DoesntExist",
|
||||||
|
|
@ -89,9 +89,7 @@ describe("RequestParserHandler", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const noteCallback = jest.fn();
|
const noteCallback = jest.fn();
|
||||||
await expect(
|
await handler.parseBody({ unknown: noteCallback });
|
||||||
handler.parseBody({ note: noteCallback }),
|
expect(noteCallback).toHaveBeenCalled();
|
||||||
).rejects.toThrow();
|
|
||||||
expect(noteCallback).not.toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
import type {
|
import type {
|
||||||
|
Delete,
|
||||||
Dislike,
|
Dislike,
|
||||||
Extension,
|
|
||||||
Follow,
|
Follow,
|
||||||
FollowAccept,
|
FollowAccept,
|
||||||
FollowReject,
|
FollowReject,
|
||||||
|
Group,
|
||||||
|
InstanceMetadata,
|
||||||
Like,
|
Like,
|
||||||
Note,
|
Note,
|
||||||
Patch,
|
Reaction,
|
||||||
ServerMetadata,
|
Share,
|
||||||
Undo,
|
Unfollow,
|
||||||
User,
|
User,
|
||||||
|
Vote,
|
||||||
} from "./schemas";
|
} from "./schemas";
|
||||||
import type { EntityValidator } from "./validator";
|
import type { EntityValidator } from "./validator";
|
||||||
|
|
||||||
|
|
@ -23,10 +26,14 @@ type ParserCallbacks<T> = {
|
||||||
user: (user: User) => MaybePromise<T>;
|
user: (user: User) => MaybePromise<T>;
|
||||||
like: (like: Like) => MaybePromise<T>;
|
like: (like: Like) => MaybePromise<T>;
|
||||||
dislike: (dislike: Dislike) => MaybePromise<T>;
|
dislike: (dislike: Dislike) => MaybePromise<T>;
|
||||||
undo: (undo: Undo) => MaybePromise<T>;
|
delete: (undo: Delete) => MaybePromise<T>;
|
||||||
serverMetadata: (serverMetadata: ServerMetadata) => MaybePromise<T>;
|
instanceMetadata: (instanceMetadata: InstanceMetadata) => MaybePromise<T>;
|
||||||
extension: (extension: Extension) => MaybePromise<T>;
|
group: (group: Group) => MaybePromise<T>;
|
||||||
patch: (patch: Patch) => MaybePromise<T>;
|
reaction: (reaction: Reaction) => MaybePromise<T>;
|
||||||
|
share: (share: Share) => MaybePromise<T>;
|
||||||
|
vote: (vote: Vote) => MaybePromise<T>;
|
||||||
|
unfollow: (unfollow: Unfollow) => MaybePromise<T>;
|
||||||
|
unknown: (data: unknown) => MaybePromise<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -92,15 +99,6 @@ export class RequestParserHandler {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Patch": {
|
|
||||||
const patch = await this.validator.Patch(this.body);
|
|
||||||
|
|
||||||
if (callbacks.patch) {
|
|
||||||
return await callbacks.patch(patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Follow": {
|
case "Follow": {
|
||||||
const follow = await this.validator.Follow(this.body);
|
const follow = await this.validator.Follow(this.body);
|
||||||
|
|
||||||
|
|
@ -159,41 +157,79 @@ export class RequestParserHandler {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Undo": {
|
case "Delete": {
|
||||||
const undo = await this.validator.Undo(this.body);
|
// "delete" isn't an allowed variable name
|
||||||
|
const delete_ = await this.validator.Delete(this.body);
|
||||||
|
|
||||||
if (callbacks.undo) {
|
if (callbacks.delete) {
|
||||||
return await callbacks.undo(undo);
|
return await callbacks.delete(delete_);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "ServerMetadata": {
|
case "InstanceMetadata": {
|
||||||
const serverMetadata = await this.validator.ServerMetadata(
|
const instanceMetadata = await this.validator.InstanceMetadata(
|
||||||
this.body,
|
this.body,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (callbacks.serverMetadata) {
|
if (callbacks.instanceMetadata) {
|
||||||
return await callbacks.serverMetadata(serverMetadata);
|
return await callbacks.instanceMetadata(instanceMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Extension": {
|
case "Group": {
|
||||||
const extension = await this.validator.Extension(this.body);
|
const group = await this.validator.Group(this.body);
|
||||||
|
|
||||||
if (callbacks.extension) {
|
if (callbacks.group) {
|
||||||
return await callbacks.extension(extension);
|
return await callbacks.group(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
case "Reaction": {
|
||||||
throw new Error(
|
const reaction = await this.validator.Reaction(this.body);
|
||||||
`Invalid type field in body: ${this.body.type}`,
|
|
||||||
);
|
if (callbacks.reaction) {
|
||||||
|
return await callbacks.reaction(reaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Invalid type field in body: ${this.body.type}`);
|
break;
|
||||||
|
}
|
||||||
|
case "Share": {
|
||||||
|
const share = await this.validator.Share(this.body);
|
||||||
|
|
||||||
|
if (callbacks.share) {
|
||||||
|
return await callbacks.share(share);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Vote": {
|
||||||
|
const vote = await this.validator.Vote(this.body);
|
||||||
|
|
||||||
|
if (callbacks.vote) {
|
||||||
|
return await callbacks.vote(vote);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Unfollow": {
|
||||||
|
const unfollow = await this.validator.Unfollow(this.body);
|
||||||
|
|
||||||
|
if (callbacks.unfollow) {
|
||||||
|
return await callbacks.unfollow(unfollow);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (callbacks.unknown) {
|
||||||
|
return await callbacks.unknown(this.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined as ReturnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,18 @@ import type {
|
||||||
UnfollowSchema,
|
UnfollowSchema,
|
||||||
UserSchema,
|
UserSchema,
|
||||||
} from "./schemas/base";
|
} from "./schemas/base";
|
||||||
import type { ContentFormatSchema } from "./schemas/content_format";
|
import type {
|
||||||
|
AudioOnlyContentFormatSchema,
|
||||||
|
ContentFormatSchema,
|
||||||
|
ImageOnlyContentFormatSchema,
|
||||||
|
TextOnlyContentFormatSchema,
|
||||||
|
} from "./schemas/content_format";
|
||||||
import type { ExtensionPropertySchema } from "./schemas/extensions";
|
import type { ExtensionPropertySchema } from "./schemas/extensions";
|
||||||
import type { CustomEmojiExtensionSchema } from "./schemas/extensions/custom_emojis";
|
import type { CustomEmojiExtensionSchema } from "./schemas/extensions/custom_emojis";
|
||||||
|
import type { LikeSchema } from "./schemas/extensions/likes";
|
||||||
|
import type { VoteSchema } from "./schemas/extensions/polls";
|
||||||
|
import type { ReactionSchema } from "./schemas/extensions/reactions";
|
||||||
|
import type { ShareSchema } from "./schemas/extensions/share";
|
||||||
import type { VanityExtensionSchema } from "./schemas/extensions/vanity";
|
import type { VanityExtensionSchema } from "./schemas/extensions/vanity";
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: Used only as a base type
|
// biome-ignore lint/suspicious/noExplicitAny: Used only as a base type
|
||||||
|
|
@ -36,9 +45,17 @@ export type Follow = InferType<typeof FollowSchema>;
|
||||||
export type FollowAccept = InferType<typeof FollowAcceptSchema>;
|
export type FollowAccept = InferType<typeof FollowAcceptSchema>;
|
||||||
export type FollowReject = InferType<typeof FollowRejectSchema>;
|
export type FollowReject = InferType<typeof FollowRejectSchema>;
|
||||||
export type ContentFormat = InferType<typeof ContentFormatSchema>;
|
export type ContentFormat = InferType<typeof ContentFormatSchema>;
|
||||||
|
export type ImageContentFormat = InferType<typeof ImageOnlyContentFormatSchema>;
|
||||||
|
export type TextContentFormat = InferType<typeof TextOnlyContentFormatSchema>;
|
||||||
|
export type AudioContentFormat = InferType<typeof AudioOnlyContentFormatSchema>;
|
||||||
export type CustomEmojiExtension = InferType<typeof CustomEmojiExtensionSchema>;
|
export type CustomEmojiExtension = InferType<typeof CustomEmojiExtensionSchema>;
|
||||||
export type Entity = InferType<typeof EntitySchema>;
|
export type Entity = InferType<typeof EntitySchema>;
|
||||||
export type Delete = InferType<typeof DeleteSchema>;
|
export type Delete = InferType<typeof DeleteSchema>;
|
||||||
export type Group = InferType<typeof GroupSchema>;
|
export type Group = InferType<typeof GroupSchema>;
|
||||||
export type InstanceMetadata = InferType<typeof InstanceMetadataSchema>;
|
export type InstanceMetadata = InferType<typeof InstanceMetadataSchema>;
|
||||||
export type Unfollow = InferType<typeof UnfollowSchema>;
|
export type Unfollow = InferType<typeof UnfollowSchema>;
|
||||||
|
export type Like = InferType<typeof LikeSchema>;
|
||||||
|
export type Dislike = InferType<typeof LikeSchema>;
|
||||||
|
export type Vote = InferType<typeof VoteSchema>;
|
||||||
|
export type Reaction = InferType<typeof ReactionSchema>;
|
||||||
|
export type Share = InferType<typeof ShareSchema>;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,25 @@
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
import { fromError } from "zod-validation-error";
|
import { fromError } from "zod-validation-error";
|
||||||
import {
|
import {
|
||||||
|
DeleteSchema,
|
||||||
EntitySchema,
|
EntitySchema,
|
||||||
FollowAcceptSchema,
|
FollowAcceptSchema,
|
||||||
FollowRejectSchema,
|
FollowRejectSchema,
|
||||||
FollowSchema,
|
FollowSchema,
|
||||||
|
GroupSchema,
|
||||||
|
InstanceMetadataSchema,
|
||||||
NoteSchema,
|
NoteSchema,
|
||||||
PublicKeyDataSchema,
|
PublicKeyDataSchema,
|
||||||
|
UnfollowSchema,
|
||||||
UserSchema,
|
UserSchema,
|
||||||
} from "./schemas/base";
|
} from "./schemas/base";
|
||||||
import { ContentFormatSchema } from "./schemas/content_format";
|
import { ContentFormatSchema } from "./schemas/content_format";
|
||||||
import { ExtensionPropertySchema } from "./schemas/extensions";
|
import { ExtensionPropertySchema } from "./schemas/extensions";
|
||||||
import { CustomEmojiExtensionSchema } from "./schemas/extensions/custom_emojis";
|
import { CustomEmojiExtensionSchema } from "./schemas/extensions/custom_emojis";
|
||||||
|
import { LikeSchema } from "./schemas/extensions/likes";
|
||||||
|
import { VoteSchema } from "./schemas/extensions/polls";
|
||||||
|
import { ReactionSchema } from "./schemas/extensions/reactions";
|
||||||
|
import { ShareSchema } from "./schemas/extensions/share";
|
||||||
import { VanityExtensionSchema } from "./schemas/extensions/vanity";
|
import { VanityExtensionSchema } from "./schemas/extensions/vanity";
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: Used only as a base type
|
// biome-ignore lint/suspicious/noExplicitAny: Used only as a base type
|
||||||
|
|
@ -174,4 +182,87 @@ export class EntityValidator {
|
||||||
): Promise<InferType<typeof ExtensionPropertySchema>> {
|
): Promise<InferType<typeof ExtensionPropertySchema>> {
|
||||||
return this.validate(ExtensionPropertySchema, data);
|
return this.validate(ExtensionPropertySchema, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Delete entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Delete(data: unknown): Promise<InferType<typeof DeleteSchema>> {
|
||||||
|
return this.validate(DeleteSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Group entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Group(data: unknown): Promise<InferType<typeof GroupSchema>> {
|
||||||
|
return this.validate(GroupSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an InstanceMetadata entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public InstanceMetadata(
|
||||||
|
data: unknown,
|
||||||
|
): Promise<InferType<typeof InstanceMetadataSchema>> {
|
||||||
|
return this.validate(InstanceMetadataSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an Unfollow entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Unfollow(data: unknown): Promise<InferType<typeof UnfollowSchema>> {
|
||||||
|
return this.validate(UnfollowSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Like entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Like(data: unknown): Promise<InferType<typeof LikeSchema>> {
|
||||||
|
return this.validate(LikeSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Dislike entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Dislike(data: unknown): Promise<InferType<typeof LikeSchema>> {
|
||||||
|
return this.validate(LikeSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Vote entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Vote(data: unknown): Promise<InferType<typeof VoteSchema>> {
|
||||||
|
return this.validate(VoteSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Reaction entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Reaction(data: unknown): Promise<InferType<typeof ReactionSchema>> {
|
||||||
|
return this.validate(ReactionSchema, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a Share entity.
|
||||||
|
* @param data - The data to validate
|
||||||
|
* @returns A promise that resolves to the validated data.
|
||||||
|
*/
|
||||||
|
public Share(data: unknown): Promise<InferType<typeof ShareSchema>> {
|
||||||
|
return this.validate(ShareSchema, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue