summaryrefslogtreecommitdiff
path: root/src/models/entities
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2019-04-14 20:38:55 +0900
committersyuilo <syuilotan@yahoo.co.jp>2019-04-14 20:38:55 +0900
commitd66e4b7ff97d512e2a2523815e2eef170456b37f (patch)
tree59ae1a102d88b5c2c2236b734ea4a584b4f9ba46 /src/models/entities
parent10.100.0 (diff)
parent11.0.0 (diff)
downloadmisskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.gz
misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.bz2
misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.zip
Merge branch 'develop'
Diffstat (limited to 'src/models/entities')
-rw-r--r--src/models/entities/abuse-user-report.ts41
-rw-r--r--src/models/entities/access-token.ts45
-rw-r--r--src/models/entities/app.ts60
-rw-r--r--src/models/entities/auth-session.ts43
-rw-r--r--src/models/entities/blocking.ts42
-rw-r--r--src/models/entities/drive-file.ts154
-rw-r--r--src/models/entities/drive-folder.ts49
-rw-r--r--src/models/entities/emoji.ts46
-rw-r--r--src/models/entities/follow-request.ts85
-rw-r--r--src/models/entities/following.ts80
-rw-r--r--src/models/entities/games/reversi/game.ts133
-rw-r--r--src/models/entities/games/reversi/matching.ts35
-rw-r--r--src/models/entities/hashtag.ts87
-rw-r--r--src/models/entities/instance.ts132
-rw-r--r--src/models/entities/log.ts46
-rw-r--r--src/models/entities/messaging-message.ts64
-rw-r--r--src/models/entities/meta.ts264
-rw-r--r--src/models/entities/muting.ts42
-rw-r--r--src/models/entities/note-favorite.ts35
-rw-r--r--src/models/entities/note-reaction.ts42
-rw-r--r--src/models/entities/note-unread.ts43
-rw-r--r--src/models/entities/note-watching.ts52
-rw-r--r--src/models/entities/note.ts231
-rw-r--r--src/models/entities/notification.ts94
-rw-r--r--src/models/entities/poll-vote.ts40
-rw-r--r--src/models/entities/poll.ts71
-rw-r--r--src/models/entities/registration-tickets.ts17
-rw-r--r--src/models/entities/signin.ts35
-rw-r--r--src/models/entities/sw-subscription.ts37
-rw-r--r--src/models/entities/user-keypair.ts33
-rw-r--r--src/models/entities/user-list-joining.ts41
-rw-r--r--src/models/entities/user-list.ts33
-rw-r--r--src/models/entities/user-note-pinings.ts35
-rw-r--r--src/models/entities/user-profile.ts209
-rw-r--r--src/models/entities/user-publickey.ts34
-rw-r--r--src/models/entities/user.ts224
36 files changed, 2754 insertions, 0 deletions
diff --git a/src/models/entities/abuse-user-report.ts b/src/models/entities/abuse-user-report.ts
new file mode 100644
index 0000000000..43ab56023a
--- /dev/null
+++ b/src/models/entities/abuse-user-report.ts
@@ -0,0 +1,41 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'reporterId'], { unique: true })
+export class AbuseUserReport {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the AbuseUserReport.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column(id())
+ public reporterId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public reporter: User | null;
+
+ @Column('varchar', {
+ length: 512,
+ })
+ public comment: string;
+}
diff --git a/src/models/entities/access-token.ts b/src/models/entities/access-token.ts
new file mode 100644
index 0000000000..d08930cf5a
--- /dev/null
+++ b/src/models/entities/access-token.ts
@@ -0,0 +1,45 @@
+import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn, RelationId } from 'typeorm';
+import { User } from './user';
+import { App } from './app';
+import { id } from '../id';
+
+@Entity()
+export class AccessToken {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the AccessToken.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column('varchar', {
+ length: 128
+ })
+ public token: string;
+
+ @Index()
+ @Column('varchar', {
+ length: 128
+ })
+ public hash: string;
+
+ @RelationId((self: AccessToken) => self.user)
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column(id())
+ public appId: App['id'];
+
+ @ManyToOne(type => App, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public app: App | null;
+}
diff --git a/src/models/entities/app.ts b/src/models/entities/app.ts
new file mode 100644
index 0000000000..ea87546311
--- /dev/null
+++ b/src/models/entities/app.ts
@@ -0,0 +1,60 @@
+import { Entity, PrimaryColumn, Column, Index, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class App {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the App.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The owner ID.'
+ })
+ public userId: User['id'] | null;
+
+ @ManyToOne(type => User, {
+ onDelete: 'SET NULL',
+ nullable: true,
+ })
+ public user: User | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 64,
+ comment: 'The secret key of the App.'
+ })
+ public secret: string;
+
+ @Column('varchar', {
+ length: 128,
+ comment: 'The name of the App.'
+ })
+ public name: string;
+
+ @Column('varchar', {
+ length: 512,
+ comment: 'The description of the App.'
+ })
+ public description: string;
+
+ @Column('varchar', {
+ length: 64, array: true,
+ comment: 'The permission of the App.'
+ })
+ public permission: string[];
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The callbackUrl of the App.'
+ })
+ public callbackUrl: string | null;
+}
diff --git a/src/models/entities/auth-session.ts b/src/models/entities/auth-session.ts
new file mode 100644
index 0000000000..4eec27e3f6
--- /dev/null
+++ b/src/models/entities/auth-session.ts
@@ -0,0 +1,43 @@
+import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } from 'typeorm';
+import { User } from './user';
+import { App } from './app';
+import { id } from '../id';
+
+@Entity()
+export class AuthSession {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the AuthSession.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column('varchar', {
+ length: 128
+ })
+ public token: string;
+
+ @Column({
+ ...id(),
+ nullable: true
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE',
+ nullable: true
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column(id())
+ public appId: App['id'];
+
+ @ManyToOne(type => App, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public app: App | null;
+}
diff --git a/src/models/entities/blocking.ts b/src/models/entities/blocking.ts
new file mode 100644
index 0000000000..48487cb086
--- /dev/null
+++ b/src/models/entities/blocking.ts
@@ -0,0 +1,42 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['blockerId', 'blockeeId'], { unique: true })
+export class Blocking {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Blocking.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The blockee user ID.'
+ })
+ public blockeeId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public blockee: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The blocker user ID.'
+ })
+ public blockerId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public blocker: User | null;
+}
diff --git a/src/models/entities/drive-file.ts b/src/models/entities/drive-file.ts
new file mode 100644
index 0000000000..130af39ede
--- /dev/null
+++ b/src/models/entities/drive-file.ts
@@ -0,0 +1,154 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { DriveFolder } from './drive-folder';
+import { id } from '../id';
+
+@Entity()
+export class DriveFile {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the DriveFile.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The owner ID.'
+ })
+ public userId: User['id'] | null;
+
+ @ManyToOne(type => User, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The host of owner. It will be null if the user in local.'
+ })
+ public userHost: string | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 32,
+ comment: 'The MD5 hash of the DriveFile.'
+ })
+ public md5: string;
+
+ @Column('varchar', {
+ length: 256,
+ comment: 'The file name of the DriveFile.'
+ })
+ public name: string;
+
+ @Index()
+ @Column('varchar', {
+ length: 128,
+ comment: 'The content type (MIME) of the DriveFile.'
+ })
+ public type: string;
+
+ @Column('integer', {
+ comment: 'The file size (bytes) of the DriveFile.'
+ })
+ public size: number;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The comment of the DriveFile.'
+ })
+ public comment: string | null;
+
+ @Column('jsonb', {
+ default: {},
+ comment: 'The any properties of the DriveFile. For example, it includes image width/height.'
+ })
+ public properties: Record<string, any>;
+
+ @Column('boolean')
+ public storedInternal: boolean;
+
+ @Column('varchar', {
+ length: 512,
+ comment: 'The URL of the DriveFile.'
+ })
+ public url: string;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The URL of the thumbnail of the DriveFile.'
+ })
+ public thumbnailUrl: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The URL of the webpublic of the DriveFile.'
+ })
+ public webpublicUrl: string | null;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 256, nullable: true,
+ })
+ public accessKey: string | null;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 256, nullable: true,
+ })
+ public thumbnailAccessKey: string | null;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 256, nullable: true,
+ })
+ public webpublicAccessKey: string | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The URI of the DriveFile. it will be null when the DriveFile is local.'
+ })
+ public uri: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ })
+ public src: string | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The parent folder ID. If null, it means the DriveFile is located in root.'
+ })
+ public folderId: DriveFolder['id'] | null;
+
+ @ManyToOne(type => DriveFolder, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public folder: DriveFolder | null;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the DriveFile is NSFW.'
+ })
+ public isSensitive: boolean;
+
+ /**
+ * 外部の(信頼されていない)URLへの直リンクか否か
+ */
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the DriveFile is direct link to remote server.'
+ })
+ public isLink: boolean;
+}
diff --git a/src/models/entities/drive-folder.ts b/src/models/entities/drive-folder.ts
new file mode 100644
index 0000000000..a80d075855
--- /dev/null
+++ b/src/models/entities/drive-folder.ts
@@ -0,0 +1,49 @@
+import { JoinColumn, ManyToOne, Entity, PrimaryColumn, Index, Column } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class DriveFolder {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the DriveFolder.'
+ })
+ public createdAt: Date;
+
+ @Column('varchar', {
+ length: 128,
+ comment: 'The name of the DriveFolder.'
+ })
+ public name: string;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The owner ID.'
+ })
+ public userId: User['id'] | null;
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The parent folder ID. If null, it means the DriveFolder is located in root.'
+ })
+ public parentId: DriveFolder['id'] | null;
+
+ @ManyToOne(type => DriveFolder, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public parent: DriveFolder | null;
+}
diff --git a/src/models/entities/emoji.ts b/src/models/entities/emoji.ts
new file mode 100644
index 0000000000..020636a7fb
--- /dev/null
+++ b/src/models/entities/emoji.ts
@@ -0,0 +1,46 @@
+import { PrimaryColumn, Entity, Index, Column } from 'typeorm';
+import { id } from '../id';
+
+@Entity()
+@Index(['name', 'host'], { unique: true })
+export class Emoji {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ nullable: true
+ })
+ public updatedAt: Date | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 128
+ })
+ public name: string;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true
+ })
+ public host: string | null;
+
+ @Column('varchar', {
+ length: 512,
+ })
+ public url: string;
+
+ @Column('varchar', {
+ length: 512, nullable: true
+ })
+ public uri: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true
+ })
+ public type: string | null;
+
+ @Column('varchar', {
+ array: true, length: 128, default: '{}'
+ })
+ public aliases: string[];
+}
diff --git a/src/models/entities/follow-request.ts b/src/models/entities/follow-request.ts
new file mode 100644
index 0000000000..22ec263962
--- /dev/null
+++ b/src/models/entities/follow-request.ts
@@ -0,0 +1,85 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['followerId', 'followeeId'], { unique: true })
+export class FollowRequest {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the FollowRequest.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The followee user ID.'
+ })
+ public followeeId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public followee: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The follower user ID.'
+ })
+ public followerId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public follower: User | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'id of Follow Activity.'
+ })
+ public requestId: string | null;
+
+ //#region Denormalized fields
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerHost: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerInbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerSharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeHost: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeInbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeSharedInbox: string | null;
+ //#endregion
+}
diff --git a/src/models/entities/following.ts b/src/models/entities/following.ts
new file mode 100644
index 0000000000..ee3286a1a1
--- /dev/null
+++ b/src/models/entities/following.ts
@@ -0,0 +1,80 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['followerId', 'followeeId'], { unique: true })
+export class Following {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Following.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The followee user ID.'
+ })
+ public followeeId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public followee: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The follower user ID.'
+ })
+ public followerId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public follower: User | null;
+
+ //#region Denormalized fields
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerHost: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerInbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerSharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeHost: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeInbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeSharedInbox: string | null;
+ //#endregion
+}
diff --git a/src/models/entities/games/reversi/game.ts b/src/models/entities/games/reversi/game.ts
new file mode 100644
index 0000000000..9deacaf5c6
--- /dev/null
+++ b/src/models/entities/games/reversi/game.ts
@@ -0,0 +1,133 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from '../../user';
+import { id } from '../../../id';
+
+@Entity()
+export class ReversiGame {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the ReversiGame.'
+ })
+ public createdAt: Date;
+
+ @Column('timestamp with time zone', {
+ nullable: true,
+ comment: 'The started date of the ReversiGame.'
+ })
+ public startedAt: Date | null;
+
+ @Column(id())
+ public user1Id: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user1: User | null;
+
+ @Column(id())
+ public user2Id: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user2: User | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public user1Accepted: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public user2Accepted: boolean;
+
+ /**
+ * どちらのプレイヤーが先行(黒)か
+ * 1 ... user1
+ * 2 ... user2
+ */
+ @Column('integer', {
+ nullable: true,
+ })
+ public black: number | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public isStarted: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public isEnded: boolean;
+
+ @Column({
+ ...id(),
+ nullable: true
+ })
+ public winnerId: User['id'] | null;
+
+ @Column({
+ ...id(),
+ nullable: true
+ })
+ public surrendered: User['id'] | null;
+
+ @Column('jsonb', {
+ default: [],
+ })
+ public logs: {
+ at: Date;
+ color: boolean;
+ pos: number;
+ }[];
+
+ @Column('varchar', {
+ array: true, length: 64,
+ })
+ public map: string[];
+
+ @Column('varchar', {
+ length: 32
+ })
+ public bw: string;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public isLlotheo: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public canPutEverywhere: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public loopedBoard: boolean;
+
+ @Column('jsonb', {
+ nullable: true, default: null,
+ })
+ public form1: any | null;
+
+ @Column('jsonb', {
+ nullable: true, default: null,
+ })
+ public form2: any | null;
+
+ /**
+ * ログのposを文字列としてすべて連結したもののCRC32値
+ */
+ @Column('varchar', {
+ length: 32, nullable: true
+ })
+ public crc32: string | null;
+}
diff --git a/src/models/entities/games/reversi/matching.ts b/src/models/entities/games/reversi/matching.ts
new file mode 100644
index 0000000000..477a29316e
--- /dev/null
+++ b/src/models/entities/games/reversi/matching.ts
@@ -0,0 +1,35 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from '../../user';
+import { id } from '../../../id';
+
+@Entity()
+export class ReversiMatching {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the ReversiMatching.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public parentId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public parent: User | null;
+
+ @Index()
+ @Column(id())
+ public childId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public child: User | null;
+}
diff --git a/src/models/entities/hashtag.ts b/src/models/entities/hashtag.ts
new file mode 100644
index 0000000000..842cdaa562
--- /dev/null
+++ b/src/models/entities/hashtag.ts
@@ -0,0 +1,87 @@
+import { Entity, PrimaryColumn, Index, Column } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class Hashtag {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 128
+ })
+ public name: string;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public mentionedUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public mentionedUsersCount: number;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public mentionedLocalUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public mentionedLocalUsersCount: number;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public mentionedRemoteUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public mentionedRemoteUsersCount: number;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public attachedUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public attachedUsersCount: number;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public attachedLocalUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public attachedLocalUsersCount: number;
+
+ @Column({
+ ...id(),
+ array: true,
+ })
+ public attachedRemoteUserIds: User['id'][];
+
+ @Index()
+ @Column('integer', {
+ default: 0
+ })
+ public attachedRemoteUsersCount: number;
+}
diff --git a/src/models/entities/instance.ts b/src/models/entities/instance.ts
new file mode 100644
index 0000000000..977054263c
--- /dev/null
+++ b/src/models/entities/instance.ts
@@ -0,0 +1,132 @@
+import { Entity, PrimaryColumn, Index, Column } from 'typeorm';
+import { id } from '../id';
+
+@Entity()
+export class Instance {
+ @PrimaryColumn(id())
+ public id: string;
+
+ /**
+ * このインスタンスを捕捉した日時
+ */
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The caught date of the Instance.'
+ })
+ public caughtAt: Date;
+
+ /**
+ * ホスト
+ */
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 128,
+ comment: 'The host of the Instance.'
+ })
+ public host: string;
+
+ /**
+ * インスタンスのシステム (MastodonとかMisskeyとかPleromaとか)
+ */
+ @Column('varchar', {
+ length: 64, nullable: true,
+ comment: 'The system of the Instance.'
+ })
+ public system: string | null;
+
+ /**
+ * インスタンスのユーザー数
+ */
+ @Column('integer', {
+ default: 0,
+ comment: 'The count of the users of the Instance.'
+ })
+ public usersCount: number;
+
+ /**
+ * インスタンスの投稿数
+ */
+ @Column('integer', {
+ default: 0,
+ comment: 'The count of the notes of the Instance.'
+ })
+ public notesCount: number;
+
+ /**
+ * このインスタンスのユーザーからフォローされている、自インスタンスのユーザーの数
+ */
+ @Column('integer', {
+ default: 0,
+ })
+ public followingCount: number;
+
+ /**
+ * このインスタンスのユーザーをフォローしている、自インスタンスのユーザーの数
+ */
+ @Column('integer', {
+ default: 0,
+ })
+ public followersCount: number;
+
+ /**
+ * ドライブ使用量
+ */
+ @Column('integer', {
+ default: 0,
+ })
+ public driveUsage: number;
+
+ /**
+ * ドライブのファイル数
+ */
+ @Column('integer', {
+ default: 0,
+ })
+ public driveFiles: number;
+
+ /**
+ * 直近のリクエスト送信日時
+ */
+ @Column('timestamp with time zone', {
+ nullable: true,
+ })
+ public latestRequestSentAt: Date | null;
+
+ /**
+ * 直近のリクエスト送信時のHTTPステータスコード
+ */
+ @Column('integer', {
+ nullable: true,
+ })
+ public latestStatus: number | null;
+
+ /**
+ * 直近のリクエスト受信日時
+ */
+ @Column('timestamp with time zone', {
+ nullable: true,
+ })
+ public latestRequestReceivedAt: Date | null;
+
+ /**
+ * このインスタンスと最後にやり取りした日時
+ */
+ @Column('timestamp with time zone')
+ public lastCommunicatedAt: Date;
+
+ /**
+ * このインスタンスと不通かどうか
+ */
+ @Column('boolean', {
+ default: false
+ })
+ public isNotResponding: boolean;
+
+ /**
+ * このインスタンスが閉鎖済みとしてマークされているか
+ */
+ @Column('boolean', {
+ default: false
+ })
+ public isMarkedAsClosed: boolean;
+}
diff --git a/src/models/entities/log.ts b/src/models/entities/log.ts
new file mode 100644
index 0000000000..99e1e8947e
--- /dev/null
+++ b/src/models/entities/log.ts
@@ -0,0 +1,46 @@
+import { Entity, PrimaryColumn, Index, Column } from 'typeorm';
+import { id } from '../id';
+
+@Entity()
+export class Log {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Log.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column('varchar', {
+ length: 64, array: true, default: '{}'
+ })
+ public domain: string[];
+
+ @Index()
+ @Column('enum', {
+ enum: ['error', 'warning', 'info', 'success', 'debug']
+ })
+ public level: string;
+
+ @Column('varchar', {
+ length: 8
+ })
+ public worker: string;
+
+ @Column('varchar', {
+ length: 128
+ })
+ public machine: string;
+
+ @Column('varchar', {
+ length: 1024
+ })
+ public message: string;
+
+ @Column('jsonb', {
+ default: {}
+ })
+ public data: Record<string, any>;
+}
diff --git a/src/models/entities/messaging-message.ts b/src/models/entities/messaging-message.ts
new file mode 100644
index 0000000000..d3c3eab3a2
--- /dev/null
+++ b/src/models/entities/messaging-message.ts
@@ -0,0 +1,64 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { DriveFile } from './drive-file';
+import { id } from '../id';
+
+@Entity()
+export class MessagingMessage {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the MessagingMessage.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The sender user ID.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The recipient user ID.'
+ })
+ public recipientId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public recipient: User | null;
+
+ @Column('varchar', {
+ length: 4096, nullable: true
+ })
+ public text: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public isRead: boolean;
+
+ @Column({
+ ...id(),
+ nullable: true,
+ })
+ public fileId: DriveFile['id'] | null;
+
+ @ManyToOne(type => DriveFile, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public file: DriveFile | null;
+}
diff --git a/src/models/entities/meta.ts b/src/models/entities/meta.ts
new file mode 100644
index 0000000000..f3ac23bac7
--- /dev/null
+++ b/src/models/entities/meta.ts
@@ -0,0 +1,264 @@
+import { Entity, Column, PrimaryColumn } from 'typeorm';
+import { id } from '../id';
+
+@Entity()
+export class Meta {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('varchar', {
+ length: 128, nullable: true
+ })
+ public name: string | null;
+
+ @Column('varchar', {
+ length: 1024, nullable: true
+ })
+ public description: string | null;
+
+ /**
+ * メンテナの名前
+ */
+ @Column('varchar', {
+ length: 128, nullable: true
+ })
+ public maintainerName: string | null;
+
+ /**
+ * メンテナの連絡先
+ */
+ @Column('varchar', {
+ length: 128, nullable: true
+ })
+ public maintainerEmail: string | null;
+
+ @Column('jsonb', {
+ default: [],
+ })
+ public announcements: Record<string, any>[];
+
+ @Column('boolean', {
+ default: false,
+ })
+ public disableRegistration: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public disableLocalTimeline: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public disableGlobalTimeline: boolean;
+
+ @Column('boolean', {
+ default: true,
+ })
+ public enableEmojiReaction: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public useStarForReactionFallback: boolean;
+
+ @Column('varchar', {
+ length: 64, array: true, default: '{}'
+ })
+ public langs: string[];
+
+ @Column('varchar', {
+ length: 256, array: true, default: '{}'
+ })
+ public hiddenTags: string[];
+
+ @Column('varchar', {
+ length: 256, array: true, default: '{}'
+ })
+ public blockedHosts: string[];
+
+ @Column('varchar', {
+ length: 512,
+ nullable: true,
+ default: '/assets/ai.png'
+ })
+ public mascotImageUrl: string | null;
+
+ @Column('varchar', {
+ length: 512,
+ nullable: true
+ })
+ public bannerUrl: string | null;
+
+ @Column('varchar', {
+ length: 512,
+ nullable: true,
+ default: 'https://xn--931a.moe/aiart/yubitun.png'
+ })
+ public errorImageUrl: string | null;
+
+ @Column('varchar', {
+ length: 512,
+ nullable: true
+ })
+ public iconUrl: string | null;
+
+ @Column('boolean', {
+ default: true,
+ })
+ public cacheRemoteFiles: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public proxyAccount: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableRecaptcha: boolean;
+
+ @Column('varchar', {
+ length: 64,
+ nullable: true
+ })
+ public recaptchaSiteKey: string | null;
+
+ @Column('varchar', {
+ length: 64,
+ nullable: true
+ })
+ public recaptchaSecretKey: string | null;
+
+ @Column('integer', {
+ default: 1024,
+ comment: 'Drive capacity of a local user (MB)'
+ })
+ public localDriveCapacityMb: number;
+
+ @Column('integer', {
+ default: 32,
+ comment: 'Drive capacity of a remote user (MB)'
+ })
+ public remoteDriveCapacityMb: number;
+
+ @Column('integer', {
+ default: 500,
+ comment: 'Max allowed note text length in characters'
+ })
+ public maxNoteTextLength: number;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public summalyProxy: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableEmail: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public email: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public smtpSecure: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public smtpHost: string | null;
+
+ @Column('integer', {
+ nullable: true
+ })
+ public smtpPort: number | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public smtpUser: string | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public smtpPass: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableServiceWorker: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public swPublicKey: string | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public swPrivateKey: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableTwitterIntegration: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public twitterConsumerKey: string | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public twitterConsumerSecret: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableGithubIntegration: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public githubClientId: string | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public githubClientSecret: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public enableDiscordIntegration: boolean;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public discordClientId: string | null;
+
+ @Column('varchar', {
+ length: 128,
+ nullable: true
+ })
+ public discordClientSecret: string | null;
+}
diff --git a/src/models/entities/muting.ts b/src/models/entities/muting.ts
new file mode 100644
index 0000000000..0084213bcc
--- /dev/null
+++ b/src/models/entities/muting.ts
@@ -0,0 +1,42 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['muterId', 'muteeId'], { unique: true })
+export class Muting {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Muting.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The mutee user ID.'
+ })
+ public muteeId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public mutee: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The muter user ID.'
+ })
+ public muterId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public muter: User | null;
+}
diff --git a/src/models/entities/note-favorite.ts b/src/models/entities/note-favorite.ts
new file mode 100644
index 0000000000..0713c3ae56
--- /dev/null
+++ b/src/models/entities/note-favorite.ts
@@ -0,0 +1,35 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { Note } from './note';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId'], { unique: true })
+export class NoteFavorite {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the NoteFavorite.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column(id())
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+}
diff --git a/src/models/entities/note-reaction.ts b/src/models/entities/note-reaction.ts
new file mode 100644
index 0000000000..1ce5d841fb
--- /dev/null
+++ b/src/models/entities/note-reaction.ts
@@ -0,0 +1,42 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { Note } from './note';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId'], { unique: true })
+export class NoteReaction {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the NoteReaction.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column(id())
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ @Column('varchar', {
+ length: 32
+ })
+ public reaction: string;
+}
diff --git a/src/models/entities/note-unread.ts b/src/models/entities/note-unread.ts
new file mode 100644
index 0000000000..2d18728256
--- /dev/null
+++ b/src/models/entities/note-unread.ts
@@ -0,0 +1,43 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { Note } from './note';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId'], { unique: true })
+export class NoteUnread {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column(id())
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ @Column({
+ ...id(),
+ comment: '[Denormalized]'
+ })
+ public noteUserId: User['id'];
+
+ /**
+ * ダイレクト投稿か
+ */
+ @Column('boolean')
+ public isSpecified: boolean;
+}
diff --git a/src/models/entities/note-watching.ts b/src/models/entities/note-watching.ts
new file mode 100644
index 0000000000..741a1c0c8b
--- /dev/null
+++ b/src/models/entities/note-watching.ts
@@ -0,0 +1,52 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { Note } from './note';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId'], { unique: true })
+export class NoteWatching {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the NoteWatching.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The watcher ID.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The target Note ID.'
+ })
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ //#region Denormalized fields
+ @Index()
+ @Column({
+ ...id(),
+ comment: '[Denormalized]'
+ })
+ public noteUserId: Note['userId'];
+ //#endregion
+}
diff --git a/src/models/entities/note.ts b/src/models/entities/note.ts
new file mode 100644
index 0000000000..969363da3b
--- /dev/null
+++ b/src/models/entities/note.ts
@@ -0,0 +1,231 @@
+import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { App } from './app';
+import { DriveFile } from './drive-file';
+import { id } from '../id';
+
+@Entity()
+export class Note {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Note.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The ID of reply target.'
+ })
+ public replyId: Note['id'] | null;
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public reply: Note | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The ID of renote target.'
+ })
+ public renoteId: Note['id'] | null;
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public renote: Note | null;
+
+ @Column({
+ type: 'text', nullable: true
+ })
+ public text: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true
+ })
+ public name: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true
+ })
+ public cw: string | null;
+
+ @Column({
+ ...id(),
+ nullable: true
+ })
+ public appId: App['id'] | null;
+
+ @ManyToOne(type => App, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public app: App | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The ID of author.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('boolean', {
+ default: false
+ })
+ public viaMobile: boolean;
+
+ @Column('boolean', {
+ default: false
+ })
+ public localOnly: boolean;
+
+ @Column('integer', {
+ default: 0
+ })
+ public renoteCount: number;
+
+ @Column('integer', {
+ default: 0
+ })
+ public repliesCount: number;
+
+ @Column('jsonb', {
+ default: {}
+ })
+ public reactions: Record<string, number>;
+
+ /**
+ * public ... 公開
+ * home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す
+ * followers ... フォロワーのみ
+ * specified ... visibleUserIds で指定したユーザーのみ
+ */
+ @Column('enum', { enum: ['public', 'home', 'followers', 'specified'] })
+ public visibility: 'public' | 'home' | 'followers' | 'specified';
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The URI of a note. it will be null when the note is local.'
+ })
+ public uri: string | null;
+
+ @Column('integer', {
+ default: 0, select: false
+ })
+ public score: number;
+
+ @Column({
+ ...id(),
+ array: true, default: '{}'
+ })
+ public fileIds: DriveFile['id'][];
+
+ @Column('varchar', {
+ length: 256, array: true, default: '{}'
+ })
+ public attachedFileTypes: string[];
+
+ @Index()
+ @Column({
+ ...id(),
+ array: true, default: '{}'
+ })
+ public visibleUserIds: User['id'][];
+
+ @Index()
+ @Column({
+ ...id(),
+ array: true, default: '{}'
+ })
+ public mentions: User['id'][];
+
+ @Column('text', {
+ default: '[]'
+ })
+ public mentionedRemoteUsers: string;
+
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public emojis: string[];
+
+ @Index()
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public tags: string[];
+
+ @Column('boolean', {
+ default: false
+ })
+ public hasPoll: boolean;
+
+ @Column('jsonb', {
+ nullable: true, default: null
+ })
+ public geo: any | null;
+
+ //#region Denormalized fields
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userHost: string | null;
+
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: '[Denormalized]'
+ })
+ public replyUserId: User['id'] | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public replyUserHost: string | null;
+
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: '[Denormalized]'
+ })
+ public renoteUserId: User['id'] | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public renoteUserHost: string | null;
+ //#endregion
+
+ constructor(data: Partial<Note>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
+
+export type IMentionedRemoteUsers = {
+ uri: string;
+ username: string;
+ host: string;
+}[];
diff --git a/src/models/entities/notification.ts b/src/models/entities/notification.ts
new file mode 100644
index 0000000000..627a57bece
--- /dev/null
+++ b/src/models/entities/notification.ts
@@ -0,0 +1,94 @@
+import { Entity, Index, JoinColumn, ManyToOne, Column, PrimaryColumn } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+import { Note } from './note';
+
+@Entity()
+export class Notification {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Notification.'
+ })
+ public createdAt: Date;
+
+ /**
+ * 通知の受信者
+ */
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The ID of recipient user of the Notification.'
+ })
+ public notifieeId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public notifiee: User | null;
+
+ /**
+ * 通知の送信者(initiator)
+ */
+ @Column({
+ ...id(),
+ comment: 'The ID of sender user of the Notification.'
+ })
+ public notifierId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public notifier: User | null;
+
+ /**
+ * 通知の種類。
+ * follow - フォローされた
+ * mention - 投稿で自分が言及された
+ * reply - (自分または自分がWatchしている)投稿が返信された
+ * renote - (自分または自分がWatchしている)投稿がRenoteされた
+ * quote - (自分または自分がWatchしている)投稿が引用Renoteされた
+ * reaction - (自分または自分がWatchしている)投稿にリアクションされた
+ * pollVote - (自分または自分がWatchしている)投稿の投票に投票された
+ */
+ @Column('varchar', {
+ length: 32,
+ comment: 'The type of the Notification.'
+ })
+ public type: string;
+
+ /**
+ * 通知が読まれたかどうか
+ */
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the Notification is read.'
+ })
+ public isRead: boolean;
+
+ @Column({
+ ...id(),
+ nullable: true
+ })
+ public noteId: Note['id'] | null;
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true
+ })
+ public reaction: string;
+
+ @Column('integer', {
+ nullable: true
+ })
+ public choice: number;
+}
diff --git a/src/models/entities/poll-vote.ts b/src/models/entities/poll-vote.ts
new file mode 100644
index 0000000000..709376f909
--- /dev/null
+++ b/src/models/entities/poll-vote.ts
@@ -0,0 +1,40 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { Note } from './note';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId', 'choice'], { unique: true })
+export class PollVote {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the PollVote.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column(id())
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ @Column('integer')
+ public choice: number;
+}
diff --git a/src/models/entities/poll.ts b/src/models/entities/poll.ts
new file mode 100644
index 0000000000..6bb67163a2
--- /dev/null
+++ b/src/models/entities/poll.ts
@@ -0,0 +1,71 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
+import { id } from '../id';
+import { Note } from './note';
+import { User } from './user';
+
+@Entity()
+export class Poll {
+ @PrimaryColumn(id())
+ public noteId: Note['id'];
+
+ @OneToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+
+ @Column('timestamp with time zone', {
+ nullable: true
+ })
+ public expiresAt: Date | null;
+
+ @Column('boolean')
+ public multiple: boolean;
+
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public choices: string[];
+
+ @Column('integer', {
+ array: true,
+ })
+ public votes: number[];
+
+ //#region Denormalized fields
+ @Column('enum', {
+ enum: ['public', 'home', 'followers', 'specified'],
+ comment: '[Denormalized]'
+ })
+ public noteVisibility: 'public' | 'home' | 'followers' | 'specified';
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: '[Denormalized]'
+ })
+ public userId: User['id'];
+
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userHost: string | null;
+ //#endregion
+
+ constructor(data: Partial<Poll>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
+
+export type IPoll = {
+ choices: string[];
+ votes?: number[];
+ multiple: boolean;
+ expiresAt: Date | null;
+};
diff --git a/src/models/entities/registration-tickets.ts b/src/models/entities/registration-tickets.ts
new file mode 100644
index 0000000000..d962f78a78
--- /dev/null
+++ b/src/models/entities/registration-tickets.ts
@@ -0,0 +1,17 @@
+import { PrimaryColumn, Entity, Index, Column } from 'typeorm';
+import { id } from '../id';
+
+@Entity()
+export class RegistrationTicket {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone')
+ public createdAt: Date;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 64,
+ })
+ public code: string;
+}
diff --git a/src/models/entities/signin.ts b/src/models/entities/signin.ts
new file mode 100644
index 0000000000..7e047084b1
--- /dev/null
+++ b/src/models/entities/signin.ts
@@ -0,0 +1,35 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class Signin {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the Signin.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 128,
+ })
+ public ip: string;
+
+ @Column('jsonb')
+ public headers: Record<string, any>;
+
+ @Column('boolean')
+ public success: boolean;
+}
diff --git a/src/models/entities/sw-subscription.ts b/src/models/entities/sw-subscription.ts
new file mode 100644
index 0000000000..7c3f6f0a6c
--- /dev/null
+++ b/src/models/entities/sw-subscription.ts
@@ -0,0 +1,37 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class SwSubscription {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone')
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 512,
+ })
+ public endpoint: string;
+
+ @Column('varchar', {
+ length: 256,
+ })
+ public auth: string;
+
+ @Column('varchar', {
+ length: 128,
+ })
+ public publickey: string;
+}
diff --git a/src/models/entities/user-keypair.ts b/src/models/entities/user-keypair.ts
new file mode 100644
index 0000000000..603321d758
--- /dev/null
+++ b/src/models/entities/user-keypair.ts
@@ -0,0 +1,33 @@
+import { PrimaryColumn, Entity, JoinColumn, Column, OneToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserKeypair {
+ @PrimaryColumn(id())
+ public userId: User['id'];
+
+ @OneToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 4096,
+ })
+ public publicKey: string;
+
+ @Column('varchar', {
+ length: 4096,
+ })
+ public privateKey: string;
+
+ constructor(data: Partial<UserKeypair>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
diff --git a/src/models/entities/user-list-joining.ts b/src/models/entities/user-list-joining.ts
new file mode 100644
index 0000000000..8af4efb6a7
--- /dev/null
+++ b/src/models/entities/user-list-joining.ts
@@ -0,0 +1,41 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { UserList } from './user-list';
+import { id } from '../id';
+
+@Entity()
+export class UserListJoining {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the UserListJoining.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The user ID.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The list ID.'
+ })
+ public userListId: UserList['id'];
+
+ @ManyToOne(type => UserList, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public userList: UserList | null;
+}
diff --git a/src/models/entities/user-list.ts b/src/models/entities/user-list.ts
new file mode 100644
index 0000000000..35a83ef8c3
--- /dev/null
+++ b/src/models/entities/user-list.ts
@@ -0,0 +1,33 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserList {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the UserList.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column({
+ ...id(),
+ comment: 'The owner ID.'
+ })
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 128,
+ comment: 'The name of the UserList.'
+ })
+ public name: string;
+}
diff --git a/src/models/entities/user-note-pinings.ts b/src/models/entities/user-note-pinings.ts
new file mode 100644
index 0000000000..04a6f8f645
--- /dev/null
+++ b/src/models/entities/user-note-pinings.ts
@@ -0,0 +1,35 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
+import { Note } from './note';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+@Index(['userId', 'noteId'], { unique: true })
+export class UserNotePining {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the UserNotePinings.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column(id())
+ public userId: User['id'];
+
+ @ManyToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column(id())
+ public noteId: Note['id'];
+
+ @ManyToOne(type => Note, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public note: Note | null;
+}
diff --git a/src/models/entities/user-profile.ts b/src/models/entities/user-profile.ts
new file mode 100644
index 0000000000..a2d7b8d2c2
--- /dev/null
+++ b/src/models/entities/user-profile.ts
@@ -0,0 +1,209 @@
+import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
+import { id } from '../id';
+import { User } from './user';
+
+@Entity()
+export class UserProfile {
+ @PrimaryColumn(id())
+ public userId: User['id'];
+
+ @OneToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The location of the User.'
+ })
+ public location: string | null;
+
+ @Column('char', {
+ length: 10, nullable: true,
+ comment: 'The birthday (YYYY-MM-DD) of the User.'
+ })
+ public birthday: string | null;
+
+ @Column('varchar', {
+ length: 1024, nullable: true,
+ comment: 'The description (bio) of the User.'
+ })
+ public description: string | null;
+
+ @Column('jsonb', {
+ default: [],
+ })
+ public fields: {
+ name: string;
+ value: string;
+ }[];
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'Remote URL of the user.'
+ })
+ public url: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The email address of the User.'
+ })
+ public email: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ })
+ public emailVerifyCode: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public emailVerified: boolean;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ })
+ public twoFactorTempSecret: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ })
+ public twoFactorSecret: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public twoFactorEnabled: boolean;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The password hash of the User. It will be null if the origin of the user is local.'
+ })
+ public password: string | null;
+
+ @Column('jsonb', {
+ default: {},
+ comment: 'The client-specific data of the User.'
+ })
+ public clientData: Record<string, any>;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public autoWatch: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public autoAcceptFollowed: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public alwaysMarkNsfw: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public carefulBot: boolean;
+
+ //#region Linking
+ @Column('boolean', {
+ default: false,
+ })
+ public twitter: boolean;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public twitterAccessToken: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public twitterAccessTokenSecret: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public twitterUserId: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public twitterScreenName: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public github: boolean;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public githubAccessToken: string | null;
+
+ @Column('integer', {
+ nullable: true, default: null,
+ })
+ public githubId: number | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public githubLogin: string | null;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public discord: boolean;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public discordAccessToken: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public discordRefreshToken: string | null;
+
+ @Column('integer', {
+ nullable: true, default: null,
+ })
+ public discordExpiresDate: number | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public discordId: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public discordUsername: string | null;
+
+ @Column('varchar', {
+ length: 64, nullable: true, default: null,
+ })
+ public discordDiscriminator: string | null;
+ //#endregion
+
+ //#region Denormalized fields
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userHost: string | null;
+ //#endregion
+
+ constructor(data: Partial<UserProfile>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
diff --git a/src/models/entities/user-publickey.ts b/src/models/entities/user-publickey.ts
new file mode 100644
index 0000000000..21edc3e9e2
--- /dev/null
+++ b/src/models/entities/user-publickey.ts
@@ -0,0 +1,34 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserPublickey {
+ @PrimaryColumn(id())
+ public userId: User['id'];
+
+ @OneToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 256,
+ })
+ public keyId: string;
+
+ @Column('varchar', {
+ length: 4096,
+ })
+ public keyPem: string;
+
+ constructor(data: Partial<UserPublickey>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
diff --git a/src/models/entities/user.ts b/src/models/entities/user.ts
new file mode 100644
index 0000000000..e40c32a76f
--- /dev/null
+++ b/src/models/entities/user.ts
@@ -0,0 +1,224 @@
+import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
+import { DriveFile } from './drive-file';
+import { id } from '../id';
+
+@Entity()
+@Index(['usernameLower', 'host'], { unique: true })
+export class User {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ comment: 'The created date of the User.'
+ })
+ public createdAt: Date;
+
+ @Index()
+ @Column('timestamp with time zone', {
+ nullable: true,
+ comment: 'The updated date of the User.'
+ })
+ public updatedAt: Date | null;
+
+ @Column('timestamp with time zone', {
+ nullable: true
+ })
+ public lastFetchedAt: Date | null;
+
+ @Column('varchar', {
+ length: 128,
+ comment: 'The username of the User.'
+ })
+ public username: string;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, select: false,
+ comment: 'The username (lowercased) of the User.'
+ })
+ public usernameLower: string;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The name of the User.'
+ })
+ public name: string | null;
+
+ @Column('integer', {
+ default: 0,
+ comment: 'The count of followers.'
+ })
+ public followersCount: number;
+
+ @Column('integer', {
+ default: 0,
+ comment: 'The count of following.'
+ })
+ public followingCount: number;
+
+ @Column('integer', {
+ default: 0,
+ comment: 'The count of notes.'
+ })
+ public notesCount: number;
+
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The ID of avatar DriveFile.'
+ })
+ public avatarId: DriveFile['id'] | null;
+
+ @OneToOne(type => DriveFile, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public avatar: DriveFile | null;
+
+ @Column({
+ ...id(),
+ nullable: true,
+ comment: 'The ID of banner DriveFile.'
+ })
+ public bannerId: DriveFile['id'] | null;
+
+ @OneToOne(type => DriveFile, {
+ onDelete: 'SET NULL'
+ })
+ @JoinColumn()
+ public banner: DriveFile | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public tags: string[];
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ })
+ public avatarUrl: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ })
+ public bannerUrl: string | null;
+
+ @Column('varchar', {
+ length: 32, nullable: true,
+ })
+ public avatarColor: string | null;
+
+ @Column('varchar', {
+ length: 32, nullable: true,
+ })
+ public bannerColor: string | null;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is suspended.'
+ })
+ public isSuspended: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is silenced.'
+ })
+ public isSilenced: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is locked.'
+ })
+ public isLocked: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is a bot.'
+ })
+ public isBot: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is a cat.'
+ })
+ public isCat: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is the admin.'
+ })
+ public isAdmin: boolean;
+
+ @Column('boolean', {
+ default: false,
+ comment: 'Whether the User is a moderator.'
+ })
+ public isModerator: boolean;
+
+ @Column('boolean', {
+ default: false,
+ })
+ public isVerified: boolean;
+
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public emojis: string[];
+
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: 'The host of the User. It will be null if the origin of the user is local.'
+ })
+ public host: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The inbox URL of the User. It will be null if the origin of the user is local.'
+ })
+ public inbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The sharedInbox URL of the User. It will be null if the origin of the user is local.'
+ })
+ public sharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The featured URL of the User. It will be null if the origin of the user is local.'
+ })
+ public featured: string | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 512, nullable: true,
+ comment: 'The URI of the User. It will be null if the origin of the user is local.'
+ })
+ public uri: string | null;
+
+ @Index({ unique: true })
+ @Column('char', {
+ length: 16, nullable: true, unique: true,
+ comment: 'The native access token of the User. It will be null if the origin of the user is local.'
+ })
+ public token: string | null;
+
+ constructor(data: Partial<User>) {
+ if (data == null) return;
+
+ for (const [k, v] of Object.entries(data)) {
+ (this as any)[k] = v;
+ }
+ }
+}
+
+export interface ILocalUser extends User {
+ host: null;
+}
+
+export interface IRemoteUser extends User {
+ host: string;
+}