mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
refactor: 🚨 Always explicitely state member accessibility
This commit is contained in:
parent
7a73b8db91
commit
54cea29ce9
|
|
@ -60,7 +60,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nursery": {
|
"nursery": {
|
||||||
"noDuplicateElseIf": "warn"
|
"noDuplicateElseIf": "warn",
|
||||||
|
"useConsistentMemberAccessibility": {
|
||||||
|
"level": "warn",
|
||||||
|
"options": {
|
||||||
|
"accessibility": "explicit"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import { BaseInterface } from "./base.ts";
|
||||||
export type ApplicationType = InferSelectModel<typeof Applications>;
|
export type ApplicationType = InferSelectModel<typeof Applications>;
|
||||||
|
|
||||||
export class Application extends BaseInterface<typeof Applications> {
|
export class Application extends BaseInterface<typeof Applications> {
|
||||||
static schema: z.ZodType<APIApplication> = z.object({
|
public static schema: z.ZodType<APIApplication> = z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
website: z.string().url().optional().nullable(),
|
website: z.string().url().optional().nullable(),
|
||||||
vapid_key: z.string().optional().nullable(),
|
vapid_key: z.string().optional().nullable(),
|
||||||
|
|
@ -23,7 +23,7 @@ export class Application extends BaseInterface<typeof Applications> {
|
||||||
scopes: z.string().optional(),
|
scopes: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Application.fromId(this.data.id);
|
const reloaded = await Application.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -95,7 +95,7 @@ export class Application extends BaseInterface<typeof Applications> {
|
||||||
return Application.fromSql(eq(Applications.clientId, clientId));
|
return Application.fromSql(eq(Applications.clientId, clientId));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newApplication: Partial<ApplicationType>,
|
newApplication: Partial<ApplicationType>,
|
||||||
): Promise<ApplicationType> {
|
): Promise<ApplicationType> {
|
||||||
await db
|
await db
|
||||||
|
|
@ -113,11 +113,11 @@ export class Application extends BaseInterface<typeof Applications> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<ApplicationType> {
|
public save(): Promise<ApplicationType> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Applications).where(inArray(Applications.id, ids));
|
await db.delete(Applications).where(inArray(Applications.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -141,7 +141,7 @@ export class Application extends BaseInterface<typeof Applications> {
|
||||||
return application;
|
return application;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { BaseInterface } from "./base.ts";
|
||||||
export type AttachmentType = InferSelectModel<typeof Attachments>;
|
export type AttachmentType = InferSelectModel<typeof Attachments>;
|
||||||
|
|
||||||
export class Attachment extends BaseInterface<typeof Attachments> {
|
export class Attachment extends BaseInterface<typeof Attachments> {
|
||||||
static schema: z.ZodType<ApiAttachment> = z.object({
|
public static schema: z.ZodType<ApiAttachment> = z.object({
|
||||||
id: z.string().uuid(),
|
id: z.string().uuid(),
|
||||||
type: z.enum(["unknown", "image", "gifv", "video", "audio"]),
|
type: z.enum(["unknown", "image", "gifv", "video", "audio"]),
|
||||||
url: z.string().url(),
|
url: z.string().url(),
|
||||||
|
|
@ -47,7 +47,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
||||||
blurhash: z.string().nullable(),
|
blurhash: z.string().nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Attachment.fromId(this.data.id);
|
const reloaded = await Attachment.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -102,7 +102,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
||||||
return found.map((s) => new Attachment(s));
|
return found.map((s) => new Attachment(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newAttachment: Partial<AttachmentType>,
|
newAttachment: Partial<AttachmentType>,
|
||||||
): Promise<AttachmentType> {
|
): Promise<AttachmentType> {
|
||||||
await db
|
await db
|
||||||
|
|
@ -120,11 +120,11 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<AttachmentType> {
|
public save(): Promise<AttachmentType> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Attachments).where(inArray(Attachments.id, ids));
|
await db.delete(Attachments).where(inArray(Attachments.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -148,7 +148,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
||||||
return attachment;
|
return attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export abstract class BaseInterface<
|
||||||
*
|
*
|
||||||
* @param data - The data for the model.
|
* @param data - The data for the model.
|
||||||
*/
|
*/
|
||||||
constructor(public data: Columns) {}
|
public constructor(public data: Columns) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current state of the model to the database.
|
* Saves the current state of the model to the database.
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ export type EmojiWithInstance = InferSelectModel<typeof Emojis> & {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
static schema = z.object({
|
public static schema = z.object({
|
||||||
shortcode: z.string(),
|
shortcode: z.string(),
|
||||||
url: z.string(),
|
url: z.string(),
|
||||||
visible_in_picker: z.boolean(),
|
visible_in_picker: z.boolean(),
|
||||||
|
|
@ -30,7 +30,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
static_url: z.string(),
|
static_url: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Emoji.fromId(this.data.id);
|
const reloaded = await Emoji.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -88,7 +88,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
return found.map((s) => new Emoji(s));
|
return found.map((s) => new Emoji(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newEmoji: Partial<EmojiWithInstance>,
|
newEmoji: Partial<EmojiWithInstance>,
|
||||||
): Promise<EmojiWithInstance> {
|
): Promise<EmojiWithInstance> {
|
||||||
await db.update(Emojis).set(newEmoji).where(eq(Emojis.id, this.id));
|
await db.update(Emojis).set(newEmoji).where(eq(Emojis.id, this.id));
|
||||||
|
|
@ -103,11 +103,11 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<EmojiWithInstance> {
|
public save(): Promise<EmojiWithInstance> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Emojis).where(inArray(Emojis.id, ids));
|
await db.delete(Emojis).where(inArray(Emojis.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -160,7 +160,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
||||||
return await Emoji.fromVersia(emojiToFetch, foundInstance?.id ?? null);
|
return await Emoji.fromVersia(emojiToFetch, foundInstance?.id ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { User } from "./user.ts";
|
||||||
export type InstanceType = InferSelectModel<typeof Instances>;
|
export type InstanceType = InferSelectModel<typeof Instances>;
|
||||||
|
|
||||||
export class Instance extends BaseInterface<typeof Instances> {
|
export class Instance extends BaseInterface<typeof Instances> {
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Instance.fromId(this.data.id);
|
const reloaded = await Instance.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -78,7 +78,9 @@ export class Instance extends BaseInterface<typeof Instances> {
|
||||||
return found.map((s) => new Instance(s));
|
return found.map((s) => new Instance(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(newInstance: Partial<InstanceType>): Promise<InstanceType> {
|
public async update(
|
||||||
|
newInstance: Partial<InstanceType>,
|
||||||
|
): Promise<InstanceType> {
|
||||||
await db
|
await db
|
||||||
.update(Instances)
|
.update(Instances)
|
||||||
.set(newInstance)
|
.set(newInstance)
|
||||||
|
|
@ -94,11 +96,11 @@ export class Instance extends BaseInterface<typeof Instances> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<InstanceType> {
|
public save(): Promise<InstanceType> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Instances).where(inArray(Instances.id, ids));
|
await db.delete(Instances).where(inArray(Instances.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -130,11 +132,11 @@ export class Instance extends BaseInterface<typeof Instances> {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchMetadata(url: string): Promise<{
|
public static async fetchMetadata(url: string): Promise<{
|
||||||
metadata: InstanceMetadata;
|
metadata: InstanceMetadata;
|
||||||
protocol: "versia" | "activitypub";
|
protocol: "versia" | "activitypub";
|
||||||
} | null> {
|
} | null> {
|
||||||
|
|
@ -315,7 +317,7 @@ export class Instance extends BaseInterface<typeof Instances> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async resolve(url: string): Promise<Instance> {
|
public static async resolve(url: string): Promise<Instance> {
|
||||||
const logger = getLogger("federation");
|
const logger = getLogger("federation");
|
||||||
const host = new URL(url).host;
|
const host = new URL(url).host;
|
||||||
|
|
||||||
|
|
@ -345,7 +347,7 @@ export class Instance extends BaseInterface<typeof Instances> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCount(): Promise<number> {
|
public static getCount(): Promise<number> {
|
||||||
return db.$count(Instances);
|
return db.$count(Instances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export type LikeType = InferSelectModel<typeof Likes> & {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Like extends BaseInterface<typeof Likes, LikeType> {
|
export class Like extends BaseInterface<typeof Likes, LikeType> {
|
||||||
static schema = z.object({
|
public static schema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
permissions: z.array(z.nativeEnum(RolePermission)),
|
permissions: z.array(z.nativeEnum(RolePermission)),
|
||||||
|
|
@ -34,7 +34,7 @@ export class Like extends BaseInterface<typeof Likes, LikeType> {
|
||||||
icon: z.string().nullable(),
|
icon: z.string().nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Like.fromId(this.data.id);
|
const reloaded = await Like.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -97,7 +97,7 @@ export class Like extends BaseInterface<typeof Likes, LikeType> {
|
||||||
return found.map((s) => new Like(s));
|
return found.map((s) => new Like(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(newRole: Partial<LikeType>): Promise<LikeType> {
|
public async update(newRole: Partial<LikeType>): Promise<LikeType> {
|
||||||
await db.update(Likes).set(newRole).where(eq(Likes.id, this.id));
|
await db.update(Likes).set(newRole).where(eq(Likes.id, this.id));
|
||||||
|
|
||||||
const updated = await Like.fromId(this.data.id);
|
const updated = await Like.fromId(this.data.id);
|
||||||
|
|
@ -109,11 +109,11 @@ export class Like extends BaseInterface<typeof Likes, LikeType> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<LikeType> {
|
public save(): Promise<LikeType> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Likes).where(inArray(Likes.id, ids));
|
await db.delete(Likes).where(inArray(Likes.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -135,7 +135,7 @@ export class Like extends BaseInterface<typeof Likes, LikeType> {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ import { User } from "./user.ts";
|
||||||
* Gives helpers to fetch notes from database in a nice format
|
* Gives helpers to fetch notes from database in a nice format
|
||||||
*/
|
*/
|
||||||
export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
static schema: z.ZodType<ApiStatus> = z.object({
|
public static schema: z.ZodType<ApiStatus> = z.object({
|
||||||
id: z.string().uuid(),
|
id: z.string().uuid(),
|
||||||
uri: z.string().url(),
|
uri: z.string().url(),
|
||||||
url: z.string().url(),
|
url: z.string().url(),
|
||||||
|
|
@ -143,14 +143,14 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
bookmarked: z.boolean(),
|
bookmarked: z.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
save(): Promise<StatusWithRelations> {
|
public save(): Promise<StatusWithRelations> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param userRequestingNoteId Used to calculate visibility of the note
|
* @param userRequestingNoteId Used to calculate visibility of the note
|
||||||
*/
|
*/
|
||||||
async reload(userRequestingNoteId?: string): Promise<void> {
|
public async reload(userRequestingNoteId?: string): Promise<void> {
|
||||||
const reloaded = await Note.fromId(this.data.id, userRequestingNoteId);
|
const reloaded = await Note.fromId(this.data.id, userRequestingNoteId);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -187,7 +187,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note)
|
* @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note)
|
||||||
* @returns The fetched note
|
* @returns The fetched note
|
||||||
*/
|
*/
|
||||||
static async fromId(
|
public static async fromId(
|
||||||
id: string | null,
|
id: string | null,
|
||||||
userRequestingNoteId?: string,
|
userRequestingNoteId?: string,
|
||||||
): Promise<Note | null> {
|
): Promise<Note | null> {
|
||||||
|
|
@ -207,7 +207,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note)
|
* @param userRequestingNoteId - The ID of the user requesting the note (used to check visibility of the note)
|
||||||
* @returns The fetched notes
|
* @returns The fetched notes
|
||||||
*/
|
*/
|
||||||
static async fromIds(
|
public static async fromIds(
|
||||||
ids: string[],
|
ids: string[],
|
||||||
userRequestingNoteId?: string,
|
userRequestingNoteId?: string,
|
||||||
): Promise<Note[]> {
|
): Promise<Note[]> {
|
||||||
|
|
@ -227,7 +227,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param userId - The ID of the user requesting the note (used to check visibility of the note)
|
* @param userId - The ID of the user requesting the note (used to check visibility of the note)
|
||||||
* @returns The fetched note
|
* @returns The fetched note
|
||||||
*/
|
*/
|
||||||
static async fromSql(
|
public static async fromSql(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
||||||
userId?: string,
|
userId?: string,
|
||||||
|
|
@ -256,7 +256,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param userId - The ID of the user requesting the note (used to check visibility of the note)
|
* @param userId - The ID of the user requesting the note (used to check visibility of the note)
|
||||||
* @returns - The fetched notes
|
* @returns - The fetched notes
|
||||||
*/
|
*/
|
||||||
static async manyFromSql(
|
public static async manyFromSql(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
||||||
limit?: number,
|
limit?: number,
|
||||||
|
|
@ -276,11 +276,11 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
return found.map((s) => new Note(s));
|
return found.map((s) => new Note(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async federateToUsers(): Promise<void> {
|
public async federateToUsers(): Promise<void> {
|
||||||
const users = await this.getUsersToFederateTo();
|
const users = await this.getUsersToFederateTo();
|
||||||
|
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
|
|
@ -296,7 +296,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* - Users that can see the note
|
* - Users that can see the note
|
||||||
* @returns The users that should be federated to
|
* @returns The users that should be federated to
|
||||||
*/
|
*/
|
||||||
async getUsersToFederateTo(): Promise<User[]> {
|
public async getUsersToFederateTo(): Promise<User[]> {
|
||||||
// Mentioned users
|
// Mentioned users
|
||||||
const mentionedUsers =
|
const mentionedUsers =
|
||||||
this.data.mentions.length > 0
|
this.data.mentions.length > 0
|
||||||
|
|
@ -339,7 +339,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
return deduplicatedUsersById;
|
return deduplicatedUsersById;
|
||||||
}
|
}
|
||||||
|
|
||||||
get author() {
|
public get author() {
|
||||||
return new User(this.data.author);
|
return new User(this.data.author);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,7 +347,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* Get the number of notes in the database (excluding remote notes)
|
* Get the number of notes in the database (excluding remote notes)
|
||||||
* @returns The number of notes in the database
|
* @returns The number of notes in the database
|
||||||
*/
|
*/
|
||||||
static async getCount(): Promise<number> {
|
public static async getCount(): Promise<number> {
|
||||||
return await db.$count(
|
return await db.$count(
|
||||||
Notes,
|
Notes,
|
||||||
sql`EXISTS (SELECT 1 FROM "Users" WHERE "Users"."id" = ${Notes.authorId} AND "Users"."instanceId" IS NULL)`,
|
sql`EXISTS (SELECT 1 FROM "Users" WHERE "Users"."id" = ${Notes.authorId} AND "Users"."instanceId" IS NULL)`,
|
||||||
|
|
@ -369,7 +369,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isRemote() {
|
public isRemote() {
|
||||||
return this.author.isRemote();
|
return this.author.isRemote();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,7 +377,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* Update a note from remote federated servers
|
* Update a note from remote federated servers
|
||||||
* @returns The updated note
|
* @returns The updated note
|
||||||
*/
|
*/
|
||||||
async updateFromRemote(): Promise<Note> {
|
public async updateFromRemote(): Promise<Note> {
|
||||||
if (!this.isRemote()) {
|
if (!this.isRemote()) {
|
||||||
throw new Error("Cannot refetch a local note (it is not remote)");
|
throw new Error("Cannot refetch a local note (it is not remote)");
|
||||||
}
|
}
|
||||||
|
|
@ -398,7 +398,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param data - The data to create the note from
|
* @param data - The data to create the note from
|
||||||
* @returns The created note
|
* @returns The created note
|
||||||
*/
|
*/
|
||||||
static async fromData(data: {
|
public static async fromData(data: {
|
||||||
author: User;
|
author: User;
|
||||||
content: ContentFormat;
|
content: ContentFormat;
|
||||||
visibility: ApiStatus["visibility"];
|
visibility: ApiStatus["visibility"];
|
||||||
|
|
@ -488,7 +488,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param data - The data to update the note from
|
* @param data - The data to update the note from
|
||||||
* @returns The updated note
|
* @returns The updated note
|
||||||
*/
|
*/
|
||||||
async updateFromData(data: {
|
public async updateFromData(data: {
|
||||||
author: User;
|
author: User;
|
||||||
content?: ContentFormat;
|
content?: ContentFormat;
|
||||||
visibility?: ApiStatus["visibility"];
|
visibility?: ApiStatus["visibility"];
|
||||||
|
|
@ -649,7 +649,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param uri - The URI of the note to resolve
|
* @param uri - The URI of the note to resolve
|
||||||
* @returns The resolved note
|
* @returns The resolved note
|
||||||
*/
|
*/
|
||||||
static async resolve(uri: string): Promise<Note | null> {
|
public static async resolve(uri: string): Promise<Note | null> {
|
||||||
// Check if note not already in database
|
// Check if note not already in database
|
||||||
const foundNote = await Note.fromSql(eq(Notes.uri, uri));
|
const foundNote = await Note.fromSql(eq(Notes.uri, uri));
|
||||||
|
|
||||||
|
|
@ -678,7 +678,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param uri - The URI of the note to save
|
* @param uri - The URI of the note to save
|
||||||
* @returns The saved note, or null if the note could not be fetched
|
* @returns The saved note, or null if the note could not be fetched
|
||||||
*/
|
*/
|
||||||
static async saveFromRemote(uri: string): Promise<Note | null> {
|
public static async saveFromRemote(uri: string): Promise<Note | null> {
|
||||||
let note: VersiaNote | null = null;
|
let note: VersiaNote | null = null;
|
||||||
|
|
||||||
if (uri) {
|
if (uri) {
|
||||||
|
|
@ -715,7 +715,10 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param author Author of the note
|
* @param author Author of the note
|
||||||
* @returns The saved note
|
* @returns The saved note
|
||||||
*/
|
*/
|
||||||
static async fromVersia(note: VersiaNote, author: User): Promise<Note> {
|
public static async fromVersia(
|
||||||
|
note: VersiaNote,
|
||||||
|
author: User,
|
||||||
|
): Promise<Note> {
|
||||||
const emojis: Emoji[] = [];
|
const emojis: Emoji[] = [];
|
||||||
const logger = getLogger("federation");
|
const logger = getLogger("federation");
|
||||||
|
|
||||||
|
|
@ -803,7 +806,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
return await Note.fromData(newData);
|
return await Note.fromData(newData);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Notes).where(inArray(Notes.id, ids));
|
await db.delete(Notes).where(inArray(Notes.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -811,7 +814,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newStatus: Partial<StatusWithRelations>,
|
newStatus: Partial<StatusWithRelations>,
|
||||||
): Promise<StatusWithRelations> {
|
): Promise<StatusWithRelations> {
|
||||||
await db.update(Notes).set(newStatus).where(eq(Notes.id, this.data.id));
|
await db.update(Notes).set(newStatus).where(eq(Notes.id, this.data.id));
|
||||||
|
|
@ -830,7 +833,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param user The user to check.
|
* @param user The user to check.
|
||||||
* @returns Whether this status is viewable by the user.
|
* @returns Whether this status is viewable by the user.
|
||||||
*/
|
*/
|
||||||
async isViewableByUser(user: User | null): Promise<boolean> {
|
public async isViewableByUser(user: User | null): Promise<boolean> {
|
||||||
if (this.author.id === user?.id) {
|
if (this.author.id === user?.id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -863,7 +866,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param userFetching - The user fetching the note (used to check if the note is favourite and such)
|
* @param userFetching - The user fetching the note (used to check if the note is favourite and such)
|
||||||
* @returns The note in the Mastodon API format
|
* @returns The note in the Mastodon API format
|
||||||
*/
|
*/
|
||||||
async toApi(userFetching?: User | null): Promise<ApiStatus> {
|
public async toApi(userFetching?: User | null): Promise<ApiStatus> {
|
||||||
const data = this.data;
|
const data = this.data;
|
||||||
|
|
||||||
// Convert mentions of local users from @username@host to @username
|
// Convert mentions of local users from @username@host to @username
|
||||||
|
|
@ -957,11 +960,14 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getUri(): string {
|
public getUri(): string {
|
||||||
return this.data.uri || localObjectUri(this.id);
|
return this.data.uri || localObjectUri(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getUri(id: string | null, uri?: string | null): string | null {
|
public static getUri(
|
||||||
|
id: string | null,
|
||||||
|
uri?: string | null,
|
||||||
|
): string | null {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -972,14 +978,14 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* Get the frontend URI of this note
|
* Get the frontend URI of this note
|
||||||
* @returns The frontend URI of this note
|
* @returns The frontend URI of this note
|
||||||
*/
|
*/
|
||||||
getMastoUri(): string {
|
public getMastoUri(): string {
|
||||||
return new URL(
|
return new URL(
|
||||||
`/@${this.author.data.username}/${this.id}`,
|
`/@${this.author.data.username}/${this.id}`,
|
||||||
config.http.base_url,
|
config.http.base_url,
|
||||||
).toString();
|
).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteToVersia(): VersiaDelete {
|
public deleteToVersia(): VersiaDelete {
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -996,7 +1002,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* Convert a note to the Versia format
|
* Convert a note to the Versia format
|
||||||
* @returns The note in the Versia format
|
* @returns The note in the Versia format
|
||||||
*/
|
*/
|
||||||
toVersia(): VersiaNote {
|
public toVersia(): VersiaNote {
|
||||||
const status = this.data;
|
const status = this.data;
|
||||||
return {
|
return {
|
||||||
type: "Note",
|
type: "Note",
|
||||||
|
|
@ -1045,7 +1051,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param fetcher - The user fetching the ancestors
|
* @param fetcher - The user fetching the ancestors
|
||||||
* @returns The ancestors of this post
|
* @returns The ancestors of this post
|
||||||
*/
|
*/
|
||||||
async getAncestors(fetcher: User | null): Promise<Note[]> {
|
public async getAncestors(fetcher: User | null): Promise<Note[]> {
|
||||||
const ancestors: Note[] = [];
|
const ancestors: Note[] = [];
|
||||||
|
|
||||||
let currentStatus: Note = this;
|
let currentStatus: Note = this;
|
||||||
|
|
@ -1080,7 +1086,10 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
||||||
* @param depth - The depth of the recursion (internal)
|
* @param depth - The depth of the recursion (internal)
|
||||||
* @returns The descendants of this post
|
* @returns The descendants of this post
|
||||||
*/
|
*/
|
||||||
async getDescendants(fetcher: User | null, depth = 0): Promise<Note[]> {
|
public async getDescendants(
|
||||||
|
fetcher: User | null,
|
||||||
|
depth = 0,
|
||||||
|
): Promise<Note[]> {
|
||||||
const descendants: Note[] = [];
|
const descendants: Note[] = [];
|
||||||
for (const child of await this.getReplyChildren(fetcher?.id)) {
|
for (const child of await this.getReplyChildren(fetcher?.id)) {
|
||||||
descendants.push(child);
|
descendants.push(child);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export class Relationship extends BaseInterface<
|
||||||
typeof Relationships,
|
typeof Relationships,
|
||||||
RelationshipWithOpposite
|
RelationshipWithOpposite
|
||||||
> {
|
> {
|
||||||
static schema = z.object({
|
public static schema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
blocked_by: z.boolean(),
|
blocked_by: z.boolean(),
|
||||||
blocking: z.boolean(),
|
blocking: z.boolean(),
|
||||||
|
|
@ -43,7 +43,7 @@ export class Relationship extends BaseInterface<
|
||||||
showing_reblogs: z.boolean(),
|
showing_reblogs: z.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Relationship.fromId(this.data.id);
|
const reloaded = await Relationship.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -232,7 +232,7 @@ export class Relationship extends BaseInterface<
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newRelationship: Partial<RelationshipType>,
|
newRelationship: Partial<RelationshipType>,
|
||||||
): Promise<RelationshipWithOpposite> {
|
): Promise<RelationshipWithOpposite> {
|
||||||
await db
|
await db
|
||||||
|
|
@ -250,11 +250,11 @@ export class Relationship extends BaseInterface<
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<RelationshipWithOpposite> {
|
public save(): Promise<RelationshipWithOpposite> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db
|
await db
|
||||||
.delete(Relationships)
|
.delete(Relationships)
|
||||||
|
|
@ -286,7 +286,7 @@ export class Relationship extends BaseInterface<
|
||||||
return relationship;
|
return relationship;
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { BaseInterface } from "./base.ts";
|
||||||
export type RoleType = InferSelectModel<typeof Roles>;
|
export type RoleType = InferSelectModel<typeof Roles>;
|
||||||
|
|
||||||
export class Role extends BaseInterface<typeof Roles> {
|
export class Role extends BaseInterface<typeof Roles> {
|
||||||
static schema = z.object({
|
public static schema = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
permissions: z.array(z.nativeEnum(RolePermission)),
|
permissions: z.array(z.nativeEnum(RolePermission)),
|
||||||
|
|
@ -28,7 +28,7 @@ export class Role extends BaseInterface<typeof Roles> {
|
||||||
icon: z.string().nullable(),
|
icon: z.string().nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await Role.fromId(this.data.id);
|
const reloaded = await Role.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -127,7 +127,7 @@ export class Role extends BaseInterface<typeof Roles> {
|
||||||
return found.map((s) => new Role(s));
|
return found.map((s) => new Role(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(newRole: Partial<RoleType>): Promise<RoleType> {
|
public async update(newRole: Partial<RoleType>): Promise<RoleType> {
|
||||||
await db.update(Roles).set(newRole).where(eq(Roles.id, this.id));
|
await db.update(Roles).set(newRole).where(eq(Roles.id, this.id));
|
||||||
|
|
||||||
const updated = await Role.fromId(this.data.id);
|
const updated = await Role.fromId(this.data.id);
|
||||||
|
|
@ -139,11 +139,11 @@ export class Role extends BaseInterface<typeof Roles> {
|
||||||
return updated.data;
|
return updated.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<RoleType> {
|
public save(): Promise<RoleType> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Roles).where(inArray(Roles.id, ids));
|
await db.delete(Roles).where(inArray(Roles.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -183,7 +183,7 @@ export class Role extends BaseInterface<typeof Roles> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ enum TimelineType {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Timeline<Type extends Note | User> {
|
export class Timeline<Type extends Note | User> {
|
||||||
constructor(private type: TimelineType) {}
|
public constructor(private type: TimelineType) {}
|
||||||
|
|
||||||
static getNoteTimeline(
|
public static getNoteTimeline(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
limit: number,
|
limit: number,
|
||||||
url: string,
|
url: string,
|
||||||
|
|
@ -26,7 +26,7 @@ export class Timeline<Type extends Note | User> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getUserTimeline(
|
public static getUserTimeline(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
limit: number,
|
limit: number,
|
||||||
url: string,
|
url: string,
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ import { Role } from "./role.ts";
|
||||||
* Gives helpers to fetch users from database in a nice format
|
* Gives helpers to fetch users from database in a nice format
|
||||||
*/
|
*/
|
||||||
export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
static schema: z.ZodType<ApiAccount> = z.object({
|
public static schema: z.ZodType<ApiAccount> = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
username: z.string(),
|
username: z.string(),
|
||||||
acct: z.string(),
|
acct: z.string(),
|
||||||
|
|
@ -125,7 +125,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
mute_expires_at: z.string().optional(),
|
mute_expires_at: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
public async reload(): Promise<void> {
|
||||||
const reloaded = await User.fromId(this.data.id);
|
const reloaded = await User.fromId(this.data.id);
|
||||||
|
|
||||||
if (!reloaded) {
|
if (!reloaded) {
|
||||||
|
|
@ -135,7 +135,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
this.data = reloaded.data;
|
this.data = reloaded.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromId(id: string | null): Promise<User | null> {
|
public static async fromId(id: string | null): Promise<User | null> {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -143,11 +143,11 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return await User.fromSql(eq(Users.id, id));
|
return await User.fromSql(eq(Users.id, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromIds(ids: string[]): Promise<User[]> {
|
public static async fromIds(ids: string[]): Promise<User[]> {
|
||||||
return await User.manyFromSql(inArray(Users.id, ids));
|
return await User.manyFromSql(inArray(Users.id, ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromSql(
|
public static async fromSql(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
orderBy: SQL<unknown> | undefined = desc(Users.id),
|
orderBy: SQL<unknown> | undefined = desc(Users.id),
|
||||||
) {
|
) {
|
||||||
|
|
@ -162,7 +162,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return new User(found[0]);
|
return new User(found[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async manyFromSql(
|
public static async manyFromSql(
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
orderBy: SQL<unknown> | undefined = desc(Users.id),
|
orderBy: SQL<unknown> | undefined = desc(Users.id),
|
||||||
limit?: number,
|
limit?: number,
|
||||||
|
|
@ -180,26 +180,26 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return found.map((s) => new User(s));
|
return found.map((s) => new User(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() {
|
public get id() {
|
||||||
return this.data.id;
|
return this.data.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
isLocal() {
|
public isLocal() {
|
||||||
return this.data.instanceId === null;
|
return this.data.instanceId === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isRemote() {
|
public isRemote() {
|
||||||
return !this.isLocal();
|
return !this.isLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
getUri() {
|
public getUri() {
|
||||||
return (
|
return (
|
||||||
this.data.uri ||
|
this.data.uri ||
|
||||||
new URL(`/users/${this.data.id}`, config.http.base_url).toString()
|
new URL(`/users/${this.data.id}`, config.http.base_url).toString()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getUri(id: string, uri: string | null, baseUrl: string) {
|
public static getUri(id: string, uri: string | null, baseUrl: string) {
|
||||||
return uri || new URL(`/users/${id}`, baseUrl).toString();
|
return uri || new URL(`/users/${id}`, baseUrl).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,7 +270,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return foundRelationship;
|
return foundRelationship;
|
||||||
}
|
}
|
||||||
|
|
||||||
async unfollow(followee: User, relationship: Relationship) {
|
public async unfollow(followee: User, relationship: Relationship) {
|
||||||
if (followee.isRemote()) {
|
if (followee.isRemote()) {
|
||||||
// TODO: This should reschedule for a later time and maybe notify the server admin if it fails too often
|
// TODO: This should reschedule for a later time and maybe notify the server admin if it fails too often
|
||||||
const { ok } = await this.federateToUser(
|
const { ok } = await this.federateToUser(
|
||||||
|
|
@ -329,7 +329,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async webFinger(
|
public static async webFinger(
|
||||||
manager: FederationRequester,
|
manager: FederationRequester,
|
||||||
username: string,
|
username: string,
|
||||||
hostname: string,
|
hostname: string,
|
||||||
|
|
@ -344,11 +344,11 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCount(): Promise<number> {
|
public static getCount(): Promise<number> {
|
||||||
return db.$count(Users, isNull(Users.instanceId));
|
return db.$count(Users, isNull(Users.instanceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getActiveInPeriod(milliseconds: number) {
|
public static async getActiveInPeriod(milliseconds: number) {
|
||||||
return (
|
return (
|
||||||
await db
|
await db
|
||||||
.select({
|
.select({
|
||||||
|
|
@ -368,7 +368,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
)[0].count;
|
)[0].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(ids?: string[]): Promise<void> {
|
public async delete(ids?: string[]): Promise<void> {
|
||||||
if (Array.isArray(ids)) {
|
if (Array.isArray(ids)) {
|
||||||
await db.delete(Users).where(inArray(Users.id, ids));
|
await db.delete(Users).where(inArray(Users.id, ids));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -376,7 +376,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async resetPassword() {
|
public async resetPassword() {
|
||||||
const resetToken = randomString(32, "hex");
|
const resetToken = randomString(32, "hex");
|
||||||
|
|
||||||
await this.update({
|
await this.update({
|
||||||
|
|
@ -386,7 +386,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return resetToken;
|
return resetToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
async pin(note: Note) {
|
public async pin(note: Note) {
|
||||||
return (
|
return (
|
||||||
await db
|
await db
|
||||||
.insert(UserToPinnedNotes)
|
.insert(UserToPinnedNotes)
|
||||||
|
|
@ -398,7 +398,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
)[0];
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async unpin(note: Note) {
|
public async unpin(note: Note) {
|
||||||
return (
|
return (
|
||||||
await db
|
await db
|
||||||
.delete(UserToPinnedNotes)
|
.delete(UserToPinnedNotes)
|
||||||
|
|
@ -412,7 +412,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
)[0];
|
)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
save(): Promise<UserWithRelations> {
|
public save(): Promise<UserWithRelations> {
|
||||||
return this.update(this.data);
|
return this.update(this.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,7 +534,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFromRemote(): Promise<User> {
|
public async updateFromRemote(): Promise<User> {
|
||||||
if (!this.isRemote()) {
|
if (!this.isRemote()) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Cannot refetch a local user (they are not remote)",
|
"Cannot refetch a local user (they are not remote)",
|
||||||
|
|
@ -548,7 +548,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async saveFromRemote(uri: string): Promise<User> {
|
public static async saveFromRemote(uri: string): Promise<User> {
|
||||||
if (!URL.canParse(uri)) {
|
if (!URL.canParse(uri)) {
|
||||||
throw new Error(`Invalid URI: ${uri}`);
|
throw new Error(`Invalid URI: ${uri}`);
|
||||||
}
|
}
|
||||||
|
|
@ -618,7 +618,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return finalUser;
|
return finalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromVersia(
|
public static async fromVersia(
|
||||||
user: VersiaUser,
|
user: VersiaUser,
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
): Promise<User> {
|
): Promise<User> {
|
||||||
|
|
@ -686,7 +686,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async resolve(uri: string): Promise<User | null> {
|
public static async resolve(uri: string): Promise<User | null> {
|
||||||
// Check if user not already in database
|
// Check if user not already in database
|
||||||
const foundUser = await User.fromSql(eq(Users.uri, uri));
|
const foundUser = await User.fromSql(eq(Users.uri, uri));
|
||||||
|
|
||||||
|
|
@ -715,7 +715,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
* @param config The config to use
|
* @param config The config to use
|
||||||
* @returns The raw URL for the user's avatar
|
* @returns The raw URL for the user's avatar
|
||||||
*/
|
*/
|
||||||
getAvatarUrl(config: Config) {
|
public getAvatarUrl(config: Config) {
|
||||||
if (!this.data.avatar) {
|
if (!this.data.avatar) {
|
||||||
return (
|
return (
|
||||||
config.defaults.avatar ||
|
config.defaults.avatar ||
|
||||||
|
|
@ -725,7 +725,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return this.data.avatar;
|
return this.data.avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async generateKeys() {
|
public static async generateKeys() {
|
||||||
const keys = await crypto.subtle.generateKey("Ed25519", true, [
|
const keys = await crypto.subtle.generateKey("Ed25519", true, [
|
||||||
"sign",
|
"sign",
|
||||||
"verify",
|
"verify",
|
||||||
|
|
@ -747,7 +747,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromDataLocal(data: {
|
public static async fromDataLocal(data: {
|
||||||
username: string;
|
username: string;
|
||||||
display_name?: string;
|
display_name?: string;
|
||||||
password: string | undefined;
|
password: string | undefined;
|
||||||
|
|
@ -807,24 +807,28 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
* @param config The config to use
|
* @param config The config to use
|
||||||
* @returns The raw URL for the user's header
|
* @returns The raw URL for the user's header
|
||||||
*/
|
*/
|
||||||
getHeaderUrl(config: Config) {
|
public getHeaderUrl(config: Config) {
|
||||||
if (!this.data.header) {
|
if (!this.data.header) {
|
||||||
return config.defaults.header || "";
|
return config.defaults.header || "";
|
||||||
}
|
}
|
||||||
return this.data.header;
|
return this.data.header;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAcct() {
|
public getAcct() {
|
||||||
return this.isLocal()
|
return this.isLocal()
|
||||||
? this.data.username
|
? this.data.username
|
||||||
: `${this.data.username}@${this.data.instance?.baseUrl}`;
|
: `${this.data.username}@${this.data.instance?.baseUrl}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getAcct(isLocal: boolean, username: string, baseUrl?: string) {
|
public static getAcct(
|
||||||
|
isLocal: boolean,
|
||||||
|
username: string,
|
||||||
|
baseUrl?: string,
|
||||||
|
) {
|
||||||
return isLocal ? username : `${username}@${baseUrl}`;
|
return isLocal ? username : `${username}@${baseUrl}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
public async update(
|
||||||
newUser: Partial<UserWithRelations>,
|
newUser: Partial<UserWithRelations>,
|
||||||
): Promise<UserWithRelations> {
|
): Promise<UserWithRelations> {
|
||||||
await db.update(Users).set(newUser).where(eq(Users.id, this.id));
|
await db.update(Users).set(newUser).where(eq(Users.id, this.id));
|
||||||
|
|
@ -865,7 +869,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
* @param signatureMethod HTTP method to embed in signature (default: POST)
|
* @param signatureMethod HTTP method to embed in signature (default: POST)
|
||||||
* @returns The signed string and headers to send with the request
|
* @returns The signed string and headers to send with the request
|
||||||
*/
|
*/
|
||||||
async sign(
|
public async sign(
|
||||||
entity: KnownEntity | Collection,
|
entity: KnownEntity | Collection,
|
||||||
signatureUrl: string | URL,
|
signatureUrl: string | URL,
|
||||||
signatureMethod: HttpVerb = "POST",
|
signatureMethod: HttpVerb = "POST",
|
||||||
|
|
@ -902,7 +906,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
*
|
*
|
||||||
* @returns The requester
|
* @returns The requester
|
||||||
*/
|
*/
|
||||||
static async getFederationRequester(): Promise<FederationRequester> {
|
public static async getFederationRequester(): Promise<FederationRequester> {
|
||||||
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
||||||
config.instance.keys.private,
|
config.instance.keys.private,
|
||||||
config.http.base_url,
|
config.http.base_url,
|
||||||
|
|
@ -916,7 +920,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
*
|
*
|
||||||
* @returns The requester
|
* @returns The requester
|
||||||
*/
|
*/
|
||||||
async getFederationRequester(): Promise<FederationRequester> {
|
public async getFederationRequester(): Promise<FederationRequester> {
|
||||||
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
||||||
this.data.privateKey ?? "",
|
this.data.privateKey ?? "",
|
||||||
this.getUri(),
|
this.getUri(),
|
||||||
|
|
@ -930,7 +934,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
*
|
*
|
||||||
* @param entity Entity to federate
|
* @param entity Entity to federate
|
||||||
*/
|
*/
|
||||||
async federateToFollowers(entity: KnownEntity): Promise<void> {
|
public async federateToFollowers(entity: KnownEntity): Promise<void> {
|
||||||
// Get followers
|
// Get followers
|
||||||
const followers = await User.manyFromSql(
|
const followers = await User.manyFromSql(
|
||||||
and(
|
and(
|
||||||
|
|
@ -951,7 +955,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
* @param user User to federate to
|
* @param user User to federate to
|
||||||
* @returns Whether the federation was successful
|
* @returns Whether the federation was successful
|
||||||
*/
|
*/
|
||||||
async federateToUser(
|
public async federateToUser(
|
||||||
entity: KnownEntity,
|
entity: KnownEntity,
|
||||||
user: User,
|
user: User,
|
||||||
): Promise<{ ok: boolean }> {
|
): Promise<{ ok: boolean }> {
|
||||||
|
|
@ -985,7 +989,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
toApi(isOwnAccount = false): ApiAccount {
|
public toApi(isOwnAccount = false): ApiAccount {
|
||||||
const user = this.data;
|
const user = this.data;
|
||||||
return {
|
return {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
|
|
@ -1055,7 +1059,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toVersia(): VersiaUser {
|
public toVersia(): VersiaUser {
|
||||||
if (this.isRemote()) {
|
if (this.isRemote()) {
|
||||||
throw new Error("Cannot convert remote user to Versia format");
|
throw new Error("Cannot convert remote user to Versia format");
|
||||||
}
|
}
|
||||||
|
|
@ -1132,7 +1136,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toMention(): ApiMention {
|
public toMention(): ApiMention {
|
||||||
return {
|
return {
|
||||||
url: this.getUri(),
|
url: this.getUri(),
|
||||||
username: this.data.username,
|
username: this.data.username,
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export class InboxProcessor {
|
||||||
* @param logger LogTape logger instance.
|
* @param logger LogTape logger instance.
|
||||||
* @param requestIp Request IP address. Grabs it from the Hono context if not provided.
|
* @param requestIp Request IP address. Grabs it from the Hono context if not provided.
|
||||||
*/
|
*/
|
||||||
constructor(
|
public constructor(
|
||||||
private context: Context,
|
private context: Context,
|
||||||
private body: Entity,
|
private body: Entity,
|
||||||
private sender: User,
|
private sender: User,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export class DiskMediaDriver implements MediaDriver {
|
||||||
* Creates a new DiskMediaDriver instance.
|
* Creates a new DiskMediaDriver instance.
|
||||||
* @param config - The configuration object.
|
* @param config - The configuration object.
|
||||||
*/
|
*/
|
||||||
constructor(private config: Config) {}
|
public constructor(private config: Config) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export class S3MediaDriver implements MediaDriver {
|
||||||
* Creates a new S3MediaDriver instance.
|
* Creates a new S3MediaDriver instance.
|
||||||
* @param config - The configuration object.
|
* @param config - The configuration object.
|
||||||
*/
|
*/
|
||||||
constructor(config: Config) {
|
public constructor(config: Config) {
|
||||||
this.s3Client = new S3Client({
|
this.s3Client = new S3Client({
|
||||||
endPoint: config.s3.endpoint,
|
endPoint: config.s3.endpoint,
|
||||||
useSSL: true,
|
useSSL: true,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export class MediaManager {
|
||||||
* Creates a new MediaManager instance.
|
* Creates a new MediaManager instance.
|
||||||
* @param config - The configuration object.
|
* @param config - The configuration object.
|
||||||
*/
|
*/
|
||||||
constructor(private config: Config) {
|
public constructor(private config: Config) {
|
||||||
this.driver = this.initializeDriver();
|
this.driver = this.initializeDriver();
|
||||||
this.initializePreprocessors();
|
this.initializePreprocessors();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export class ImageConversionPreprocessor implements MediaPreprocessor {
|
||||||
* Creates a new ImageConversionPreprocessor instance.
|
* Creates a new ImageConversionPreprocessor instance.
|
||||||
* @param config - The configuration object.
|
* @param config - The configuration object.
|
||||||
*/
|
*/
|
||||||
constructor(private config: Config) {}
|
public constructor(private config: Config) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export class SonicSearchManager {
|
||||||
/**
|
/**
|
||||||
* @param config Configuration for Sonic
|
* @param config Configuration for Sonic
|
||||||
*/
|
*/
|
||||||
constructor(private config: Config) {
|
public constructor(private config: Config) {
|
||||||
this.searchChannel = new SonicChannelSearch({
|
this.searchChannel = new SonicChannelSearch({
|
||||||
host: config.sonic.host,
|
host: config.sonic.host,
|
||||||
port: config.sonic.port,
|
port: config.sonic.port,
|
||||||
|
|
@ -48,7 +48,7 @@ export class SonicSearchManager {
|
||||||
/**
|
/**
|
||||||
* Connect to Sonic
|
* Connect to Sonic
|
||||||
*/
|
*/
|
||||||
async connect(silent = false): Promise<void> {
|
public async connect(silent = false): Promise<void> {
|
||||||
if (!this.config.sonic.enabled) {
|
if (!this.config.sonic.enabled) {
|
||||||
!silent && this.logger.info`Sonic search is disabled`;
|
!silent && this.logger.info`Sonic search is disabled`;
|
||||||
return;
|
return;
|
||||||
|
|
@ -125,7 +125,7 @@ export class SonicSearchManager {
|
||||||
* Add a user to Sonic
|
* Add a user to Sonic
|
||||||
* @param user User to add
|
* @param user User to add
|
||||||
*/
|
*/
|
||||||
async addUser(user: User): Promise<void> {
|
public async addUser(user: User): Promise<void> {
|
||||||
if (!this.config.sonic.enabled) {
|
if (!this.config.sonic.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +192,7 @@ export class SonicSearchManager {
|
||||||
* @param batchSize Size of each batch
|
* @param batchSize Size of each batch
|
||||||
* @param progressCallback Callback for progress updates
|
* @param progressCallback Callback for progress updates
|
||||||
*/
|
*/
|
||||||
async rebuildSearchIndexes(
|
public async rebuildSearchIndexes(
|
||||||
indexes: SonicIndexType[],
|
indexes: SonicIndexType[],
|
||||||
batchSize = 100,
|
batchSize = 100,
|
||||||
progressCallback?: (progress: number) => void,
|
progressCallback?: (progress: number) => void,
|
||||||
|
|
@ -275,7 +275,11 @@ export class SonicSearchManager {
|
||||||
* @param limit Maximum number of results
|
* @param limit Maximum number of results
|
||||||
* @param offset Offset for pagination
|
* @param offset Offset for pagination
|
||||||
*/
|
*/
|
||||||
searchAccounts(query: string, limit = 10, offset = 0): Promise<string[]> {
|
public searchAccounts(
|
||||||
|
query: string,
|
||||||
|
limit = 10,
|
||||||
|
offset = 0,
|
||||||
|
): Promise<string[]> {
|
||||||
return this.searchChannel.query(
|
return this.searchChannel.query(
|
||||||
SonicIndexType.Accounts,
|
SonicIndexType.Accounts,
|
||||||
"users",
|
"users",
|
||||||
|
|
@ -290,7 +294,11 @@ export class SonicSearchManager {
|
||||||
* @param limit Maximum number of results
|
* @param limit Maximum number of results
|
||||||
* @param offset Offset for pagination
|
* @param offset Offset for pagination
|
||||||
*/
|
*/
|
||||||
searchStatuses(query: string, limit = 10, offset = 0): Promise<string[]> {
|
public searchStatuses(
|
||||||
|
query: string,
|
||||||
|
limit = 10,
|
||||||
|
offset = 0,
|
||||||
|
): Promise<string[]> {
|
||||||
return this.searchChannel.query(
|
return this.searchChannel.query(
|
||||||
SonicIndexType.Statuses,
|
SonicIndexType.Statuses,
|
||||||
"notes",
|
"notes",
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export type ArgsType<T extends typeof Command> = Interfaces.InferredArgs<
|
||||||
export abstract class UserFinderCommand<
|
export abstract class UserFinderCommand<
|
||||||
T extends typeof BaseCommand,
|
T extends typeof BaseCommand,
|
||||||
> extends BaseCommand<typeof UserFinderCommand> {
|
> extends BaseCommand<typeof UserFinderCommand> {
|
||||||
static baseFlags = {
|
public static baseFlags = {
|
||||||
pattern: Flags.boolean({
|
pattern: Flags.boolean({
|
||||||
char: "p",
|
char: "p",
|
||||||
description:
|
description:
|
||||||
|
|
@ -48,7 +48,7 @@ export abstract class UserFinderCommand<
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static baseArgs = {
|
public static baseArgs = {
|
||||||
identifier: Args.string({
|
identifier: Args.string({
|
||||||
description:
|
description:
|
||||||
"Identifier of the user (by default this must be an address, i.e. name@host.com)",
|
"Identifier of the user (by default this must be an address, i.e. name@host.com)",
|
||||||
|
|
@ -156,7 +156,7 @@ export abstract class UserFinderCommand<
|
||||||
export abstract class EmojiFinderCommand<
|
export abstract class EmojiFinderCommand<
|
||||||
T extends typeof BaseCommand,
|
T extends typeof BaseCommand,
|
||||||
> extends BaseCommand<typeof EmojiFinderCommand> {
|
> extends BaseCommand<typeof EmojiFinderCommand> {
|
||||||
static baseFlags = {
|
public static baseFlags = {
|
||||||
pattern: Flags.boolean({
|
pattern: Flags.boolean({
|
||||||
char: "p",
|
char: "p",
|
||||||
description:
|
description:
|
||||||
|
|
@ -181,7 +181,7 @@ export abstract class EmojiFinderCommand<
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static baseArgs = {
|
public static baseArgs = {
|
||||||
identifier: Args.string({
|
identifier: Args.string({
|
||||||
description: "Identifier of the emoji (defaults to shortcode)",
|
description: "Identifier of the emoji (defaults to shortcode)",
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { BaseCommand } from "~/cli/base";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
export default class EmojiAdd extends BaseCommand<typeof EmojiAdd> {
|
export default class EmojiAdd extends BaseCommand<typeof EmojiAdd> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
shortcode: Args.string({
|
shortcode: Args.string({
|
||||||
description: "Shortcode of the emoji",
|
description: "Shortcode of the emoji",
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -20,14 +20,14 @@ export default class EmojiAdd extends BaseCommand<typeof EmojiAdd> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Adds a new emoji";
|
public static override description = "Adds a new emoji";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> baba_yassie ./emojis/baba_yassie.png",
|
"<%= config.bin %> <%= command.id %> baba_yassie ./emojis/baba_yassie.png",
|
||||||
"<%= config.bin %> <%= command.id %> baba_yassie https://example.com/emojis/baba_yassie.png",
|
"<%= config.bin %> <%= command.id %> baba_yassie https://example.com/emojis/baba_yassie.png",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {};
|
public static override flags = {};
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const { args } = await this.parse(EmojiAdd);
|
const { args } = await this.parse(EmojiAdd);
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,18 @@ import { config } from "~/packages/config-manager";
|
||||||
export default class EmojiDelete extends EmojiFinderCommand<
|
export default class EmojiDelete extends EmojiFinderCommand<
|
||||||
typeof EmojiDelete
|
typeof EmojiDelete
|
||||||
> {
|
> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
identifier: EmojiFinderCommand.baseArgs.identifier,
|
identifier: EmojiFinderCommand.baseArgs.identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Deletes an emoji";
|
public static override description = "Deletes an emoji";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> baba_yassie",
|
"<%= config.bin %> <%= command.id %> baba_yassie",
|
||||||
'<%= config.bin %> <%= command.id %> "baba\\*" --pattern',
|
'<%= config.bin %> <%= command.id %> "baba\\*" --pattern',
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
confirm: Flags.boolean({
|
confirm: Flags.boolean({
|
||||||
description:
|
description:
|
||||||
"Ask for confirmation before deleting the emoji (default yes)",
|
"Ask for confirmation before deleting the emoji (default yes)",
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,22 @@ type MetaType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class EmojiImport extends BaseCommand<typeof EmojiImport> {
|
export default class EmojiImport extends BaseCommand<typeof EmojiImport> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
path: Args.string({
|
path: Args.string({
|
||||||
description: "Path to the emoji archive (can be an URL)",
|
description: "Path to the emoji archive (can be an URL)",
|
||||||
required: true,
|
required: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description =
|
public static override description =
|
||||||
"Imports emojis from a zip file (which can be fetched from a zip URL, e.g. for Pleroma emoji packs)";
|
"Imports emojis from a zip file (which can be fetched from a zip URL, e.g. for Pleroma emoji packs)";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> https://volpeon.ink/emojis/neocat/neocat.zip",
|
"<%= config.bin %> <%= command.id %> https://volpeon.ink/emojis/neocat/neocat.zip",
|
||||||
"<%= config.bin %> <%= command.id %> export.zip",
|
"<%= config.bin %> <%= command.id %> export.zip",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
confirm: Flags.boolean({
|
confirm: Flags.boolean({
|
||||||
description:
|
description:
|
||||||
"Ask for confirmation before deleting the emoji (default yes)",
|
"Ask for confirmation before deleting the emoji (default yes)",
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,16 @@ import { BaseCommand } from "~/cli/base";
|
||||||
import { formatArray } from "~/cli/utils/format";
|
import { formatArray } from "~/cli/utils/format";
|
||||||
|
|
||||||
export default class EmojiList extends BaseCommand<typeof EmojiList> {
|
export default class EmojiList extends BaseCommand<typeof EmojiList> {
|
||||||
static override args = {};
|
public static override args = {};
|
||||||
|
|
||||||
static override description = "List all emojis";
|
public static override description = "List all emojis";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> --format json --local",
|
"<%= config.bin %> <%= command.id %> --format json --local",
|
||||||
"<%= config.bin %> <%= command.id %>",
|
"<%= config.bin %> <%= command.id %>",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
format: Flags.string({
|
format: Flags.string({
|
||||||
char: "f",
|
char: "f",
|
||||||
description: "Output format",
|
description: "Output format",
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,18 @@ import { formatArray } from "~/cli/utils/format";
|
||||||
export default class FederationInstanceFetch extends BaseCommand<
|
export default class FederationInstanceFetch extends BaseCommand<
|
||||||
typeof FederationInstanceFetch
|
typeof FederationInstanceFetch
|
||||||
> {
|
> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
url: Args.string({
|
url: Args.string({
|
||||||
description: "URL of the remote instance",
|
description: "URL of the remote instance",
|
||||||
required: true,
|
required: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Fetch metadata from remote instances";
|
public static override description = "Fetch metadata from remote instances";
|
||||||
|
|
||||||
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
public static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
static override flags = {};
|
public static override flags = {};
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const { args } = await this.parse(FederationInstanceFetch);
|
const { args } = await this.parse(FederationInstanceFetch);
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,18 @@ import { BaseCommand } from "~/cli/base";
|
||||||
export default class FederationUserFetch extends BaseCommand<
|
export default class FederationUserFetch extends BaseCommand<
|
||||||
typeof FederationUserFetch
|
typeof FederationUserFetch
|
||||||
> {
|
> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
address: Args.string({
|
address: Args.string({
|
||||||
description: "Address of remote user (name@host.com)",
|
description: "Address of remote user (name@host.com)",
|
||||||
required: true,
|
required: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Fetch remote users";
|
public static override description = "Fetch remote users";
|
||||||
|
|
||||||
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
public static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
static override flags = {};
|
public static override flags = {};
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const { args } = await this.parse(FederationUserFetch);
|
const { args } = await this.parse(FederationUserFetch);
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,19 @@ import { BaseCommand } from "~/cli/base";
|
||||||
export default class FederationUserFinger extends BaseCommand<
|
export default class FederationUserFinger extends BaseCommand<
|
||||||
typeof FederationUserFinger
|
typeof FederationUserFinger
|
||||||
> {
|
> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
address: Args.string({
|
address: Args.string({
|
||||||
description: "Address of remote user (name@host.com)",
|
description: "Address of remote user (name@host.com)",
|
||||||
required: true,
|
required: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Fetch the URL of remote users via WebFinger";
|
public static override description =
|
||||||
|
"Fetch the URL of remote users via WebFinger";
|
||||||
|
|
||||||
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
public static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
static override flags = {};
|
public static override flags = {};
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const { args } = await this.parse(FederationUserFinger);
|
const { args } = await this.parse(FederationUserFinger);
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,12 @@ import chalk from "chalk";
|
||||||
import { BaseCommand } from "~/cli/base";
|
import { BaseCommand } from "~/cli/base";
|
||||||
|
|
||||||
export default class GenerateKeys extends BaseCommand<typeof GenerateKeys> {
|
export default class GenerateKeys extends BaseCommand<typeof GenerateKeys> {
|
||||||
static override args = {};
|
public static override args = {};
|
||||||
|
|
||||||
static override description = "Generates keys to use in Versia Server";
|
public static override description =
|
||||||
|
"Generates keys to use in Versia Server";
|
||||||
|
|
||||||
static override flags = {};
|
public static override flags = {};
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
const { public_key, private_key } = await User.generateKeys();
|
const { public_key, private_key } = await User.generateKeys();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { BaseCommand } from "~/cli/base";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
export default class IndexRebuild extends BaseCommand<typeof IndexRebuild> {
|
export default class IndexRebuild extends BaseCommand<typeof IndexRebuild> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
type: Args.string({
|
type: Args.string({
|
||||||
description: "Index category to rebuild",
|
description: "Index category to rebuild",
|
||||||
options: ["accounts", "statuses"],
|
options: ["accounts", "statuses"],
|
||||||
|
|
@ -13,11 +13,11 @@ export default class IndexRebuild extends BaseCommand<typeof IndexRebuild> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Rebuild search indexes";
|
public static override description = "Rebuild search indexes";
|
||||||
|
|
||||||
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
public static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
"batch-size": Flags.integer({
|
"batch-size": Flags.integer({
|
||||||
char: "b",
|
char: "b",
|
||||||
description: "Number of items to process in each batch",
|
description: "Number of items to process in each batch",
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@ import { Flags } from "@oclif/core";
|
||||||
import { BaseCommand } from "~/cli/base";
|
import { BaseCommand } from "~/cli/base";
|
||||||
|
|
||||||
export default class Start extends BaseCommand<typeof Start> {
|
export default class Start extends BaseCommand<typeof Start> {
|
||||||
static override args = {};
|
public static override args = {};
|
||||||
|
|
||||||
static override description = "Starts Versia Server";
|
public static override description = "Starts Versia Server";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> --threads 4",
|
"<%= config.bin %> <%= command.id %> --threads 4",
|
||||||
"<%= config.bin %> <%= command.id %> --all-threads",
|
"<%= config.bin %> <%= command.id %> --all-threads",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
threads: Flags.integer({
|
threads: Flags.integer({
|
||||||
char: "t",
|
char: "t",
|
||||||
description: "Number of threads to use",
|
description: "Number of threads to use",
|
||||||
|
|
|
||||||
|
|
@ -9,21 +9,21 @@ import { BaseCommand } from "~/cli/base";
|
||||||
import { formatArray } from "~/cli/utils/format";
|
import { formatArray } from "~/cli/utils/format";
|
||||||
|
|
||||||
export default class UserCreate extends BaseCommand<typeof UserCreate> {
|
export default class UserCreate extends BaseCommand<typeof UserCreate> {
|
||||||
static override args = {
|
public static override args = {
|
||||||
username: Args.string({
|
username: Args.string({
|
||||||
description: "Username",
|
description: "Username",
|
||||||
required: true,
|
required: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override description = "Creates a new user";
|
public static override description = "Creates a new user";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> johngastron --email joe@gamer.com",
|
"<%= config.bin %> <%= command.id %> johngastron --email joe@gamer.com",
|
||||||
"<%= config.bin %> <%= command.id %> bimbobaggins",
|
"<%= config.bin %> <%= command.id %> bimbobaggins",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
format: Flags.string({
|
format: Flags.string({
|
||||||
char: "f",
|
char: "f",
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,15 @@ import { UserFinderCommand } from "~/cli/classes";
|
||||||
import { formatArray } from "~/cli/utils/format";
|
import { formatArray } from "~/cli/utils/format";
|
||||||
|
|
||||||
export default class UserDelete extends UserFinderCommand<typeof UserDelete> {
|
export default class UserDelete extends UserFinderCommand<typeof UserDelete> {
|
||||||
static override description = "Deletes users";
|
public static override description = "Deletes users";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
||||||
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
||||||
'<%= config.bin %> <%= command.id %> "*badword*" --pattern --type username',
|
'<%= config.bin %> <%= command.id %> "*badword*" --pattern --type username',
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
confirm: Flags.boolean({
|
confirm: Flags.boolean({
|
||||||
description:
|
description:
|
||||||
"Ask for confirmation before deleting the user (default yes)",
|
"Ask for confirmation before deleting the user (default yes)",
|
||||||
|
|
@ -23,7 +23,7 @@ export default class UserDelete extends UserFinderCommand<typeof UserDelete> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override args = {
|
public static override args = {
|
||||||
identifier: UserFinderCommand.baseArgs.identifier,
|
identifier: UserFinderCommand.baseArgs.identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,16 @@ import { BaseCommand } from "~/cli/base";
|
||||||
import { formatArray } from "~/cli/utils/format";
|
import { formatArray } from "~/cli/utils/format";
|
||||||
|
|
||||||
export default class UserList extends BaseCommand<typeof UserList> {
|
export default class UserList extends BaseCommand<typeof UserList> {
|
||||||
static override args = {};
|
public static override args = {};
|
||||||
|
|
||||||
static override description = "List all users";
|
public static override description = "List all users";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> --format json --local",
|
"<%= config.bin %> <%= command.id %> --format json --local",
|
||||||
"<%= config.bin %> <%= command.id %>",
|
"<%= config.bin %> <%= command.id %>",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
format: Flags.string({
|
format: Flags.string({
|
||||||
char: "f",
|
char: "f",
|
||||||
description: "Output format",
|
description: "Output format",
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ import { UserFinderCommand } from "~/cli/classes";
|
||||||
import { formatArray } from "~/cli/utils/format";
|
import { formatArray } from "~/cli/utils/format";
|
||||||
|
|
||||||
export default class UserRefetch extends UserFinderCommand<typeof UserRefetch> {
|
export default class UserRefetch extends UserFinderCommand<typeof UserRefetch> {
|
||||||
static override description = "Refetch remote users";
|
public static override description = "Refetch remote users";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
||||||
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
confirm: Flags.boolean({
|
confirm: Flags.boolean({
|
||||||
description:
|
description:
|
||||||
"Ask for confirmation before refetching the user (default yes)",
|
"Ask for confirmation before refetching the user (default yes)",
|
||||||
|
|
@ -27,7 +27,7 @@ export default class UserRefetch extends UserFinderCommand<typeof UserRefetch> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override args = {
|
public static override args = {
|
||||||
identifier: UserFinderCommand.baseArgs.identifier,
|
identifier: UserFinderCommand.baseArgs.identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ import { formatArray } from "~/cli/utils/format";
|
||||||
import { config } from "~/packages/config-manager";
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
export default class UserReset extends UserFinderCommand<typeof UserReset> {
|
export default class UserReset extends UserFinderCommand<typeof UserReset> {
|
||||||
static override description = "Resets users' passwords";
|
public static override description = "Resets users' passwords";
|
||||||
|
|
||||||
static override examples = [
|
public static override examples = [
|
||||||
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
"<%= config.bin %> <%= command.id %> johngastron --type username",
|
||||||
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
"<%= config.bin %> <%= command.id %> 018ec11c-c6cb-7a67-bd20-a4c81bf42912",
|
||||||
];
|
];
|
||||||
|
|
||||||
static override flags = {
|
public static override flags = {
|
||||||
confirm: Flags.boolean({
|
confirm: Flags.boolean({
|
||||||
description:
|
description:
|
||||||
"Ask for confirmation before deleting the user (default yes)",
|
"Ask for confirmation before deleting the user (default yes)",
|
||||||
|
|
@ -32,7 +32,7 @@ export default class UserReset extends UserFinderCommand<typeof UserReset> {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
static override args = {
|
public static override args = {
|
||||||
identifier: UserFinderCommand.baseArgs.identifier,
|
identifier: UserFinderCommand.baseArgs.identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ export class Plugin<ConfigSchema extends z.ZodTypeAny> {
|
||||||
fn: (app: OpenAPIHono<HonoPluginEnv<ConfigSchema>>) => void;
|
fn: (app: OpenAPIHono<HonoPluginEnv<ConfigSchema>>) => void;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
|
|
||||||
constructor(private configSchema: ConfigSchema) {}
|
public constructor(private configSchema: ConfigSchema) {}
|
||||||
|
|
||||||
get middleware() {
|
public get middleware() {
|
||||||
// Middleware that adds the plugin's configuration to the request object
|
// Middleware that adds the plugin's configuration to the request object
|
||||||
return createMiddleware<HonoPluginEnv<ConfigSchema>>(
|
return createMiddleware<HonoPluginEnv<ConfigSchema>>(
|
||||||
async (context, next) => {
|
async (context, next) => {
|
||||||
|
|
@ -70,7 +70,7 @@ export class Plugin<ConfigSchema extends z.ZodTypeAny> {
|
||||||
this.handlers[hook] = handler;
|
this.handlers[hook] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static [Symbol.hasInstance](instance: unknown): boolean {
|
public static [Symbol.hasInstance](instance: unknown): boolean {
|
||||||
return (
|
return (
|
||||||
typeof instance === "object" &&
|
typeof instance === "object" &&
|
||||||
instance !== null &&
|
instance !== null &&
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ export type HonoEnv = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ApiRouteExports {
|
export interface ApiRouteExports {
|
||||||
meta: ApiRouteMetadata;
|
meta?: ApiRouteMetadata;
|
||||||
schemas?: {
|
schemas?: {
|
||||||
query?: z.AnyZodObject;
|
query?: z.AnyZodObject;
|
||||||
body?: z.AnyZodObject;
|
body?: z.AnyZodObject;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue