mirror of
https://github.com/versia-pub/api.git
synced 2025-12-06 16:38:20 +01:00
refactor(federation): ♻️ Refactor FederationRequester to be simpler
This commit is contained in:
parent
db92a51412
commit
39f27cd87f
21
client/LICENSE
Normal file
21
client/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Lysand
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
21
federation/LICENSE
Normal file
21
federation/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Lysand
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { beforeEach, describe, expect, jest, test } from "bun:test";
|
||||
import { RequestParserHandler } from "../http/index.ts";
|
||||
import { EntityValidator } from "../validator/index.ts";
|
||||
import { RequestParserHandler } from "./http.ts";
|
||||
import { EntityValidator } from "./validator.ts";
|
||||
|
||||
// Pulled from social.lysand.org
|
||||
const validUser = {
|
||||
|
|
@ -10,8 +10,8 @@ import type {
|
|||
ServerMetadata,
|
||||
Undo,
|
||||
User,
|
||||
} from "../schemas";
|
||||
import type { EntityValidator } from "../validator/index";
|
||||
} from "./schemas";
|
||||
import type { EntityValidator } from "./validator";
|
||||
|
||||
type MaybePromise<T> = T | Promise<T>;
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ import {
|
|||
type Output,
|
||||
ResponseError,
|
||||
} from "./requester/index";
|
||||
import { EntityValidator } from "./validator/index";
|
||||
import { EntityValidator } from "./validator";
|
||||
|
||||
export {
|
||||
EntityValidator,
|
||||
|
|
|
|||
|
|
@ -39,12 +39,10 @@ export class ResponseError<
|
|||
|
||||
/**
|
||||
* Class to handle requests to a remote server.
|
||||
* @param serverUrl The URL of the server to send requests to.
|
||||
* @param signatureConstructor The constructor to sign requests with.
|
||||
* @param globalCatch A function to call when a request fails.
|
||||
* @example
|
||||
* const requester = new FederationRequester(
|
||||
* new URL("https://example.com"),
|
||||
* new SignatureConstructor(privateKey, keyId),
|
||||
* );
|
||||
*
|
||||
|
|
@ -58,17 +56,12 @@ export class ResponseError<
|
|||
*/
|
||||
export class FederationRequester {
|
||||
constructor(
|
||||
private serverUrl: URL,
|
||||
private signatureConstructor?: SignatureConstructor,
|
||||
public globalCatch: (error: ResponseError) => void = () => {
|
||||
// Do nothing by default
|
||||
},
|
||||
) {}
|
||||
|
||||
get url(): URL {
|
||||
return this.serverUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's profile link from their username.
|
||||
* @param username The username to get the profile link for.
|
||||
|
|
@ -84,7 +77,7 @@ export class FederationRequester {
|
|||
*/
|
||||
public async webFinger(
|
||||
username: string,
|
||||
hostname = this.serverUrl.hostname,
|
||||
hostname: string,
|
||||
contentType = "application/json",
|
||||
): Promise<string> {
|
||||
const result = await this.get<User>(
|
||||
|
|
@ -185,7 +178,7 @@ export class FederationRequester {
|
|||
|
||||
headers.set("Accept", "application/json");
|
||||
|
||||
const request = new Request(new URL(path, this.serverUrl).toString(), {
|
||||
const request = new Request(path, {
|
||||
method,
|
||||
headers,
|
||||
body: body
|
||||
|
|
@ -201,6 +194,12 @@ export class FederationRequester {
|
|||
: request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a GET request to a URL.
|
||||
* @param path The path to make the request to.
|
||||
* @param extra Any extra options to pass to the fetch function.
|
||||
* @returns The data returned by the request.
|
||||
*/
|
||||
public async get<ReturnType>(
|
||||
path: string,
|
||||
extra?: RequestInit,
|
||||
|
|
@ -213,19 +212,13 @@ export class FederationRequester {
|
|||
});
|
||||
}
|
||||
|
||||
public static get<ReturnType>(
|
||||
url: string | URL,
|
||||
extra?: RequestInit,
|
||||
): Promise<Output<ReturnType>> {
|
||||
const urlUrl = new URL(url);
|
||||
const requester = new FederationRequester(urlUrl);
|
||||
|
||||
return requester.get<ReturnType>(
|
||||
urlUrl.pathname + urlUrl.search,
|
||||
extra,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a POST request to a URL.
|
||||
* @param path The path to make the request to.
|
||||
* @param body The body of the request.
|
||||
* @param extra Any extra options to pass to the fetch function.
|
||||
* @returns The data returned by the request.
|
||||
*/
|
||||
public async post<ReturnType>(
|
||||
path: string,
|
||||
body: object,
|
||||
|
|
@ -238,19 +231,4 @@ export class FederationRequester {
|
|||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
public static post<ReturnType>(
|
||||
url: string,
|
||||
body: object,
|
||||
extra?: RequestInit,
|
||||
): Promise<Output<ReturnType>> {
|
||||
const urlUrl = new URL(url);
|
||||
const requester = new FederationRequester(urlUrl);
|
||||
|
||||
return requester.post<ReturnType>(
|
||||
urlUrl.pathname + urlUrl.search,
|
||||
body,
|
||||
extra,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* @file TypeScript type definitions
|
||||
* @module federation/types
|
||||
*/
|
||||
|
||||
import type { z } from "zod";
|
||||
import type {
|
||||
ActionSchema,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
UserSchema,
|
||||
VanityExtensionSchema,
|
||||
VisibilitySchema,
|
||||
} from "../schemas/base";
|
||||
} from "./schemas/base";
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Used only as a base type
|
||||
type AnyZod = z.ZodType<any, any, any>;
|
||||
Loading…
Reference in a new issue