mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
refactor(api): 🏷️ Replace API types with those from @lysand-org/client
This commit is contained in:
parent
99b8c35f7b
commit
106e34848a
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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" })
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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({
|
||||||
|
|
|
||||||
|
|
@ -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: {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 () => {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 () => {
|
||||||
|
|
|
||||||
|
|
@ -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 () => {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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()) {
|
||||||
|
|
|
||||||
|
|
@ -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()) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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! <script>alert('Hello, world!');</script></p>",
|
"<p>Hi! <script>alert('Hello, world!');</script></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 <script>alert('Hello, world!');</script>",
|
"uwu <script>alert('Hello, world!');</script>",
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type Activity = {
|
|
||||||
week: string;
|
|
||||||
statuses: string;
|
|
||||||
logins: string;
|
|
||||||
registrations: string;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export type Application = {
|
|
||||||
name: string;
|
|
||||||
website?: string | null;
|
|
||||||
vapid_key?: string | null;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
import type { Status } from "./status";
|
|
||||||
|
|
||||||
export type Context = {
|
|
||||||
ancestors: Status[];
|
|
||||||
descendants: Status[];
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export type Emoji = {
|
|
||||||
shortcode: string;
|
|
||||||
static_url: string;
|
|
||||||
url: string;
|
|
||||||
visible_in_picker: boolean;
|
|
||||||
category?: string;
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type FeaturedTag = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
statuses_count: number;
|
|
||||||
last_status_at: string;
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type Field = {
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
verified_at?: string | null;
|
|
||||||
verified?: boolean | false;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
@ -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[];
|
|
||||||
};
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export type History = {
|
|
||||||
day: string;
|
|
||||||
uses: number;
|
|
||||||
accounts: number;
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export type IdentityProof = {
|
|
||||||
provider: string;
|
|
||||||
provider_username: string;
|
|
||||||
updated_at: string;
|
|
||||||
proof_url: string;
|
|
||||||
profile_url: string;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export type List = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
replies_policy: RepliesPolicy | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RepliesPolicy = "followed" | "list" | "none";
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type Mention = {
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
url: string;
|
|
||||||
acct: string;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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[];
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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";
|
|
||||||
|
|
@ -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[];
|
|
||||||
};
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export type Role = {
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -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[];
|
|
||||||
};
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export type Stats = {
|
|
||||||
user_count: number;
|
|
||||||
status_count: number;
|
|
||||||
domain_count: number;
|
|
||||||
};
|
|
||||||
|
|
@ -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";
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export type StatusSource = {
|
|
||||||
id: string;
|
|
||||||
text: string;
|
|
||||||
spoiler_text: string;
|
|
||||||
};
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import type { History } from "./history";
|
|
||||||
|
|
||||||
export type Tag = {
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
history: History[];
|
|
||||||
following?: boolean;
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type Token = {
|
|
||||||
access_token: string;
|
|
||||||
token_type: string;
|
|
||||||
scope: string;
|
|
||||||
created_at: number;
|
|
||||||
};
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
export type URLs = {
|
|
||||||
streaming_api: string;
|
|
||||||
};
|
|
||||||
Loading…
Reference in a new issue