2023-09-29 01:58:05 +02:00
|
|
|
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
2023-11-04 04:34:31 +01:00
|
|
|
import { ContentFormat, ServerMetadata } from "~types/lysand/Object";
|
2023-09-12 22:48:10 +02:00
|
|
|
|
2023-09-28 20:19:21 +02:00
|
|
|
/**
|
|
|
|
|
* Represents an instance in the database.
|
|
|
|
|
*/
|
2023-09-12 22:48:10 +02:00
|
|
|
@Entity({
|
|
|
|
|
name: "instances",
|
|
|
|
|
})
|
|
|
|
|
export class Instance extends BaseEntity {
|
2023-09-28 20:19:21 +02:00
|
|
|
/**
|
|
|
|
|
* The unique identifier of the instance.
|
|
|
|
|
*/
|
2023-09-12 22:48:10 +02:00
|
|
|
@PrimaryGeneratedColumn("uuid")
|
|
|
|
|
id!: string;
|
|
|
|
|
|
2023-09-28 20:19:21 +02:00
|
|
|
/**
|
2023-09-29 01:58:05 +02:00
|
|
|
* The base URL of the instance.
|
|
|
|
|
* Must not have the https:// or http:// prefix.
|
2023-09-28 20:19:21 +02:00
|
|
|
*/
|
2023-09-29 01:58:05 +02:00
|
|
|
@Column("varchar")
|
|
|
|
|
base_url!: string;
|
2023-09-12 22:48:10 +02:00
|
|
|
|
2023-09-28 20:19:21 +02:00
|
|
|
/**
|
2023-11-04 04:34:31 +01:00
|
|
|
* The name of the instance.
|
|
|
|
|
*/
|
|
|
|
|
@Column("varchar")
|
|
|
|
|
name!: string;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The description of the instance.
|
2023-09-28 20:19:21 +02:00
|
|
|
*/
|
2023-11-04 04:34:31 +01:00
|
|
|
@Column("varchar")
|
|
|
|
|
version!: string;
|
2023-09-29 01:58:05 +02:00
|
|
|
|
|
|
|
|
/**
|
2023-11-04 04:34:31 +01:00
|
|
|
* The logo of the instance.
|
2023-09-29 01:58:05 +02:00
|
|
|
*/
|
|
|
|
|
@Column("jsonb")
|
2023-11-04 04:34:31 +01:00
|
|
|
logo?: ContentFormat[];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The banner of the instance.
|
|
|
|
|
*/
|
|
|
|
|
banner?: ContentFormat[];
|
2023-09-29 01:58:05 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds an instance to the database if it doesn't already exist.
|
|
|
|
|
* @param url
|
|
|
|
|
* @returns Either the database instance if it already exists, or a newly created instance.
|
|
|
|
|
*/
|
|
|
|
|
static async addIfNotExists(url: string): Promise<Instance> {
|
|
|
|
|
const origin = new URL(url).origin;
|
|
|
|
|
const hostname = new URL(url).hostname;
|
|
|
|
|
|
|
|
|
|
const found = await Instance.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
base_url: hostname,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (found) return found;
|
|
|
|
|
|
|
|
|
|
const instance = new Instance();
|
|
|
|
|
|
|
|
|
|
instance.base_url = hostname;
|
|
|
|
|
|
|
|
|
|
// Fetch the instance configuration
|
2023-11-04 04:34:31 +01:00
|
|
|
const metadata = (await fetch(`${origin}/.well-known/lysand`).then(
|
2023-09-29 01:58:05 +02:00
|
|
|
res => res.json()
|
2023-11-04 04:34:31 +01:00
|
|
|
)) as Partial<ServerMetadata>;
|
|
|
|
|
|
|
|
|
|
if (metadata.type !== "ServerMetadata") {
|
|
|
|
|
throw new Error("Invalid instance metadata");
|
2023-09-29 01:58:05 +02:00
|
|
|
}
|
|
|
|
|
|
2023-11-04 04:34:31 +01:00
|
|
|
if (!(metadata.name && metadata.version)) {
|
|
|
|
|
throw new Error("Invalid instance metadata");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instance.name = metadata.name;
|
|
|
|
|
instance.version = metadata.version;
|
|
|
|
|
instance.logo = metadata.logo;
|
|
|
|
|
instance.banner = metadata.banner;
|
2023-09-29 01:58:05 +02:00
|
|
|
|
|
|
|
|
await instance.save();
|
|
|
|
|
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
2023-09-13 02:29:13 +02:00
|
|
|
}
|