mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
More work on converting old Prisma calls to Drizzle
This commit is contained in:
parent
66922faa51
commit
ad0bf1a350
21
biome.json
21
biome.json
|
|
@ -2,19 +2,34 @@
|
|||
"$schema": "https://biomejs.dev/schemas/1.6.4/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true,
|
||||
"ignore": ["node_modules/**/*", "dist/**/*"]
|
||||
"ignore": [
|
||||
"node_modules/**/*",
|
||||
"dist/**/*",
|
||||
"packages/frontend/.output",
|
||||
"packages/frontend/.nuxt"
|
||||
]
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
},
|
||||
"ignore": ["node_modules/**/*", "dist/**/*"]
|
||||
"ignore": [
|
||||
"node_modules/**/*",
|
||||
"dist/**/*",
|
||||
"packages/frontend/.output",
|
||||
"packages/frontend/.nuxt"
|
||||
]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 4,
|
||||
"ignore": ["node_modules/**/*", "dist/**/*"]
|
||||
"ignore": [
|
||||
"node_modules/**/*",
|
||||
"dist/**/*",
|
||||
"packages/frontend/.output",
|
||||
"packages/frontend/.nuxt"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
cli.ts
2
cli.ts
|
|
@ -9,12 +9,12 @@ import { CliBuilder, CliCommand } from "cli-parser";
|
|||
import Table from "cli-table";
|
||||
import extract from "extract-zip";
|
||||
import { MediaBackend } from "media-manager";
|
||||
import { lookup } from "mime-types";
|
||||
import { client } from "~database/datasource";
|
||||
import { getUrl } from "~database/entities/Attachment";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
import { CliParameterType } from "~packages/cli-parser/cli-builder.type";
|
||||
import { config } from "~packages/config-manager";
|
||||
import { lookup } from "mime-types";
|
||||
|
||||
const args = process.argv;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { Config } from "config-manager";
|
||||
import { MediaBackendType } from "media-manager";
|
||||
import type { APIAsyncAttachment } from "~types/entities/async_attachment";
|
||||
import type { APIAttachment } from "~types/entities/attachment";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { MediaBackendType } from "media-manager";
|
||||
import { db } from "~drizzle/db";
|
||||
import { attachment } from "~drizzle/schema";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type { APIAsyncAttachment } from "~types/entities/async_attachment";
|
||||
import type { APIAttachment } from "~types/entities/attachment";
|
||||
|
||||
export type Attachment = InferSelectModel<typeof attachment>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import type { APIEmoji } from "~types/entities/emoji";
|
||||
import { type InferSelectModel, and, eq } from "drizzle-orm";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { addInstanceIfNotExists } from "./Instance";
|
||||
import { db } from "~drizzle/db";
|
||||
import { emoji, instance } from "~drizzle/schema";
|
||||
import { and, eq, type InferSelectModel } from "drizzle-orm";
|
||||
import type { APIEmoji } from "~types/entities/emoji";
|
||||
import { addInstanceIfNotExists } from "./Instance";
|
||||
|
||||
export type EmojiWithInstance = InferSelectModel<typeof emoji> & {
|
||||
instance: InferSelectModel<typeof instance> | null;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type * as Lysand from "lysand-types";
|
||||
import { config } from "config-manager";
|
||||
import { getUserUri, type User } from "./User";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { type User, getUserUri } from "./User";
|
||||
|
||||
export const objectToInboxRequest = async (
|
||||
object: Lysand.Entity,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { db } from "~drizzle/db";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { db } from "~drizzle/db";
|
||||
import { instance } from "~drizzle/schema";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { config } from "config-manager";
|
||||
import { type InferSelectModel, and, eq } from "drizzle-orm";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { db } from "~drizzle/db";
|
||||
import { like, notification } from "~drizzle/schema";
|
||||
import type { StatusWithRelations } from "./Status";
|
||||
import type { UserWithRelations } from "./User";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { and, eq, type InferSelectModel } from "drizzle-orm";
|
||||
import { notification, like } from "~drizzle/schema";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export type Like = InferSelectModel<typeof like>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import { db } from "~drizzle/db";
|
||||
import type { notification } from "~drizzle/schema";
|
||||
import type { APINotification } from "~types/entities/notification";
|
||||
import {
|
||||
type StatusWithRelations,
|
||||
statusToAPI,
|
||||
findFirstStatuses,
|
||||
statusToAPI,
|
||||
} from "./Status";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
userToAPI,
|
||||
userRelations,
|
||||
userExtrasTemplate,
|
||||
transformOutputToUserWithRelations,
|
||||
userExtrasTemplate,
|
||||
userRelations,
|
||||
userToAPI,
|
||||
} from "./User";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type { notification } from "~drizzle/schema";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export type Notification = InferSelectModel<typeof notification>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { db } from "~drizzle/db";
|
||||
import { lysandObject } from "~drizzle/schema";
|
||||
import { findFirstUser } from "./User";
|
||||
import type * as Lysand from "lysand-types";
|
||||
|
||||
export type LysandObject = InferSelectModel<typeof lysandObject>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { client } from "~database/datasource";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
import type { APIRelationship } from "~types/entities/relationship";
|
||||
import type { User } from "./User";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export type Relationship = InferSelectModel<typeof relationship>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,34 @@
|
|||
import { sanitizeHtml } from "@sanitization";
|
||||
import { config } from "config-manager";
|
||||
import {
|
||||
type InferSelectModel,
|
||||
and,
|
||||
eq,
|
||||
inArray,
|
||||
isNotNull,
|
||||
isNull,
|
||||
or,
|
||||
sql,
|
||||
} from "drizzle-orm";
|
||||
import { htmlToText } from "html-to-text";
|
||||
import linkifyHtml from "linkify-html";
|
||||
import linkifyStr from "linkify-string";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { parse } from "marked";
|
||||
import { db } from "~drizzle/db";
|
||||
import {
|
||||
type application,
|
||||
attachment,
|
||||
emojiToStatus,
|
||||
instance,
|
||||
type like,
|
||||
status,
|
||||
statusToUser,
|
||||
user,
|
||||
} from "~drizzle/schema";
|
||||
import type { APIAttachment } from "~types/entities/attachment";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import type { Note } from "~types/lysand/Object";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { applicationToAPI } from "./Application";
|
||||
import {
|
||||
attachmentFromLysand,
|
||||
|
|
@ -15,48 +36,27 @@ import {
|
|||
attachmentToLysand,
|
||||
} from "./Attachment";
|
||||
import {
|
||||
type EmojiWithInstance,
|
||||
emojiToAPI,
|
||||
emojiToLysand,
|
||||
fetchEmoji,
|
||||
parseEmojis,
|
||||
type EmojiWithInstance,
|
||||
} from "./Emoji";
|
||||
import { objectToInboxRequest } from "./Federation";
|
||||
import {
|
||||
getUserUri,
|
||||
resolveUser,
|
||||
resolveWebFinger,
|
||||
userToAPI,
|
||||
userExtras,
|
||||
userRelations,
|
||||
userExtrasTemplate,
|
||||
type User,
|
||||
type UserWithRelations,
|
||||
type UserWithRelationsAndRelationships,
|
||||
transformOutputToUserWithRelations,
|
||||
findManyUsers,
|
||||
getUserUri,
|
||||
resolveUser,
|
||||
resolveWebFinger,
|
||||
transformOutputToUserWithRelations,
|
||||
userExtras,
|
||||
userExtrasTemplate,
|
||||
userRelations,
|
||||
userToAPI,
|
||||
} from "./User";
|
||||
import { objectToInboxRequest } from "./Federation";
|
||||
import {
|
||||
and,
|
||||
eq,
|
||||
or,
|
||||
type InferSelectModel,
|
||||
sql,
|
||||
isNotNull,
|
||||
inArray,
|
||||
isNull,
|
||||
} from "drizzle-orm";
|
||||
import {
|
||||
status,
|
||||
type application,
|
||||
attachment,
|
||||
type like,
|
||||
user,
|
||||
statusToUser,
|
||||
emojiToStatus,
|
||||
instance,
|
||||
} from "~drizzle/schema";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export type Status = InferSelectModel<typeof status>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,10 @@
|
|||
import { getBestContentType, urlToContentFormat } from "@content_types";
|
||||
import { addUserToMeilisearch } from "@meilisearch";
|
||||
import { type Config, config } from "config-manager";
|
||||
import { type InferSelectModel, and, eq, sql } from "drizzle-orm";
|
||||
import { htmlToText } from "html-to-text";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APISource } from "~types/entities/source";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import {
|
||||
fetchEmoji,
|
||||
emojiToAPI,
|
||||
emojiToLysand,
|
||||
type EmojiWithInstance,
|
||||
} from "./Emoji";
|
||||
import { addInstanceIfNotExists } from "./Instance";
|
||||
import { createNewRelationship } from "./Relationship";
|
||||
import { getBestContentType, urlToContentFormat } from "@content_types";
|
||||
import { objectToInboxRequest } from "./Federation";
|
||||
import { and, eq, sql, type InferSelectModel } from "drizzle-orm";
|
||||
import { db } from "~drizzle/db";
|
||||
import {
|
||||
emojiToUser,
|
||||
instance,
|
||||
|
|
@ -22,7 +12,17 @@ import {
|
|||
relationship,
|
||||
user,
|
||||
} from "~drizzle/schema";
|
||||
import { db } from "~drizzle/db";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APISource } from "~types/entities/source";
|
||||
import {
|
||||
type EmojiWithInstance,
|
||||
emojiToAPI,
|
||||
emojiToLysand,
|
||||
fetchEmoji,
|
||||
} from "./Emoji";
|
||||
import { objectToInboxRequest } from "./Federation";
|
||||
import { addInstanceIfNotExists } from "./Instance";
|
||||
import { createNewRelationship } from "./Relationship";
|
||||
|
||||
export type User = InferSelectModel<typeof user> & {
|
||||
endpoints?: Partial<{
|
||||
|
|
|
|||
|
|
@ -1,462 +0,0 @@
|
|||
-- Current sql file was generated after introspecting the database
|
||||
-- If you want to run this migration please uncomment this code before executing migrations
|
||||
/*
|
||||
CREATE TABLE IF NOT EXISTS "_prisma_migrations" (
|
||||
"id" varchar(36) PRIMARY KEY NOT NULL,
|
||||
"checksum" varchar(64) NOT NULL,
|
||||
"finished_at" timestamp with time zone,
|
||||
"migration_name" varchar(255) NOT NULL,
|
||||
"logs" text,
|
||||
"rolled_back_at" timestamp with time zone,
|
||||
"started_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"applied_steps_count" integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Emoji" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"shortcode" text NOT NULL,
|
||||
"url" text NOT NULL,
|
||||
"visible_in_picker" boolean NOT NULL,
|
||||
"instanceId" uuid,
|
||||
"alt" text,
|
||||
"content_type" text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Like" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"likerId" uuid NOT NULL,
|
||||
"likedId" uuid NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "LysandObject" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"remote_id" text NOT NULL,
|
||||
"type" text NOT NULL,
|
||||
"uri" text NOT NULL,
|
||||
"created_at" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"authorId" uuid,
|
||||
"extra_data" jsonb NOT NULL,
|
||||
"extensions" jsonb NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Relationship" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"ownerId" uuid NOT NULL,
|
||||
"subjectId" uuid NOT NULL,
|
||||
"following" boolean NOT NULL,
|
||||
"showingReblogs" boolean NOT NULL,
|
||||
"notifying" boolean NOT NULL,
|
||||
"followedBy" boolean NOT NULL,
|
||||
"blocking" boolean NOT NULL,
|
||||
"blockedBy" boolean NOT NULL,
|
||||
"muting" boolean NOT NULL,
|
||||
"mutingNotifications" boolean NOT NULL,
|
||||
"requested" boolean NOT NULL,
|
||||
"domainBlocking" boolean NOT NULL,
|
||||
"endorsed" boolean NOT NULL,
|
||||
"languages" text[],
|
||||
"note" text NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"updatedAt" timestamp(3) NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Application" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"website" text,
|
||||
"vapid_key" text,
|
||||
"client_id" text NOT NULL,
|
||||
"secret" text NOT NULL,
|
||||
"scopes" text NOT NULL,
|
||||
"redirect_uris" text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Token" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"token_type" text NOT NULL,
|
||||
"scope" text NOT NULL,
|
||||
"access_token" text NOT NULL,
|
||||
"code" text NOT NULL,
|
||||
"created_at" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"userId" uuid,
|
||||
"applicationId" uuid
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "_EmojiToUser" (
|
||||
"A" uuid NOT NULL,
|
||||
"B" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "_EmojiToStatus" (
|
||||
"A" uuid NOT NULL,
|
||||
"B" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "_StatusToUser" (
|
||||
"A" uuid NOT NULL,
|
||||
"B" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "_UserPinnedNotes" (
|
||||
"A" uuid NOT NULL,
|
||||
"B" uuid NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Attachment" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"url" text NOT NULL,
|
||||
"remote_url" text,
|
||||
"thumbnail_url" text,
|
||||
"mime_type" text NOT NULL,
|
||||
"description" text,
|
||||
"blurhash" text,
|
||||
"sha256" text,
|
||||
"fps" integer,
|
||||
"duration" integer,
|
||||
"width" integer,
|
||||
"height" integer,
|
||||
"size" integer,
|
||||
"statusId" uuid
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Notification" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"type" text NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"notifiedId" uuid NOT NULL,
|
||||
"accountId" uuid NOT NULL,
|
||||
"statusId" uuid
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Status" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"uri" text,
|
||||
"authorId" uuid NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"updatedAt" timestamp(3) NOT NULL,
|
||||
"reblogId" uuid,
|
||||
"content" text DEFAULT '' NOT NULL,
|
||||
"contentType" text DEFAULT 'text/plain' NOT NULL,
|
||||
"visibility" text NOT NULL,
|
||||
"inReplyToPostId" uuid,
|
||||
"quotingPostId" uuid,
|
||||
"instanceId" uuid,
|
||||
"sensitive" boolean NOT NULL,
|
||||
"spoilerText" text DEFAULT '' NOT NULL,
|
||||
"applicationId" uuid,
|
||||
"contentSource" text DEFAULT '' NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Instance" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"base_url" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"version" text NOT NULL,
|
||||
"logo" jsonb NOT NULL,
|
||||
"disableAutomoderation" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "OpenIdAccount" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"userId" uuid,
|
||||
"serverId" text NOT NULL,
|
||||
"issuerId" text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "User" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"uri" text,
|
||||
"username" text NOT NULL,
|
||||
"displayName" text NOT NULL,
|
||||
"password" text,
|
||||
"email" text,
|
||||
"note" text DEFAULT '' NOT NULL,
|
||||
"isAdmin" boolean DEFAULT false NOT NULL,
|
||||
"endpoints" jsonb,
|
||||
"source" jsonb NOT NULL,
|
||||
"avatar" text NOT NULL,
|
||||
"header" text NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"updatedAt" timestamp(3) NOT NULL,
|
||||
"isBot" boolean DEFAULT false NOT NULL,
|
||||
"isLocked" boolean DEFAULT false NOT NULL,
|
||||
"isDiscoverable" boolean DEFAULT false NOT NULL,
|
||||
"sanctions" text[] DEFAULT 'RRAY[',
|
||||
"publicKey" text NOT NULL,
|
||||
"privateKey" text,
|
||||
"instanceId" uuid,
|
||||
"disableAutomoderation" boolean DEFAULT false NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "OpenIdLoginFlow" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"codeVerifier" text NOT NULL,
|
||||
"applicationId" uuid,
|
||||
"issuerId" text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "Flag" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"flagType" text DEFAULT 'other' NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
"flaggeStatusId" uuid,
|
||||
"flaggedUserId" uuid
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "ModNote" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"notedStatusId" uuid,
|
||||
"notedUserId" uuid,
|
||||
"modId" uuid NOT NULL,
|
||||
"note" text NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "ModTag" (
|
||||
"id" uuid PRIMARY KEY DEFAULT uuid_generate_v7() NOT NULL,
|
||||
"taggedStatusId" uuid,
|
||||
"taggedUserId" uuid,
|
||||
"modId" uuid NOT NULL,
|
||||
"tag" text NOT NULL,
|
||||
"createdAt" timestamp(3) DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "LysandObject_remote_id_key" ON "LysandObject" ("remote_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "LysandObject_uri_key" ON "LysandObject" ("uri");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Application_client_id_key" ON "Application" ("client_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "_EmojiToUser_AB_unique" ON "_EmojiToUser" ("A","B");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "_EmojiToUser_B_index" ON "_EmojiToUser" ("B");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "_EmojiToStatus_AB_unique" ON "_EmojiToStatus" ("A","B");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "_EmojiToStatus_B_index" ON "_EmojiToStatus" ("B");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "_StatusToUser_AB_unique" ON "_StatusToUser" ("A","B");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "_StatusToUser_B_index" ON "_StatusToUser" ("B");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "_UserPinnedNotes_AB_unique" ON "_UserPinnedNotes" ("A","B");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "_UserPinnedNotes_B_index" ON "_UserPinnedNotes" ("B");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Status_uri_key" ON "Status" ("uri");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "User_uri_key" ON "User" ("uri");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "User_username_key" ON "User" ("username");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "User_email_key" ON "User" ("email");--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Emoji" ADD CONSTRAINT "Emoji_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "public"."Instance"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Like" ADD CONSTRAINT "Like_likerId_fkey" FOREIGN KEY ("likerId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Like" ADD CONSTRAINT "Like_likedId_fkey" FOREIGN KEY ("likedId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "LysandObject" ADD CONSTRAINT "LysandObject_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "public"."LysandObject"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Relationship" ADD CONSTRAINT "Relationship_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Relationship" ADD CONSTRAINT "Relationship_subjectId_fkey" FOREIGN KEY ("subjectId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Token" ADD CONSTRAINT "Token_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "public"."Application"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_EmojiToUser" ADD CONSTRAINT "_EmojiToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Emoji"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_EmojiToUser" ADD CONSTRAINT "_EmojiToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_EmojiToStatus" ADD CONSTRAINT "_EmojiToStatus_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Emoji"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_EmojiToStatus" ADD CONSTRAINT "_EmojiToStatus_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_StatusToUser" ADD CONSTRAINT "_StatusToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_StatusToUser" ADD CONSTRAINT "_StatusToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_UserPinnedNotes" ADD CONSTRAINT "_UserPinnedNotes_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "_UserPinnedNotes" ADD CONSTRAINT "_UserPinnedNotes_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Attachment" ADD CONSTRAINT "Attachment_statusId_fkey" FOREIGN KEY ("statusId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_notifiedId_fkey" FOREIGN KEY ("notifiedId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_statusId_fkey" FOREIGN KEY ("statusId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_reblogId_fkey" FOREIGN KEY ("reblogId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_inReplyToPostId_fkey" FOREIGN KEY ("inReplyToPostId") REFERENCES "public"."Status"("id") ON DELETE set null ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_quotingPostId_fkey" FOREIGN KEY ("quotingPostId") REFERENCES "public"."Status"("id") ON DELETE set null ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "public"."Instance"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Status" ADD CONSTRAINT "Status_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "public"."Application"("id") ON DELETE set null ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "OpenIdAccount" ADD CONSTRAINT "OpenIdAccount_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE set null ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "User" ADD CONSTRAINT "User_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "public"."Instance"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "OpenIdLoginFlow" ADD CONSTRAINT "OpenIdLoginFlow_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "public"."Application"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Flag" ADD CONSTRAINT "Flag_flaggeStatusId_fkey" FOREIGN KEY ("flaggeStatusId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "Flag" ADD CONSTRAINT "Flag_flaggedUserId_fkey" FOREIGN KEY ("flaggedUserId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_notedStatusId_fkey" FOREIGN KEY ("notedStatusId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_notedUserId_fkey" FOREIGN KEY ("notedUserId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_modId_fkey" FOREIGN KEY ("modId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_taggedStatusId_fkey" FOREIGN KEY ("taggedStatusId") REFERENCES "public"."Status"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_taggedUserId_fkey" FOREIGN KEY ("taggedUserId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_modId_fkey" FOREIGN KEY ("modId") REFERENCES "public"."User"("id") ON DELETE cascade ON UPDATE cascade;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
*/
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"version": "5",
|
||||
"dialect": "pg",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "5",
|
||||
"when": 1712812153499,
|
||||
"tag": "0000_third_misty_knight",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,292 +0,0 @@
|
|||
import { pgTable, varchar, timestamp, text, integer, foreignKey, uuid, boolean, uniqueIndex, jsonb, index } from "drizzle-orm/pg-core"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
|
||||
|
||||
export const prismaMigrations = pgTable("_prisma_migrations", {
|
||||
id: varchar("id", { length: 36 }).primaryKey().notNull(),
|
||||
checksum: varchar("checksum", { length: 64 }).notNull(),
|
||||
finishedAt: timestamp("finished_at", { withTimezone: true, mode: 'string' }),
|
||||
migrationName: varchar("migration_name", { length: 255 }).notNull(),
|
||||
logs: text("logs"),
|
||||
rolledBackAt: timestamp("rolled_back_at", { withTimezone: true, mode: 'string' }),
|
||||
startedAt: timestamp("started_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
|
||||
appliedStepsCount: integer("applied_steps_count").default(0).notNull(),
|
||||
});
|
||||
|
||||
export const emoji = pgTable("Emoji", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
shortcode: text("shortcode").notNull(),
|
||||
url: text("url").notNull(),
|
||||
visibleInPicker: boolean("visible_in_picker").notNull(),
|
||||
instanceId: uuid("instanceId").references(() => instance.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
alt: text("alt"),
|
||||
contentType: text("content_type").notNull(),
|
||||
});
|
||||
|
||||
export const like = pgTable("Like", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
likerId: uuid("likerId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
likedId: uuid("likedId").notNull().references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const lysandObject = pgTable("LysandObject", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
remoteId: text("remote_id").notNull(),
|
||||
type: text("type").notNull(),
|
||||
uri: text("uri").notNull(),
|
||||
createdAt: timestamp("created_at", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
authorId: uuid("authorId"),
|
||||
extraData: jsonb("extra_data").notNull(),
|
||||
extensions: jsonb("extensions").notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
remoteIdKey: uniqueIndex("LysandObject_remote_id_key").on(table.remoteId),
|
||||
uriKey: uniqueIndex("LysandObject_uri_key").on(table.uri),
|
||||
lysandObjectAuthorIdFkey: foreignKey({
|
||||
columns: [table.authorId],
|
||||
foreignColumns: [table.id],
|
||||
name: "LysandObject_authorId_fkey"
|
||||
}).onUpdate("cascade").onDelete("cascade"),
|
||||
}
|
||||
});
|
||||
|
||||
export const relationship = pgTable("Relationship", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
ownerId: uuid("ownerId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
subjectId: uuid("subjectId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
following: boolean("following").notNull(),
|
||||
showingReblogs: boolean("showingReblogs").notNull(),
|
||||
notifying: boolean("notifying").notNull(),
|
||||
followedBy: boolean("followedBy").notNull(),
|
||||
blocking: boolean("blocking").notNull(),
|
||||
blockedBy: boolean("blockedBy").notNull(),
|
||||
muting: boolean("muting").notNull(),
|
||||
mutingNotifications: boolean("mutingNotifications").notNull(),
|
||||
requested: boolean("requested").notNull(),
|
||||
domainBlocking: boolean("domainBlocking").notNull(),
|
||||
endorsed: boolean("endorsed").notNull(),
|
||||
languages: text("languages").array(),
|
||||
note: text("note").notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt", { precision: 3, mode: 'string' }).notNull(),
|
||||
});
|
||||
|
||||
export const application = pgTable("Application", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
name: text("name").notNull(),
|
||||
website: text("website"),
|
||||
vapidKey: text("vapid_key"),
|
||||
clientId: text("client_id").notNull(),
|
||||
secret: text("secret").notNull(),
|
||||
scopes: text("scopes").notNull(),
|
||||
redirectUris: text("redirect_uris").notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
clientIdKey: uniqueIndex("Application_client_id_key").on(table.clientId),
|
||||
}
|
||||
});
|
||||
|
||||
export const token = pgTable("Token", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
tokenType: text("token_type").notNull(),
|
||||
scope: text("scope").notNull(),
|
||||
accessToken: text("access_token").notNull(),
|
||||
code: text("code").notNull(),
|
||||
createdAt: timestamp("created_at", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
userId: uuid("userId").references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
applicationId: uuid("applicationId").references(() => application.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
});
|
||||
|
||||
export const emojiToUser = pgTable("_EmojiToUser", {
|
||||
a: uuid("A").notNull().references(() => emoji.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
b: uuid("B").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
abUnique: uniqueIndex("_EmojiToUser_AB_unique").on(table.a, table.b),
|
||||
bIdx: index().on(table.b),
|
||||
}
|
||||
});
|
||||
|
||||
export const emojiToStatus = pgTable("_EmojiToStatus", {
|
||||
a: uuid("A").notNull().references(() => emoji.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
b: uuid("B").notNull().references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
abUnique: uniqueIndex("_EmojiToStatus_AB_unique").on(table.a, table.b),
|
||||
bIdx: index().on(table.b),
|
||||
}
|
||||
});
|
||||
|
||||
export const statusToUser = pgTable("_StatusToUser", {
|
||||
a: uuid("A").notNull().references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
b: uuid("B").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
abUnique: uniqueIndex("_StatusToUser_AB_unique").on(table.a, table.b),
|
||||
bIdx: index().on(table.b),
|
||||
}
|
||||
});
|
||||
|
||||
export const userPinnedNotes = pgTable("_UserPinnedNotes", {
|
||||
a: uuid("A").notNull().references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
b: uuid("B").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
abUnique: uniqueIndex("_UserPinnedNotes_AB_unique").on(table.a, table.b),
|
||||
bIdx: index().on(table.b),
|
||||
}
|
||||
});
|
||||
|
||||
export const attachment = pgTable("Attachment", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
url: text("url").notNull(),
|
||||
remoteUrl: text("remote_url"),
|
||||
thumbnailUrl: text("thumbnail_url"),
|
||||
mimeType: text("mime_type").notNull(),
|
||||
description: text("description"),
|
||||
blurhash: text("blurhash"),
|
||||
sha256: text("sha256"),
|
||||
fps: integer("fps"),
|
||||
duration: integer("duration"),
|
||||
width: integer("width"),
|
||||
height: integer("height"),
|
||||
size: integer("size"),
|
||||
statusId: uuid("statusId").references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
});
|
||||
|
||||
export const notification = pgTable("Notification", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
type: text("type").notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
notifiedId: uuid("notifiedId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
accountId: uuid("accountId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
statusId: uuid("statusId").references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
});
|
||||
|
||||
export const status = pgTable("Status", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
uri: text("uri"),
|
||||
authorId: uuid("authorId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt", { precision: 3, mode: 'string' }).notNull(),
|
||||
reblogId: uuid("reblogId"),
|
||||
content: text("content").default('').notNull(),
|
||||
contentType: text("contentType").default('text/plain').notNull(),
|
||||
visibility: text("visibility").notNull(),
|
||||
inReplyToPostId: uuid("inReplyToPostId"),
|
||||
quotingPostId: uuid("quotingPostId"),
|
||||
instanceId: uuid("instanceId").references(() => instance.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
sensitive: boolean("sensitive").notNull(),
|
||||
spoilerText: text("spoilerText").default('').notNull(),
|
||||
applicationId: uuid("applicationId").references(() => application.id, { onDelete: "set null", onUpdate: "cascade" } ),
|
||||
contentSource: text("contentSource").default('').notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
uriKey: uniqueIndex("Status_uri_key").on(table.uri),
|
||||
statusReblogIdFkey: foreignKey({
|
||||
columns: [table.reblogId],
|
||||
foreignColumns: [table.id],
|
||||
name: "Status_reblogId_fkey"
|
||||
}).onUpdate("cascade").onDelete("cascade"),
|
||||
statusInReplyToPostIdFkey: foreignKey({
|
||||
columns: [table.inReplyToPostId],
|
||||
foreignColumns: [table.id],
|
||||
name: "Status_inReplyToPostId_fkey"
|
||||
}).onUpdate("cascade").onDelete("set null"),
|
||||
statusQuotingPostIdFkey: foreignKey({
|
||||
columns: [table.quotingPostId],
|
||||
foreignColumns: [table.id],
|
||||
name: "Status_quotingPostId_fkey"
|
||||
}).onUpdate("cascade").onDelete("set null"),
|
||||
}
|
||||
});
|
||||
|
||||
export const instance = pgTable("Instance", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
baseUrl: text("base_url").notNull(),
|
||||
name: text("name").notNull(),
|
||||
version: text("version").notNull(),
|
||||
logo: jsonb("logo").notNull(),
|
||||
disableAutomoderation: boolean("disableAutomoderation").default(false).notNull(),
|
||||
});
|
||||
|
||||
export const openIdAccount = pgTable("OpenIdAccount", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
userId: uuid("userId").references(() => user.id, { onDelete: "set null", onUpdate: "cascade" } ),
|
||||
serverId: text("serverId").notNull(),
|
||||
issuerId: text("issuerId").notNull(),
|
||||
});
|
||||
|
||||
export const user = pgTable("User", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
uri: text("uri"),
|
||||
username: text("username").notNull(),
|
||||
displayName: text("displayName").notNull(),
|
||||
password: text("password"),
|
||||
email: text("email"),
|
||||
note: text("note").default('').notNull(),
|
||||
isAdmin: boolean("isAdmin").default(false).notNull(),
|
||||
endpoints: jsonb("endpoints"),
|
||||
source: jsonb("source").notNull(),
|
||||
avatar: text("avatar").notNull(),
|
||||
header: text("header").notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt", { precision: 3, mode: 'string' }).notNull(),
|
||||
isBot: boolean("isBot").default(false).notNull(),
|
||||
isLocked: boolean("isLocked").default(false).notNull(),
|
||||
isDiscoverable: boolean("isDiscoverable").default(false).notNull(),
|
||||
sanctions: text("sanctions").default('RRAY[').array(),
|
||||
publicKey: text("publicKey").notNull(),
|
||||
privateKey: text("privateKey"),
|
||||
instanceId: uuid("instanceId").references(() => instance.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
disableAutomoderation: boolean("disableAutomoderation").default(false).notNull(),
|
||||
},
|
||||
(table) => {
|
||||
return {
|
||||
uriKey: uniqueIndex("User_uri_key").on(table.uri),
|
||||
usernameKey: uniqueIndex("User_username_key").on(table.username),
|
||||
emailKey: uniqueIndex("User_email_key").on(table.email),
|
||||
}
|
||||
});
|
||||
|
||||
export const openIdLoginFlow = pgTable("OpenIdLoginFlow", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
codeVerifier: text("codeVerifier").notNull(),
|
||||
applicationId: uuid("applicationId").references(() => application.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
issuerId: text("issuerId").notNull(),
|
||||
});
|
||||
|
||||
export const flag = pgTable("Flag", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
flagType: text("flagType").default('other').notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
flaggeStatusId: uuid("flaggeStatusId").references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
flaggedUserId: uuid("flaggedUserId").references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
});
|
||||
|
||||
export const modNote = pgTable("ModNote", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
notedStatusId: uuid("notedStatusId").references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
notedUserId: uuid("notedUserId").references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
modId: uuid("modId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
note: text("note").notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const modTag = pgTable("ModTag", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
taggedStatusId: uuid("taggedStatusId").references(() => status.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
taggedUserId: uuid("taggedUserId").references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
modId: uuid("modId").notNull().references(() => user.id, { onDelete: "cascade", onUpdate: "cascade" } ),
|
||||
tag: text("tag").notNull(),
|
||||
createdAt: timestamp("createdAt", { precision: 3, mode: 'string' }).defaultNow().notNull(),
|
||||
});
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Config } from "drizzle-kit";
|
||||
import { config } from "config-manager";
|
||||
import type { Config } from "drizzle-kit";
|
||||
|
||||
export default {
|
||||
driver: "pg",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Client } from "pg";
|
||||
import { config } from "config-manager";
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import { Client } from "pg";
|
||||
import * as schema from "./schema";
|
||||
|
||||
export const client = new Client({
|
||||
|
|
|
|||
|
|
@ -119,12 +119,8 @@
|
|||
"tableFrom": "Emoji",
|
||||
"tableTo": "Instance",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"instanceId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["instanceId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -170,12 +166,8 @@
|
|||
"tableFrom": "Like",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"likerId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["likerId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -184,12 +176,8 @@
|
|||
"tableFrom": "Like",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"likedId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["likedId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -255,16 +243,12 @@
|
|||
"indexes": {
|
||||
"LysandObject_remote_id_key": {
|
||||
"name": "LysandObject_remote_id_key",
|
||||
"columns": [
|
||||
"remote_id"
|
||||
],
|
||||
"columns": ["remote_id"],
|
||||
"isUnique": true
|
||||
},
|
||||
"LysandObject_uri_key": {
|
||||
"name": "LysandObject_uri_key",
|
||||
"columns": [
|
||||
"uri"
|
||||
],
|
||||
"columns": ["uri"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
|
|
@ -274,12 +258,8 @@
|
|||
"tableFrom": "LysandObject",
|
||||
"tableTo": "LysandObject",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"authorId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["authorId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -409,12 +389,8 @@
|
|||
"tableFrom": "Relationship",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"ownerId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["ownerId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -423,12 +399,8 @@
|
|||
"tableFrom": "Relationship",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"subjectId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["subjectId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -493,9 +465,7 @@
|
|||
"indexes": {
|
||||
"Application_client_id_key": {
|
||||
"name": "Application_client_id_key",
|
||||
"columns": [
|
||||
"client_id"
|
||||
],
|
||||
"columns": ["client_id"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
|
|
@ -565,12 +535,8 @@
|
|||
"tableFrom": "Token",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"userId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["userId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -579,12 +545,8 @@
|
|||
"tableFrom": "Token",
|
||||
"tableTo": "Application",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"applicationId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["applicationId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -612,17 +574,12 @@
|
|||
"indexes": {
|
||||
"_EmojiToUser_AB_unique": {
|
||||
"name": "_EmojiToUser_AB_unique",
|
||||
"columns": [
|
||||
"A",
|
||||
"B"
|
||||
],
|
||||
"columns": ["A", "B"],
|
||||
"isUnique": true
|
||||
},
|
||||
"_EmojiToUser_B_index": {
|
||||
"name": "_EmojiToUser_B_index",
|
||||
"columns": [
|
||||
"B"
|
||||
],
|
||||
"columns": ["B"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
|
|
@ -632,12 +589,8 @@
|
|||
"tableFrom": "_EmojiToUser",
|
||||
"tableTo": "Emoji",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"A"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["A"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -646,12 +599,8 @@
|
|||
"tableFrom": "_EmojiToUser",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"B"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["B"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -679,17 +628,12 @@
|
|||
"indexes": {
|
||||
"_EmojiToStatus_AB_unique": {
|
||||
"name": "_EmojiToStatus_AB_unique",
|
||||
"columns": [
|
||||
"A",
|
||||
"B"
|
||||
],
|
||||
"columns": ["A", "B"],
|
||||
"isUnique": true
|
||||
},
|
||||
"_EmojiToStatus_B_index": {
|
||||
"name": "_EmojiToStatus_B_index",
|
||||
"columns": [
|
||||
"B"
|
||||
],
|
||||
"columns": ["B"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
|
|
@ -699,12 +643,8 @@
|
|||
"tableFrom": "_EmojiToStatus",
|
||||
"tableTo": "Emoji",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"A"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["A"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -713,12 +653,8 @@
|
|||
"tableFrom": "_EmojiToStatus",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"B"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["B"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -746,17 +682,12 @@
|
|||
"indexes": {
|
||||
"_StatusToUser_AB_unique": {
|
||||
"name": "_StatusToUser_AB_unique",
|
||||
"columns": [
|
||||
"A",
|
||||
"B"
|
||||
],
|
||||
"columns": ["A", "B"],
|
||||
"isUnique": true
|
||||
},
|
||||
"_StatusToUser_B_index": {
|
||||
"name": "_StatusToUser_B_index",
|
||||
"columns": [
|
||||
"B"
|
||||
],
|
||||
"columns": ["B"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
|
|
@ -766,12 +697,8 @@
|
|||
"tableFrom": "_StatusToUser",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"A"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["A"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -780,12 +707,8 @@
|
|||
"tableFrom": "_StatusToUser",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"B"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["B"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -813,17 +736,12 @@
|
|||
"indexes": {
|
||||
"_UserPinnedNotes_AB_unique": {
|
||||
"name": "_UserPinnedNotes_AB_unique",
|
||||
"columns": [
|
||||
"A",
|
||||
"B"
|
||||
],
|
||||
"columns": ["A", "B"],
|
||||
"isUnique": true
|
||||
},
|
||||
"_UserPinnedNotes_B_index": {
|
||||
"name": "_UserPinnedNotes_B_index",
|
||||
"columns": [
|
||||
"B"
|
||||
],
|
||||
"columns": ["B"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
|
|
@ -833,12 +751,8 @@
|
|||
"tableFrom": "_UserPinnedNotes",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"A"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["A"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -847,12 +761,8 @@
|
|||
"tableFrom": "_UserPinnedNotes",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"B"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["B"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -957,12 +867,8 @@
|
|||
"tableFrom": "Attachment",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"statusId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["statusId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1020,12 +926,8 @@
|
|||
"tableFrom": "Notification",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"notifiedId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["notifiedId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1034,12 +936,8 @@
|
|||
"tableFrom": "Notification",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"accountId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["accountId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1048,12 +946,8 @@
|
|||
"tableFrom": "Notification",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"statusId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["statusId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1171,9 +1065,7 @@
|
|||
"indexes": {
|
||||
"Status_uri_key": {
|
||||
"name": "Status_uri_key",
|
||||
"columns": [
|
||||
"uri"
|
||||
],
|
||||
"columns": ["uri"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
|
|
@ -1183,12 +1075,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"authorId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["authorId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1197,12 +1085,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"reblogId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["reblogId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1211,12 +1095,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"inReplyToPostId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["inReplyToPostId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1225,12 +1105,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"quotingPostId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["quotingPostId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1239,12 +1115,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "Instance",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"instanceId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["instanceId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1253,12 +1125,8 @@
|
|||
"tableFrom": "Status",
|
||||
"tableTo": "Application",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"applicationId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["applicationId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1351,12 +1219,8 @@
|
|||
"tableFrom": "OpenIdAccount",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"userId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["userId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1513,23 +1377,17 @@
|
|||
"indexes": {
|
||||
"User_uri_key": {
|
||||
"name": "User_uri_key",
|
||||
"columns": [
|
||||
"uri"
|
||||
],
|
||||
"columns": ["uri"],
|
||||
"isUnique": true
|
||||
},
|
||||
"User_username_key": {
|
||||
"name": "User_username_key",
|
||||
"columns": [
|
||||
"username"
|
||||
],
|
||||
"columns": ["username"],
|
||||
"isUnique": true
|
||||
},
|
||||
"User_email_key": {
|
||||
"name": "User_email_key",
|
||||
"columns": [
|
||||
"email"
|
||||
],
|
||||
"columns": ["email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
|
|
@ -1539,12 +1397,8 @@
|
|||
"tableFrom": "User",
|
||||
"tableTo": "Instance",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"instanceId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["instanceId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1589,12 +1443,8 @@
|
|||
"tableFrom": "OpenIdLoginFlow",
|
||||
"tableTo": "Application",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"applicationId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["applicationId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1647,12 +1497,8 @@
|
|||
"tableFrom": "Flag",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"flaggeStatusId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["flaggeStatusId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1661,12 +1507,8 @@
|
|||
"tableFrom": "Flag",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"flaggedUserId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["flaggedUserId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1724,12 +1566,8 @@
|
|||
"tableFrom": "ModNote",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"notedStatusId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["notedStatusId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1738,12 +1576,8 @@
|
|||
"tableFrom": "ModNote",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"notedUserId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["notedUserId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1752,12 +1586,8 @@
|
|||
"tableFrom": "ModNote",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"modId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["modId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
@ -1815,12 +1645,8 @@
|
|||
"tableFrom": "ModTag",
|
||||
"tableTo": "Status",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"taggedStatusId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["taggedStatusId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1829,12 +1655,8 @@
|
|||
"tableFrom": "ModTag",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"taggedUserId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["taggedUserId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
},
|
||||
|
|
@ -1843,12 +1665,8 @@
|
|||
"tableFrom": "ModTag",
|
||||
"tableTo": "User",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"modId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"columnsFrom": ["modId"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "cascade"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import {
|
||||
pgTable,
|
||||
timestamp,
|
||||
text,
|
||||
integer,
|
||||
foreignKey,
|
||||
uuid,
|
||||
boolean,
|
||||
uniqueIndex,
|
||||
jsonb,
|
||||
index,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { relations, sql } from "drizzle-orm";
|
||||
import {
|
||||
boolean,
|
||||
foreignKey,
|
||||
index,
|
||||
integer,
|
||||
jsonb,
|
||||
pgTable,
|
||||
text,
|
||||
timestamp,
|
||||
uniqueIndex,
|
||||
uuid,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
export const emoji = pgTable("Emoji", {
|
||||
id: uuid("id").default(sql`uuid_generate_v7()`).primaryKey().notNull(),
|
||||
|
|
|
|||
4
index.ts
4
index.ts
|
|
@ -4,11 +4,11 @@ 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";
|
||||
import { createServer } from "~server";
|
||||
import { db, client as pgClient } from "~drizzle/db";
|
||||
import { status } from "~drizzle/schema";
|
||||
import { count, sql } from "drizzle-orm";
|
||||
import { createServer } from "~server";
|
||||
|
||||
await pgClient.connect();
|
||||
const timeAtStart = performance.now();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ETailwind, EButton } from "vue-email";
|
||||
import { EButton, ETailwind } from "vue-email";
|
||||
import tailwindConfig from "~/tailwind.config";
|
||||
|
||||
defineProps<{
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import { getHighlighterCore } from "shiki/core";
|
||||
import getWasm from "shiki/wasm";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import { getHighlighterCore } from "shiki/core";
|
||||
import getWasm from "shiki/wasm";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const config = (await useFetch("/api/config")).data.value;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Config } from "tailwindcss";
|
||||
import forms from "@tailwindcss/forms";
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
// Default are on https://tailwindcss.nuxtjs.org/tailwind/config#default-configuration
|
||||
export default (<Partial<Config>>{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { appendFile, mkdir, exists } from "node:fs/promises";
|
||||
import { appendFile, exists, mkdir } from "node:fs/promises";
|
||||
import { dirname } from "node:path";
|
||||
import type { BunFile } from "bun";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Config } from "config-manager";
|
||||
import { S3Client } from "@jsr/bradenmacdonald__s3-lite-client";
|
||||
import type { Config } from "config-manager";
|
||||
import type { ConvertableMediaFormats } from "./media-converter";
|
||||
import { MediaConverter } from "./media-converter";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ import type { S3Client } from "@jsr/bradenmacdonald__s3-lite-client";
|
|||
import type { Config } from "config-manager";
|
||||
// FILEPATH: /home/jessew/Dev/lysand/packages/media-manager/backends/s3.test.ts
|
||||
import {
|
||||
LocalMediaBackend,
|
||||
MediaBackend,
|
||||
MediaBackendType,
|
||||
MediaHasher,
|
||||
LocalMediaBackend,
|
||||
S3MediaBackend,
|
||||
} from "..";
|
||||
import { ConvertableMediaFormats, MediaConverter } from "../media-converter";
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { randomBytes } from "node:crypto";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { client } from "~database/datasource";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import { findFirstUser } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { token } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -47,45 +48,28 @@ export default apiRoute<{
|
|||
if (!email || !password)
|
||||
return redirectToLogin("Invalid username or password");
|
||||
|
||||
// Get user
|
||||
const user = await client.user.findFirst({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
include: userRelations,
|
||||
const user = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.email, email),
|
||||
});
|
||||
|
||||
if (!user || !(await Bun.password.verify(password, user.password || "")))
|
||||
return redirectToLogin("Invalid username or password");
|
||||
|
||||
// Get application
|
||||
const application = await client.application.findFirst({
|
||||
where: {
|
||||
client_id,
|
||||
},
|
||||
const application = await db.query.application.findFirst({
|
||||
where: (app, { eq }) => eq(app.clientId, client_id),
|
||||
});
|
||||
|
||||
if (!application) return redirectToLogin("Invalid client_id");
|
||||
|
||||
const code = randomBytes(32).toString("hex");
|
||||
|
||||
await client.application.update({
|
||||
where: { id: application.id },
|
||||
data: {
|
||||
tokens: {
|
||||
create: {
|
||||
access_token: randomBytes(64).toString("base64url"),
|
||||
await db.insert(token).values({
|
||||
accessToken: randomBytes(64).toString("base64url"),
|
||||
code: code,
|
||||
scope: scopes.join(" "),
|
||||
token_type: TokenType.BEARER,
|
||||
user: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tokenType: TokenType.BEARER,
|
||||
applicationId: application.id,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
// Redirect to OAuth confirmation screen
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { client } from "~database/datasource";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { db } from "~drizzle/db";
|
||||
import { application, token } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -34,23 +35,15 @@ export default apiRoute<{
|
|||
302,
|
||||
);
|
||||
|
||||
// Get token
|
||||
const token = await client.token.findFirst({
|
||||
where: {
|
||||
code,
|
||||
application: {
|
||||
client_id,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: {
|
||||
include: userRelations,
|
||||
},
|
||||
application: true,
|
||||
},
|
||||
});
|
||||
const foundToken = await db
|
||||
.select()
|
||||
.from(token)
|
||||
.leftJoin(application, eq(token.applicationId, application.id))
|
||||
.where(and(eq(token.code, code), eq(application.clientId, client_id)))
|
||||
.limit(1);
|
||||
|
||||
if (!token) return redirectToLogin("Invalid code");
|
||||
if (!foundToken || foundToken.length <= 0)
|
||||
return redirectToLogin("Invalid code");
|
||||
|
||||
// Redirect back to application
|
||||
return Response.redirect(`${redirect_uri}?code=${code}`, 302);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,52 +32,24 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
if (!foundRelationship.blocking) {
|
||||
foundRelationship.blocking = true;
|
||||
}
|
||||
|
||||
if (!relationship.blocking) {
|
||||
relationship.blocking = true;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
blocking: true,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
findFirstUser,
|
||||
followRequestUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
|
|
@ -39,27 +36,19 @@ export default apiRoute<{
|
|||
|
||||
const { languages, notify, reblogs } = extraData.parsedRequest;
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
let relationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship.following) {
|
||||
relationship = await followRequestUser(
|
||||
self,
|
||||
user,
|
||||
otherUser,
|
||||
relationship.id,
|
||||
reblogs,
|
||||
notify,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import { type UserWithRelations, userToAPI } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findFirstUser,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -32,36 +35,27 @@ export default apiRoute<{
|
|||
// TODO: Add pinned
|
||||
const { max_id, min_id, since_id, limit = 20 } = extraData.parsedRequest;
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: userRelations,
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (limit < 1 || limit > 40) return errorResponse("Invalid limit", 400);
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
const { objects, link } = await fetchTimeline<UserWithRelations>(
|
||||
client.user,
|
||||
findManyUsers,
|
||||
{
|
||||
where: {
|
||||
relationships: {
|
||||
some: {
|
||||
subjectId: user.id,
|
||||
following: true,
|
||||
},
|
||||
},
|
||||
id: {
|
||||
lt: max_id,
|
||||
gt: min_id,
|
||||
gte: since_id,
|
||||
},
|
||||
},
|
||||
include: userRelations,
|
||||
take: Number(limit),
|
||||
orderBy: {
|
||||
id: "desc",
|
||||
},
|
||||
// @ts-ignore
|
||||
where: (follower, { and, lt, gt, gte, eq, sql }) =>
|
||||
and(
|
||||
max_id ? lt(follower.id, max_id) : undefined,
|
||||
since_id ? gte(follower.id, since_id) : undefined,
|
||||
min_id ? gt(follower.id, min_id) : undefined,
|
||||
sql`EXISTS (SELECT 1 FROM "Relationship" WHERE "Relationship"."subjectId" = ${otherUser.id} AND "Relationship"."objectId" = ${follower.id} AND "Relationship"."following" = true)`,
|
||||
),
|
||||
// @ts-expect-error Yes I KNOW the types are wrong
|
||||
orderBy: (liker, { desc }) => desc(liker.id),
|
||||
},
|
||||
req,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import { userToAPI, type UserWithRelations } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findFirstUser,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -32,36 +35,27 @@ export default apiRoute<{
|
|||
// TODO: Add pinned
|
||||
const { max_id, min_id, since_id, limit = 20 } = extraData.parsedRequest;
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: userRelations,
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (limit < 1 || limit > 40) return errorResponse("Invalid limit", 400);
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
const { objects, link } = await fetchTimeline<UserWithRelations>(
|
||||
client.user,
|
||||
findManyUsers,
|
||||
{
|
||||
where: {
|
||||
relationshipSubjects: {
|
||||
some: {
|
||||
ownerId: user.id,
|
||||
following: true,
|
||||
},
|
||||
},
|
||||
id: {
|
||||
lt: max_id,
|
||||
gt: min_id,
|
||||
gte: since_id,
|
||||
},
|
||||
},
|
||||
include: userRelations,
|
||||
take: Number(limit),
|
||||
orderBy: {
|
||||
id: "desc",
|
||||
},
|
||||
// @ts-ignore
|
||||
where: (following, { and, lt, gt, gte, eq, sql }) =>
|
||||
and(
|
||||
max_id ? lt(following.id, max_id) : undefined,
|
||||
since_id ? gte(following.id, since_id) : undefined,
|
||||
min_id ? gt(following.id, min_id) : undefined,
|
||||
sql`EXISTS (SELECT 1 FROM "Relationship" WHERE "Relationship"."subjectId" = ${following.id} AND "Relationship"."objectId" = ${otherUser.id} AND "Relationship"."following" = true)`,
|
||||
),
|
||||
// @ts-expect-error Yes I KNOW the types are wrong
|
||||
orderBy: (liker, { desc }) => desc(liker.id),
|
||||
},
|
||||
req,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./index";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import { meta } from "./index";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -35,58 +37,31 @@ export default apiRoute<{
|
|||
|
||||
const { notifications, duration } = extraData.parsedRequest;
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const user = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, user);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (!relationship.muting) {
|
||||
relationship.muting = true;
|
||||
if (!foundRelationship.muting) {
|
||||
foundRelationship.muting = true;
|
||||
}
|
||||
if (notifications ?? true) {
|
||||
relationship.mutingNotifications = true;
|
||||
foundRelationship.mutingNotifications = true;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
muting: true,
|
||||
mutingNotifications: notifications ?? true,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
|
||||
// TODO: Implement duration
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -34,50 +36,23 @@ export default apiRoute<{
|
|||
|
||||
const { comment } = extraData.parsedRequest;
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
foundRelationship.note = comment ?? "";
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
note: foundRelationship.note,
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
relationship.note = comment ?? "";
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
note: relationship.note,
|
||||
},
|
||||
});
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,52 +32,25 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (!foundRelationship.endorsed) {
|
||||
foundRelationship.endorsed = true;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (!relationship.endorsed) {
|
||||
relationship.endorsed = true;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
endorsed: true,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,66 +32,40 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (foundRelationship.followedBy) {
|
||||
foundRelationship.followedBy = false;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (relationship.followedBy) {
|
||||
relationship.followedBy = false;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
followedBy: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
|
||||
if (user.instanceId === null) {
|
||||
if (otherUser.instanceId === null) {
|
||||
// Also remove from followers list
|
||||
await client.relationship.updateMany({
|
||||
where: {
|
||||
ownerId: user.id,
|
||||
subjectId: self.id,
|
||||
following: true,
|
||||
},
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
following: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(relationship.ownerId, otherUser.id),
|
||||
eq(relationship.subjectId, self.id),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,18 +1,12 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { sql } from "drizzle-orm";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
type StatusWithRelations,
|
||||
findManyStatuses,
|
||||
statusToAPI,
|
||||
type StatusWithRelations,
|
||||
} from "~database/entities/Status";
|
||||
import { findFirstUser } from "~database/entities/User";
|
||||
import {
|
||||
statusAndUserRelations,
|
||||
userRelations,
|
||||
} from "~database/entities/relations";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -20,9 +22,6 @@ export const meta = applyConfig({
|
|||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Blocks a user
|
||||
*/
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const id = matchedRoute.params.id;
|
||||
|
||||
|
|
@ -30,52 +29,24 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (foundRelationship.blocking) {
|
||||
foundRelationship.blocking = false;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (relationship.blocking) {
|
||||
relationship.blocking = false;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
blocking: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,53 +32,26 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (foundRelationship.following) {
|
||||
foundRelationship.following = false;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (relationship.following) {
|
||||
relationship.following = false;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
following: false,
|
||||
requested: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,54 +32,27 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const user = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, user);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (foundRelationship.muting) {
|
||||
foundRelationship.muting = false;
|
||||
foundRelationship.mutingNotifications = false;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (relationship.muting) {
|
||||
relationship.muting = false;
|
||||
}
|
||||
|
||||
// TODO: Implement duration
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
muting: false,
|
||||
},
|
||||
});
|
||||
mutingNotifications: false,
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { relationshipToAPI } from "~database/entities/Relationship";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { getRelationshipToOtherUser } from "~database/entities/User";
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -30,52 +32,25 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
relationships: {
|
||||
include: {
|
||||
owner: true,
|
||||
subject: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
const otherUser = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, id),
|
||||
});
|
||||
|
||||
if (!user) return errorResponse("User not found", 404);
|
||||
if (!otherUser) return errorResponse("User not found", 404);
|
||||
|
||||
// Check if already following
|
||||
let relationship = await getRelationshipToOtherUser(self, user);
|
||||
const foundRelationship = await getRelationshipToOtherUser(self, otherUser);
|
||||
|
||||
if (!relationship) {
|
||||
// Create new relationship
|
||||
if (foundRelationship.endorsed) {
|
||||
foundRelationship.endorsed = false;
|
||||
|
||||
const newRelationship = await createNewRelationship(self, user);
|
||||
|
||||
await client.user.update({
|
||||
where: { id: self.id },
|
||||
data: {
|
||||
relationships: {
|
||||
connect: {
|
||||
id: newRelationship.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
relationship = newRelationship;
|
||||
}
|
||||
|
||||
if (relationship.endorsed) {
|
||||
relationship.endorsed = false;
|
||||
}
|
||||
|
||||
await client.relationship.update({
|
||||
where: { id: relationship.id },
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
endorsed: false,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(eq(relationship.id, foundRelationship.id));
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { userToAPI } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import { findManyUsers, userToAPI } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -34,34 +33,52 @@ export default apiRoute<{
|
|||
return errorResponse("Number of ids must be between 1 and 10", 422);
|
||||
}
|
||||
|
||||
const followersOfIds = await client.user.findMany({
|
||||
where: {
|
||||
relationships: {
|
||||
some: {
|
||||
subjectId: {
|
||||
in: ids,
|
||||
},
|
||||
following: true,
|
||||
},
|
||||
},
|
||||
const idFollowerRelationships = await db.query.relationship.findMany({
|
||||
columns: {
|
||||
ownerId: true,
|
||||
},
|
||||
where: (relationship, { inArray, and, eq }) =>
|
||||
and(
|
||||
inArray(relationship.subjectId, ids),
|
||||
eq(relationship.following, true),
|
||||
),
|
||||
});
|
||||
|
||||
// Find users that you follow in followersOfIds
|
||||
const output = await client.user.findMany({
|
||||
where: {
|
||||
relationships: {
|
||||
some: {
|
||||
ownerId: self.id,
|
||||
subjectId: {
|
||||
in: followersOfIds.map((f) => f.id),
|
||||
if (idFollowerRelationships.length === 0) {
|
||||
return jsonResponse([]);
|
||||
}
|
||||
|
||||
// Find users that you follow in idFollowerRelationships
|
||||
const relevantRelationships = await db.query.relationship.findMany({
|
||||
columns: {
|
||||
subjectId: true,
|
||||
},
|
||||
following: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: userRelations,
|
||||
where: (relationship, { inArray, and, eq }) =>
|
||||
and(
|
||||
eq(relationship.ownerId, self.id),
|
||||
inArray(
|
||||
relationship.subjectId,
|
||||
idFollowerRelationships.map((f) => f.ownerId),
|
||||
),
|
||||
eq(relationship.following, true),
|
||||
),
|
||||
});
|
||||
|
||||
return jsonResponse(output.map((o) => userToAPI(o)));
|
||||
if (relevantRelationships.length === 0) {
|
||||
return jsonResponse([]);
|
||||
}
|
||||
|
||||
const finalUsers = await findManyUsers({
|
||||
where: (user, { inArray }) =>
|
||||
inArray(
|
||||
user.id,
|
||||
relevantRelationships.map((r) => r.subjectId),
|
||||
),
|
||||
});
|
||||
|
||||
if (finalUsers.length === 0) {
|
||||
return jsonResponse([]);
|
||||
}
|
||||
|
||||
return jsonResponse(finalUsers.map((o) => userToAPI(o)));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { jsonResponse, response } from "@response";
|
||||
import { tempmailDomains } from "@tempmail";
|
||||
import ISO6391 from "iso-639-1";
|
||||
import { client } from "~database/datasource";
|
||||
import { createNewLocalUser } from "~database/entities/User";
|
||||
import { createNewLocalUser, findFirstUser } from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -127,11 +126,16 @@ export default apiRoute<{
|
|||
});
|
||||
|
||||
// Check if username is taken
|
||||
if (await client.user.findFirst({ where: { username: body.username } }))
|
||||
if (
|
||||
await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.username, body.username ?? ""),
|
||||
})
|
||||
) {
|
||||
errors.details.username.push({
|
||||
error: "ERR_TAKEN",
|
||||
description: "is already taken",
|
||||
});
|
||||
}
|
||||
|
||||
// Check if email is valid
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { getUserUri } from "~database/entities/User";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./index";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import { getUserUri } from "~database/entities/User";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./index";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import type { User } from "@prisma/client";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
createNewRelationship,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import type { User } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -37,13 +37,12 @@ export default apiRoute<{
|
|||
return errorResponse("Number of ids must be between 1 and 10", 422);
|
||||
}
|
||||
|
||||
const relationships = await client.relationship.findMany({
|
||||
where: {
|
||||
ownerId: self.id,
|
||||
subjectId: {
|
||||
in: ids,
|
||||
},
|
||||
},
|
||||
const relationships = await db.query.relationship.findMany({
|
||||
where: (relationship, { inArray, and, eq }) =>
|
||||
and(
|
||||
inArray(relationship.subjectId, ids),
|
||||
eq(relationship.ownerId, self.id),
|
||||
),
|
||||
});
|
||||
|
||||
// Find IDs that dont have a relationship
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { getUserUri } from "~database/entities/User";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./index";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import { getUserUri } from "~database/entities/User";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./index";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { sql } from "drizzle-orm";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findManyUsers,
|
||||
resolveWebFinger,
|
||||
userToAPI,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
import { user } from "~drizzle/schema";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { convertTextToHtml } from "@formatting";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { sanitizeHtml } from "@sanitization";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import ISO6391 from "iso-639-1";
|
||||
import { MediaBackendType } from "media-manager";
|
||||
import type { MediaBackend } from "media-manager";
|
||||
import { client } from "~database/datasource";
|
||||
import { LocalMediaBackend, S3MediaBackend } from "media-manager";
|
||||
import { getUrl } from "~database/entities/Attachment";
|
||||
import { parseEmojis } from "~database/entities/Emoji";
|
||||
import { userToAPI } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import { S3MediaBackend, LocalMediaBackend } from "media-manager";
|
||||
import { findFirstUser, userToAPI } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { emojiToUser, user } from "~drizzle/schema";
|
||||
import type { APISource } from "~types/entities/source";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -38,9 +39,9 @@ export default apiRoute<{
|
|||
"source[sensitive]": string;
|
||||
"source[language]": string;
|
||||
}>(async (req, matchedRoute, extraData) => {
|
||||
const { user } = extraData.auth;
|
||||
const { user: self } = extraData.auth;
|
||||
|
||||
if (!user) return errorResponse("Unauthorized", 401);
|
||||
if (!self) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
|
|
@ -109,12 +110,12 @@ export default apiRoute<{
|
|||
}
|
||||
|
||||
// Remove emojis
|
||||
user.emojis = [];
|
||||
self.emojis = [];
|
||||
|
||||
user.displayName = sanitizedDisplayName;
|
||||
self.displayName = sanitizedDisplayName;
|
||||
}
|
||||
|
||||
if (note && user.source) {
|
||||
if (note && self.source) {
|
||||
// Check if within allowed note length
|
||||
if (sanitizedNote.length > config.validation.max_note_size) {
|
||||
return errorResponse(
|
||||
|
|
@ -128,12 +129,12 @@ export default apiRoute<{
|
|||
return errorResponse("Bio contains blocked words", 422);
|
||||
}
|
||||
|
||||
(user.source as APISource).note = sanitizedNote;
|
||||
(self.source as APISource).note = sanitizedNote;
|
||||
// TODO: Convert note to HTML
|
||||
user.note = await convertTextToHtml(sanitizedNote);
|
||||
self.note = await convertTextToHtml(sanitizedNote);
|
||||
}
|
||||
|
||||
if (source_privacy && user.source) {
|
||||
if (source_privacy && self.source) {
|
||||
// Check if within allowed privacy values
|
||||
if (
|
||||
!["public", "unlisted", "private", "direct"].includes(
|
||||
|
|
@ -146,19 +147,19 @@ export default apiRoute<{
|
|||
);
|
||||
}
|
||||
|
||||
(user.source as APISource).privacy = source_privacy;
|
||||
(self.source as APISource).privacy = source_privacy;
|
||||
}
|
||||
|
||||
if (source_sensitive && user.source) {
|
||||
if (source_sensitive && self.source) {
|
||||
// Check if within allowed sensitive values
|
||||
if (source_sensitive !== "true" && source_sensitive !== "false") {
|
||||
return errorResponse("Sensitive must be a boolean", 422);
|
||||
}
|
||||
|
||||
(user.source as APISource).sensitive = source_sensitive === "true";
|
||||
(self.source as APISource).sensitive = source_sensitive === "true";
|
||||
}
|
||||
|
||||
if (source_language && user.source) {
|
||||
if (source_language && self.source) {
|
||||
if (!ISO6391.validate(source_language)) {
|
||||
return errorResponse(
|
||||
"Language must be a valid ISO 639-1 code",
|
||||
|
|
@ -166,7 +167,7 @@ export default apiRoute<{
|
|||
);
|
||||
}
|
||||
|
||||
(user.source as APISource).language = source_language;
|
||||
(self.source as APISource).language = source_language;
|
||||
}
|
||||
|
||||
if (avatar) {
|
||||
|
|
@ -180,7 +181,7 @@ export default apiRoute<{
|
|||
|
||||
const { path } = await mediaManager.addFile(avatar);
|
||||
|
||||
user.avatar = getUrl(path, config);
|
||||
self.avatar = getUrl(path, config);
|
||||
}
|
||||
|
||||
if (header) {
|
||||
|
|
@ -194,7 +195,7 @@ export default apiRoute<{
|
|||
|
||||
const { path } = await mediaManager.addFile(header);
|
||||
|
||||
user.header = getUrl(path, config);
|
||||
self.header = getUrl(path, config);
|
||||
}
|
||||
|
||||
if (locked) {
|
||||
|
|
@ -203,7 +204,7 @@ export default apiRoute<{
|
|||
return errorResponse("Locked must be a boolean", 422);
|
||||
}
|
||||
|
||||
user.isLocked = locked === "true";
|
||||
self.isLocked = locked === "true";
|
||||
}
|
||||
|
||||
if (bot) {
|
||||
|
|
@ -212,7 +213,7 @@ export default apiRoute<{
|
|||
return errorResponse("Bot must be a boolean", 422);
|
||||
}
|
||||
|
||||
user.isBot = bot === "true";
|
||||
self.isBot = bot === "true";
|
||||
}
|
||||
|
||||
if (discoverable) {
|
||||
|
|
@ -221,7 +222,7 @@ export default apiRoute<{
|
|||
return errorResponse("Discoverable must be a boolean", 422);
|
||||
}
|
||||
|
||||
user.isDiscoverable = discoverable === "true";
|
||||
self.isDiscoverable = discoverable === "true";
|
||||
}
|
||||
|
||||
// Parse emojis
|
||||
|
|
@ -229,36 +230,49 @@ export default apiRoute<{
|
|||
const displaynameEmojis = await parseEmojis(sanitizedDisplayName);
|
||||
const noteEmojis = await parseEmojis(sanitizedNote);
|
||||
|
||||
user.emojis = [...displaynameEmojis, ...noteEmojis];
|
||||
self.emojis = [...displaynameEmojis, ...noteEmojis];
|
||||
|
||||
// Deduplicate emojis
|
||||
user.emojis = user.emojis.filter(
|
||||
self.emojis = self.emojis.filter(
|
||||
(emoji, index, self) =>
|
||||
self.findIndex((e) => e.id === emoji.id) === index,
|
||||
);
|
||||
|
||||
const output = await client.user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
displayName: user.displayName,
|
||||
note: user.note,
|
||||
avatar: user.avatar,
|
||||
header: user.header,
|
||||
isLocked: user.isLocked,
|
||||
isBot: user.isBot,
|
||||
isDiscoverable: user.isDiscoverable,
|
||||
emojis: {
|
||||
disconnect: user.emojis.map((e) => ({
|
||||
id: e.id,
|
||||
})),
|
||||
connect: user.emojis.map((e) => ({
|
||||
id: e.id,
|
||||
})),
|
||||
},
|
||||
source: user.source || undefined,
|
||||
},
|
||||
include: userRelations,
|
||||
await db
|
||||
.update(user)
|
||||
.set({
|
||||
displayName: self.displayName,
|
||||
note: self.note,
|
||||
avatar: self.avatar,
|
||||
header: self.header,
|
||||
isLocked: self.isLocked,
|
||||
isBot: self.isBot,
|
||||
isDiscoverable: self.isDiscoverable,
|
||||
source: self.source || undefined,
|
||||
})
|
||||
.where(eq(user.id, self.id));
|
||||
|
||||
// Connect emojis, if any
|
||||
for (const emoji of self.emojis) {
|
||||
await db
|
||||
.delete(emojiToUser)
|
||||
.where(and(eq(emojiToUser.a, emoji.id), eq(emojiToUser.b, self.id)))
|
||||
.execute();
|
||||
|
||||
await db
|
||||
.insert(emojiToUser)
|
||||
.values({
|
||||
a: emoji.id,
|
||||
b: self.id,
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
const output = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, self.id),
|
||||
});
|
||||
|
||||
if (!output) return errorResponse("Couldn't edit user", 500);
|
||||
|
||||
return jsonResponse(userToAPI(output));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { randomBytes } from "node:crypto";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { db } from "~drizzle/db";
|
||||
import { application } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -33,24 +34,28 @@ export default apiRoute<{
|
|||
return errorResponse("Redirect URI must be a valid URI", 422);
|
||||
}
|
||||
}
|
||||
const application = await client.application.create({
|
||||
data: {
|
||||
|
||||
const app = (
|
||||
await db
|
||||
.insert(application)
|
||||
.values({
|
||||
name: client_name || "",
|
||||
redirect_uris: redirect_uris || "",
|
||||
redirectUris: redirect_uris || "",
|
||||
scopes: scopes || "read",
|
||||
website: website || null,
|
||||
client_id: randomBytes(32).toString("base64url"),
|
||||
clientId: randomBytes(32).toString("base64url"),
|
||||
secret: randomBytes(64).toString("base64url"),
|
||||
},
|
||||
});
|
||||
})
|
||||
.returning()
|
||||
)[0];
|
||||
|
||||
return jsonResponse({
|
||||
id: application.id,
|
||||
name: application.name,
|
||||
website: application.website,
|
||||
client_id: application.client_id,
|
||||
client_secret: application.secret,
|
||||
redirect_uri: application.redirect_uris,
|
||||
vapid_link: application.vapid_key,
|
||||
id: app.id,
|
||||
name: app.name,
|
||||
website: app.website,
|
||||
client_id: app.clientId,
|
||||
client_secret: app.secret,
|
||||
redirect_uri: app.redirectUris,
|
||||
vapid_link: app.vapidKey,
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { emojiToAPI } from "~database/entities/Emoji";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
statusToAPI,
|
||||
type StatusWithRelations,
|
||||
findManyStatuses,
|
||||
statusToAPI,
|
||||
} from "~database/entities/Status";
|
||||
import { statusAndUserRelations } from "~database/entities/relations";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -37,25 +36,18 @@ export default apiRoute<{
|
|||
if (!user) return errorResponse("Unauthorized", 401);
|
||||
|
||||
const { objects, link } = await fetchTimeline<StatusWithRelations>(
|
||||
client.status,
|
||||
findManyStatuses,
|
||||
{
|
||||
where: {
|
||||
id: {
|
||||
lt: max_id ?? undefined,
|
||||
gte: since_id ?? undefined,
|
||||
gt: min_id ?? undefined,
|
||||
},
|
||||
likes: {
|
||||
some: {
|
||||
likerId: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: statusAndUserRelations,
|
||||
take: Number(limit),
|
||||
orderBy: {
|
||||
id: "desc",
|
||||
},
|
||||
// @ts-ignore
|
||||
where: (status, { and, lt, gt, gte, eq, sql }) =>
|
||||
and(
|
||||
max_id ? lt(status.id, max_id) : undefined,
|
||||
since_id ? gte(status.id, since_id) : undefined,
|
||||
min_id ? gt(status.id, min_id) : undefined,
|
||||
sql`EXISTS (SELECT 1 FROM "Like" WHERE "Like"."likedId" = ${status.id} AND "Like"."likerId" = ${user.id})`,
|
||||
),
|
||||
// @ts-expect-error Yes I KNOW the types are wrong
|
||||
orderBy: (status, { desc }) => desc(status.id),
|
||||
},
|
||||
req,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import {
|
||||
checkForBidirectionalRelationships,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { sendFollowAccept } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import {
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
sendFollowAccept,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -27,11 +32,8 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
const { account_id } = matchedRoute.params;
|
||||
|
||||
const account = await client.user.findUnique({
|
||||
where: {
|
||||
id: account_id,
|
||||
},
|
||||
include: userRelations,
|
||||
const account = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, account_id),
|
||||
});
|
||||
|
||||
if (!account) return errorResponse("Account not found", 404);
|
||||
|
|
@ -40,37 +42,35 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
await checkForBidirectionalRelationships(user, account);
|
||||
|
||||
// Authorize follow request
|
||||
await client.relationship.updateMany({
|
||||
where: {
|
||||
subjectId: user.id,
|
||||
ownerId: account.id,
|
||||
requested: true,
|
||||
},
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
requested: false,
|
||||
following: true,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(relationship.subjectId, user.id),
|
||||
eq(relationship.ownerId, account.id),
|
||||
),
|
||||
);
|
||||
|
||||
// Update followedBy for other user
|
||||
await client.relationship.updateMany({
|
||||
where: {
|
||||
subjectId: account.id,
|
||||
ownerId: user.id,
|
||||
},
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
followedBy: true,
|
||||
},
|
||||
});
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(relationship.subjectId, account.id),
|
||||
eq(relationship.ownerId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
const relationship = await client.relationship.findFirst({
|
||||
where: {
|
||||
subjectId: account.id,
|
||||
ownerId: user.id,
|
||||
},
|
||||
});
|
||||
const foundRelationship = await getRelationshipToOtherUser(user, account);
|
||||
|
||||
if (!relationship) return errorResponse("Relationship not found", 404);
|
||||
if (!foundRelationship) return errorResponse("Relationship not found", 404);
|
||||
|
||||
// Check if accepting remote follow
|
||||
if (account.instanceId) {
|
||||
|
|
@ -78,5 +78,5 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
await sendFollowAccept(account, user);
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import {
|
||||
checkForBidirectionalRelationships,
|
||||
relationshipToAPI,
|
||||
} from "~database/entities/Relationship";
|
||||
import { sendFollowReject } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import {
|
||||
findFirstUser,
|
||||
getRelationshipToOtherUser,
|
||||
sendFollowReject,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { relationship } from "~drizzle/schema";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -27,11 +32,8 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
|
||||
const { account_id } = matchedRoute.params;
|
||||
|
||||
const account = await client.user.findUnique({
|
||||
where: {
|
||||
id: account_id,
|
||||
},
|
||||
include: userRelations,
|
||||
const account = await findFirstUser({
|
||||
where: (user, { eq }) => eq(user.id, account_id),
|
||||
});
|
||||
|
||||
if (!account) return errorResponse("Account not found", 404);
|
||||
|
|
@ -40,25 +42,35 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
await checkForBidirectionalRelationships(user, account);
|
||||
|
||||
// Reject follow request
|
||||
await client.relationship.updateMany({
|
||||
where: {
|
||||
subjectId: user.id,
|
||||
ownerId: account.id,
|
||||
requested: true,
|
||||
},
|
||||
data: {
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
requested: false,
|
||||
},
|
||||
});
|
||||
following: false,
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(relationship.subjectId, user.id),
|
||||
eq(relationship.ownerId, account.id),
|
||||
),
|
||||
);
|
||||
|
||||
const relationship = await client.relationship.findFirst({
|
||||
where: {
|
||||
subjectId: account.id,
|
||||
ownerId: user.id,
|
||||
},
|
||||
});
|
||||
// Update followedBy for other user
|
||||
await db
|
||||
.update(relationship)
|
||||
.set({
|
||||
followedBy: false,
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(relationship.subjectId, account.id),
|
||||
eq(relationship.ownerId, user.id),
|
||||
),
|
||||
);
|
||||
|
||||
if (!relationship) return errorResponse("Relationship not found", 404);
|
||||
const foundRelationship = await getRelationshipToOtherUser(user, account);
|
||||
|
||||
if (!foundRelationship) return errorResponse("Relationship not found", 404);
|
||||
|
||||
// Check if rejecting remote follow
|
||||
if (account.instanceId) {
|
||||
|
|
@ -66,5 +78,5 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
await sendFollowReject(account, user);
|
||||
}
|
||||
|
||||
return jsonResponse(relationshipToAPI(relationship));
|
||||
return jsonResponse(relationshipToAPI(foundRelationship));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
import { count, isNull } from "drizzle-orm";
|
||||
import { client } from "~database/datasource";
|
||||
import { userToAPI } from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import { and, count, countDistinct, eq, gte, isNull } from "drizzle-orm";
|
||||
import { findFirstUser, userToAPI } from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { status, user } from "~drizzle/schema";
|
||||
import { instance, status, user } from "~drizzle/schema";
|
||||
import manifest from "~package.json";
|
||||
import type { APIInstance } from "~types/entities/instance";
|
||||
|
||||
|
|
@ -45,33 +43,39 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
.where(isNull(user.instanceId))
|
||||
)[0].count;
|
||||
|
||||
// Get the first created admin user
|
||||
const contactAccount = await client.user.findFirst({
|
||||
where: {
|
||||
instanceId: null,
|
||||
isAdmin: true,
|
||||
},
|
||||
orderBy: {
|
||||
id: "asc",
|
||||
},
|
||||
include: userRelations,
|
||||
const contactAccount = await findFirstUser({
|
||||
where: (user, { isNull, eq, and }) =>
|
||||
and(isNull(user.instanceId), eq(user.isAdmin, true)),
|
||||
orderBy: (user, { asc }) => asc(user.id),
|
||||
});
|
||||
|
||||
// Get user that have posted once in the last 30 days
|
||||
const monthlyActiveUsers = await client.user.count({
|
||||
where: {
|
||||
instanceId: null,
|
||||
statuses: {
|
||||
some: {
|
||||
createdAt: {
|
||||
gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const monthlyActiveUsers = (
|
||||
await db
|
||||
.select({
|
||||
count: countDistinct(user),
|
||||
})
|
||||
.from(user)
|
||||
.leftJoin(status, eq(user.id, status.authorId))
|
||||
.where(
|
||||
and(
|
||||
isNull(user.instanceId),
|
||||
gte(
|
||||
status.createdAt,
|
||||
new Date(
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
).toISOString(),
|
||||
),
|
||||
),
|
||||
)
|
||||
)[0].count;
|
||||
|
||||
const knownDomainsCount = await client.instance.count();
|
||||
const knownDomainsCount = (
|
||||
await db
|
||||
.select({
|
||||
count: count(),
|
||||
})
|
||||
.from(instance)
|
||||
)[0].count;
|
||||
|
||||
// TODO: fill in more values
|
||||
return jsonResponse({
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse, response } from "@response";
|
||||
import { eq } from "drizzle-orm";
|
||||
import type { MediaBackend } from "media-manager";
|
||||
import { MediaBackendType } from "media-manager";
|
||||
import { client } from "~database/datasource";
|
||||
import { attachmentToAPI, getUrl } from "~database/entities/Attachment";
|
||||
import { db } from "~drizzle/db";
|
||||
import { attachment } from "~drizzle/schema";
|
||||
import { LocalMediaBackend, S3MediaBackend } from "~packages/media-manager";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -35,13 +37,11 @@ export default apiRoute<{
|
|||
|
||||
const id = matchedRoute.params.id;
|
||||
|
||||
const attachment = await client.attachment.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
const foundAttachment = await db.query.attachment.findFirst({
|
||||
where: (attachment, { eq }) => eq(attachment.id, id),
|
||||
});
|
||||
|
||||
if (!attachment) {
|
||||
if (!foundAttachment) {
|
||||
return errorResponse("Media not found", 404);
|
||||
}
|
||||
|
||||
|
|
@ -49,15 +49,15 @@ export default apiRoute<{
|
|||
|
||||
switch (req.method) {
|
||||
case "GET": {
|
||||
if (attachment.url) {
|
||||
return jsonResponse(attachmentToAPI(attachment));
|
||||
if (foundAttachment.url) {
|
||||
return jsonResponse(attachmentToAPI(foundAttachment));
|
||||
}
|
||||
return response(null, 206);
|
||||
}
|
||||
case "PUT": {
|
||||
const { description, thumbnail } = extraData.parsedRequest;
|
||||
|
||||
let thumbnailUrl = attachment.thumbnail_url;
|
||||
let thumbnailUrl = foundAttachment.thumbnailUrl;
|
||||
|
||||
let mediaManager: MediaBackend;
|
||||
|
||||
|
|
@ -78,26 +78,27 @@ export default apiRoute<{
|
|||
thumbnailUrl = getUrl(path, config);
|
||||
}
|
||||
|
||||
const descriptionText = description || attachment.description;
|
||||
const descriptionText = description || foundAttachment.description;
|
||||
|
||||
if (
|
||||
descriptionText !== attachment.description ||
|
||||
thumbnailUrl !== attachment.thumbnail_url
|
||||
descriptionText !== foundAttachment.description ||
|
||||
thumbnailUrl !== foundAttachment.thumbnailUrl
|
||||
) {
|
||||
const newAttachment = await client.attachment.update({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
data: {
|
||||
const newAttachment = (
|
||||
await db
|
||||
.update(attachment)
|
||||
.set({
|
||||
description: descriptionText,
|
||||
thumbnail_url: thumbnailUrl,
|
||||
},
|
||||
});
|
||||
thumbnailUrl,
|
||||
})
|
||||
.where(eq(attachment.id, id))
|
||||
.returning()
|
||||
)[0];
|
||||
|
||||
return jsonResponse(attachmentToAPI(newAttachment));
|
||||
}
|
||||
|
||||
return jsonResponse(attachmentToAPI(attachment));
|
||||
return jsonResponse(attachmentToAPI(foundAttachment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import { encode } from "blurhash";
|
|||
import { MediaBackendType } from "media-manager";
|
||||
import type { MediaBackend } from "media-manager";
|
||||
import sharp from "sharp";
|
||||
import { client } from "~database/datasource";
|
||||
import { attachmentToAPI, getUrl } from "~database/entities/Attachment";
|
||||
import { db } from "~drizzle/db";
|
||||
import { attachment } from "~drizzle/schema";
|
||||
import { LocalMediaBackend, S3MediaBackend } from "~packages/media-manager";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -132,20 +133,22 @@ export default apiRoute<{
|
|||
thumbnailUrl = getUrl(path, config);
|
||||
}
|
||||
|
||||
const newAttachment = await client.attachment.create({
|
||||
data: {
|
||||
const newAttachment = (
|
||||
await db
|
||||
.insert(attachment)
|
||||
.values({
|
||||
url,
|
||||
thumbnail_url: thumbnailUrl,
|
||||
thumbnailUrl,
|
||||
sha256: sha256.update(await file.arrayBuffer()).digest("hex"),
|
||||
mime_type: file.type,
|
||||
mimeType: file.type,
|
||||
description: description ?? "",
|
||||
size: file.size,
|
||||
blurhash: blurhash ?? undefined,
|
||||
width: metadata?.width ?? undefined,
|
||||
height: metadata?.height ?? undefined,
|
||||
},
|
||||
});
|
||||
|
||||
})
|
||||
.returning()
|
||||
)[0];
|
||||
// TODO: Add job to process videos and other media
|
||||
|
||||
return jsonResponse(attachmentToAPI(newAttachment));
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
|
|||
|
|
@ -1,20 +1,11 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
findManyNotifications,
|
||||
notificationToAPI,
|
||||
} from "~database/entities/Notification";
|
||||
import {
|
||||
statusAndUserRelations,
|
||||
userRelations,
|
||||
} from "~database/entities/relations";
|
||||
import type {
|
||||
Notification,
|
||||
NotificationWithRelations,
|
||||
} from "~database/entities/Notification";
|
||||
import { db } from "~drizzle/db";
|
||||
import type { NotificationWithRelations } from "~database/entities/Notification";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { createLike } from "~database/entities/Like";
|
||||
import {
|
||||
findFirstStatuses,
|
||||
isViewableByUser,
|
||||
statusToAPI,
|
||||
} from "~database/entities/Status";
|
||||
import { statusAndUserRelations } from "~database/entities/relations";
|
||||
import { db } from "~drizzle/db";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -40,11 +39,9 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
|
|||
if (!status || !isViewableByUser(status, user))
|
||||
return errorResponse("Record not found", 404);
|
||||
|
||||
const existingLike = await client.like.findFirst({
|
||||
where: {
|
||||
likedId: status.id,
|
||||
likerId: user.id,
|
||||
},
|
||||
const existingLike = await db.query.like.findFirst({
|
||||
where: (like, { and, eq }) =>
|
||||
and(eq(like.likedId, status.id), eq(like.likerId, user.id)),
|
||||
});
|
||||
|
||||
if (!existingLike) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./favourited_by";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import { meta } from "./favourited_by";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ afterAll(async () => {
|
|||
|
||||
beforeAll(async () => {
|
||||
for (const status of timeline) {
|
||||
await fetch(
|
||||
const res = await fetch(
|
||||
new URL(
|
||||
`/api/v1/statuses/${status.id}/favourite`,
|
||||
config.http.base_url,
|
||||
|
|
@ -29,6 +28,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ import { errorResponse, jsonResponse } from "@response";
|
|||
import { fetchTimeline } from "@timelines";
|
||||
import { findFirstStatuses, isViewableByUser } from "~database/entities/Status";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./reblogged_by";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import type { APIAccount } from "~types/entities/account";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./reblogged_by";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
@ -29,6 +29,7 @@ beforeAll(async () => {
|
|||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import { fetchTimeline } from "@timelines";
|
|||
import { findFirstStatuses, isViewableByUser } from "~database/entities/Status";
|
||||
import {
|
||||
type UserWithRelations,
|
||||
userToAPI,
|
||||
findManyUsers,
|
||||
userToAPI,
|
||||
} from "~database/entities/User";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./index";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./index";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ import { apiRoute, applyConfig } from "@api";
|
|||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { sanitizeHtml } from "@sanitization";
|
||||
import { parse } from "marked";
|
||||
import { client } from "~database/datasource";
|
||||
import { getFromToken } from "~database/entities/Application";
|
||||
import type { StatusWithRelations } from "~database/entities/Status";
|
||||
import {
|
||||
createNewStatus,
|
||||
|
|
@ -12,10 +10,7 @@ import {
|
|||
parseTextMentions,
|
||||
statusToAPI,
|
||||
} from "~database/entities/Status";
|
||||
import type { UserWithRelations } from "~database/entities/User";
|
||||
import { statusAndUserRelations } from "~database/entities/relations";
|
||||
import { db } from "~drizzle/db";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./home";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./home";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { errorResponse, jsonResponse } from "@response";
|
|||
import { fetchTimeline } from "@timelines";
|
||||
import {
|
||||
type StatusWithRelations,
|
||||
statusToAPI,
|
||||
findManyStatuses,
|
||||
statusToAPI,
|
||||
} from "~database/entities/Status";
|
||||
import { db } from "~drizzle/db";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "~index";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { config } from "~index";
|
||||
import { meta } from "./public";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import { meta } from "./public";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ import { errorResponse, jsonResponse } from "@response";
|
|||
import { fetchTimeline } from "@timelines";
|
||||
import { client } from "~database/datasource";
|
||||
import {
|
||||
type StatusWithRelations,
|
||||
findManyStatuses,
|
||||
statusToAPI,
|
||||
type StatusWithRelations,
|
||||
} from "~database/entities/Status";
|
||||
import { statusAndUserRelations } from "~database/entities/relations";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { client } from "~database/datasource";
|
||||
import { statusToLysand } from "~database/entities/Status";
|
||||
import { userToLysand } from "~database/entities/User";
|
||||
import { statusAndUserRelations } from "~database/entities/relations";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { statusToLysand } from "~database/entities/Status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, response } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import type * as Lysand from "lysand-types";
|
||||
import { client } from "~database/datasource";
|
||||
import { objectToInboxRequest } from "~database/entities/Federation";
|
||||
import { createNewStatus, resolveStatus } from "~database/entities/Status";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
import {
|
||||
followAcceptToLysand,
|
||||
getRelationshipToOtherUser,
|
||||
resolveUser,
|
||||
sendFollowAccept,
|
||||
} from "~database/entities/User";
|
||||
import { objectToInboxRequest } from "~database/entities/Federation";
|
||||
import { userRelations } from "~database/entities/relations";
|
||||
import type { APIStatus } from "~types/entities/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
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 { db } from "~drizzle/db";
|
||||
import { application, user } from "~drizzle/schema";
|
||||
import type { APIEmoji } from "~types/entities/emoji";
|
||||
import type { APIInstance } from "~types/entities/instance";
|
||||
import { sendTestRequest, wrapRelativeUrl } from "./utils";
|
||||
import { db } from "~drizzle/db";
|
||||
import { inArray } from "drizzle-orm";
|
||||
import { application, user } from "~drizzle/schema";
|
||||
|
||||
const base_url = config.http.base_url;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import {
|
||||
createNewLocalUser,
|
||||
type User,
|
||||
type UserWithRelations,
|
||||
} from "~database/entities/User";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { server } from "~index";
|
||||
import { db } from "~drizzle/db";
|
||||
import { status, token, user } from "~drizzle/schema";
|
||||
import { inArray, like } from "drizzle-orm";
|
||||
import type { Status } from "~database/entities/Status";
|
||||
import {
|
||||
type User,
|
||||
type UserWithRelations,
|
||||
createNewLocalUser,
|
||||
} from "~database/entities/User";
|
||||
import { db } from "~drizzle/db";
|
||||
import { status, token, user } from "~drizzle/schema";
|
||||
import { server } from "~index";
|
||||
|
||||
/**
|
||||
* This allows us to send a test request to the server even when it isnt running
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { findManyStatuses, Status } from "~database/entities/Status";
|
||||
import type { findManyUsers, User } from "~database/entities/User";
|
||||
import type {
|
||||
findManyNotifications,
|
||||
Notification,
|
||||
} from "~database/entities/Notification";
|
||||
import type { db } from "~drizzle/db";
|
||||
import { config } from "config-manager";
|
||||
import type {
|
||||
Notification,
|
||||
findManyNotifications,
|
||||
} from "~database/entities/Notification";
|
||||
import type { Status, findManyStatuses } from "~database/entities/Status";
|
||||
import type { User, findManyUsers } from "~database/entities/User";
|
||||
import type { db } from "~drizzle/db";
|
||||
|
||||
export async function fetchTimeline<T extends User | Status | Notification>(
|
||||
model:
|
||||
|
|
|
|||
Loading…
Reference in a new issue