refactor(api): 🏷️ Replace API types with those from @lysand-org/client

This commit is contained in:
Jesse Wierzbinski 2024-06-28 20:36:15 -10:00
parent 99b8c35f7b
commit 106e34848a
No known key found for this signature in database
81 changed files with 171 additions and 690 deletions

View file

@ -6,7 +6,6 @@ Lysand Server `0.7.0` is backwards compatible with `0.6.0`. However, some new fe
## Features ## Features
- Switched over to [**`@lysand-org/federation`**](https://github.com/lysand-org/api), our new federation library, for the federation logic.
- Upgrade Bun to `1.1.17`. This brings performance upgrades and better stability. - Upgrade Bun to `1.1.17`. This brings performance upgrades and better stability.
- Note deletions are now federated. - Note deletions are now federated.
- Note edits are now federated. - Note edits are now federated.

BIN
bun.lockb

Binary file not shown.

View file

@ -1,7 +1,7 @@
import type { Application as APIApplication } from "@lysand-org/client/types";
import type { InferSelectModel } from "drizzle-orm"; import type { InferSelectModel } from "drizzle-orm";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import type { Applications } from "~/drizzle/schema"; import type { Applications } from "~/drizzle/schema";
import type { Application as apiApplication } from "~/types/mastodon/application";
export type Application = InferSelectModel<typeof Applications>; export type Application = InferSelectModel<typeof Applications>;
@ -27,7 +27,7 @@ export const getFromToken = async (
* Converts this application to an API application. * Converts this application to an API application.
* @returns The API application representation of this application. * @returns The API application representation of this application.
*/ */
export const applicationToApi = (app: Application): apiApplication => { export const applicationToApi = (app: Application): APIApplication => {
return { return {
name: app.name, name: app.name,
website: app.website, website: app.website,

View file

@ -1,9 +1,9 @@
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import type { InferSelectModel } from "drizzle-orm"; import type { InferSelectModel } from "drizzle-orm";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import type { Notifications } from "~/drizzle/schema"; import type { Notifications } from "~/drizzle/schema";
import { Note } from "~/packages/database-interface/note"; import { Note } from "~/packages/database-interface/note";
import { User } from "~/packages/database-interface/user"; import { User } from "~/packages/database-interface/user";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import type { StatusWithRelations } from "./status"; import type { StatusWithRelations } from "./status";
import { import {
type UserWithRelations, type UserWithRelations,
@ -50,7 +50,7 @@ export const findManyNotifications = async (
export const notificationToApi = async ( export const notificationToApi = async (
notification: NotificationWithRelations, notification: NotificationWithRelations,
): Promise<apiNotification> => { ): Promise<ApiNotification> => {
const account = new User(notification.account); const account = new User(notification.account);
return { return {
account: account.toApi(), account: account.toApi(),

View file

@ -1,8 +1,8 @@
import type { Relationship as ApiRelationship } from "@lysand-org/client/types";
import type { InferSelectModel } from "drizzle-orm"; import type { InferSelectModel } from "drizzle-orm";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Relationships } from "~/drizzle/schema"; import { Relationships } from "~/drizzle/schema";
import type { User } from "~/packages/database-interface/user"; import type { User } from "~/packages/database-interface/user";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
export type Relationship = InferSelectModel<typeof Relationships> & { export type Relationship = InferSelectModel<typeof Relationships> & {
requestedBy: boolean; requestedBy: boolean;
@ -76,7 +76,7 @@ export const checkForBidirectionalRelationships = async (
* Converts the relationship to an API-friendly format. * Converts the relationship to an API-friendly format.
* @returns The API-friendly relationship. * @returns The API-friendly relationship.
*/ */
export const relationshipToApi = (rel: Relationship): apiRelationship => { export const relationshipToApi = (rel: Relationship): ApiRelationship => {
return { return {
blocked_by: rel.blockedBy, blocked_by: rel.blockedBy,
blocking: rel.blocking, blocking: rel.blocking,

View file

@ -1,3 +1,4 @@
import type { Source as ApiSource } from "@lysand-org/client/types";
import type { ContentFormat } from "@lysand-org/federation/types"; import type { ContentFormat } from "@lysand-org/federation/types";
import type { Challenge } from "altcha-lib/types"; import type { Challenge } from "altcha-lib/types";
import { relations, sql } from "drizzle-orm"; import { relations, sql } from "drizzle-orm";
@ -14,7 +15,6 @@ import {
uniqueIndex, uniqueIndex,
uuid, uuid,
} from "drizzle-orm/pg-core"; } from "drizzle-orm/pg-core";
import type { Source as apiSource } from "~/types/mastodon/source";
export const Challenges = pgTable("Challenges", { export const Challenges = pgTable("Challenges", {
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(), id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
@ -388,7 +388,7 @@ export const Users = pgTable(
inbox: string; inbox: string;
outbox: string; outbox: string;
}> | null>(), }> | null>(),
source: jsonb("source").notNull().$type<apiSource>(), source: jsonb("source").notNull().$type<ApiSource>(),
avatar: text("avatar").notNull(), avatar: text("avatar").notNull(),
header: text("header").notNull(), header: text("header").notNull(),
createdAt: timestamp("created_at", { precision: 3, mode: "string" }) createdAt: timestamp("created_at", { precision: 3, mode: "string" })

View file

@ -102,6 +102,7 @@
"@inquirer/input": "^2.1.11", "@inquirer/input": "^2.1.11",
"@json2csv/plainjs": "^7.0.6", "@json2csv/plainjs": "^7.0.6",
"@logtape/logtape": "npm:@jsr/logtape__logtape", "@logtape/logtape": "npm:@jsr/logtape__logtape",
"@lysand-org/client": "^0.2.3",
"@lysand-org/federation": "^2.0.0", "@lysand-org/federation": "^2.0.0",
"@oclif/core": "^4.0.7", "@oclif/core": "^4.0.7",
"@tufjs/canonical-json": "^2.0.0", "@tufjs/canonical-json": "^2.0.0",

View file

@ -1,4 +1,8 @@
import { proxyUrl } from "@/response"; import { proxyUrl } from "@/response";
import type {
AsyncAttachment as ApiAsyncAttachment,
Attachment as ApiAttachment,
} from "@lysand-org/client/types";
import type { ContentFormat } from "@lysand-org/federation/types"; import type { ContentFormat } from "@lysand-org/federation/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { MediaBackendType } from "config-manager/config.type"; import { MediaBackendType } from "config-manager/config.type";
@ -12,8 +16,6 @@ import {
} from "drizzle-orm"; } from "drizzle-orm";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Attachments } from "~/drizzle/schema"; import { Attachments } from "~/drizzle/schema";
import type { AsyncAttachment as APIAsyncAttachment } from "~/types/mastodon/async_attachment";
import type { Attachment as APIAttachment } from "~/types/mastodon/attachment";
import { BaseInterface } from "./base"; import { BaseInterface } from "./base";
export type AttachmentType = InferSelectModel<typeof Attachments>; export type AttachmentType = InferSelectModel<typeof Attachments>;
@ -136,7 +138,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
return ""; return "";
} }
public getMastodonType(): APIAttachment["type"] { public getMastodonType(): ApiAttachment["type"] {
if (this.data.mimeType.startsWith("image/")) { if (this.data.mimeType.startsWith("image/")) {
return "image"; return "image";
} }
@ -150,7 +152,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
return "unknown"; return "unknown";
} }
public toApiMeta(): APIAttachment["meta"] { public toApiMeta(): ApiAttachment["meta"] {
return { return {
width: this.data.width || undefined, width: this.data.width || undefined,
height: this.data.height || undefined, height: this.data.height || undefined,
@ -181,7 +183,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
}; };
} }
public toApi(): APIAttachment | APIAsyncAttachment { public toApi(): ApiAttachment | ApiAsyncAttachment {
return { return {
id: this.data.id, id: this.data.id,
type: this.getMastodonType(), type: this.getMastodonType(),

View file

@ -1,4 +1,5 @@
import { proxyUrl } from "@/response"; import { proxyUrl } from "@/response";
import type { Emoji as ApiEmoji } from "@lysand-org/client/types";
import type { CustomEmojiExtension } from "@lysand-org/federation/types"; import type { CustomEmojiExtension } from "@lysand-org/federation/types";
import { import {
type InferInsertModel, type InferInsertModel,
@ -12,7 +13,6 @@ import type { EmojiWithInstance } from "~/classes/functions/emoji";
import { addInstanceIfNotExists } from "~/classes/functions/instance"; import { addInstanceIfNotExists } from "~/classes/functions/instance";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Emojis, Instances } from "~/drizzle/schema"; import { Emojis, Instances } from "~/drizzle/schema";
import type { Emoji as APIEmoji } from "~/types/mastodon/emoji";
import { BaseInterface } from "./base"; import { BaseInterface } from "./base";
export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> { export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
@ -152,7 +152,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
return this.data.id; return this.data.id;
} }
public toApi(): APIEmoji { public toApi(): ApiEmoji {
return { return {
// @ts-expect-error ID is not in regular Mastodon API // @ts-expect-error ID is not in regular Mastodon API
id: this.id, id: this.id,

View file

@ -2,6 +2,10 @@ import { idValidator } from "@/api";
import { proxyUrl } from "@/response"; import { proxyUrl } from "@/response";
import { sanitizedHtmlStrip } from "@/sanitization"; import { sanitizedHtmlStrip } from "@/sanitization";
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import type {
Attachment as ApiAttachment,
Status as ApiStatus,
} from "@lysand-org/client/types";
import { EntityValidator } from "@lysand-org/federation"; import { EntityValidator } from "@lysand-org/federation";
import type { import type {
ContentFormat, ContentFormat,
@ -42,8 +46,6 @@ import {
Users, Users,
} from "~/drizzle/schema"; } from "~/drizzle/schema";
import { config } from "~/packages/config-manager"; import { config } from "~/packages/config-manager";
import type { Attachment as apiAttachment } from "~/types/mastodon/attachment";
import type { Status as APIStatus } from "~/types/mastodon/status";
import { Attachment } from "./attachment"; import { Attachment } from "./attachment";
import { BaseInterface } from "./base"; import { BaseInterface } from "./base";
import { Emoji } from "./emoji"; import { Emoji } from "./emoji";
@ -306,7 +308,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
static async fromData(data: { static async fromData(data: {
author: User; author: User;
content: ContentFormat; content: ContentFormat;
visibility: APIStatus["visibility"]; visibility: ApiStatus["visibility"];
isSensitive: boolean; isSensitive: boolean;
spoilerText: string; spoilerText: string;
emojis?: Emoji[]; emojis?: Emoji[];
@ -396,7 +398,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
async updateFromData(data: { async updateFromData(data: {
author?: User; author?: User;
content?: ContentFormat; content?: ContentFormat;
visibility?: APIStatus["visibility"]; visibility?: ApiStatus["visibility"];
isSensitive?: boolean; isSensitive?: boolean;
spoilerText?: string; spoilerText?: string;
emojis?: Emoji[]; emojis?: Emoji[];
@ -659,7 +661,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
content: "", content: "",
}, },
}, },
visibility: note.visibility as APIStatus["visibility"], visibility: note.visibility as ApiStatus["visibility"],
isSensitive: note.is_sensitive ?? false, isSensitive: note.is_sensitive ?? false,
spoilerText: note.subject ?? "", spoilerText: note.subject ?? "",
emojis, emojis,
@ -755,7 +757,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> { 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
@ -804,7 +806,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
favourited: data.liked, favourited: data.liked,
favourites_count: data.likeCount, favourites_count: data.likeCount,
media_attachments: (data.attachments ?? []).map( media_attachments: (data.attachments ?? []).map(
(a) => new Attachment(a).toApi() as apiAttachment, (a) => new Attachment(a).toApi() as ApiAttachment,
), ),
mentions: data.mentions.map((mention) => ({ mentions: data.mentions.map((mention) => ({
id: mention.id, id: mention.id,
@ -833,16 +835,19 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
spoiler_text: data.spoilerText, spoiler_text: data.spoilerText,
tags: [], tags: [],
uri: data.uri || this.getUri(), uri: data.uri || this.getUri(),
visibility: data.visibility as APIStatus["visibility"], visibility: data.visibility as ApiStatus["visibility"],
url: data.uri || this.getMastoUri(), url: data.uri || this.getMastoUri(),
bookmarked: false, bookmarked: false,
// @ts-expect-error Glitch-SOC extension
quote: data.quotingId quote: data.quotingId
? (await Note.fromId(data.quotingId, userFetching?.id).then( ? (await Note.fromId(data.quotingId, userFetching?.id).then(
(n) => n?.toApi(userFetching), (n) => n?.toApi(userFetching),
)) ?? null )) ?? null
: null, : null,
quote_id: data.quotingId || undefined, edited_at: data.updatedAt
? new Date(data.updatedAt).toISOString()
: null,
emoji_reactions: [],
plain_content: data.contentSource,
}; };
} }

View file

@ -1,4 +1,5 @@
import { proxyUrl } from "@/response"; import { proxyUrl } from "@/response";
import type { RolePermission } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { import {
type InferInsertModel, type InferInsertModel,
@ -181,7 +182,7 @@ export class Role extends BaseInterface<typeof Roles> {
return { return {
id: this.id, id: this.id,
name: this.data.name, name: this.data.name,
permissions: this.data.permissions, permissions: this.data.permissions as unknown as RolePermission[],
priority: this.data.priority, priority: this.data.priority,
description: this.data.description, description: this.data.description,
visible: this.data.visible, visible: this.data.visible,

View file

@ -3,6 +3,10 @@ import { getBestContentType, urlToContentFormat } from "@/content_types";
import { randomString } from "@/math"; import { randomString } from "@/math";
import { addUserToMeilisearch } from "@/meilisearch"; import { addUserToMeilisearch } from "@/meilisearch";
import { proxyUrl } from "@/response"; import { proxyUrl } from "@/response";
import type {
Account as ApiAccount,
Mention as ApiMention,
} from "@lysand-org/client/types";
import { EntityValidator } from "@lysand-org/federation"; import { EntityValidator } from "@lysand-org/federation";
import type { Entity, User as LysandUser } from "@lysand-org/federation/types"; import type { Entity, User as LysandUser } from "@lysand-org/federation/types";
import { import {
@ -38,8 +42,6 @@ import {
Users, Users,
} from "~/drizzle/schema"; } from "~/drizzle/schema";
import { type Config, config } from "~/packages/config-manager"; import { type Config, config } from "~/packages/config-manager";
import type { Account as apiAccount } from "~/types/mastodon/account";
import type { Mention as apiMention } from "~/types/mastodon/mention";
import { BaseInterface } from "./base"; import { BaseInterface } from "./base";
import { Emoji } from "./emoji"; import { Emoji } from "./emoji";
import type { Note } from "./note"; import type { Note } from "./note";
@ -558,7 +560,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
} }
} }
toApi(isOwnAccount = false): apiAccount { toApi(isOwnAccount = false): ApiAccount {
const user = this.data; const user = this.data;
return { return {
id: user.id, id: user.id,
@ -698,7 +700,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
}; };
} }
toMention(): apiMention { toMention(): ApiMention {
return { return {
url: this.getUri(), url: this.getUri(),
username: this.data.username, username: this.data.username,

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Relationship as ApiRelationship } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
import { meta } from "./block"; import { meta } from "./block";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
@ -65,7 +65,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.blocking).toBe(true); expect(relationship.blocking).toBe(true);
}); });
@ -86,7 +86,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.blocking).toBe(true); expect(relationship.blocking).toBe(true);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Relationship as ApiRelationship } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
import { meta } from "./follow"; import { meta } from "./follow";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
@ -73,7 +73,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.following).toBe(true); expect(relationship.following).toBe(true);
}); });
@ -96,7 +96,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.following).toBe(true); expect(relationship.following).toBe(true);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./followers"; import { meta } from "./followers";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -51,7 +51,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiAccount[]; const data = (await response.json()) as ApiAccount[];
expect(data).toBeInstanceOf(Array); expect(data).toBeInstanceOf(Array);
expect(data.length).toBe(1); expect(data.length).toBe(1);
@ -93,7 +93,7 @@ describe(meta.route, () => {
expect(response2.status).toBe(200); expect(response2.status).toBe(200);
const data = (await response2.json()) as apiAccount[]; const data = (await response2.json()) as ApiAccount[];
expect(data).toBeInstanceOf(Array); expect(data).toBeInstanceOf(Array);
expect(data.length).toBe(0); expect(data.length).toBe(0);

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./following"; import { meta } from "./following";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -51,7 +51,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiAccount[]; const data = (await response.json()) as ApiAccount[];
expect(data).toBeInstanceOf(Array); expect(data).toBeInstanceOf(Array);
expect(data.length).toBe(1); expect(data.length).toBe(1);
@ -93,7 +93,7 @@ describe(meta.route, () => {
expect(response2.status).toBe(200); expect(response2.status).toBe(200);
const data = (await response2.json()) as apiAccount[]; const data = (await response2.json()) as ApiAccount[];
expect(data).toBeInstanceOf(Array); expect(data).toBeInstanceOf(Array);
expect(data.length).toBe(0); expect(data.length).toBe(0);

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -58,7 +58,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiAccount; const data = (await response.json()) as ApiAccount;
expect(data).toMatchObject({ expect(data).toMatchObject({
id: users[0].id, id: users[0].id,
username: users[0].data.username, username: users[0].data.username,
@ -93,6 +93,6 @@ describe(meta.route, () => {
icon: null, icon: null,
}), }),
]), ]),
} satisfies apiAccount); } satisfies ApiAccount);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Relationship as ApiRelationship } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
import { meta } from "./mute"; import { meta } from "./mute";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
@ -73,7 +73,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.muting).toBe(true); expect(relationship.muting).toBe(true);
}); });
@ -96,7 +96,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.muting).toBe(true); expect(relationship.muting).toBe(true);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./statuses"; import { meta } from "./statuses";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -50,7 +50,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiStatus[]; const data = (await response.json()) as ApiStatus[];
expect(data.length).toBe(20); expect(data.length).toBe(20);
// Should have reblogs // Should have reblogs
@ -77,7 +77,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiStatus[]; const data = (await response.json()) as ApiStatus[];
expect(data.length).toBe(20); expect(data.length).toBe(20);
// Should not have reblogs // Should not have reblogs
@ -121,7 +121,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiStatus[]; const data = (await response.json()) as ApiStatus[];
expect(data.length).toBe(20); expect(data.length).toBe(20);
// Should not have replies // Should not have replies
@ -145,7 +145,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiStatus[]; const data = (await response.json()) as ApiStatus[];
expect(data.length).toBe(0); expect(data.length).toBe(0);
@ -183,7 +183,7 @@ describe(meta.route, () => {
expect(response2.status).toBe(200); expect(response2.status).toBe(200);
const data2 = (await response2.json()) as apiStatus[]; const data2 = (await response2.json()) as ApiStatus[];
expect(data2.length).toBe(1); expect(data2.length).toBe(1);
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Relationship as ApiRelationship } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
import { meta } from "./unmute"; import { meta } from "./unmute";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
@ -82,7 +82,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.muting).toBe(false); expect(relationship.muting).toBe(false);
}); });
@ -103,7 +103,7 @@ describe(meta.route, () => {
); );
expect(response.status).toBe(200); expect(response.status).toBe(200);
const relationship = (await response.json()) as apiRelationship; const relationship = (await response.json()) as ApiRelationship;
expect(relationship.muting).toBe(false); expect(relationship.muting).toBe(false);
}); });
}); });

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -29,7 +29,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiAccount[]; const data = (await response.json()) as ApiAccount[];
expect(data).toEqual( expect(data).toEqual(
expect.objectContaining({ expect.objectContaining({
id: users[0].id, id: users[0].id,

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -29,7 +29,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const data = (await response.json()) as apiAccount[]; const data = (await response.json()) as ApiAccount[];
expect(data).toEqual( expect(data).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({

View file

@ -8,7 +8,6 @@ import manifest from "~/package.json";
import { config } from "~/packages/config-manager"; import { config } from "~/packages/config-manager";
import { Note } from "~/packages/database-interface/note"; import { Note } from "~/packages/database-interface/note";
import { User } from "~/packages/database-interface/user"; import { User } from "~/packages/database-interface/user";
import type { Instance as apiInstance } from "~/types/mastodon/instance";
export const meta = applyConfig({ export const meta = applyConfig({
allowedMethods: ["GET"], allowedMethods: ["GET"],
@ -97,7 +96,7 @@ export default (app: Hono) =>
})), })),
}, },
contact_account: contactAccount?.toApi() || undefined, contact_account: contactAccount?.toApi() || undefined,
} satisfies apiInstance & { } satisfies Record<string, unknown> & {
banner: string | null; banner: string | null;
lysand_version: string; lysand_version: string;
sso: { sso: {

View file

@ -1,12 +1,12 @@
import { applyConfig, auth, handleZodError, idValidator } from "@/api"; import { applyConfig, auth, handleZodError, idValidator } from "@/api";
import { errorResponse, jsonResponse } from "@/response"; import { errorResponse, jsonResponse } from "@/response";
import { zValidator } from "@hono/zod-validator"; import { zValidator } from "@hono/zod-validator";
import type { Marker as ApiMarker } from "@lysand-org/client/types";
import { and, count, eq } from "drizzle-orm"; import { and, count, eq } from "drizzle-orm";
import type { Hono } from "hono"; import type { Hono } from "hono";
import { z } from "zod"; import { z } from "zod";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Markers, RolePermissions } from "~/drizzle/schema"; import { Markers, RolePermissions } from "~/drizzle/schema";
import type { Marker as apiMarker } from "~/types/mastodon/marker";
export const meta = applyConfig({ export const meta = applyConfig({
allowedMethods: ["GET", "POST"], allowedMethods: ["GET", "POST"],
@ -58,7 +58,7 @@ export default (app: Hono) =>
return jsonResponse({}); return jsonResponse({});
} }
const markers: apiMarker = { const markers: ApiMarker = {
home: undefined, home: undefined,
notifications: undefined, notifications: undefined,
}; };
@ -136,7 +136,7 @@ export default (app: Hono) =>
"notifications[last_read_id]": notificationsId, "notifications[last_read_id]": notificationsId,
} = context.req.valid("query"); } = context.req.valid("query");
const markers: apiMarker = { const markers: ApiMarker = {
home: undefined, home: undefined,
notifications: undefined, notifications: undefined,
}; };

View file

@ -1,11 +1,11 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import { meta } from "./dismiss"; import { meta } from "./dismiss";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
let notifications: apiNotification[] = []; let notifications: ApiNotification[] = [];
// Create some test notifications: follow, favourite, reblog, mention // Create some test notifications: follow, favourite, reblog, mention
beforeAll(async () => { beforeAll(async () => {

View file

@ -1,11 +1,11 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
let notifications: apiNotification[] = []; let notifications: ApiNotification[] = [];
// Create some test notifications: follow, favourite, reblog, mention // Create some test notifications: follow, favourite, reblog, mention
beforeAll(async () => { beforeAll(async () => {
@ -114,7 +114,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const notification = (await response.json()) as apiNotification; const notification = (await response.json()) as ApiNotification;
expect(notification).toBeDefined(); expect(notification).toBeDefined();
expect(notification.id).toBe(notifications[0].id); expect(notification.id).toBe(notifications[0].id);

View file

@ -1,11 +1,11 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
let notifications: apiNotification[] = []; let notifications: ApiNotification[] = [];
// Create some test notifications: follow, favourite, reblog, mention // Create some test notifications: follow, favourite, reblog, mention
beforeAll(async () => { beforeAll(async () => {

View file

@ -1,12 +1,12 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(2); const { users, tokens, deleteUsers } = await getTestUsers(2);
const statuses = await getTestStatuses(40, users[0]); const statuses = await getTestStatuses(40, users[0]);
let notifications: apiNotification[] = []; let notifications: ApiNotification[] = [];
// Create some test notifications // Create some test notifications
beforeAll(async () => { beforeAll(async () => {

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Notification as ApiNotification } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Notification as apiNotification } from "~/types/mastodon/notification";
import { meta } from "./index"; import { meta } from "./index";
const getFormData = (object: Record<string, string | number | boolean>) => const getFormData = (object: Record<string, string | number | boolean>) =>
@ -113,7 +113,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiNotification[]; const objects = (await response.json()) as ApiNotification[];
expect(objects.length).toBe(4); expect(objects.length).toBe(4);
for (const [index, notification] of objects.entries()) { for (const [index, notification] of objects.entries()) {
@ -165,7 +165,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiNotification[]; const objects = (await response.json()) as ApiNotification[];
expect(objects.length).toBe(2); expect(objects.length).toBe(2);
// There should be no element with a status with id of timeline[0].id // There should be no element with a status with id of timeline[0].id

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./favourite"; import { meta } from "./favourite";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -47,7 +47,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const json = (await response.json()) as apiStatus; const json = (await response.json()) as ApiStatus;
expect(json.favourited).toBe(true); expect(json.favourited).toBe(true);
expect(json.favourites_count).toBe(1); expect(json.favourites_count).toBe(1);
@ -70,7 +70,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const json = (await response.json()) as apiStatus; const json = (await response.json()) as ApiStatus;
expect(json.favourited).toBe(true); expect(json.favourited).toBe(true);
expect(json.favourites_count).toBe(1); expect(json.favourites_count).toBe(1);

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./favourited_by"; import { meta } from "./favourited_by";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -63,7 +63,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiAccount[]; const objects = (await response.json()) as ApiAccount[];
expect(objects.length).toBe(1); expect(objects.length).toBe(1);
for (const [, status] of objects.entries()) { for (const [, status] of objects.entries()) {

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Account as ApiAccount } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import { meta } from "./reblogged_by"; import { meta } from "./reblogged_by";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -63,7 +63,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiAccount[]; const objects = (await response.json()) as ApiAccount[];
expect(objects.length).toBe(1); expect(objects.length).toBe(1);
for (const [, status] of objects.entries()) { for (const [, status] of objects.entries()) {

View file

@ -1,11 +1,11 @@
import { applyConfig, auth, handleZodError } from "@/api"; import { applyConfig, auth, handleZodError } from "@/api";
import { errorResponse, jsonResponse } from "@/response"; import { errorResponse, jsonResponse } from "@/response";
import { zValidator } from "@hono/zod-validator"; import { zValidator } from "@hono/zod-validator";
import type { StatusSource as ApiStatusSource } from "@lysand-org/client/types";
import type { Hono } from "hono"; import type { Hono } from "hono";
import { z } from "zod"; import { z } from "zod";
import { RolePermissions } from "~/drizzle/schema"; import { RolePermissions } from "~/drizzle/schema";
import { Note } from "~/packages/database-interface/note"; import { Note } from "~/packages/database-interface/note";
import type { StatusSource as apiStatusSource } from "~/types/mastodon/status_source";
export const meta = applyConfig({ export const meta = applyConfig({
allowedMethods: ["GET"], allowedMethods: ["GET"],
@ -53,6 +53,6 @@ export default (app: Hono) =>
// TODO: Give real source for spoilerText // TODO: Give real source for spoilerText
spoiler_text: status.data.spoilerText, spoiler_text: status.data.spoilerText,
text: status.data.contentSource, text: status.data.contentSource,
} as apiStatusSource); } as ApiStatusSource);
}, },
); );

View file

@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./unfavourite"; import { meta } from "./unfavourite";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -83,7 +83,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const json = (await response.json()) as apiStatus; const json = (await response.json()) as ApiStatus;
expect(json.favourited).toBe(false); expect(json.favourited).toBe(false);
expect(json.favourites_count).toBe(0); expect(json.favourites_count).toBe(0);
@ -106,7 +106,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
const json = (await response.json()) as apiStatus; const json = (await response.json()) as ApiStatus;
expect(json.favourited).toBe(false); expect(json.favourited).toBe(false);
expect(json.favourites_count).toBe(0); expect(json.favourites_count).toBe(0);

View file

@ -1,10 +1,10 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { db } from "~/drizzle/db"; import { db } from "~/drizzle/db";
import { Emojis } from "~/drizzle/schema"; import { Emojis } from "~/drizzle/schema";
import { getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./index"; import { meta } from "./index";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -175,7 +175,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.content).toBe("<p>Hello, world!</p>"); expect(object.content).toBe("<p>Hello, world!</p>");
}); });
@ -200,7 +200,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.content).toBe("<p>Hello, world!</p>"); expect(object.content).toBe("<p>Hello, world!</p>");
expect(object.visibility).toBe("unlisted"); expect(object.visibility).toBe("unlisted");
@ -220,7 +220,7 @@ describe(meta.route, () => {
}), }),
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
const response2 = await sendTestRequest( const response2 = await sendTestRequest(
new Request(new URL(meta.route, config.http.base_url), { new Request(new URL(meta.route, config.http.base_url), {
@ -239,7 +239,7 @@ describe(meta.route, () => {
expect(response2.status).toBe(200); expect(response2.status).toBe(200);
expect(response2.headers.get("content-type")).toBe("application/json"); expect(response2.headers.get("content-type")).toBe("application/json");
const object2 = (await response2.json()) as apiStatus; const object2 = (await response2.json()) as ApiStatus;
expect(object2.content).toBe("<p>Hello, world again!</p>"); expect(object2.content).toBe("<p>Hello, world again!</p>");
expect(object2.in_reply_to_id).toBe(object.id); expect(object2.in_reply_to_id).toBe(object.id);
@ -259,7 +259,7 @@ describe(meta.route, () => {
}), }),
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
const response2 = await sendTestRequest( const response2 = await sendTestRequest(
new Request(new URL(meta.route, config.http.base_url), { new Request(new URL(meta.route, config.http.base_url), {
@ -278,12 +278,9 @@ describe(meta.route, () => {
expect(response2.status).toBe(200); expect(response2.status).toBe(200);
expect(response2.headers.get("content-type")).toBe("application/json"); expect(response2.headers.get("content-type")).toBe("application/json");
const object2 = (await response2.json()) as apiStatus; const object2 = (await response2.json()) as ApiStatus;
expect(object2.content).toBe("<p>Hello, world again!</p>"); expect(object2.content).toBe("<p>Hello, world again!</p>");
// @ts-expect-error Pleroma extension
expect(object2.quote_id).toBe(object.id);
// @ts-expect-error Glitch SOC extension
expect(object2.quote?.id).toBe(object.id); expect(object2.quote?.id).toBe(object.id);
}); });
@ -304,7 +301,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.emojis).toBeArrayOfSize(1); expect(object.emojis).toBeArrayOfSize(1);
expect(object.emojis[0]).toMatchObject({ expect(object.emojis[0]).toMatchObject({
@ -333,7 +330,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.mentions).toBeArrayOfSize(1); expect(object.mentions).toBeArrayOfSize(1);
expect(object.mentions[0]).toMatchObject({ expect(object.mentions[0]).toMatchObject({
@ -364,7 +361,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.mentions).toBeArrayOfSize(1); expect(object.mentions).toBeArrayOfSize(1);
expect(object.mentions[0]).toMatchObject({ expect(object.mentions[0]).toMatchObject({
@ -395,7 +392,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.content).toBe( expect(object.content).toBe(
"<p>Hi! &lt;script&gt;alert('Hello, world!');&lt;/script&gt;</p>", "<p>Hi! &lt;script&gt;alert('Hello, world!');&lt;/script&gt;</p>",
@ -423,7 +420,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
expect(object.spoiler_text).toBe( expect(object.spoiler_text).toBe(
"uwu &#x3C;script&#x3E;alert(&#x27;Hello, world!&#x27;);&#x3C;/script&#x3E;", "uwu &#x3C;script&#x3E;alert(&#x27;Hello, world!&#x27;);&#x3C;/script&#x3E;",
@ -449,7 +446,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const object = (await response.json()) as apiStatus; const object = (await response.json()) as ApiStatus;
// Proxy url is base_url/media/proxy/<base64url encoded url> // Proxy url is base_url/media/proxy/<base64url encoded url>
expect(object.content).toBe( expect(object.content).toBe(
`<p><img src="${config.http.base_url}/media/proxy/${Buffer.from( `<p><img src="${config.http.base_url}/media/proxy/${Buffer.from(

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./home"; import { meta } from "./home";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -35,7 +35,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(5); expect(objects.length).toBe(5);
}); });
@ -52,7 +52,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -102,7 +102,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -154,7 +154,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -203,7 +203,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
// There should be no element with id of timeline[0].id // There should be no element with id of timeline[0].id

View file

@ -1,7 +1,7 @@
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils"; import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
import type { Status as apiStatus } from "~/types/mastodon/status";
import { meta } from "./public"; import { meta } from "./public";
const { users, tokens, deleteUsers } = await getTestUsers(5); const { users, tokens, deleteUsers } = await getTestUsers(5);
@ -27,7 +27,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(5); expect(objects.length).toBe(5);
}); });
@ -44,7 +44,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -74,7 +74,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -104,7 +104,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects).toBeArray(); expect(objects).toBeArray();
}); });
@ -147,7 +147,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -199,7 +199,7 @@ describe(meta.route, () => {
"application/json", "application/json",
); );
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
for (const [index, status] of objects.entries()) { for (const [index, status] of objects.entries()) {
@ -247,7 +247,7 @@ describe(meta.route, () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const objects = (await response.json()) as apiStatus[]; const objects = (await response.json()) as ApiStatus[];
expect(objects.length).toBe(20); expect(objects.length).toBe(20);
// There should be no element with id of timeline[0].id // There should be no element with id of timeline[0].id

View file

@ -1,5 +1,6 @@
import { applyConfig } from "@/api"; import { applyConfig } from "@/api";
import { jsonResponse, proxyUrl } from "@/response"; import { jsonResponse, proxyUrl } from "@/response";
import type { Instance as ApiInstance } from "@lysand-org/client/types";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import type { Hono } from "hono"; import type { Hono } from "hono";
import { Users } from "~/drizzle/schema"; import { Users } from "~/drizzle/schema";
@ -59,7 +60,6 @@ export default (app: Hono) =>
}, },
accounts: { accounts: {
max_featured_tags: 100, max_featured_tags: 100,
max_note_characters: config.validation.max_bio_size,
max_displayname_characters: max_displayname_characters:
config.validation.max_displayname_size, config.validation.max_displayname_size,
avatar_size_limit: config.validation.max_avatar_size, avatar_size_limit: config.validation.max_avatar_size,
@ -71,6 +71,7 @@ export default (app: Hono) =>
max_fields: config.validation.max_field_count, max_fields: config.validation.max_field_count,
max_username_characters: max_username_characters:
config.validation.max_username_size, config.validation.max_username_size,
max_note_characters: config.validation.max_bio_size,
}, },
statuses: { statuses: {
max_characters: config.validation.max_note_size, max_characters: config.validation.max_note_size,
@ -118,9 +119,9 @@ export default (app: Hono) =>
forced: false, forced: false,
providers: config.oidc.providers.map((p) => ({ providers: config.oidc.providers.map((p) => ({
name: p.name, name: p.name,
icon: proxyUrl(p.icon) || undefined, icon: proxyUrl(p.icon) ?? "",
id: p.id, id: p.id,
})), })),
}, },
}); } satisfies ApiInstance);
}); });

View file

@ -2,10 +2,12 @@
* @deprecated * @deprecated
*/ */
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type {
Account as ApiAccount,
Relationship as ApiRelationship,
} from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "~/tests/utils"; import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "~/tests/utils";
import type { Account as apiAccount } from "~/types/mastodon/account";
import type { Relationship as apiRelationship } from "~/types/mastodon/relationship";
const baseUrl = config.http.base_url; const baseUrl = config.http.base_url;
@ -50,7 +52,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const user = (await response.json()) as apiAccount; const user = (await response.json()) as ApiAccount;
expect(user.display_name).toBe("New Display Name"); expect(user.display_name).toBe("New Display Name");
}); });
@ -77,7 +79,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiAccount; const account = (await response.json()) as ApiAccount;
expect(account.username).toBe(user.data.username); expect(account.username).toBe(user.data.username);
expect(account.bot).toBe(false); expect(account.bot).toBe(false);
@ -131,7 +133,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiRelationship; const account = (await response.json()) as ApiRelationship;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.followed_by).toBe(false); expect(account.followed_by).toBe(false);
@ -162,7 +164,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiRelationship; const account = (await response.json()) as ApiRelationship;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.blocking).toBe(true); expect(account.blocking).toBe(true);
@ -184,7 +186,7 @@ describe("API Tests", () => {
expect(response.headers.get("content-type")).toBe( expect(response.headers.get("content-type")).toBe(
"application/json", "application/json",
); );
const body = (await response.json()) as apiAccount[]; const body = (await response.json()) as ApiAccount[];
expect(Array.isArray(body)).toBe(true); expect(Array.isArray(body)).toBe(true);
expect(body.length).toBe(1); expect(body.length).toBe(1);
@ -216,7 +218,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiRelationship; const account = (await response.json()) as ApiRelationship;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.blocking).toBe(false); expect(account.blocking).toBe(false);
@ -247,7 +249,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiRelationship; const account = (await response.json()) as ApiRelationship;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.endorsed).toBe(true); expect(account.endorsed).toBe(true);
@ -278,7 +280,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiRelationship; const account = (await response.json()) as ApiRelationship;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.endorsed).toBe(false); expect(account.endorsed).toBe(false);
@ -309,7 +311,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiAccount; const account = (await response.json()) as ApiAccount;
expect(account.id).toBe(user2.id); expect(account.id).toBe(user2.id);
expect(account.note).toBe("This is a new note"); expect(account.note).toBe("This is a new note");
@ -338,7 +340,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const relationships = (await response.json()) as apiRelationship[]; const relationships = (await response.json()) as ApiRelationship[];
expect(Array.isArray(relationships)).toBe(true); expect(Array.isArray(relationships)).toBe(true);
expect(relationships.length).toBeGreaterThan(0); expect(relationships.length).toBeGreaterThan(0);
@ -373,7 +375,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiAccount; const account = (await response.json()) as ApiAccount;
expect(account.id).toBeDefined(); expect(account.id).toBeDefined();
expect(account.avatar).toBeDefined(); expect(account.avatar).toBeDefined();
@ -399,7 +401,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const account = (await response.json()) as apiAccount; const account = (await response.json()) as ApiAccount;
expect(account.id).toBeDefined(); expect(account.id).toBeDefined();
expect(account.header).toBe(""); expect(account.header).toBe("");
@ -454,7 +456,7 @@ describe("API Tests", () => {
const familiarFollowers = (await response.json()) as { const familiarFollowers = (await response.json()) as {
id: string; id: string;
accounts: apiAccount[]; accounts: ApiAccount[];
}[]; }[];
expect(Array.isArray(familiarFollowers)).toBe(true); expect(Array.isArray(familiarFollowers)).toBe(true);

View file

@ -2,20 +2,22 @@
* @deprecated * @deprecated
*/ */
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type {
AsyncAttachment as ApiAsyncAttachment,
Context as ApiContext,
Status as ApiStatus,
} from "@lysand-org/client/types";
import { config } from "config-manager"; import { config } from "config-manager";
import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "~/tests/utils"; import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "~/tests/utils";
import type { AsyncAttachment as apiAsyncAttachment } from "~/types/mastodon/async_attachment";
import type { Context as apiContext } from "~/types/mastodon/context";
import type { Status as apiStatus } from "~/types/mastodon/status";
const baseUrl = config.http.base_url; const baseUrl = config.http.base_url;
const { users, tokens, deleteUsers } = await getTestUsers(1); const { users, tokens, deleteUsers } = await getTestUsers(1);
const user = users[0]; const user = users[0];
const token = tokens[0]; const token = tokens[0];
let status: apiStatus | null = null; let status: ApiStatus | null = null;
let status2: apiStatus | null = null; let status2: ApiStatus | null = null;
let media1: apiAsyncAttachment | null = null; let media1: ApiAsyncAttachment | null = null;
describe("API Tests", () => { describe("API Tests", () => {
afterAll(async () => { afterAll(async () => {
@ -45,7 +47,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
media1 = (await response.json()) as apiAsyncAttachment; media1 = (await response.json()) as ApiAsyncAttachment;
expect(media1.id).toBeDefined(); expect(media1.id).toBeDefined();
expect(media1.type).toBe("unknown"); expect(media1.type).toBe("unknown");
@ -78,7 +80,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
status = (await response.json()) as apiStatus; status = (await response.json()) as ApiStatus;
expect(status.content).toContain("Hello, world!"); expect(status.content).toContain("Hello, world!");
expect(status.visibility).toBe("public"); expect(status.visibility).toBe("public");
expect(status.account.id).toBe(user.id); expect(status.account.id).toBe(user.id);
@ -125,7 +127,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
status2 = (await response.json()) as apiStatus; status2 = (await response.json()) as ApiStatus;
expect(status2.content).toContain("This is a reply!"); expect(status2.content).toContain("This is a reply!");
expect(status2.visibility).toBe("public"); expect(status2.visibility).toBe("public");
expect(status2.account.id).toBe(user.id); expect(status2.account.id).toBe(user.id);
@ -170,7 +172,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const statusJson = (await response.json()) as apiStatus; const statusJson = (await response.json()) as ApiStatus;
expect(statusJson.id).toBe(status?.id || ""); expect(statusJson.id).toBe(status?.id || "");
expect(statusJson.content).toBeDefined(); expect(statusJson.content).toBeDefined();
@ -220,7 +222,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const rebloggedStatus = (await response.json()) as apiStatus; const rebloggedStatus = (await response.json()) as ApiStatus;
expect(rebloggedStatus.id).toBeDefined(); expect(rebloggedStatus.id).toBeDefined();
expect(rebloggedStatus.reblog?.id).toEqual(status?.id ?? ""); expect(rebloggedStatus.reblog?.id).toEqual(status?.id ?? "");
@ -250,7 +252,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const unrebloggedStatus = (await response.json()) as apiStatus; const unrebloggedStatus = (await response.json()) as ApiStatus;
expect(unrebloggedStatus.id).toBeDefined(); expect(unrebloggedStatus.id).toBeDefined();
expect(unrebloggedStatus.reblogged).toBe(false); expect(unrebloggedStatus.reblogged).toBe(false);
@ -278,7 +280,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const context = (await response.json()) as apiContext; const context = (await response.json()) as ApiContext;
expect(context.ancestors.length).toBe(0); expect(context.ancestors.length).toBe(0);
expect(context.descendants.length).toBe(1); expect(context.descendants.length).toBe(1);
@ -310,7 +312,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const statuses = (await response.json()) as apiStatus[]; const statuses = (await response.json()) as ApiStatus[];
expect(statuses.length).toBe(2); expect(statuses.length).toBe(2);
@ -367,7 +369,7 @@ describe("API Tests", () => {
"application/json", "application/json",
); );
const updatedStatus = (await response.json()) as apiStatus; const updatedStatus = (await response.json()) as ApiStatus;
expect(updatedStatus.favourited).toBe(false); expect(updatedStatus.favourited).toBe(false);
expect(updatedStatus.favourites_count).toBe(0); expect(updatedStatus.favourites_count).toBe(0);

View file

@ -2,9 +2,11 @@
* @deprecated * @deprecated
*/ */
import { afterAll, describe, expect, test } from "bun:test"; import { afterAll, describe, expect, test } from "bun:test";
import type {
Application as ApiApplication,
Token as ApiToken,
} from "@lysand-org/client/types";
import { config } from "~/packages/config-manager"; import { config } from "~/packages/config-manager";
import type { Application as apiApplication } from "~/types/mastodon/application";
import type { Token as apiToken } from "~/types/mastodon/token";
import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "./utils"; import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "./utils";
const baseUrl = config.http.base_url; const baseUrl = config.http.base_url;
@ -13,7 +15,7 @@ let clientId: string;
let clientSecret: string; let clientSecret: string;
let code: string; let code: string;
let jwt: string; let jwt: string;
let token: apiToken; let token: ApiToken;
const { users, passwords, deleteUsers } = await getTestUsers(1); const { users, passwords, deleteUsers } = await getTestUsers(1);
afterAll(async () => { afterAll(async () => {
@ -178,7 +180,7 @@ describe("GET /api/v1/apps/verify_credentials", () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json"); expect(response.headers.get("content-type")).toBe("application/json");
const credentials = (await response.json()) as Partial<apiApplication>; const credentials = (await response.json()) as Partial<ApiApplication>;
expect(credentials.name).toBe("Test Application"); expect(credentials.name).toBe("Test Application");
expect(credentials.website).toBe("https://example.com"); expect(credentials.website).toBe("https://example.com");

View file

View file

@ -1,36 +0,0 @@
import type { Emoji } from "./emoji";
import type { Field } from "./field";
import type { LysandRole } from "./lysand";
import type { Role } from "./role";
import type { Source } from "./source";
export type Account = {
id: string;
username: string;
acct: string;
display_name: string;
locked: boolean;
discoverable?: boolean;
group: boolean | null;
noindex: boolean | null;
suspended: boolean | null;
limited: boolean | null;
created_at: string;
followers_count: number;
following_count: number;
statuses_count: number;
note: string;
url: string;
avatar: string;
avatar_static: string;
header: string;
header_static: string;
emojis: Emoji[];
moved: Account | null;
fields: Field[];
bot: boolean | null;
source?: Source;
role?: Role;
roles: LysandRole[];
mute_expires_at?: string;
};

View file

@ -1,6 +0,0 @@
export type Activity = {
week: string;
statuses: string;
logins: string;
registrations: string;
};

View file

@ -1,39 +0,0 @@
import type { Emoji } from "./emoji";
import type { StatusTag } from "./status";
export type Announcement = {
id: string;
content: string;
starts_at: string | null;
ends_at: string | null;
published: boolean;
all_day: boolean;
published_at: string;
updated_at: string | null;
read: boolean | null;
mentions: AnnouncementAccount[];
statuses: AnnouncementStatus[];
tags: StatusTag[];
emojis: Emoji[];
reactions: AnnouncementReaction[];
};
export type AnnouncementAccount = {
id: string;
username: string;
url: string;
acct: string;
};
export type AnnouncementStatus = {
id: string;
url: string;
};
export type AnnouncementReaction = {
name: string;
count: number;
me: boolean | null;
url: string | null;
static_url: string | null;
};

View file

@ -1,5 +0,0 @@
export type Application = {
name: string;
website?: string | null;
vapid_key?: string | null;
};

View file

@ -1,13 +0,0 @@
import type { Meta } from "./attachment";
export type AsyncAttachment = {
id: string;
type: "unknown" | "image" | "gifv" | "video" | "audio";
url: string | null;
remote_url: string | null;
preview_url: string;
text_url: string | null;
meta: Meta | null;
description: string | null;
blurhash: string | null;
};

View file

@ -1,47 +0,0 @@
export type Sub = {
// For Image, Gifv, and Video
width?: number;
height?: number;
size?: string;
aspect?: number;
// For Gifv and Video
frame_rate?: string;
// For Audio, Gifv, and Video
duration?: number;
bitrate?: number;
};
export type Focus = {
x: number;
y: number;
};
export type Meta = {
original?: Sub;
small?: Sub;
focus?: Focus;
length?: string;
duration?: number;
fps?: number;
size?: string;
width?: number;
height?: number;
aspect?: number;
audio_encode?: string;
audio_bitrate?: string;
audio_channel?: string;
};
export type Attachment = {
id: string;
type: "unknown" | "image" | "gifv" | "video" | "audio";
url: string;
remote_url: string | null;
preview_url: string | null;
text_url: string | null;
meta: Meta | null;
description: string | null;
blurhash: string | null;
};

View file

@ -1,16 +0,0 @@
export type Card = {
url: string;
title: string;
description: string;
type: "link" | "photo" | "video" | "rich";
image: string | null;
author_name: string | null;
author_url: string | null;
provider_name: string | null;
provider_url: string | null;
html: string | null;
width: number | null;
height: number | null;
embed_url: string | null;
blurhash: string | null;
};

View file

@ -1,6 +0,0 @@
import type { Status } from "./status";
export type Context = {
ancestors: Status[];
descendants: Status[];
};

View file

@ -1,9 +0,0 @@
import type { Account } from "./account";
import type { Status } from "./status";
export type Conversation = {
id: string;
accounts: Account[];
last_status: Status | null;
unread: boolean;
};

View file

@ -1,7 +0,0 @@
export type Emoji = {
shortcode: string;
static_url: string;
url: string;
visible_in_picker: boolean;
category?: string;
};

View file

@ -1,6 +0,0 @@
export type FeaturedTag = {
id: string;
name: string;
statuses_count: number;
last_status_at: string;
};

View file

@ -1,6 +0,0 @@
export type Field = {
name: string;
value: string;
verified_at?: string | null;
verified?: boolean | false;
};

View file

@ -1,10 +0,0 @@
export type Filter = {
id: string;
phrase: string;
context: FilterContext[];
expires_at: string | null;
irreversible: boolean;
whole_word: boolean;
};
export type FilterContext = string;

View file

@ -1,25 +0,0 @@
import type { Emoji } from "./emoji";
import type { Field } from "./field";
export type FollowRequest = {
id: number;
username: string;
acct: string;
display_name: string;
locked: boolean;
bot: boolean;
discoverable?: boolean;
group: boolean;
created_at: string;
note: string;
url: string;
avatar: string;
avatar_static: string;
header: string;
header_static: string;
followers_count: number;
following_count: number;
statuses_count: number;
emojis: Emoji[];
fields: Field[];
};

View file

@ -1,5 +0,0 @@
export type History = {
day: string;
uses: number;
accounts: number;
};

View file

@ -1,7 +0,0 @@
export type IdentityProof = {
provider: string;
provider_username: string;
updated_at: string;
proof_url: string;
profile_url: string;
};

View file

@ -1,38 +0,0 @@
import type { Account } from "./account";
import type { Stats } from "./stats";
import type { URLs } from "./urls";
export type Instance = {
uri: string;
title: string;
description: string;
email: string;
version: string;
thumbnail: string | null;
urls: URLs | null;
stats: Stats;
languages: string[];
registrations: boolean;
approval_required: boolean;
invites_enabled?: boolean;
configuration: {
statuses: {
max_characters: number;
max_media_attachments?: number;
characters_reserved_per_url?: number;
};
polls?: {
max_options: number;
max_characters_per_option: number;
min_expiration: number;
max_expiration: number;
};
};
contact_account?: Account;
rules?: InstanceRule[];
};
export type InstanceRule = {
id: string;
text: string;
};

View file

@ -1,7 +0,0 @@
export type List = {
id: string;
title: string;
replies_policy: RepliesPolicy | null;
};
export type RepliesPolicy = "followed" | "list" | "none";

View file

@ -1,11 +0,0 @@
import type { RolePermissions } from "~/drizzle/schema";
export type LysandRole = {
id: string;
name: string;
permissions: RolePermissions[];
priority: number;
description: string | null;
visible: boolean;
icon: string | null;
};

View file

@ -1,13 +0,0 @@
export type Marker = {
home?: {
last_read_id: string;
version: number;
updated_at: string;
};
notifications?: {
last_read_id: string;
version: number;
updated_at: string;
unread_count?: number;
};
};

View file

@ -1,6 +0,0 @@
export type Mention = {
id: string;
username: string;
url: string;
acct: string;
};

View file

@ -1,15 +0,0 @@
import type { Account } from "./account";
import type { Reaction } from "./reaction";
import type { Status } from "./status";
export type Notification = {
account: Account | null;
created_at: string;
id: string;
status?: Status;
reaction?: Reaction;
type: NotificationType;
target?: Account;
};
export type NotificationType = string;

View file

@ -1,14 +0,0 @@
export type Poll = {
id: string;
expires_at: string | null;
expired: boolean;
multiple: boolean;
votes_count: number;
options: PollOption[];
voted: boolean;
};
export type PollOption = {
title: string;
votes_count: number | null;
};

View file

@ -1,9 +0,0 @@
import type { StatusVisibility } from "./status";
export type Preferences = {
"posting:default:visibility": StatusVisibility;
"posting:default:sensitive": boolean;
"posting:default:language": string | null;
"reading:expand:media": "default" | "show_all" | "hide_all";
"reading:expand:spoilers": boolean;
};

View file

@ -1,14 +0,0 @@
export type Alerts = {
follow: boolean;
favourite: boolean;
mention: boolean;
reblog: boolean;
poll: boolean;
};
export type PushSubscription = {
id: string;
endpoint: string;
server_key: string;
alerts: Alerts;
};

View file

@ -1,11 +0,0 @@
import type { Account } from "./account";
export type Reaction = {
count: number;
me: boolean;
name: string;
url?: string;
static_url?: string;
accounts?: Account[];
account_ids?: string[];
};

View file

@ -1,16 +0,0 @@
export type Relationship = {
id: string;
following: boolean;
followed_by: boolean;
blocking: boolean;
blocked_by: boolean;
muting: boolean;
muting_notifications: boolean;
requested: boolean;
requested_by: boolean;
domain_blocking: boolean;
showing_reblogs: boolean;
endorsed: boolean;
notifying: boolean;
note: string | null;
};

View file

@ -1,16 +0,0 @@
import type { Account } from "./account";
export type Report = {
id: string;
action_taken: boolean;
action_taken_at: string | null;
status_ids: string[] | null;
rule_ids: string[] | null;
// These parameters don't exist in Pleroma
category: Category | null;
comment: string | null;
forwarded: boolean | null;
target_account?: Account | null;
};
export type Category = "spam" | "violation" | "other";

View file

@ -1,9 +0,0 @@
import type { Account } from "./account";
import type { Status } from "./status";
import type { Tag } from "./tag";
export type Results = {
accounts: Account[];
statuses: Status[];
hashtags: Tag[];
};

View file

@ -1,3 +0,0 @@
export type Role = {
name: string;
};

View file

@ -1,9 +0,0 @@
import type { Attachment } from "./attachment";
import type { StatusParams } from "./status_params";
export type ScheduledStatus = {
id: string;
scheduled_at: string;
params: StatusParams;
media_attachments: Attachment[] | null;
};

View file

@ -1,9 +0,0 @@
import type { Field } from "./field";
export type Source = {
privacy: string | null;
sensitive: boolean | null;
language: string | null;
note: string;
fields: Field[];
};

View file

@ -1,5 +0,0 @@
export type Stats = {
user_count: number;
status_count: number;
domain_count: number;
};

View file

@ -1,50 +0,0 @@
import type { Account } from "./account";
import type { Application } from "./application";
import type { Attachment } from "./attachment";
import type { Card } from "./card";
import type { Emoji } from "./emoji";
import type { Mention } from "./mention";
import type { Poll } from "./poll";
import type { Reaction } from "./reaction";
export type Status = {
id: string;
uri: string;
url: string;
account: Account;
in_reply_to_id: string | null;
in_reply_to_account_id: string | null;
reblog: Status | null;
content: string;
plain_content: string | null;
created_at: string;
edited_at: string | null;
emojis: Emoji[];
replies_count: number;
reblogs_count: number;
favourites_count: number;
reblogged: boolean | null;
favourited: boolean | null;
muted: boolean | null;
sensitive: boolean;
spoiler_text: string;
visibility: StatusVisibility;
media_attachments: Attachment[];
mentions: Mention[];
tags: StatusTag[];
card: Card | null;
poll: Poll | null;
application: Application | null;
language: string | null;
pinned: boolean | null;
emoji_reactions: Reaction[];
quote: boolean;
bookmarked: boolean;
};
export type StatusTag = {
name: string;
url: string;
};
export type StatusVisibility = "public" | "unlisted" | "private" | "direct";

View file

@ -1,12 +0,0 @@
import type { StatusVisibility } from "./status";
export type StatusParams = {
text: string;
in_reply_to_id: string | null;
media_ids: string[] | null;
sensitive: boolean | null;
spoiler_text: string | null;
visibility: StatusVisibility | null;
scheduled_at: string | null;
application_id: number | null;
};

View file

@ -1,5 +0,0 @@
export type StatusSource = {
id: string;
text: string;
spoiler_text: string;
};

View file

@ -1,8 +0,0 @@
import type { History } from "./history";
export type Tag = {
name: string;
url: string;
history: History[];
following?: boolean;
};

View file

@ -1,6 +0,0 @@
export type Token = {
access_token: string;
token_type: string;
scope: string;
created_at: number;
};

View file

@ -1,3 +0,0 @@
export type URLs = {
streaming_api: string;
};