refactor: 🚚 Begin rebranding to Versia Server

This commit is contained in:
Jesse Wierzbinski 2024-08-19 15:16:01 +02:00
parent 64cef5c6d6
commit 771097d037
No known key found for this signature in database
58 changed files with 2377 additions and 242 deletions

View file

@ -32,7 +32,7 @@ export const configValidator = z.object({
.default(5432),
username: z.string().min(1),
password: z.string().default(""),
database: z.string().min(1).default("lysand"),
database: z.string().min(1).default("versia"),
}),
redis: z.object({
queue: z
@ -109,7 +109,7 @@ export const configValidator = z.object({
jwt_key: z.string().min(3).includes(";").default("").or(z.literal("")),
}),
http: z.object({
base_url: z.string().min(1).default("http://lysand.social"),
base_url: z.string().min(1).default("http://versia.social"),
bind: z.string().min(1).default("0.0.0.0"),
bind_port: z
.number()
@ -260,7 +260,7 @@ export const configValidator = z.object({
access_key: z.string(),
secret_access_key: z.string(),
region: z.string().optional(),
bucket_name: z.string().default("lysand"),
bucket_name: z.string().default("versia"),
public_url: zUrl,
})
.default({
@ -268,7 +268,7 @@ export const configValidator = z.object({
access_key: "",
secret_access_key: "",
region: undefined,
bucket_name: "lysand",
bucket_name: "versia",
public_url: "https://cdn.example.com",
}),
validation: z
@ -507,8 +507,8 @@ export const configValidator = z.object({
}),
instance: z
.object({
name: z.string().min(1).default("Lysand"),
description: z.string().min(1).default("A Lysand instance"),
name: z.string().min(1).default("Versia"),
description: z.string().min(1).default("A Versia instance"),
extended_description_path: z.string().optional(),
tos_path: z.string().optional(),
privacy_policy_path: z.string().optional(),
@ -525,8 +525,8 @@ export const configValidator = z.object({
}),
})
.default({
name: "Lysand",
description: "A Lysand instance",
name: "Versia",
description: "A Versia instance",
extended_description_path: undefined,
tos_path: undefined,
privacy_policy_path: undefined,

View file

@ -197,7 +197,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
};
}
public toLysand(): ContentFormat {
public toVersia(): ContentFormat {
return {
[this.data.mimeType]: {
content: this.data.url,
@ -217,7 +217,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
};
}
public static fromLysand(
public static fromVersia(
attachmentToConvert: ContentFormat,
): Promise<Attachment> {
const key = Object.keys(attachmentToConvert)[0];

View file

@ -150,7 +150,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
const foundInstance = host ? await Instance.resolve(host) : null;
return await Emoji.fromLysand(emojiToFetch, foundInstance?.id ?? null);
return await Emoji.fromVersia(emojiToFetch, foundInstance?.id ?? null);
}
get id() {
@ -189,7 +189,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
};
}
public toLysand(): CustomEmojiExtension["emojis"][0] {
public toVersia(): CustomEmojiExtension["emojis"][0] {
return {
name: this.data.shortcode,
url: {
@ -201,7 +201,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
};
}
public static fromLysand(
public static fromVersia(
emoji: CustomEmojiExtension["emojis"][0],
instanceId: string | null,
): Promise<Emoji> {

View file

@ -133,10 +133,10 @@ export class Instance extends BaseInterface<typeof Instances> {
static async fetchMetadata(url: string): Promise<{
metadata: ServerMetadata;
protocol: "lysand" | "activitypub";
protocol: "versia" | "activitypub";
} | null> {
const origin = new URL(url).origin;
const wellKnownUrl = new URL("/.well-known/lysand", origin);
const wellKnownUrl = new URL("/.well-known/versia", origin);
const logger = getLogger("federation");
const requester = await User.getServerActor().getFederationRequester();
@ -152,7 +152,7 @@ export class Instance extends BaseInterface<typeof Instances> {
}));
if (!(ok && raw.headers.get("content-type")?.includes("json"))) {
// If the server doesn't have a Lysand well-known endpoint, it's not a Lysand instance
// If the server doesn't have a Versia well-known endpoint, it's not a Versia instance
// Try to resolve ActivityPub metadata instead
const data = await Instance.fetchActivityPubMetadata(url);
@ -171,7 +171,7 @@ export class Instance extends BaseInterface<typeof Instances> {
data,
);
return { metadata, protocol: "lysand" };
return { metadata, protocol: "versia" };
} catch (error) {
logger.error`Instance ${chalk.bold(
origin,
@ -179,7 +179,7 @@ export class Instance extends BaseInterface<typeof Instances> {
return null;
}
} catch (error) {
logger.error`Failed to fetch Lysand metadata for instance ${chalk.bold(
logger.error`Failed to fetch Versia metadata for instance ${chalk.bold(
origin,
)} - Error! ${error}`;
return null;

View file

@ -11,7 +11,7 @@ import type {
import { EntityValidator } from "@lysand-org/federation";
import type {
ContentFormat,
Note as LysandNote,
Note as VersiaNote,
} from "@lysand-org/federation/types";
import {
type InferInsertModel,
@ -193,7 +193,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
const users = await this.getUsersToFederateTo();
for (const user of users) {
await this.author.federateToUser(this.toLysand(), user);
await this.author.federateToUser(this.toVersia(), user);
}
}
@ -594,7 +594,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
* @returns The saved note, or null if the note could not be fetched
*/
static async saveFromRemote(uri: string): Promise<Note | null> {
let note: LysandNote | null = null;
let note: VersiaNote | null = null;
if (uri) {
if (!URL.canParse(uri)) {
@ -622,16 +622,16 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
throw new Error("Invalid object author");
}
return await Note.fromLysand(note, author);
return await Note.fromVersia(note, author);
}
/**
* Turns a Lysand Note into a database note (saved)
* @param note Lysand Note
* Turns a Versia Note into a database note (saved)
* @param note Versia Note
* @param author Author of the note
* @returns The saved note
*/
static async fromLysand(note: LysandNote, author: User): Promise<Note> {
static async fromVersia(note: VersiaNote, author: User): Promise<Note> {
const emojis: Emoji[] = [];
const logger = getLogger("federation");
@ -653,7 +653,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
const attachments: Attachment[] = [];
for (const attachment of note.attachments ?? []) {
const resolvedAttachment = await Attachment.fromLysand(
const resolvedAttachment = await Attachment.fromVersia(
attachment,
).catch((e) => {
logger.error`${e}`;
@ -886,10 +886,10 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
}
/**
* Convert a note to the Lysand format
* @returns The note in the Lysand format
* Convert a note to the Versia format
* @returns The note in the Versia format
*/
toLysand(): LysandNote {
toVersia(): VersiaNote {
const status = this.data;
return {
type: "Note",
@ -906,7 +906,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
},
},
attachments: (status.attachments ?? []).map((attachment) =>
new Attachment(attachment).toLysand(),
new Attachment(attachment).toVersia(),
),
is_sensitive: status.sensitive,
mentions: status.mentions.map((mention) =>
@ -925,7 +925,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
extensions: {
"org.lysand:custom_emojis": {
emojis: status.emojis.map((emoji) =>
new Emoji(emoji).toLysand(),
new Emoji(emoji).toVersia(),
),
},
// TODO: Add polls and reactions

View file

@ -14,7 +14,7 @@ import {
type HttpVerb,
SignatureConstructor,
} from "@lysand-org/federation";
import type { Entity, User as LysandUser } from "@lysand-org/federation/types";
import type { Entity, User as VersiaUser } from "@lysand-org/federation/types";
import chalk from "chalk";
import {
type InferInsertModel,
@ -34,7 +34,7 @@ import { htmlToText } from "html-to-text";
import {
type UserWithRelations,
findManyUsers,
followRequestToLysand,
followRequestToVersia,
} from "~/classes/functions/user";
import { searchManager } from "~/classes/search/search-manager";
import { db } from "~/drizzle/db";
@ -232,7 +232,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
if (otherUser.isRemote()) {
const { ok } = await this.federateToUser(
followRequestToLysand(this, otherUser),
followRequestToVersia(this, otherUser),
otherUser,
);
@ -412,8 +412,8 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
const instance = await Instance.resolve(uri);
if (instance.data.protocol === "lysand") {
return await User.saveFromLysand(uri, instance);
if (instance.data.protocol === "versia") {
return await User.saveFromVersia(uri, instance);
}
if (instance.data.protocol === "activitypub") {
@ -428,18 +428,18 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
config.federation.bridge.url,
);
return await User.saveFromLysand(bridgeUri.toString(), instance);
return await User.saveFromVersia(bridgeUri.toString(), instance);
}
throw new Error(`Unsupported protocol: ${instance.data.protocol}`);
}
private static async saveFromLysand(
private static async saveFromVersia(
uri: string,
instance: Instance,
): Promise<User> {
const requester = await User.getServerActor().getFederationRequester();
const { data: json } = await requester.get<Partial<LysandUser>>(uri, {
const { data: json } = await requester.get<Partial<VersiaUser>>(uri, {
// @ts-expect-error Bun extension
proxy: config.http.proxy.address,
});
@ -447,12 +447,12 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
const validator = new EntityValidator();
const data = await validator.User(json);
const user = await User.fromLysand(data, instance);
const user = await User.fromVersia(data, instance);
const userEmojis =
data.extensions?.["org.lysand:custom_emojis"]?.emojis ?? [];
const emojis = await Promise.all(
userEmojis.map((emoji) => Emoji.fromLysand(emoji, instance.id)),
userEmojis.map((emoji) => Emoji.fromVersia(emoji, instance.id)),
);
if (emojis.length > 0) {
@ -475,8 +475,8 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
return finalUser;
}
static async fromLysand(
user: LysandUser,
static async fromVersia(
user: VersiaUser,
instance: Instance,
): Promise<User> {
const data = {
@ -707,14 +707,14 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
newUser.endpoints ||
newUser.isDiscoverable)
) {
await this.federateToFollowers(this.toLysand());
await this.federateToFollowers(this.toVersia());
}
return updated.data;
}
/**
* Signs a Lysand entity with that user's private key
* Signs a Versia entity with that user's private key
*
* @param entity Entity to sign
* @param signatureUrl URL to embed in signature (must be the same URI of queries made with this signature)
@ -754,7 +754,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
}
/**
* Helper to get the appropriate Lysand SDK requester with this user's private key
* Helper to get the appropriate Versia SDK requester with this user's private key
*
* @returns The requester
*/
@ -894,9 +894,9 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
};
}
toLysand(): LysandUser {
toVersia(): VersiaUser {
if (this.isRemote()) {
throw new Error("Cannot convert remote user to Lysand format");
throw new Error("Cannot convert remote user to Versia format");
}
const user = this.data;
@ -958,7 +958,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
extensions: {
"org.lysand:custom_emojis": {
emojis: user.emojis.map((emoji) =>
new Emoji(emoji).toLysand(),
new Emoji(emoji).toVersia(),
),
},
},

View file

@ -216,17 +216,17 @@ const brandingTransforms = (
newFileContents = newFileContents.replaceAll(
"Glitch-soc is free open source software forked from Mastodon.",
"Lysand is free and open-source software using the Glitch-Soc frontend.",
"Versia Server is free and open-source software using the Glitch-Soc frontend.",
);
newFileContents = newFileContents.replaceAll("Mastodon", "Lysand");
newFileContents = newFileContents.replaceAll("Mastodon", "Versia Server");
newFileContents = newFileContents.replaceAll(
"Lysand is free, open-source software, and a trademark of Lysand gGmbH.",
"Versia is free, open-source software, and a trademark of Versia gGmbH.",
"This is not a Mastodon instance.",
);
newFileContents = newFileContents.replaceAll(
"joinmastodon.org",
"lysand.org",
"versia.pub",
);
return newFileContents;

View file

@ -1,9 +1,9 @@
{
"name": "@lysand-org/kit",
"name": "@versia-org/kit",
"module": "index.ts",
"type": "module",
"version": "0.0.0",
"description": "Framework for building Lysand Server plugins",
"description": "Framework for building Versia Server plugins",
"author": {
"email": "contact@cpluspatch.com",
"name": "CPlusPatch",

View file

@ -18,7 +18,7 @@ export class Plugin<ConfigSchema extends z.ZodTypeAny> {
}
/**
* Loads the plugin's configuration from the Lysand Server configuration file.
* Loads the plugin's configuration from the Versia Server configuration file.
* This will be called when the plugin is loaded.
* @param config Values the user has set in the configuration file.
*/
@ -65,7 +65,7 @@ export class PluginConfigManager<Schema extends z.ZodTypeAny> {
}
/**
* Loads the configuration from the Lysand Server configuration file.
* Loads the configuration from the Versia Server configuration file.
* This will be called when the plugin is loaded.
* @param config Values the user has set in the configuration file.
*/