mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Remove Prisma once and for all
This commit is contained in:
parent
90d522eaa3
commit
a65249b79d
11
build.ts
11
build.ts
|
|
@ -13,7 +13,6 @@ await $`rm -rf dist && mkdir dist`;
|
|||
await Bun.build({
|
||||
entrypoints: [
|
||||
`${process.cwd()}/index.ts`,
|
||||
`${process.cwd()}/prisma.ts`,
|
||||
`${process.cwd()}/cli.ts`,
|
||||
// Force Bun to include endpoints
|
||||
...Object.values(rawRoutes),
|
||||
|
|
@ -22,7 +21,7 @@ await Bun.build({
|
|||
target: "bun",
|
||||
splitting: true,
|
||||
minify: true,
|
||||
external: ["bullmq", "@prisma/client", "frontend"],
|
||||
external: ["bullmq", "frontend"],
|
||||
}).then((output) => {
|
||||
if (!output.success) {
|
||||
console.log(output.logs);
|
||||
|
|
@ -33,14 +32,6 @@ await Bun.build({
|
|||
// I apologize for this
|
||||
await $`sed -i 's|import("node_modules/|import("./node_modules/|g' dist/*.js`;
|
||||
|
||||
// Copy generated Prisma client to dist
|
||||
await $`mkdir -p dist/node_modules/@prisma`;
|
||||
await $`cp -r ${process.cwd()}/node_modules/@prisma dist/node_modules/`;
|
||||
await $`cp -r ${process.cwd()}/node_modules/.prisma dist/node_modules`;
|
||||
await $`mkdir -p dist/node_modules/.bin`;
|
||||
await $`cp -r ${process.cwd()}/node_modules/.bin/prisma dist/node_modules/.bin`;
|
||||
await $`cp -r ${process.cwd()}/node_modules/prisma dist/node_modules/`;
|
||||
|
||||
// Copy Sharp to dist
|
||||
await $`mkdir -p dist/node_modules/@img`;
|
||||
await $`cp -r node_modules/@img/sharp-libvips-linux-* dist/node_modules/@img`;
|
||||
|
|
|
|||
22
cli.ts
22
cli.ts
|
|
@ -3,26 +3,25 @@ import { tmpdir } from "node:os";
|
|||
import { join } from "node:path";
|
||||
import { Parser } from "@json2csv/plainjs";
|
||||
import { MeiliIndexType, rebuildSearchIndexes } from "@meilisearch";
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import chalk from "chalk";
|
||||
import { CliBuilder, CliCommand } from "cli-parser";
|
||||
import Table from "cli-table";
|
||||
import { type SQL, eq, inArray, isNotNull, isNull, like } from "drizzle-orm";
|
||||
import extract from "extract-zip";
|
||||
import { MediaBackend } from "media-manager";
|
||||
import { lookup } from "mime-types";
|
||||
import { getUrl } from "~database/entities/Attachment";
|
||||
import { findFirstStatuses, findManyStatuses } from "~database/entities/Status";
|
||||
import {
|
||||
type User,
|
||||
createNewLocalUser,
|
||||
findFirstUser,
|
||||
findManyUsers,
|
||||
type User,
|
||||
} from "~database/entities/User";
|
||||
import { CliParameterType } from "~packages/cli-parser/cli-builder.type";
|
||||
import { config } from "~packages/config-manager";
|
||||
import { db } from "~drizzle/db";
|
||||
import { emoji, openIdAccount, status, user } from "~drizzle/schema";
|
||||
import { type SQL, eq, inArray, isNotNull, isNull, like } from "drizzle-orm";
|
||||
import { findFirstStatuses, findManyStatuses } from "~database/entities/Status";
|
||||
import { CliParameterType } from "~packages/cli-parser/cli-builder.type";
|
||||
import { config } from "~packages/config-manager";
|
||||
|
||||
const args = process.argv;
|
||||
|
||||
|
|
@ -949,17 +948,6 @@ const cliBuilder = new CliBuilder([
|
|||
return 1;
|
||||
}
|
||||
|
||||
const queries: Prisma.StatusWhereInput[] = [];
|
||||
|
||||
for (const field of fields) {
|
||||
queries.push({
|
||||
[field]: {
|
||||
contains: query,
|
||||
mode: caseSensitive ? "default" : "insensitive",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let instanceQuery: SQL<unknown> | undefined = isNull(
|
||||
status.instanceId,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
// import { Queue } from "bullmq";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { config } from "config-manager";
|
||||
|
||||
const client = new PrismaClient({
|
||||
datasourceUrl: `postgresql://${config.database.username}:${config.database.password}@${config.database.host}:${config.database.port}/${config.database.database}`,
|
||||
});
|
||||
|
||||
/* const federationQueue = new Queue("federation", {
|
||||
connection: {
|
||||
|
|
@ -14,5 +8,3 @@ const client = new PrismaClient({
|
|||
db: config.redis.queue.database || undefined,
|
||||
},
|
||||
}); */
|
||||
|
||||
export { client /* federationQueue */ };
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
import type { Prisma } from "@prisma/client";
|
||||
|
||||
export const userRelations: Prisma.UserInclude = {
|
||||
emojis: true,
|
||||
instance: true,
|
||||
likes: true,
|
||||
relationships: true,
|
||||
relationshipSubjects: true,
|
||||
pinnedNotes: true,
|
||||
_count: {
|
||||
select: {
|
||||
statuses: true,
|
||||
likes: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const statusAndUserRelations: Prisma.StatusInclude = {
|
||||
author: {
|
||||
include: userRelations,
|
||||
},
|
||||
application: true,
|
||||
emojis: true,
|
||||
inReplyToPost: {
|
||||
include: {
|
||||
author: {
|
||||
include: userRelations,
|
||||
},
|
||||
application: true,
|
||||
emojis: true,
|
||||
inReplyToPost: {
|
||||
include: {
|
||||
author: true,
|
||||
},
|
||||
},
|
||||
instance: true,
|
||||
mentions: true,
|
||||
pinnedBy: true,
|
||||
_count: {
|
||||
select: {
|
||||
replies: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
reblogs: true,
|
||||
attachments: true,
|
||||
instance: true,
|
||||
mentions: {
|
||||
include: userRelations,
|
||||
},
|
||||
pinnedBy: true,
|
||||
_count: {
|
||||
select: {
|
||||
replies: true,
|
||||
likes: true,
|
||||
reblogs: true,
|
||||
},
|
||||
},
|
||||
reblog: {
|
||||
include: {
|
||||
author: {
|
||||
include: userRelations,
|
||||
},
|
||||
application: true,
|
||||
emojis: true,
|
||||
inReplyToPost: {
|
||||
include: {
|
||||
author: true,
|
||||
},
|
||||
},
|
||||
instance: true,
|
||||
mentions: {
|
||||
include: userRelations,
|
||||
},
|
||||
pinnedBy: true,
|
||||
_count: {
|
||||
select: {
|
||||
replies: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
quotingPost: {
|
||||
include: {
|
||||
author: {
|
||||
include: userRelations,
|
||||
},
|
||||
application: true,
|
||||
emojis: true,
|
||||
inReplyToPost: {
|
||||
include: {
|
||||
author: true,
|
||||
},
|
||||
},
|
||||
instance: true,
|
||||
mentions: true,
|
||||
pinnedBy: true,
|
||||
_count: {
|
||||
select: {
|
||||
replies: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
likes: {
|
||||
include: {
|
||||
liker: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
3
index.ts
3
index.ts
|
|
@ -2,7 +2,6 @@ import { exists, mkdir, writeFile } from "node:fs/promises";
|
|||
import { dirname } from "node:path";
|
||||
import { connectMeili } from "@meilisearch";
|
||||
import { moduleIsEntry } from "@module";
|
||||
import { initializeRedisCache } from "@redis";
|
||||
import { config } from "config-manager";
|
||||
import { count, sql } from "drizzle-orm";
|
||||
import { LogLevel, LogManager, MultiLogManager } from "log-manager";
|
||||
|
|
@ -39,8 +38,6 @@ await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
|
|||
const isProd =
|
||||
process.env.NODE_ENV === "production" || process.argv.includes("--prod");
|
||||
|
||||
const redisCache = await initializeRedisCache();
|
||||
|
||||
if (config.meilisearch.enabled) {
|
||||
await connectMeili(dualLogger);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
"prisma": "DATABASE_URL=$(bun run prisma.ts) bunx prisma",
|
||||
"generate": "bun prisma generate",
|
||||
"benchmark:timeline": "bun run benchmarks/timelines.ts",
|
||||
"cloc": "cloc . --exclude-dir node_modules,dist",
|
||||
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs --exclude-ext sql,log",
|
||||
"cli": "bun run cli.ts"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
|
|
@ -51,14 +51,11 @@
|
|||
"@fortawesome/fontawesome-common-types",
|
||||
"@fortawesome/free-regular-svg-icons",
|
||||
"@fortawesome/free-solid-svg-icons",
|
||||
"@prisma/client",
|
||||
"@prisma/engines",
|
||||
"es5-ext",
|
||||
"esbuild",
|
||||
"json-editor-vue",
|
||||
"msgpackr-extract",
|
||||
"nuxt-app",
|
||||
"prisma",
|
||||
"sharp",
|
||||
"vue-demi"
|
||||
],
|
||||
|
|
@ -99,7 +96,6 @@
|
|||
"@aws-sdk/client-s3": "^3.461.0",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@json2csv/plainjs": "^7.0.6",
|
||||
"@prisma/client": "^5.6.0",
|
||||
"blurhash": "^2.0.5",
|
||||
"bullmq": "latest",
|
||||
"chalk": "^5.3.0",
|
||||
|
|
@ -128,9 +124,6 @@
|
|||
"next-route-matcher": "^1.0.1",
|
||||
"oauth4webapi": "^2.4.0",
|
||||
"pg": "^8.11.5",
|
||||
"prisma": "^5.6.0",
|
||||
"prisma-json-types-generator": "^3.0.4",
|
||||
"prisma-redis-middleware": "^4.8.0",
|
||||
"request-parser": "workspace:*",
|
||||
"semver": "^7.5.4",
|
||||
"sharp": "^0.33.3",
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import {
|
|||
validateAuthResponse,
|
||||
} from "oauth4webapi";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import { findFirstUser } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { token } from "~drizzle/schema";
|
||||
import { findFirstUser } from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
|
|||
|
|
@ -1,74 +1,19 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import type { Token } from "@prisma/client";
|
||||
import { config } from "config-manager";
|
||||
import { inArray } from "drizzle-orm";
|
||||
import { client } from "~database/datasource";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
createNewLocalUser,
|
||||
} from "~database/entities/User";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "~drizzle/db";
|
||||
import { application, user } from "~drizzle/schema";
|
||||
import { emoji } from "~drizzle/schema";
|
||||
import type { APIEmoji } from "~types/entities/emoji";
|
||||
import type { APIInstance } from "~types/entities/instance";
|
||||
import { sendTestRequest, wrapRelativeUrl } from "./utils";
|
||||
import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "./utils";
|
||||
|
||||
const base_url = config.http.base_url;
|
||||
|
||||
let token: Token;
|
||||
let dummyUser: UserWithRelations;
|
||||
const { tokens, deleteUsers } = await getTestUsers(1);
|
||||
|
||||
describe("API Tests", () => {
|
||||
beforeAll(async () => {
|
||||
await db.delete(user).where(inArray(user.username, ["test", "test2"]));
|
||||
await db
|
||||
.delete(application)
|
||||
.where(inArray(application.clientId, ["test"]));
|
||||
|
||||
// Initialize test user
|
||||
dummyUser = await createNewLocalUser({
|
||||
email: "test@test.com",
|
||||
username: "test",
|
||||
password: "test",
|
||||
display_name: "",
|
||||
});
|
||||
|
||||
if (!dummyUser) {
|
||||
throw new Error("Failed to create test user");
|
||||
}
|
||||
|
||||
token = await client.token.create({
|
||||
data: {
|
||||
access_token: "test",
|
||||
application: {
|
||||
create: {
|
||||
client_id: "test",
|
||||
name: "Test Application",
|
||||
redirect_uris: "https://example.com",
|
||||
scopes: "read write",
|
||||
secret: "test",
|
||||
website: "https://example.com",
|
||||
vapid_key: null,
|
||||
},
|
||||
},
|
||||
code: "test",
|
||||
scope: "read write",
|
||||
token_type: TokenType.BEARER,
|
||||
user: {
|
||||
connect: {
|
||||
id: dummyUser.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await db.delete(user).where(inArray(user.username, ["test", "test2"]));
|
||||
await db
|
||||
.delete(application)
|
||||
.where(inArray(application.clientId, ["test"]));
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
describe("GET /api/v1/instance", () => {
|
||||
|
|
@ -111,14 +56,11 @@ describe("API Tests", () => {
|
|||
|
||||
describe("GET /api/v1/custom_emojis", () => {
|
||||
beforeAll(async () => {
|
||||
await client.emoji.create({
|
||||
data: {
|
||||
instanceId: null,
|
||||
url: "https://example.com/test.png",
|
||||
content_type: "image/png",
|
||||
await db.insert(emoji).values({
|
||||
shortcode: "test",
|
||||
visible_in_picker: true,
|
||||
},
|
||||
url: "https://example.com/test.png",
|
||||
contentType: "image/png",
|
||||
visibleInPicker: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -132,7 +74,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
@ -151,11 +93,7 @@ describe("API Tests", () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await client.emoji.deleteMany({
|
||||
where: {
|
||||
shortcode: "test",
|
||||
},
|
||||
});
|
||||
await db.delete(emoji).where(eq(emoji.shortcode, "test"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,86 +1,19 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import type { Token } from "@prisma/client";
|
||||
import { config } from "config-manager";
|
||||
import { client } from "~database/datasource";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
createNewLocalUser,
|
||||
} from "~database/entities/User";
|
||||
import { sendTestRequest, wrapRelativeUrl } from "~tests/utils";
|
||||
import { getTestUsers, sendTestRequest, wrapRelativeUrl } from "~tests/utils";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APIRelationship } from "~types/entities/relationship";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
|
||||
const base_url = config.http.base_url;
|
||||
|
||||
let token: Token;
|
||||
let user: UserWithRelations;
|
||||
let user2: UserWithRelations;
|
||||
|
||||
beforeAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: {
|
||||
in: ["test", "test2"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
user = await createNewLocalUser({
|
||||
email: "test@test.com",
|
||||
username: "test",
|
||||
password: "test",
|
||||
display_name: "",
|
||||
});
|
||||
|
||||
user2 = await createNewLocalUser({
|
||||
email: "test2@test.com",
|
||||
username: "test2",
|
||||
password: "test2",
|
||||
display_name: "",
|
||||
});
|
||||
|
||||
token = await client.token.create({
|
||||
data: {
|
||||
access_token: "test",
|
||||
application: {
|
||||
create: {
|
||||
client_id: "test",
|
||||
name: "Test Application",
|
||||
redirect_uris: "https://example.com",
|
||||
scopes: "read write",
|
||||
secret: "test",
|
||||
website: "https://example.com",
|
||||
vapid_key: null,
|
||||
},
|
||||
},
|
||||
code: "test",
|
||||
scope: "read write",
|
||||
token_type: TokenType.BEARER,
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(2);
|
||||
const user = users[0];
|
||||
const user2 = users[1];
|
||||
const token = tokens[0];
|
||||
|
||||
afterAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: {
|
||||
in: ["test", "test2"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await client.application.deleteMany({
|
||||
where: {
|
||||
client_id: "test",
|
||||
},
|
||||
});
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
describe("API Tests", () => {
|
||||
|
|
@ -92,7 +25,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -117,7 +50,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
@ -149,7 +82,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -199,7 +132,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -228,7 +161,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -259,7 +192,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -290,7 +223,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -321,7 +254,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -347,7 +280,7 @@ describe("API Tests", () => {
|
|||
new Request(wrapRelativeUrl("/api/v1/blocks", base_url), {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
@ -375,7 +308,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -406,7 +339,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ notifications: true }),
|
||||
|
|
@ -436,7 +369,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ notifications: false }),
|
||||
|
|
@ -463,7 +396,7 @@ describe("API Tests", () => {
|
|||
new Request(wrapRelativeUrl("/api/v1/mutes", base_url), {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
@ -492,7 +425,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -523,7 +456,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -554,7 +487,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -585,7 +518,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ comment: "This is a new note" }),
|
||||
|
|
@ -616,7 +549,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
@ -651,7 +584,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -678,7 +611,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -708,7 +641,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
|
|
@ -732,7 +665,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import type { Token } from "@prisma/client";
|
||||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "config-manager";
|
||||
import { client } from "~database/datasource";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import { statusToAPI } from "~database/entities/Status";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
createNewLocalUser,
|
||||
} from "~database/entities/User";
|
||||
import { sendTestRequest, wrapRelativeUrl } from "~tests/utils";
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
wrapRelativeUrl,
|
||||
} from "~tests/utils";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APIAsyncAttachment } from "~types/entities/async_attachment";
|
||||
import type { APIContext } from "~types/entities/context";
|
||||
|
|
@ -15,69 +14,16 @@ import type { APIStatus } from "~types/entities/status";
|
|||
|
||||
const base_url = config.http.base_url;
|
||||
|
||||
let token: Token;
|
||||
let user: UserWithRelations;
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(1);
|
||||
const user = users[0];
|
||||
const token = tokens[0];
|
||||
let status: APIStatus | null = null;
|
||||
let status2: APIStatus | null = null;
|
||||
let media1: APIAsyncAttachment | null = null;
|
||||
|
||||
describe("API Tests", () => {
|
||||
beforeAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: {
|
||||
in: ["test", "test2"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
user = await createNewLocalUser({
|
||||
email: "test@test.com",
|
||||
username: "test",
|
||||
password: "test",
|
||||
display_name: "",
|
||||
});
|
||||
|
||||
token = await client.token.create({
|
||||
data: {
|
||||
access_token: "test",
|
||||
application: {
|
||||
create: {
|
||||
client_id: "test",
|
||||
name: "Test Application",
|
||||
redirect_uris: "https://example.com",
|
||||
scopes: "read write",
|
||||
secret: "test",
|
||||
website: "https://example.com",
|
||||
vapid_key: null,
|
||||
},
|
||||
},
|
||||
code: "test",
|
||||
scope: "read write",
|
||||
token_type: TokenType.BEARER,
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: {
|
||||
in: ["test", "test2"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await client.application.deleteMany({
|
||||
where: {
|
||||
client_id: "test",
|
||||
},
|
||||
});
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
describe("POST /api/v2/media", () => {
|
||||
|
|
@ -91,7 +37,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
body: formData,
|
||||
},
|
||||
|
|
@ -119,7 +65,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
@ -167,7 +113,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
|
@ -220,7 +166,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -271,7 +217,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -302,7 +248,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -332,7 +278,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -365,7 +311,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -394,7 +340,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -430,7 +376,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -452,7 +398,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -483,7 +429,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
|
|
@ -513,7 +459,7 @@ describe("API Tests", () => {
|
|||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.access_token}`,
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
|
||||
import { client } from "~database/datasource";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
|
||||
describe("cli.ts", () => {
|
||||
describe("User creation", () => {
|
||||
it("should execute user create command without admin flag", async () => {
|
||||
afterAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: "testuser297",
|
||||
email: "testuser297@gmail.com",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Run command and wait for it to finish
|
||||
Bun.spawnSync([
|
||||
"bun",
|
||||
"run",
|
||||
"cli.ts",
|
||||
"user",
|
||||
"create",
|
||||
"testuser297",
|
||||
"password123",
|
||||
"testuser297@gmail.com",
|
||||
]);
|
||||
|
||||
const createdUser = await client.user.findFirst({
|
||||
where: {
|
||||
username: "testuser297",
|
||||
email: "testuser297@gmail.com",
|
||||
},
|
||||
});
|
||||
|
||||
expect(createdUser).toBeDefined();
|
||||
});
|
||||
|
||||
it("should execute user create command with admin flag", async () => {
|
||||
afterAll(async () => {
|
||||
await client.user.deleteMany({
|
||||
where: {
|
||||
username: "testuser297",
|
||||
email: "testuser297@gmail.com",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Run command and wait for it to finish
|
||||
Bun.spawnSync([
|
||||
"bun",
|
||||
"run",
|
||||
"cli.ts",
|
||||
"user",
|
||||
"create",
|
||||
"testuser297",
|
||||
"password123",
|
||||
"testuser297@gmail.com",
|
||||
"--admin",
|
||||
]);
|
||||
|
||||
const createdUser = await client.user.findFirst({
|
||||
where: {
|
||||
username: "testuser297",
|
||||
email: "testuser297@gmail.com",
|
||||
isAdmin: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(createdUser).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("should execute user delete command", async () => {
|
||||
beforeAll(async () => {
|
||||
await createNewLocalUser({
|
||||
username: "bob124",
|
||||
password: "jesus",
|
||||
email: "bob124@bob124.com",
|
||||
});
|
||||
});
|
||||
|
||||
Bun.spawnSync(["bun", "run", "cli", "user", "delete", "bob124"]);
|
||||
|
||||
const userExists = await client.user.findFirst({
|
||||
where: {
|
||||
username: "bob124",
|
||||
email: "bob124@bob124.com",
|
||||
},
|
||||
});
|
||||
|
||||
expect(!!userExists).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from "bun:test";
|
||||
import { checkIfOauthIsValid } from "@oauth";
|
||||
import type { Application } from "@prisma/client";
|
||||
import type { Application } from "~database/entities/Application";
|
||||
|
||||
describe("checkIfOauthIsValid", () => {
|
||||
it("should return true when routeScopes and application.scopes are empty", () => {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,25 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import type { Application, Token } from "@prisma/client";
|
||||
import { client } from "~database/datasource";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
import { sendTestRequest, wrapRelativeUrl } from "./utils";
|
||||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import type { APIApplication } from "~types/entities/application";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
wrapRelativeUrl,
|
||||
} from "./utils";
|
||||
import type { APIToken } from "~types/entities/token";
|
||||
|
||||
const base_url = "http://lysand.localhost:8080"; //config.http.base_url;
|
||||
|
||||
let client_id: string;
|
||||
let client_secret: string;
|
||||
let code: string;
|
||||
let token: Token;
|
||||
let token: APIToken;
|
||||
const { users, passwords, deleteUsers } = await getTestUsers(1);
|
||||
|
||||
beforeAll(async () => {
|
||||
// Init test user
|
||||
await createNewLocalUser({
|
||||
email: "test@test.com",
|
||||
username: "test",
|
||||
password: "test",
|
||||
display_name: "",
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
await deleteOldTestUsers();
|
||||
});
|
||||
});
|
||||
|
||||
describe("POST /api/v1/apps/", () => {
|
||||
test("should create an application", async () => {
|
||||
const formData = new FormData();
|
||||
|
|
@ -61,8 +60,10 @@ describe("POST /api/auth/login/", () => {
|
|||
test("should get a code", async () => {
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append("email", "test@test.com");
|
||||
formData.append("password", "test");
|
||||
console.log(users[0]?.email ?? "");
|
||||
|
||||
formData.append("email", users[0]?.email ?? "");
|
||||
formData.append("password", passwords[0]);
|
||||
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
|
|
@ -139,20 +140,9 @@ describe("GET /api/v1/apps/verify_credentials", () => {
|
|||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("content-type")).toBe("application/json");
|
||||
|
||||
const credentials = (await response.json()) as Partial<Application>;
|
||||
const credentials = (await response.json()) as Partial<APIApplication>;
|
||||
|
||||
expect(credentials.name).toBe("Test Application");
|
||||
expect(credentials.website).toBe("https://example.com");
|
||||
expect(credentials.redirect_uris).toBe("https://example.com");
|
||||
expect(credentials.scopes).toBe("read write");
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// Clean up user
|
||||
await client.user.delete({
|
||||
where: {
|
||||
username: "test",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { randomBytes } from "node:crypto";
|
||||
import { inArray, like } from "drizzle-orm";
|
||||
import type { Status } from "~database/entities/Status";
|
||||
import { type Status, findManyStatuses } from "~database/entities/Status";
|
||||
import {
|
||||
type User,
|
||||
type UserWithRelations,
|
||||
|
|
@ -31,19 +31,22 @@ export const deleteOldTestUsers = async () => {
|
|||
|
||||
export const getTestUsers = async (count: number) => {
|
||||
const users: UserWithRelations[] = [];
|
||||
const passwords: string[] = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const password = randomBytes(32).toString("hex");
|
||||
|
||||
const user = await createNewLocalUser({
|
||||
username: `test-${randomBytes(32).toString("hex")}`,
|
||||
email: `${randomBytes(32).toString("hex")}@test.com`,
|
||||
password: randomBytes(32).toString("hex"),
|
||||
skipPasswordHash: true,
|
||||
password,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new Error("Failed to create test user");
|
||||
}
|
||||
|
||||
passwords.push(password);
|
||||
users.push(user);
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +67,7 @@ export const getTestUsers = async (count: number) => {
|
|||
return {
|
||||
users,
|
||||
tokens,
|
||||
passwords,
|
||||
deleteUsers: async () => {
|
||||
await db.delete(user).where(
|
||||
inArray(
|
||||
|
|
@ -104,5 +108,14 @@ export const getTestStatuses = async (
|
|||
statuses.push(newStatus);
|
||||
}
|
||||
|
||||
return statuses.toSorted((a, b) => a.id.localeCompare(b.id));
|
||||
const statusesWithRelations = await findManyStatuses({
|
||||
where: (status, { inArray }) =>
|
||||
inArray(
|
||||
status.id,
|
||||
statuses.map((s) => s.id),
|
||||
),
|
||||
orderBy: (status, { asc }) => asc(status.id),
|
||||
});
|
||||
|
||||
return statusesWithRelations;
|
||||
};
|
||||
|
|
|
|||
28
types.d.ts
vendored
28
types.d.ts
vendored
|
|
@ -1,28 +0,0 @@
|
|||
import type { LysandObject } from "@prisma/client";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APIField } from "~types/entities/field";
|
||||
import type { ContentFormat } from "~types/lysand/Object";
|
||||
|
||||
declare namespace global {
|
||||
namespace PrismaJson {
|
||||
type InstanceLogo = ContentFormat[];
|
||||
type ObjectData = LysandObject;
|
||||
type ObjectExtensions = LysandObject["extensions"];
|
||||
interface UserEndpoints {
|
||||
inbox: string;
|
||||
liked: string;
|
||||
outbox: string;
|
||||
disliked: string;
|
||||
featured: string;
|
||||
followers: string;
|
||||
following: string;
|
||||
}
|
||||
interface UserSource {
|
||||
note: string;
|
||||
fields: APIField[];
|
||||
privacy: APIAccount["privacy"];
|
||||
language: string;
|
||||
sensitive: boolean;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Application } from "@prisma/client";
|
||||
import type { Application } from "~database/entities/Application";
|
||||
|
||||
/**
|
||||
* Check if an OAuth application is valid for a route
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Prisma } from "@prisma/client";
|
||||
/* import type { Prisma } from "@prisma/client";
|
||||
import chalk from "chalk";
|
||||
import { config } from "config-manager";
|
||||
import Redis from "ioredis";
|
||||
|
|
@ -56,3 +56,4 @@ export const initializeRedisCache = async () => {
|
|||
|
||||
return null;
|
||||
};
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue