summaryrefslogtreecommitdiff
path: root/src/models/entities
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2019-04-07 21:50:36 +0900
committerGitHub <noreply@github.com>2019-04-07 21:50:36 +0900
commitf0a29721c9fb10f97faf386bc9d6b1b2fad97895 (patch)
treeb5c1d38d698589bb444c0881a431391db91eb5bc /src/models/entities
parentUpdate README.md [AUTOGEN] (#4639) (diff)
downloadmisskey-f0a29721c9fb10f97faf386bc9d6b1b2fad97895.tar.gz
misskey-f0a29721c9fb10f97faf386bc9d6b1b2fad97895.tar.bz2
misskey-f0a29721c9fb10f97faf386bc9d6b1b2fad97895.zip
Use PostgreSQL instead of MongoDB (#4572)
* wip * Update note.ts * Update timeline.ts * Update core.ts * wip * Update generate-visibility-query.ts * wip * wip * wip * wip * wip * Update global-timeline.ts * wip * wip * wip * Update vote.ts * wip * wip * Update create.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update files.ts * wip * wip * Update CONTRIBUTING.md * wip * wip * wip * wip * wip * wip * wip * wip * Update read-notification.ts * wip * wip * wip * wip * wip * wip * wip * Update cancel.ts * wip * wip * wip * Update show.ts * wip * wip * Update gen-id.ts * Update create.ts * Update id.ts * wip * wip * wip * wip * wip * wip * wip * Docker: Update files about Docker (#4599) * Docker: Use cache if files used by `yarn install` was not updated This patch reduces the number of times to installing node_modules. For example, `yarn install` step will be skipped when only ".config/default.yml" is updated. * Docker: Migrate MongoDB to Postgresql Misskey uses Postgresql as a database instead of Mongodb since version 11. * Docker: Uncomment about data persistence This patch will save a lot of databases. * wip * wip * wip * Update activitypub.ts * wip * wip * wip * Update logs.ts * wip * Update drive-file.ts * Update register.ts * wip * wip * Update mentions.ts * wip * wip * wip * Update recommendation.ts * wip * Update index.ts * wip * Update recommendation.ts * Doc: Update docker.ja.md and docker.en.md (#1) (#4608) Update how to set up misskey. * wip * :v: * wip * Update note.ts * Update postgre.ts * wip * wip * wip * wip * Update add-file.ts * wip * wip * wip * Clean up * Update logs.ts * wip * :pizza: * wip * Ad notes * wip * Update api-visibility.ts * Update note.ts * Update add-file.ts * tests * tests * Update postgre.ts * Update utils.ts * wip * wip * Refactor * wip * Refactor * wip * wip * Update show-users.ts * Update update-instance.ts * wip * Update feed.ts * Update outbox.ts * Update outbox.ts * Update user.ts * wip * Update list.ts * Update update-hashtag.ts * wip * Update update-hashtag.ts * Refactor * Update update.ts * wip * wip * :v: * clean up * docs * Update push.ts * wip * Update api.ts * wip * :v: * Update make-pagination-query.ts * :v: * Delete hashtags.ts * Update instances.ts * Update instances.ts * Update create.ts * Update search.ts * Update reversi-game.ts * Update signup.ts * Update user.ts * id * Update example.yml * :art: * objectid * fix * reversi * reversi * Fix bug of chart engine * Add test of chart engine * Improve test * Better testing * Improve chart engine * Refactor * Add test of chart engine * Refactor * Add chart test * Fix bug * コミットし忘れ * Refactoring * :v: * Add tests * Add test * Extarct note tests * Refactor * 存在しないユーザーにメンションできなくなっていた問題を修正 * Fix bug * Update update-meta.ts * Fix bug * Update mention.vue * Fix bug * Update meta.ts * Update CONTRIBUTING.md * Fix bug * Fix bug * Fix bug * Clean up * Clean up * Update notification.ts * Clean up * Add mute tests * Add test * Refactor * Add test * Fix test * Refactor * Refactor * Add tests * Update utils.ts * Update utils.ts * Fix test * Update package.json * Update update.ts * Update manifest.ts * Fix bug * Fix bug * Add test * :art: * Update endpoint permissions * Updaye permisison * Update person.ts #4299 * データベースと同期しないように * Fix bug * Fix bug * Update reversi-game.ts * Use a feature of Node v11.7.0 to extract a public key (#4644) * wip * wip * :v: * Refactoring #1540 * test * test * test * test * test * test * test * Fix bug * Fix test * :sushi: * wip * #4471 * Add test for #4335 * Refactor * Fix test * Add tests * :clock4: * Fix bug * Add test * Add test * rename * Fix bug
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.ts39
-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.ts236
-rw-r--r--src/models/entities/notification.ts94
-rw-r--r--src/models/entities/poll-vote.ts40
-rw-r--r--src/models/entities/poll.ts67
-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.ts24
-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-publickey.ts30
-rw-r--r--src/models/entities/user-service-linking.ts108
-rw-r--r--src/models/entities/user.ts297
36 files changed, 2710 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..d0c89000fc
--- /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: 256, 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..83f8365630
--- /dev/null
+++ b/src/models/entities/auth-session.ts
@@ -0,0 +1,39 @@
+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())
+ 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/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..a8f8c69e56
--- /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,
+ })
+ public accessKey: string;
+
+ @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 isRemote: 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..da04da897e
--- /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: 256,
+ })
+ public url: string;
+
+ @Column('varchar', {
+ length: 256, 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..80a71fe482
--- /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: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerInbox: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerSharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeHost: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeInbox: string | null;
+
+ @Column('varchar', {
+ length: 256, 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..963873d112
--- /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: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerInbox: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followerSharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeHost: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public followeeInbox: string | null;
+
+ @Column('varchar', {
+ length: 256, 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..c34f5b6904
--- /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: 256,
+ nullable: true,
+ default: '/assets/ai.png'
+ })
+ public mascotImageUrl: string | null;
+
+ @Column('varchar', {
+ length: 256,
+ nullable: true
+ })
+ public bannerUrl: string | null;
+
+ @Column('varchar', {
+ length: 256,
+ nullable: true,
+ default: 'https://ai.misskey.xyz/aiart/yubitun.png'
+ })
+ public errorImageUrl: string | null;
+
+ @Column('varchar', {
+ length: 256,
+ 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..0bcb9b4a44
--- /dev/null
+++ b/src/models/entities/note.ts
@@ -0,0 +1,236 @@
+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('timestamp with time zone', {
+ nullable: true,
+ comment: 'The updated date of the Note.'
+ })
+ public updatedAt: Date | null;
+
+ @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: 256, 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
+ })
+ 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: {}
+ })
+ public geo: any | null;
+
+ //#region Denormalized fields
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userHost: string | null;
+
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userInbox: 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
+}
+
+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..204f102f51
--- /dev/null
+++ b/src/models/entities/poll.ts
@@ -0,0 +1,67 @@
+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 id: string;
+
+ @Index({ unique: true })
+ @Column(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
+}
+
+export type IPoll = {
+ choices: string[];
+ votes?: number[];
+ multiple: boolean;
+ expiresAt: Date;
+};
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..f0f2a69f1b
--- /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: 256,
+ })
+ 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..06b98d2536
--- /dev/null
+++ b/src/models/entities/user-keypair.ts
@@ -0,0 +1,24 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserKeypair {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index({ unique: true })
+ @Column(id())
+ public userId: User['id'];
+
+ @OneToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @Column('varchar', {
+ length: 4096,
+ })
+ public keyPem: string;
+}
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-publickey.ts b/src/models/entities/user-publickey.ts
new file mode 100644
index 0000000000..6c019f3313
--- /dev/null
+++ b/src/models/entities/user-publickey.ts
@@ -0,0 +1,30 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserPublickey {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index({ unique: true })
+ @Column(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;
+}
diff --git a/src/models/entities/user-service-linking.ts b/src/models/entities/user-service-linking.ts
new file mode 100644
index 0000000000..3d99554e1e
--- /dev/null
+++ b/src/models/entities/user-service-linking.ts
@@ -0,0 +1,108 @@
+import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
+import { User } from './user';
+import { id } from '../id';
+
+@Entity()
+export class UserServiceLinking {
+ @PrimaryColumn(id())
+ public id: string;
+
+ @Index({ unique: true })
+ @Column(id())
+ public userId: User['id'];
+
+ @OneToOne(type => User, {
+ onDelete: 'CASCADE'
+ })
+ @JoinColumn()
+ public user: User | null;
+
+ @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;
+
+ //#region Denormalized fields
+ @Index()
+ @Column('varchar', {
+ length: 128, nullable: true,
+ comment: '[Denormalized]'
+ })
+ public userHost: string | null;
+ //#endregion
+}
diff --git a/src/models/entities/user.ts b/src/models/entities/user.ts
new file mode 100644
index 0000000000..1ef98cadc2
--- /dev/null
+++ b/src/models/entities/user.ts
@@ -0,0 +1,297 @@
+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('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('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;
+
+ @Column('varchar', {
+ length: 1024, nullable: true,
+ comment: 'The description (bio) of the User.'
+ })
+ public description: string | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 128, array: true, default: '{}'
+ })
+ public tags: string[];
+
+ @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('varchar', {
+ length: 256, nullable: true,
+ })
+ public avatarUrl: string | null;
+
+ @Column('varchar', {
+ length: 256, 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('boolean', {
+ default: false,
+ })
+ public twoFactorEnabled: 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: 256, nullable: true,
+ comment: 'The inbox of the User. It will be null if the origin of the user is local.'
+ })
+ public inbox: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: 'The sharedInbox of the User. It will be null if the origin of the user is local.'
+ })
+ public sharedInbox: string | null;
+
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: 'The featured of the User. It will be null if the origin of the user is local.'
+ })
+ public featured: string | null;
+
+ @Index()
+ @Column('varchar', {
+ length: 256, nullable: true,
+ comment: 'The URI of the User. It will be null if the origin of the user is local.'
+ })
+ public uri: string | null;
+
+ @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;
+
+ @Index({ unique: true })
+ @Column('varchar', {
+ length: 32, 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;
+
+ @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;
+}
+
+export interface ILocalUser extends User {
+ host: null;
+}
+
+export interface IRemoteUser extends User {
+ host: string;
+}