diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
| commit | 0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch) | |
| tree | 40874799472fa07416f17b50a398ac33b7771905 /src/models | |
| parent | update deps (diff) | |
| download | sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2 sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip | |
refactoring
Resolve #7779
Diffstat (limited to 'src/models')
100 files changed, 0 insertions, 8283 deletions
diff --git a/src/models/entities/abuse-user-report.ts b/src/models/entities/abuse-user-report.ts deleted file mode 100644 index c0cff139f6..0000000000 --- a/src/models/entities/abuse-user-report.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -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 targetUserId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public targetUser: User | null; - - @Index() - @Column(id()) - public reporterId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public reporter: User | null; - - @Column({ - ...id(), - nullable: true - }) - public assigneeId: User['id'] | null; - - @ManyToOne(type => User, { - onDelete: 'SET NULL' - }) - @JoinColumn() - public assignee: User | null; - - @Index() - @Column('boolean', { - default: false - }) - public resolved: boolean; - - @Column('varchar', { - length: 2048, - }) - public comment: string; - - //#region Denormalized fields - @Index() - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public targetUserHost: string | null; - - @Index() - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public reporterHost: string | null; - //#endregion -} diff --git a/src/models/entities/access-token.ts b/src/models/entities/access-token.ts deleted file mode 100644 index 5f41b3c1fc..0000000000 --- a/src/models/entities/access-token.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } 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; - - @Column('timestamp with time zone', { - nullable: true, - default: null, - }) - public lastUsedAt: Date | null; - - @Index() - @Column('varchar', { - length: 128 - }) - public token: string; - - @Index() - @Column('varchar', { - length: 128, - nullable: true, - default: null - }) - public session: string | null; - - @Index() - @Column('varchar', { - length: 128 - }) - public hash: string; - - @Index() - @Column(id()) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Column({ - ...id(), - nullable: true, - default: null - }) - public appId: App['id'] | null; - - @ManyToOne(type => App, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public app: App | null; - - @Column('varchar', { - length: 128, - nullable: true, - default: null - }) - public name: string | null; - - @Column('varchar', { - length: 512, - nullable: true, - default: null - }) - public description: string | null; - - @Column('varchar', { - length: 512, - nullable: true, - default: null - }) - public iconUrl: string | null; - - @Column('varchar', { - length: 64, array: true, - default: '{}' - }) - public permission: string[]; - - @Column('boolean', { - default: false - }) - public fetched: boolean; -} diff --git a/src/models/entities/ad.ts b/src/models/entities/ad.ts deleted file mode 100644 index b2fc04c4f0..0000000000 --- a/src/models/entities/ad.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Entity, Index, Column, PrimaryColumn } from 'typeorm'; -import { id } from '../id'; - -@Entity() -export class Ad { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the Ad.' - }) - public createdAt: Date; - - @Index() - @Column('timestamp with time zone', { - comment: 'The expired date of the Ad.' - }) - public expiresAt: Date; - - @Column('varchar', { - length: 32, nullable: false - }) - public place: string; - - // 今は使われていないが将来的に活用される可能性はある - @Column('varchar', { - length: 32, nullable: false - }) - public priority: string; - - @Column('integer', { - default: 1, nullable: false - }) - public ratio: number; - - @Column('varchar', { - length: 1024, nullable: false - }) - public url: string; - - @Column('varchar', { - length: 1024, nullable: false - }) - public imageUrl: string; - - @Column('varchar', { - length: 8192, nullable: false - }) - public memo: string; - - constructor(data: Partial<Ad>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/announcement-read.ts b/src/models/entities/announcement-read.ts deleted file mode 100644 index 892beb826f..0000000000 --- a/src/models/entities/announcement-read.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { Announcement } from './announcement'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'announcementId'], { unique: true }) -export class AnnouncementRead { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the AnnouncementRead.' - }) - public createdAt: Date; - - @Index() - @Column(id()) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Index() - @Column(id()) - public announcementId: Announcement['id']; - - @ManyToOne(type => Announcement, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public announcement: Announcement | null; -} diff --git a/src/models/entities/announcement.ts b/src/models/entities/announcement.ts deleted file mode 100644 index 06d379c229..0000000000 --- a/src/models/entities/announcement.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Entity, Index, Column, PrimaryColumn } from 'typeorm'; -import { id } from '../id'; - -@Entity() -export class Announcement { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the Announcement.' - }) - public createdAt: Date; - - @Column('timestamp with time zone', { - comment: 'The updated date of the Announcement.', - nullable: true - }) - public updatedAt: Date | null; - - @Column('varchar', { - length: 8192, nullable: false - }) - public text: string; - - @Column('varchar', { - length: 256, nullable: false - }) - public title: string; - - @Column('varchar', { - length: 1024, nullable: true - }) - public imageUrl: string | null; - - constructor(data: Partial<Announcement>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/antenna-note.ts b/src/models/entities/antenna-note.ts deleted file mode 100644 index 9b911524ef..0000000000 --- a/src/models/entities/antenna-note.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; -import { Note } from './note'; -import { Antenna } from './antenna'; -import { id } from '../id'; - -@Entity() -@Index(['noteId', 'antennaId'], { unique: true }) -export class AntennaNote { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column({ - ...id(), - comment: 'The note ID.' - }) - public noteId: Note['id']; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public note: Note | null; - - @Index() - @Column({ - ...id(), - comment: 'The antenna ID.' - }) - public antennaId: Antenna['id']; - - @ManyToOne(type => Antenna, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public antenna: Antenna | null; - - @Index() - @Column('boolean', { - default: false - }) - public read: boolean; -} diff --git a/src/models/entities/antenna.ts b/src/models/entities/antenna.ts deleted file mode 100644 index bcfe09a829..0000000000 --- a/src/models/entities/antenna.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { UserList } from './user-list'; -import { UserGroupJoining } from './user-group-joining'; - -@Entity() -export class Antenna { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the Antenna.' - }) - 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 Antenna.' - }) - public name: string; - - @Column('enum', { enum: ['home', 'all', 'users', 'list', 'group'] }) - public src: 'home' | 'all' | 'users' | 'list' | 'group'; - - @Column({ - ...id(), - nullable: true - }) - public userListId: UserList['id'] | null; - - @ManyToOne(type => UserList, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public userList: UserList | null; - - @Column({ - ...id(), - nullable: true - }) - public userGroupJoiningId: UserGroupJoining['id'] | null; - - @ManyToOne(type => UserGroupJoining, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public userGroupJoining: UserGroupJoining | null; - - @Column('varchar', { - length: 1024, array: true, - default: '{}' - }) - public users: string[]; - - @Column('jsonb', { - default: [] - }) - public keywords: string[][]; - - @Column('jsonb', { - default: [] - }) - public excludeKeywords: string[][]; - - @Column('boolean', { - default: false - }) - public caseSensitive: boolean; - - @Column('boolean', { - default: false - }) - public withReplies: boolean; - - @Column('boolean') - public withFile: boolean; - - @Column('varchar', { - length: 2048, nullable: true, - }) - public expression: string | null; - - @Column('boolean') - public notify: boolean; -} diff --git a/src/models/entities/app.ts b/src/models/entities/app.ts deleted file mode 100644 index ea87546311..0000000000 --- a/src/models/entities/app.ts +++ /dev/null @@ -1,60 +0,0 @@ -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/attestation-challenge.ts b/src/models/entities/attestation-challenge.ts deleted file mode 100644 index 942747c02f..0000000000 --- a/src/models/entities/attestation-challenge.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { PrimaryColumn, Entity, JoinColumn, Column, ManyToOne, Index } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class AttestationChallenge { - @PrimaryColumn(id()) - public id: string; - - @Index() - @PrimaryColumn(id()) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Index() - @Column('varchar', { - length: 64, - comment: 'Hex-encoded sha256 hash of the challenge.' - }) - public challenge: string; - - @Column('timestamp with time zone', { - comment: 'The date challenge was created for expiry purposes.' - }) - public createdAt: Date; - - @Column('boolean', { - comment: - 'Indicates that the challenge is only for registration purposes if true to prevent the challenge for being used as authentication.', - default: false - }) - public registrationChallenge: boolean; - - constructor(data: Partial<AttestationChallenge>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/auth-session.ts b/src/models/entities/auth-session.ts deleted file mode 100644 index 4eec27e3f6..0000000000 --- a/src/models/entities/auth-session.ts +++ /dev/null @@ -1,43 +0,0 @@ -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 deleted file mode 100644 index 48487cb086..0000000000 --- a/src/models/entities/blocking.ts +++ /dev/null @@ -1,42 +0,0 @@ -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/channel-following.ts b/src/models/entities/channel-following.ts deleted file mode 100644 index fca801e5ab..0000000000 --- a/src/models/entities/channel-following.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { Channel } from './channel'; - -@Entity() -@Index(['followerId', 'followeeId'], { unique: true }) -export class ChannelFollowing { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the ChannelFollowing.' - }) - public createdAt: Date; - - @Index() - @Column({ - ...id(), - comment: 'The followee channel ID.' - }) - public followeeId: Channel['id']; - - @ManyToOne(type => Channel, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public followee: Channel | null; - - @Index() - @Column({ - ...id(), - comment: 'The follower user ID.' - }) - public followerId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public follower: User | null; -} diff --git a/src/models/entities/channel-note-pining.ts b/src/models/entities/channel-note-pining.ts deleted file mode 100644 index 26a7eb501f..0000000000 --- a/src/models/entities/channel-note-pining.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { Note } from './note'; -import { Channel } from './channel'; -import { id } from '../id'; - -@Entity() -@Index(['channelId', 'noteId'], { unique: true }) -export class ChannelNotePining { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the ChannelNotePining.' - }) - public createdAt: Date; - - @Index() - @Column(id()) - public channelId: Channel['id']; - - @ManyToOne(type => Channel, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public channel: Channel | null; - - @Column(id()) - public noteId: Note['id']; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public note: Note | null; -} diff --git a/src/models/entities/channel.ts b/src/models/entities/channel.ts deleted file mode 100644 index f2d713612d..0000000000 --- a/src/models/entities/channel.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { DriveFile } from './drive-file'; - -@Entity() -export class Channel { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the Channel.' - }) - public createdAt: Date; - - @Index() - @Column('timestamp with time zone', { - nullable: true - }) - public lastNotedAt: Date | null; - - @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; - - @Column('varchar', { - length: 128, - comment: 'The name of the Channel.' - }) - public name: string; - - @Column('varchar', { - length: 2048, nullable: true, - comment: 'The description of the Channel.' - }) - public description: string | null; - - @Column({ - ...id(), - nullable: true, - comment: 'The ID of banner Channel.' - }) - public bannerId: DriveFile['id'] | null; - - @ManyToOne(type => DriveFile, { - onDelete: 'SET NULL' - }) - @JoinColumn() - public banner: DriveFile | null; - - @Index() - @Column('integer', { - default: 0, - comment: 'The count of notes.' - }) - public notesCount: number; - - @Index() - @Column('integer', { - default: 0, - comment: 'The count of users.' - }) - public usersCount: number; -} diff --git a/src/models/entities/clip-note.ts b/src/models/entities/clip-note.ts deleted file mode 100644 index 7d96b2ef7a..0000000000 --- a/src/models/entities/clip-note.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; -import { Note } from './note'; -import { Clip } from './clip'; -import { id } from '../id'; - -@Entity() -@Index(['noteId', 'clipId'], { unique: true }) -export class ClipNote { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column({ - ...id(), - comment: 'The note ID.' - }) - public noteId: Note['id']; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public note: Note | null; - - @Index() - @Column({ - ...id(), - comment: 'The clip ID.' - }) - public clipId: Clip['id']; - - @ManyToOne(type => Clip, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public clip: Clip | null; -} diff --git a/src/models/entities/clip.ts b/src/models/entities/clip.ts deleted file mode 100644 index 66b5b8847e..0000000000 --- a/src/models/entities/clip.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class Clip { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the Clip.' - }) - 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 Clip.' - }) - public name: string; - - @Column('boolean', { - default: false - }) - public isPublic: boolean; - - @Column('varchar', { - length: 2048, nullable: true, default: null, - comment: 'The description of the Clip.' - }) - public description: string | null; -} diff --git a/src/models/entities/drive-file.ts b/src/models/entities/drive-file.ts deleted file mode 100644 index 698dfac222..0000000000 --- a/src/models/entities/drive-file.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { DriveFolder } from './drive-folder'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'folderId', 'id']) -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('varchar', { - length: 128, nullable: true, - comment: 'The BlurHash string.' - }) - public blurhash: string | null; - - @Column('jsonb', { - default: {}, - comment: 'The any properties of the DriveFile. For example, it includes image width/height.' - }) - public properties: { width?: number; height?: number; avgColor?: string }; - - @Index() - @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; - - @Index() - @Column('boolean', { - default: false, - comment: 'Whether the DriveFile is NSFW.' - }) - public isSensitive: boolean; - - /** - * 外部の(信頼されていない)URLへの直リンクか否か - */ - @Index() - @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 deleted file mode 100644 index a80d075855..0000000000 --- a/src/models/entities/drive-folder.ts +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index d6080ae099..0000000000 --- a/src/models/entities/emoji.ts +++ /dev/null @@ -1,51 +0,0 @@ -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: 128, nullable: true - }) - public category: 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 deleted file mode 100644 index 22ec263962..0000000000 --- a/src/models/entities/follow-request.ts +++ /dev/null @@ -1,85 +0,0 @@ -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 deleted file mode 100644 index ee3286a1a1..0000000000 --- a/src/models/entities/following.ts +++ /dev/null @@ -1,80 +0,0 @@ -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/gallery-like.ts b/src/models/entities/gallery-like.ts deleted file mode 100644 index 7d084a2275..0000000000 --- a/src/models/entities/gallery-like.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { GalleryPost } from './gallery-post'; - -@Entity() -@Index(['userId', 'postId'], { unique: true }) -export class GalleryLike { - @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(id()) - public postId: GalleryPost['id']; - - @ManyToOne(type => GalleryPost, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public post: GalleryPost | null; -} diff --git a/src/models/entities/gallery-post.ts b/src/models/entities/gallery-post.ts deleted file mode 100644 index f59cd671f3..0000000000 --- a/src/models/entities/gallery-post.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { DriveFile } from './drive-file'; - -@Entity() -export class GalleryPost { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the GalleryPost.' - }) - public createdAt: Date; - - @Index() - @Column('timestamp with time zone', { - comment: 'The updated date of the GalleryPost.' - }) - public updatedAt: Date; - - @Column('varchar', { - length: 256, - }) - public title: string; - - @Column('varchar', { - length: 2048, nullable: true - }) - public description: string | null; - - @Index() - @Column({ - ...id(), - comment: 'The ID of author.' - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public fileIds: DriveFile['id'][]; - - @Index() - @Column('boolean', { - default: false, - comment: 'Whether the post is sensitive.' - }) - public isSensitive: boolean; - - @Index() - @Column('integer', { - default: 0 - }) - public likedCount: number; - - @Index() - @Column('varchar', { - length: 128, array: true, default: '{}' - }) - public tags: string[]; - - constructor(data: Partial<GalleryPost>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/games/reversi/game.ts b/src/models/entities/games/reversi/game.ts deleted file mode 100644 index 9deacaf5c6..0000000000 --- a/src/models/entities/games/reversi/game.ts +++ /dev/null @@ -1,133 +0,0 @@ -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 deleted file mode 100644 index 477a29316e..0000000000 --- a/src/models/entities/games/reversi/matching.ts +++ /dev/null @@ -1,35 +0,0 @@ -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 deleted file mode 100644 index 842cdaa562..0000000000 --- a/src/models/entities/hashtag.ts +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index 7c8719e06a..0000000000 --- a/src/models/entities/instance.ts +++ /dev/null @@ -1,180 +0,0 @@ -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; - - /** - * インスタンスのユーザー数 - */ - @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('bigint', { - 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; - - /** - * このインスタンスへの配信を停止するか - */ - @Index() - @Column('boolean', { - default: false - }) - public isSuspended: boolean; - - @Column('varchar', { - length: 64, nullable: true, default: null, - comment: 'The software of the Instance.' - }) - public softwareName: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public softwareVersion: string | null; - - @Column('boolean', { - nullable: true, default: null, - }) - public openRegistrations: boolean | null; - - @Column('varchar', { - length: 256, nullable: true, default: null, - }) - public name: string | null; - - @Column('varchar', { - length: 4096, nullable: true, default: null, - }) - public description: string | null; - - @Column('varchar', { - length: 128, nullable: true, default: null, - }) - public maintainerName: string | null; - - @Column('varchar', { - length: 256, nullable: true, default: null, - }) - public maintainerEmail: string | null; - - @Column('varchar', { - length: 256, nullable: true, default: null, - }) - public iconUrl: string | null; - - @Column('varchar', { - length: 256, nullable: true, default: null, - }) - public faviconUrl: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public themeColor: string | null; - - @Column('timestamp with time zone', { - nullable: true, - }) - public infoUpdatedAt: Date | null; -} diff --git a/src/models/entities/messaging-message.ts b/src/models/entities/messaging-message.ts deleted file mode 100644 index ac0764674c..0000000000 --- a/src/models/entities/messaging-message.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { DriveFile } from './drive-file'; -import { id } from '../id'; -import { UserGroup } from './user-group'; - -@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(), nullable: true, - comment: 'The recipient user ID.' - }) - public recipientId: User['id'] | null; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public recipient: User | null; - - @Index() - @Column({ - ...id(), nullable: true, - comment: 'The recipient group ID.' - }) - public groupId: UserGroup['id'] | null; - - @ManyToOne(type => UserGroup, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public group: UserGroup | null; - - @Column('varchar', { - length: 4096, nullable: true - }) - public text: string | null; - - @Column('boolean', { - default: false, - }) - public isRead: boolean; - - @Column('varchar', { - length: 512, nullable: true, - }) - public uri: string | null; - - @Column({ - ...id(), - array: true, default: '{}' - }) - public reads: User['id'][]; - - @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 deleted file mode 100644 index 9a1a87c155..0000000000 --- a/src/models/entities/meta.ts +++ /dev/null @@ -1,423 +0,0 @@ -import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { Clip } from './clip'; - -@Entity() -export class Meta { - @PrimaryColumn({ - type: 'varchar', - length: 32 - }) - 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('boolean', { - default: false, - }) - public disableRegistration: boolean; - - @Column('boolean', { - default: false, - }) - public disableLocalTimeline: boolean; - - @Column('boolean', { - default: false, - }) - public disableGlobalTimeline: 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 pinnedUsers: 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, array: true, default: '{"/featured", "/channels", "/explore", "/pages", "/about-misskey"}' - }) - public pinnedPages: string[]; - - @Column({ - ...id(), - nullable: true, - }) - public pinnedClipId: Clip['id'] | null; - - @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 - }) - public backgroundImageUrl: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public logoImageUrl: 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('boolean', { - default: false, - }) - public proxyRemoteFiles: boolean; - - @Column({ - ...id(), - nullable: true, - }) - public proxyAccountId: User['id'] | null; - - @ManyToOne(type => User, { - onDelete: 'SET NULL' - }) - @JoinColumn() - public proxyAccount: User | null; - - @Column('boolean', { - default: false, - }) - public emailRequiredForSignup: boolean; - - @Column('boolean', { - default: false, - }) - public enableHcaptcha: boolean; - - @Column('varchar', { - length: 64, - nullable: true - }) - public hcaptchaSiteKey: string | null; - - @Column('varchar', { - length: 64, - nullable: true - }) - public hcaptchaSecretKey: 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; - - @Column('varchar', { - length: 128, - nullable: true - }) - public deeplAuthKey: string | null; - - @Column('boolean', { - default: false, - }) - public deeplIsPro: boolean; - - @Column('varchar', { - length: 512, - nullable: true - }) - public ToSUrl: string | null; - - @Column('varchar', { - length: 512, - default: 'https://github.com/misskey-dev/misskey', - nullable: false - }) - public repositoryUrl: string; - - @Column('varchar', { - length: 512, - default: 'https://github.com/misskey-dev/misskey/issues/new', - nullable: true - }) - public feedbackUrl: string | null; - - @Column('boolean', { - default: false, - }) - public useObjectStorage: boolean; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageBucket: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStoragePrefix: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageBaseUrl: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageEndpoint: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageRegion: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageAccessKey: string | null; - - @Column('varchar', { - length: 512, - nullable: true - }) - public objectStorageSecretKey: string | null; - - @Column('integer', { - nullable: true - }) - public objectStoragePort: number | null; - - @Column('boolean', { - default: true, - }) - public objectStorageUseSSL: boolean; - - @Column('boolean', { - default: true, - }) - public objectStorageUseProxy: boolean; - - @Column('boolean', { - default: false, - }) - public objectStorageSetPublicRead: boolean; - - @Column('boolean', { - default: true, - }) - public objectStorageS3ForcePathStyle: boolean; -} diff --git a/src/models/entities/moderation-log.ts b/src/models/entities/moderation-log.ts deleted file mode 100644 index 33d3d683ae..0000000000 --- a/src/models/entities/moderation-log.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class ModerationLog { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the ModerationLog.' - }) - 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 type: string; - - @Column('jsonb') - public info: Record<string, any>; -} diff --git a/src/models/entities/muted-note.ts b/src/models/entities/muted-note.ts deleted file mode 100644 index 521876688c..0000000000 --- a/src/models/entities/muted-note.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; -import { Note } from './note'; -import { User } from './user'; -import { id } from '../id'; -import { mutedNoteReasons } from '../../types'; - -@Entity() -@Index(['noteId', 'userId'], { unique: true }) -export class MutedNote { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column({ - ...id(), - comment: 'The note ID.' - }) - public noteId: Note['id']; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public note: Note | null; - - @Index() - @Column({ - ...id(), - comment: 'The user ID.' - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - /** - * ミュートされた理由。 - */ - @Index() - @Column('enum', { - enum: mutedNoteReasons, - comment: 'The reason of the MutedNote.' - }) - public reason: typeof mutedNoteReasons[number]; -} diff --git a/src/models/entities/muting.ts b/src/models/entities/muting.ts deleted file mode 100644 index 0084213bcc..0000000000 --- a/src/models/entities/muting.ts +++ /dev/null @@ -1,42 +0,0 @@ -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 deleted file mode 100644 index 0713c3ae56..0000000000 --- a/src/models/entities/note-favorite.ts +++ /dev/null @@ -1,35 +0,0 @@ -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 deleted file mode 100644 index 674dc3639e..0000000000 --- a/src/models/entities/note-reaction.ts +++ /dev/null @@ -1,44 +0,0 @@ -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; - - // TODO: 対象noteのuserIdを非正規化したい(「受け取ったリアクション一覧」のようなものを(JOIN無しで)実装したいため) - - @Column('varchar', { - length: 260 - }) - public reaction: string; -} diff --git a/src/models/entities/note-thread-muting.ts b/src/models/entities/note-thread-muting.ts deleted file mode 100644 index b438522a4c..0000000000 --- a/src/models/entities/note-thread-muting.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { Note } from './note'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'threadId'], { unique: true }) -export class NoteThreadMuting { - @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; - - @Index() - @Column('varchar', { - length: 256, - }) - public threadId: string; -} diff --git a/src/models/entities/note-unread.ts b/src/models/entities/note-unread.ts deleted file mode 100644 index 57dda4fafd..0000000000 --- a/src/models/entities/note-unread.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { Note } from './note'; -import { id } from '../id'; -import { Channel } from './channel'; - -@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; - - /** - * メンションか否か - */ - @Index() - @Column('boolean') - public isMentioned: boolean; - - /** - * ダイレクト投稿か否か - */ - @Index() - @Column('boolean') - public isSpecified: boolean; - - //#region Denormalized fields - @Index() - @Column({ - ...id(), - comment: '[Denormalized]' - }) - public noteUserId: User['id']; - - @Index() - @Column({ - ...id(), - nullable: true, - comment: '[Denormalized]' - }) - public noteChannelId: Channel['id'] | null; - //#endregion -} diff --git a/src/models/entities/note-watching.ts b/src/models/entities/note-watching.ts deleted file mode 100644 index 741a1c0c8b..0000000000 --- a/src/models/entities/note-watching.ts +++ /dev/null @@ -1,52 +0,0 @@ -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 deleted file mode 100644 index 4a5411f93d..0000000000 --- a/src/models/entities/note.ts +++ /dev/null @@ -1,247 +0,0 @@ -import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { DriveFile } from './drive-file'; -import { id } from '../id'; -import { noteVisibilities } from '../../types'; -import { Channel } from './channel'; - -@Entity() -@Index('IDX_NOTE_TAGS', { synchronize: false }) -@Index('IDX_NOTE_MENTIONS', { synchronize: false }) -@Index('IDX_NOTE_VISIBLE_USER_IDS', { synchronize: false }) -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; - - @Index() - @Column('varchar', { - length: 256, nullable: true - }) - public threadId: string | null; - - @Column('varchar', { - length: 8192, 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; - - @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('smallint', { - default: 0 - }) - public renoteCount: number; - - @Column('smallint', { - default: 0 - }) - public repliesCount: number; - - @Column('jsonb', { - default: {} - }) - public reactions: Record<string, number>; - - /** - * public ... 公開 - * home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す - * followers ... フォロワーのみ - * specified ... visibleUserIds で指定したユーザーのみ - */ - @Column('enum', { enum: noteVisibilities }) - public visibility: typeof noteVisibilities[number]; - - @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('varchar', { - length: 512, nullable: true, - comment: 'The human readable url of a note. it will be null when the note is local.' - }) - public url: string | null; - - @Column('integer', { - default: 0, select: false - }) - public score: number; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public fileIds: DriveFile['id'][]; - - @Index() - @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; - - @Index() - @Column({ - ...id(), - nullable: true, default: null, - comment: 'The ID of source channel.' - }) - public channelId: Channel['id'] | null; - - @ManyToOne(type => Channel, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public channel: Channel | 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; - url?: string; - username: string; - host: string; -}[]; diff --git a/src/models/entities/notification.ts b/src/models/entities/notification.ts deleted file mode 100644 index 47184caacc..0000000000 --- a/src/models/entities/notification.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { Entity, Index, JoinColumn, ManyToOne, Column, PrimaryColumn } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { Note } from './note'; -import { FollowRequest } from './follow-request'; -import { UserGroupInvitation } from './user-group-invitation'; -import { AccessToken } from './access-token'; -import { notificationTypes } from '@/types'; - -@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) - */ - @Index() - @Column({ - ...id(), - nullable: true, - comment: 'The ID of sender user of the Notification.' - }) - public notifierId: User['id'] | null; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public notifier: User | null; - - /** - * 通知の種類。 - * follow - フォローされた - * mention - 投稿で自分が言及された - * reply - (自分または自分がWatchしている)投稿が返信された - * renote - (自分または自分がWatchしている)投稿がRenoteされた - * quote - (自分または自分がWatchしている)投稿が引用Renoteされた - * reaction - (自分または自分がWatchしている)投稿にリアクションされた - * pollVote - (自分または自分がWatchしている)投稿の投票に投票された - * receiveFollowRequest - フォローリクエストされた - * followRequestAccepted - 自分の送ったフォローリクエストが承認された - * groupInvited - グループに招待された - * app - アプリ通知 - */ - @Index() - @Column('enum', { - enum: notificationTypes, - comment: 'The type of the Notification.' - }) - public type: typeof notificationTypes[number]; - - /** - * 通知が読まれたかどうか - */ - @Index() - @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({ - ...id(), - nullable: true - }) - public followRequestId: FollowRequest['id'] | null; - - @ManyToOne(type => FollowRequest, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public followRequest: FollowRequest | null; - - @Column({ - ...id(), - nullable: true - }) - public userGroupInvitationId: UserGroupInvitation['id'] | null; - - @ManyToOne(type => UserGroupInvitation, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public userGroupInvitation: UserGroupInvitation | null; - - @Column('varchar', { - length: 128, nullable: true - }) - public reaction: string | null; - - @Column('integer', { - nullable: true - }) - public choice: number | null; - - /** - * アプリ通知のbody - */ - @Column('varchar', { - length: 2048, nullable: true - }) - public customBody: string | null; - - /** - * アプリ通知のheader - * (省略時はアプリ名で表示されることを期待) - */ - @Column('varchar', { - length: 256, nullable: true - }) - public customHeader: string | null; - - /** - * アプリ通知のicon(URL) - * (省略時はアプリアイコンで表示されることを期待) - */ - @Column('varchar', { - length: 1024, nullable: true - }) - public customIcon: string | null; - - /** - * アプリ通知のアプリ(のトークン) - */ - @Index() - @Column({ - ...id(), - nullable: true - }) - public appAccessTokenId: AccessToken['id'] | null; - - @ManyToOne(type => AccessToken, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public appAccessToken: AccessToken | null; -} diff --git a/src/models/entities/page-like.ts b/src/models/entities/page-like.ts deleted file mode 100644 index ca84ece8fd..0000000000 --- a/src/models/entities/page-like.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { Page } from './page'; - -@Entity() -@Index(['userId', 'pageId'], { unique: true }) -export class PageLike { - @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(id()) - public pageId: Page['id']; - - @ManyToOne(type => Page, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public page: Page | null; -} diff --git a/src/models/entities/page.ts b/src/models/entities/page.ts deleted file mode 100644 index ed0411a3d0..0000000000 --- a/src/models/entities/page.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; -import { DriveFile } from './drive-file'; - -@Entity() -@Index(['userId', 'name'], { unique: true }) -export class Page { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the Page.' - }) - public createdAt: Date; - - @Index() - @Column('timestamp with time zone', { - comment: 'The updated date of the Page.' - }) - public updatedAt: Date; - - @Column('varchar', { - length: 256, - }) - public title: string; - - @Index() - @Column('varchar', { - length: 256, - }) - public name: string; - - @Column('varchar', { - length: 256, nullable: true - }) - public summary: string | null; - - @Column('boolean') - public alignCenter: boolean; - - @Column('boolean', { - default: false - }) - public hideTitleWhenPinned: boolean; - - @Column('varchar', { - length: 32, - }) - public font: string; - - @Index() - @Column({ - ...id(), - comment: 'The ID of author.' - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Column({ - ...id(), - nullable: true, - }) - public eyeCatchingImageId: DriveFile['id'] | null; - - @ManyToOne(type => DriveFile, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public eyeCatchingImage: DriveFile | null; - - @Column('jsonb', { - default: [] - }) - public content: Record<string, any>[]; - - @Column('jsonb', { - default: [] - }) - public variables: Record<string, any>[]; - - @Column('varchar', { - length: 16384, - default: '' - }) - public script: string; - - /** - * public ... 公開 - * followers ... フォロワーのみ - * specified ... visibleUserIds で指定したユーザーのみ - */ - @Column('enum', { enum: ['public', 'followers', 'specified'] }) - public visibility: 'public' | 'followers' | 'specified'; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public visibleUserIds: User['id'][]; - - @Column('integer', { - default: 0 - }) - public likedCount: number; - - constructor(data: Partial<Page>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/password-reset-request.ts b/src/models/entities/password-reset-request.ts deleted file mode 100644 index 6d41d38a93..0000000000 --- a/src/models/entities/password-reset-request.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { PrimaryColumn, Entity, Index, Column, ManyToOne, JoinColumn } from 'typeorm'; -import { id } from '../id'; -import { User } from './user'; - -@Entity() -export class PasswordResetRequest { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone') - public createdAt: Date; - - @Index({ unique: true }) - @Column('varchar', { - length: 256, - }) - public token: string; - - @Index() - @Column({ - ...id(), - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; -} diff --git a/src/models/entities/poll-vote.ts b/src/models/entities/poll-vote.ts deleted file mode 100644 index 709376f909..0000000000 --- a/src/models/entities/poll-vote.ts +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index e3bbb1c3f2..0000000000 --- a/src/models/entities/poll.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm'; -import { id } from '../id'; -import { Note } from './note'; -import { User } from './user'; -import { noteVisibilities } from '../../types'; - -@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: noteVisibilities, - comment: '[Denormalized]' - }) - public noteVisibility: typeof noteVisibilities[number]; - - @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/promo-note.ts b/src/models/entities/promo-note.ts deleted file mode 100644 index 474f1cb235..0000000000 --- a/src/models/entities/promo-note.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm'; -import { Note } from './note'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class PromoNote { - @PrimaryColumn(id()) - public noteId: Note['id']; - - @OneToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public note: Note | null; - - @Column('timestamp with time zone') - public expiresAt: Date; - - //#region Denormalized fields - @Index() - @Column({ - ...id(), - comment: '[Denormalized]' - }) - public userId: User['id']; - //#endregion -} diff --git a/src/models/entities/promo-read.ts b/src/models/entities/promo-read.ts deleted file mode 100644 index 2e0977b6b5..0000000000 --- a/src/models/entities/promo-read.ts +++ /dev/null @@ -1,35 +0,0 @@ -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 PromoRead { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the PromoRead.' - }) - 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/registration-tickets.ts b/src/models/entities/registration-tickets.ts deleted file mode 100644 index d962f78a78..0000000000 --- a/src/models/entities/registration-tickets.ts +++ /dev/null @@ -1,17 +0,0 @@ -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/registry-item.ts b/src/models/entities/registry-item.ts deleted file mode 100644 index 54d2ef2082..0000000000 --- a/src/models/entities/registry-item.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -// TODO: 同じdomain、同じscope、同じkeyのレコードは二つ以上存在しないように制約付けたい -@Entity() -export class RegistryItem { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the RegistryItem.' - }) - public createdAt: Date; - - @Column('timestamp with time zone', { - comment: 'The updated date of the RegistryItem.' - }) - public updatedAt: 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: 1024, - comment: 'The key of the RegistryItem.' - }) - public key: string; - - @Column('jsonb', { - default: {}, nullable: true, - comment: 'The value of the RegistryItem.' - }) - public value: any | null; - - @Index() - @Column('varchar', { - length: 1024, array: true, default: '{}' - }) - public scope: string[]; - - // サードパーティアプリに開放するときのためのカラム - @Index() - @Column('varchar', { - length: 512, nullable: true - }) - public domain: string | null; -} diff --git a/src/models/entities/relay.ts b/src/models/entities/relay.ts deleted file mode 100644 index 4c82ccb125..0000000000 --- a/src/models/entities/relay.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { PrimaryColumn, Entity, Index, Column } from 'typeorm'; -import { id } from '../id'; - -@Entity() -export class Relay { - @PrimaryColumn(id()) - public id: string; - - @Index({ unique: true }) - @Column('varchar', { - length: 512, nullable: false, - }) - public inbox: string; - - @Column('enum', { - enum: ['requesting', 'accepted', 'rejected'], - }) - public status: 'requesting' | 'accepted' | 'rejected'; -} diff --git a/src/models/entities/signin.ts b/src/models/entities/signin.ts deleted file mode 100644 index 7e047084b1..0000000000 --- a/src/models/entities/signin.ts +++ /dev/null @@ -1,35 +0,0 @@ -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 deleted file mode 100644 index 7c3f6f0a6c..0000000000 --- a/src/models/entities/sw-subscription.ts +++ /dev/null @@ -1,37 +0,0 @@ -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/used-username.ts b/src/models/entities/used-username.ts deleted file mode 100644 index eb90bef6ca..0000000000 --- a/src/models/entities/used-username.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PrimaryColumn, Entity, Column } from 'typeorm'; - -@Entity() -export class UsedUsername { - @PrimaryColumn('varchar', { - length: 128, - }) - public username: string; - - @Column('timestamp with time zone') - public createdAt: Date; - - constructor(data: Partial<UsedUsername>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/user-group-invitation.ts b/src/models/entities/user-group-invitation.ts deleted file mode 100644 index 6fe8f20134..0000000000 --- a/src/models/entities/user-group-invitation.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { UserGroup } from './user-group'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'userGroupId'], { unique: true }) -export class UserGroupInvitation { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the UserGroupInvitation.' - }) - 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 group ID.' - }) - public userGroupId: UserGroup['id']; - - @ManyToOne(type => UserGroup, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public userGroup: UserGroup | null; -} diff --git a/src/models/entities/user-group-joining.ts b/src/models/entities/user-group-joining.ts deleted file mode 100644 index e09c3230f1..0000000000 --- a/src/models/entities/user-group-joining.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { UserGroup } from './user-group'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'userGroupId'], { unique: true }) -export class UserGroupJoining { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone', { - comment: 'The created date of the UserGroupJoining.' - }) - 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 group ID.' - }) - public userGroupId: UserGroup['id']; - - @ManyToOne(type => UserGroup, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public userGroup: UserGroup | null; -} diff --git a/src/models/entities/user-group.ts b/src/models/entities/user-group.ts deleted file mode 100644 index f4bac03223..0000000000 --- a/src/models/entities/user-group.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class UserGroup { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the UserGroup.' - }) - public createdAt: Date; - - @Column('varchar', { - length: 256, - }) - public name: string; - - @Index() - @Column({ - ...id(), - comment: 'The ID of owner.' - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Column('boolean', { - default: false, - }) - public isPrivate: boolean; - - constructor(data: Partial<UserGroup>) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/entities/user-keypair.ts b/src/models/entities/user-keypair.ts deleted file mode 100644 index 603321d758..0000000000 --- a/src/models/entities/user-keypair.ts +++ /dev/null @@ -1,33 +0,0 @@ -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 deleted file mode 100644 index bb7dc40b95..0000000000 --- a/src/models/entities/user-list-joining.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { UserList } from './user-list'; -import { id } from '../id'; - -@Entity() -@Index(['userId', 'userListId'], { unique: true }) -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 deleted file mode 100644 index 35a83ef8c3..0000000000 --- a/src/models/entities/user-list.ts +++ /dev/null @@ -1,33 +0,0 @@ -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-pining.ts b/src/models/entities/user-note-pining.ts deleted file mode 100644 index 04a6f8f645..0000000000 --- a/src/models/entities/user-note-pining.ts +++ /dev/null @@ -1,35 +0,0 @@ -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-pending.ts b/src/models/entities/user-pending.ts deleted file mode 100644 index 40482af333..0000000000 --- a/src/models/entities/user-pending.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PrimaryColumn, Entity, Index, Column } from 'typeorm'; -import { id } from '../id'; - -@Entity() -export class UserPending { - @PrimaryColumn(id()) - public id: string; - - @Column('timestamp with time zone') - public createdAt: Date; - - @Index({ unique: true }) - @Column('varchar', { - length: 128, - }) - public code: string; - - @Column('varchar', { - length: 128, - }) - public username: string; - - @Column('varchar', { - length: 128, - }) - public email: string; - - @Column('varchar', { - length: 128, - }) - public password: string; -} diff --git a/src/models/entities/user-profile.ts b/src/models/entities/user-profile.ts deleted file mode 100644 index 8a8cacfd52..0000000000 --- a/src/models/entities/user-profile.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; -import { id } from '../id'; -import { User } from './user'; -import { Page } from './page'; -import { ffVisibility, notificationTypes } from '@/types'; - -// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも -// ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン -@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: 2048, 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: 32, nullable: true, - }) - public lang: string | null; - - @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('jsonb', { - default: ['follow', 'receiveFollowRequest', 'groupInvited'] - }) - public emailNotificationTypes: string[]; - - @Column('boolean', { - default: false, - }) - public publicReactions: boolean; - - @Column('enum', { - enum: ffVisibility, - default: 'public', - }) - public ffVisibility: typeof ffVisibility[number]; - - @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('boolean', { - default: false, - }) - public securityKeysAvailable: boolean; - - @Column('boolean', { - default: false, - }) - public usePasswordLessLogin: 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; - - // TODO: そのうち消す - @Column('jsonb', { - default: {}, - comment: 'The client-specific data of the User.' - }) - public clientData: Record<string, any>; - - @Column('jsonb', { - default: {}, - comment: 'The room data of the User.' - }) - public room: Record<string, any>; - - @Column('boolean', { - default: false, - }) - public autoAcceptFollowed: boolean; - - @Column('boolean', { - default: false, - comment: 'Whether reject index by crawler.' - }) - public noCrawle: boolean; - - @Column('boolean', { - default: false, - }) - public alwaysMarkNsfw: boolean; - - @Column('boolean', { - default: false, - }) - public carefulBot: boolean; - - @Column('boolean', { - default: true, - }) - public injectFeaturedNote: boolean; - - @Column('boolean', { - default: true, - }) - public receiveAnnouncementEmail: boolean; - - @Column({ - ...id(), - nullable: true - }) - public pinnedPageId: Page['id'] | null; - - @OneToOne(type => Page, { - onDelete: 'SET NULL' - }) - @JoinColumn() - public pinnedPage: Page | null; - - @Column('jsonb', { - default: {} - }) - public integrations: Record<string, any>; - - @Index() - @Column('boolean', { - default: false, select: false, - }) - public enableWordMute: boolean; - - @Column('jsonb', { - default: [] - }) - public mutedWords: string[][]; - - @Column('enum', { - enum: notificationTypes, - array: true, - default: [], - }) - public mutingNotificationTypes: typeof notificationTypes[number][]; - - //#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 deleted file mode 100644 index 21edc3e9e2..0000000000 --- a/src/models/entities/user-publickey.ts +++ /dev/null @@ -1,34 +0,0 @@ -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-security-key.ts b/src/models/entities/user-security-key.ts deleted file mode 100644 index d54c728e53..0000000000 --- a/src/models/entities/user-security-key.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { PrimaryColumn, Entity, JoinColumn, Column, ManyToOne, Index } from 'typeorm'; -import { User } from './user'; -import { id } from '../id'; - -@Entity() -export class UserSecurityKey { - @PrimaryColumn('varchar', { - comment: 'Variable-length id given to navigator.credentials.get()' - }) - public id: string; - - @Index() - @Column(id()) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Index() - @Column('varchar', { - comment: - 'Variable-length public key used to verify attestations (hex-encoded).' - }) - public publicKey: string; - - @Column('timestamp with time zone', { - comment: - 'The date of the last time the UserSecurityKey was successfully validated.' - }) - public lastUsed: Date; - - @Column('varchar', { - comment: 'User-defined name for this key', - length: 30 - }) - public name: string; - - constructor(data: Partial<UserSecurityKey>) { - 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 deleted file mode 100644 index 65aebd2d1a..0000000000 --- a/src/models/entities/user.ts +++ /dev/null @@ -1,250 +0,0 @@ -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; - - @Index() - @Column('timestamp with time zone', { - nullable: true - }) - public lastActiveDate: Date | null; - - @Column('boolean', { - default: false, - }) - public hideOnlineStatus: boolean; - - @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: 128, nullable: true, - }) - public avatarBlurhash: string | null; - - @Column('varchar', { - length: 128, nullable: true, - }) - public bannerBlurhash: 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; - - @Index() - @Column('boolean', { - default: true, - comment: 'Whether the User is explorable.' - }) - public isExplorable: boolean; - - // アカウントが削除されたかどうかのフラグだが、完全に削除される際は物理削除なので実質削除されるまでの「削除が進行しているかどうか」のフラグ - @Column('boolean', { - default: false, - comment: 'Whether the User is deleted.' - }) - public isDeleted: 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; - - @Column('varchar', { - length: 512, nullable: true, - comment: 'The URI of the user Follower Collection. It will be null if the origin of the user is local.' - }) - public followersUri: 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; -} diff --git a/src/models/id.ts b/src/models/id.ts deleted file mode 100644 index cdb8259073..0000000000 --- a/src/models/id.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const id = () => ({ - type: 'varchar' as const, - length: 32 -}); diff --git a/src/models/index.ts b/src/models/index.ts deleted file mode 100644 index 7154cca550..0000000000 --- a/src/models/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { getRepository, getCustomRepository } from 'typeorm'; -import { Announcement } from './entities/announcement'; -import { AnnouncementRead } from './entities/announcement-read'; -import { Instance } from './entities/instance'; -import { Poll } from './entities/poll'; -import { PollVote } from './entities/poll-vote'; -import { Meta } from './entities/meta'; -import { SwSubscription } from './entities/sw-subscription'; -import { NoteWatching } from './entities/note-watching'; -import { NoteThreadMuting } from './entities/note-thread-muting'; -import { NoteUnread } from './entities/note-unread'; -import { RegistrationTicket } from './entities/registration-tickets'; -import { UserRepository } from './repositories/user'; -import { NoteRepository } from './repositories/note'; -import { DriveFileRepository } from './repositories/drive-file'; -import { DriveFolderRepository } from './repositories/drive-folder'; -import { AccessToken } from './entities/access-token'; -import { UserNotePining } from './entities/user-note-pining'; -import { SigninRepository } from './repositories/signin'; -import { MessagingMessageRepository } from './repositories/messaging-message'; -import { ReversiGameRepository } from './repositories/games/reversi/game'; -import { UserListRepository } from './repositories/user-list'; -import { UserListJoining } from './entities/user-list-joining'; -import { UserGroupRepository } from './repositories/user-group'; -import { UserGroupJoining } from './entities/user-group-joining'; -import { UserGroupInvitationRepository } from './repositories/user-group-invitation'; -import { FollowRequestRepository } from './repositories/follow-request'; -import { MutingRepository } from './repositories/muting'; -import { BlockingRepository } from './repositories/blocking'; -import { NoteReactionRepository } from './repositories/note-reaction'; -import { NotificationRepository } from './repositories/notification'; -import { NoteFavoriteRepository } from './repositories/note-favorite'; -import { ReversiMatchingRepository } from './repositories/games/reversi/matching'; -import { UserPublickey } from './entities/user-publickey'; -import { UserKeypair } from './entities/user-keypair'; -import { AppRepository } from './repositories/app'; -import { FollowingRepository } from './repositories/following'; -import { AbuseUserReportRepository } from './repositories/abuse-user-report'; -import { AuthSessionRepository } from './repositories/auth-session'; -import { UserProfile } from './entities/user-profile'; -import { AttestationChallenge } from './entities/attestation-challenge'; -import { UserSecurityKey } from './entities/user-security-key'; -import { HashtagRepository } from './repositories/hashtag'; -import { PageRepository } from './repositories/page'; -import { PageLikeRepository } from './repositories/page-like'; -import { GalleryPostRepository } from './repositories/gallery-post'; -import { GalleryLikeRepository } from './repositories/gallery-like'; -import { ModerationLogRepository } from './repositories/moderation-logs'; -import { UsedUsername } from './entities/used-username'; -import { ClipRepository } from './repositories/clip'; -import { ClipNote } from './entities/clip-note'; -import { AntennaRepository } from './repositories/antenna'; -import { AntennaNote } from './entities/antenna-note'; -import { PromoNote } from './entities/promo-note'; -import { PromoRead } from './entities/promo-read'; -import { EmojiRepository } from './repositories/emoji'; -import { RelayRepository } from './repositories/relay'; -import { ChannelRepository } from './repositories/channel'; -import { MutedNote } from './entities/muted-note'; -import { ChannelFollowing } from './entities/channel-following'; -import { ChannelNotePining } from './entities/channel-note-pining'; -import { RegistryItem } from './entities/registry-item'; -import { Ad } from './entities/ad'; -import { PasswordResetRequest } from './entities/password-reset-request'; -import { UserPending } from './entities/user-pending'; - -export const Announcements = getRepository(Announcement); -export const AnnouncementReads = getRepository(AnnouncementRead); -export const Apps = getCustomRepository(AppRepository); -export const Notes = getCustomRepository(NoteRepository); -export const NoteFavorites = getCustomRepository(NoteFavoriteRepository); -export const NoteWatchings = getRepository(NoteWatching); -export const NoteThreadMutings = getRepository(NoteThreadMuting); -export const NoteReactions = getCustomRepository(NoteReactionRepository); -export const NoteUnreads = getRepository(NoteUnread); -export const Polls = getRepository(Poll); -export const PollVotes = getRepository(PollVote); -export const Users = getCustomRepository(UserRepository); -export const UserProfiles = getRepository(UserProfile); -export const UserKeypairs = getRepository(UserKeypair); -export const UserPendings = getRepository(UserPending); -export const AttestationChallenges = getRepository(AttestationChallenge); -export const UserSecurityKeys = getRepository(UserSecurityKey); -export const UserPublickeys = getRepository(UserPublickey); -export const UserLists = getCustomRepository(UserListRepository); -export const UserListJoinings = getRepository(UserListJoining); -export const UserGroups = getCustomRepository(UserGroupRepository); -export const UserGroupJoinings = getRepository(UserGroupJoining); -export const UserGroupInvitations = getCustomRepository(UserGroupInvitationRepository); -export const UserNotePinings = getRepository(UserNotePining); -export const UsedUsernames = getRepository(UsedUsername); -export const Followings = getCustomRepository(FollowingRepository); -export const FollowRequests = getCustomRepository(FollowRequestRepository); -export const Instances = getRepository(Instance); -export const Emojis = getCustomRepository(EmojiRepository); -export const DriveFiles = getCustomRepository(DriveFileRepository); -export const DriveFolders = getCustomRepository(DriveFolderRepository); -export const Notifications = getCustomRepository(NotificationRepository); -export const Metas = getRepository(Meta); -export const Mutings = getCustomRepository(MutingRepository); -export const Blockings = getCustomRepository(BlockingRepository); -export const SwSubscriptions = getRepository(SwSubscription); -export const Hashtags = getCustomRepository(HashtagRepository); -export const AbuseUserReports = getCustomRepository(AbuseUserReportRepository); -export const RegistrationTickets = getRepository(RegistrationTicket); -export const AuthSessions = getCustomRepository(AuthSessionRepository); -export const AccessTokens = getRepository(AccessToken); -export const Signins = getCustomRepository(SigninRepository); -export const MessagingMessages = getCustomRepository(MessagingMessageRepository); -export const ReversiGames = getCustomRepository(ReversiGameRepository); -export const ReversiMatchings = getCustomRepository(ReversiMatchingRepository); -export const Pages = getCustomRepository(PageRepository); -export const PageLikes = getCustomRepository(PageLikeRepository); -export const GalleryPosts = getCustomRepository(GalleryPostRepository); -export const GalleryLikes = getCustomRepository(GalleryLikeRepository); -export const ModerationLogs = getCustomRepository(ModerationLogRepository); -export const Clips = getCustomRepository(ClipRepository); -export const ClipNotes = getRepository(ClipNote); -export const Antennas = getCustomRepository(AntennaRepository); -export const AntennaNotes = getRepository(AntennaNote); -export const PromoNotes = getRepository(PromoNote); -export const PromoReads = getRepository(PromoRead); -export const Relays = getCustomRepository(RelayRepository); -export const MutedNotes = getRepository(MutedNote); -export const Channels = getCustomRepository(ChannelRepository); -export const ChannelFollowings = getRepository(ChannelFollowing); -export const ChannelNotePinings = getRepository(ChannelNotePining); -export const RegistryItems = getRepository(RegistryItem); -export const Ads = getRepository(Ad); -export const PasswordResetRequests = getRepository(PasswordResetRequest); diff --git a/src/models/repositories/abuse-user-report.ts b/src/models/repositories/abuse-user-report.ts deleted file mode 100644 index 039a9924d2..0000000000 --- a/src/models/repositories/abuse-user-report.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../index'; -import { AbuseUserReport } from '@/models/entities/abuse-user-report'; -import { awaitAll } from '@/prelude/await-all'; - -@EntityRepository(AbuseUserReport) -export class AbuseUserReportRepository extends Repository<AbuseUserReport> { - public async pack( - src: AbuseUserReport['id'] | AbuseUserReport, - ) { - const report = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: report.id, - createdAt: report.createdAt, - comment: report.comment, - resolved: report.resolved, - reporterId: report.reporterId, - targetUserId: report.targetUserId, - assigneeId: report.assigneeId, - reporter: Users.pack(report.reporter || report.reporterId, null, { - detail: true - }), - targetUser: Users.pack(report.targetUser || report.targetUserId, null, { - detail: true - }), - assignee: report.assigneeId ? Users.pack(report.assignee || report.assigneeId, null, { - detail: true - }) : null, - }); - } - - public packMany( - reports: any[], - ) { - return Promise.all(reports.map(x => this.pack(x))); - } -} diff --git a/src/models/repositories/antenna.ts b/src/models/repositories/antenna.ts deleted file mode 100644 index 657de55581..0000000000 --- a/src/models/repositories/antenna.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Antenna } from '@/models/entities/antenna'; -import { Packed } from '@/misc/schema'; -import { AntennaNotes, UserGroupJoinings } from '../index'; - -@EntityRepository(Antenna) -export class AntennaRepository extends Repository<Antenna> { - public async pack( - src: Antenna['id'] | Antenna, - ): Promise<Packed<'Antenna'>> { - const antenna = typeof src === 'object' ? src : await this.findOneOrFail(src); - - const hasUnreadNote = (await AntennaNotes.findOne({ antennaId: antenna.id, read: false })) != null; - const userGroupJoining = antenna.userGroupJoiningId ? await UserGroupJoinings.findOne(antenna.userGroupJoiningId) : null; - - return { - id: antenna.id, - createdAt: antenna.createdAt.toISOString(), - name: antenna.name, - keywords: antenna.keywords, - excludeKeywords: antenna.excludeKeywords, - src: antenna.src, - userListId: antenna.userListId, - userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null, - users: antenna.users, - caseSensitive: antenna.caseSensitive, - notify: antenna.notify, - withReplies: antenna.withReplies, - withFile: antenna.withFile, - hasUnreadNote - }; - } -} - -export const packedAntennaSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time' - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const - }, - keywords: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const - } - } - }, - excludeKeywords: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const - } - } - }, - src: { - type: 'string' as const, - optional: false as const, nullable: false as const, - enum: ['home', 'all', 'users', 'list', 'group'] - }, - userListId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id' - }, - userGroupId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id' - }, - users: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const - } - }, - caseSensitive: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - default: false - }, - notify: { - type: 'boolean' as const, - optional: false as const, nullable: false as const - }, - withReplies: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - default: false - }, - withFile: { - type: 'boolean' as const, - optional: false as const, nullable: false as const - }, - hasUnreadNote: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - default: false - } - }, -}; diff --git a/src/models/repositories/app.ts b/src/models/repositories/app.ts deleted file mode 100644 index 0226edad11..0000000000 --- a/src/models/repositories/app.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { App } from '@/models/entities/app'; -import { AccessTokens } from '../index'; -import { Packed } from '@/misc/schema'; -import { User } from '../entities/user'; - -@EntityRepository(App) -export class AppRepository extends Repository<App> { - public async pack( - src: App['id'] | App, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean, - includeSecret?: boolean, - includeProfileImageIds?: boolean - } - ): Promise<Packed<'App'>> { - const opts = Object.assign({ - detail: false, - includeSecret: false, - includeProfileImageIds: false - }, options); - - const app = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: app.id, - name: app.name, - callbackUrl: app.callbackUrl, - permission: app.permission, - ...(opts.includeSecret ? { secret: app.secret } : {}), - ...(me ? { - isAuthorized: await AccessTokens.count({ - appId: app.id, - userId: me, - }).then(count => count > 0) - } : {}) - }; - } -} - -export const packedAppSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const - }, - callbackUrl: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - permission: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const - } - }, - secret: { - type: 'string' as const, - optional: true as const, nullable: false as const - }, - isAuthorized: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - } - } -}; diff --git a/src/models/repositories/auth-session.ts b/src/models/repositories/auth-session.ts deleted file mode 100644 index c8f4c10f2a..0000000000 --- a/src/models/repositories/auth-session.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Apps } from '../index'; -import { AuthSession } from '@/models/entities/auth-session'; -import { awaitAll } from '@/prelude/await-all'; -import { User } from '@/models/entities/user'; - -@EntityRepository(AuthSession) -export class AuthSessionRepository extends Repository<AuthSession> { - public async pack( - src: AuthSession['id'] | AuthSession, - me?: { id: User['id'] } | null | undefined - ) { - const session = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: session.id, - app: Apps.pack(session.appId, me), - token: session.token - }); - } -} diff --git a/src/models/repositories/blocking.ts b/src/models/repositories/blocking.ts deleted file mode 100644 index ac60c9a4ce..0000000000 --- a/src/models/repositories/blocking.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../index'; -import { Blocking } from '@/models/entities/blocking'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; -import { User } from '@/models/entities/user'; - -@EntityRepository(Blocking) -export class BlockingRepository extends Repository<Blocking> { - public async pack( - src: Blocking['id'] | Blocking, - me?: { id: User['id'] } | null | undefined - ): Promise<Packed<'Blocking'>> { - const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: blocking.id, - createdAt: blocking.createdAt.toISOString(), - blockeeId: blocking.blockeeId, - blockee: Users.pack(blocking.blockeeId, me, { - detail: true - }) - }); - } - - public packMany( - blockings: any[], - me: { id: User['id'] } - ) { - return Promise.all(blockings.map(x => this.pack(x, me))); - } -} - -export const packedBlockingSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - blockeeId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - blockee: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - } -}; diff --git a/src/models/repositories/channel.ts b/src/models/repositories/channel.ts deleted file mode 100644 index 5c7d095473..0000000000 --- a/src/models/repositories/channel.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Channel } from '@/models/entities/channel'; -import { Packed } from '@/misc/schema'; -import { DriveFiles, ChannelFollowings, NoteUnreads } from '../index'; -import { User } from '@/models/entities/user'; - -@EntityRepository(Channel) -export class ChannelRepository extends Repository<Channel> { - public async pack( - src: Channel['id'] | Channel, - me?: { id: User['id'] } | null | undefined, - ): Promise<Packed<'Channel'>> { - const channel = typeof src === 'object' ? src : await this.findOneOrFail(src); - const meId = me ? me.id : null; - - const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null; - - const hasUnreadNote = meId ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined; - - const following = meId ? await ChannelFollowings.findOne({ - followerId: meId, - followeeId: channel.id, - }) : null; - - return { - id: channel.id, - createdAt: channel.createdAt.toISOString(), - lastNotedAt: channel.lastNotedAt ? channel.lastNotedAt.toISOString() : null, - name: channel.name, - description: channel.description, - userId: channel.userId, - bannerUrl: banner ? DriveFiles.getPublicUrl(banner, false) : null, - usersCount: channel.usersCount, - notesCount: channel.notesCount, - - ...(me ? { - isFollowing: following != null, - hasUnreadNote, - } : {}) - }; - } -} - -export const packedChannelSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - lastNotedAt: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'date-time', - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - description: { - type: 'string' as const, - nullable: true as const, optional: false as const, - }, - bannerUrl: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: false as const, - }, - notesCount: { - type: 'number' as const, - nullable: false as const, optional: false as const, - }, - usersCount: { - type: 'number' as const, - nullable: false as const, optional: false as const, - }, - isFollowing: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - userId: { - type: 'string' as const, - nullable: true as const, optional: false as const, - format: 'id', - }, - }, -}; diff --git a/src/models/repositories/clip.ts b/src/models/repositories/clip.ts deleted file mode 100644 index 7892811d48..0000000000 --- a/src/models/repositories/clip.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Clip } from '@/models/entities/clip'; -import { Packed } from '@/misc/schema'; -import { Users } from '../index'; -import { awaitAll } from '@/prelude/await-all'; - -@EntityRepository(Clip) -export class ClipRepository extends Repository<Clip> { - public async pack( - src: Clip['id'] | Clip, - ): Promise<Packed<'Clip'>> { - const clip = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: clip.id, - createdAt: clip.createdAt.toISOString(), - userId: clip.userId, - user: Users.pack(clip.user || clip.userId), - name: clip.name, - description: clip.description, - isPublic: clip.isPublic, - }); - } - - public packMany( - clips: Clip[], - ) { - return Promise.all(clips.map(x => this.pack(x))); - } -} - -export const packedClipSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: false as const, nullable: false as const, - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - description: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - isPublic: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - }, -}; diff --git a/src/models/repositories/drive-file.ts b/src/models/repositories/drive-file.ts deleted file mode 100644 index ddf9a46afd..0000000000 --- a/src/models/repositories/drive-file.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { DriveFile } from '@/models/entities/drive-file'; -import { Users, DriveFolders } from '../index'; -import { User } from '@/models/entities/user'; -import { toPuny } from '@/misc/convert-host'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; -import config from '@/config/index'; -import { query, appendQuery } from '@/prelude/url'; -import { Meta } from '@/models/entities/meta'; -import { fetchMeta } from '@/misc/fetch-meta'; - -type PackOptions = { - detail?: boolean, - self?: boolean, - withUser?: boolean, -}; - -@EntityRepository(DriveFile) -export class DriveFileRepository extends Repository<DriveFile> { - public validateFileName(name: string): boolean { - return ( - (name.trim().length > 0) && - (name.length <= 200) && - (name.indexOf('\\') === -1) && - (name.indexOf('/') === -1) && - (name.indexOf('..') === -1) - ); - } - - public getPublicUrl(file: DriveFile, thumbnail = false, meta?: Meta): string | null { - // リモートかつメディアプロキシ - if (file.uri != null && file.userHost != null && config.mediaProxy != null) { - return appendQuery(config.mediaProxy, query({ - url: file.uri, - thumbnail: thumbnail ? '1' : undefined - })); - } - - // リモートかつ期限切れはローカルプロキシを試みる - if (file.uri != null && file.isLink && meta && meta.proxyRemoteFiles) { - const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey; - - if (key && !key.match('/')) { // 古いものはここにオブジェクトストレージキーが入ってるので除外 - return `${config.url}/files/${key}`; - } - } - - const isImage = file.type && ['image/png', 'image/apng', 'image/gif', 'image/jpeg', 'image/webp', 'image/svg+xml'].includes(file.type); - - return thumbnail ? (file.thumbnailUrl || (isImage ? (file.webpublicUrl || file.url) : null)) : (file.webpublicUrl || file.url); - } - - public async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise<number> { - const id = typeof user === 'object' ? user.id : user; - - const { sum } = await this - .createQueryBuilder('file') - .where('file.userId = :id', { id: id }) - .andWhere('file.isLink = FALSE') - .select('SUM(file.size)', 'sum') - .getRawOne(); - - return parseInt(sum, 10) || 0; - } - - public async calcDriveUsageOfHost(host: string): Promise<number> { - const { sum } = await this - .createQueryBuilder('file') - .where('file.userHost = :host', { host: toPuny(host) }) - .andWhere('file.isLink = FALSE') - .select('SUM(file.size)', 'sum') - .getRawOne(); - - return parseInt(sum, 10) || 0; - } - - public async calcDriveUsageOfLocal(): Promise<number> { - const { sum } = await this - .createQueryBuilder('file') - .where('file.userHost IS NULL') - .andWhere('file.isLink = FALSE') - .select('SUM(file.size)', 'sum') - .getRawOne(); - - return parseInt(sum, 10) || 0; - } - - public async calcDriveUsageOfRemote(): Promise<number> { - const { sum } = await this - .createQueryBuilder('file') - .where('file.userHost IS NOT NULL') - .andWhere('file.isLink = FALSE') - .select('SUM(file.size)', 'sum') - .getRawOne(); - - return parseInt(sum, 10) || 0; - } - - public async pack(src: DriveFile['id'], options?: PackOptions): Promise<Packed<'DriveFile'> | null>; - public async pack(src: DriveFile, options?: PackOptions): Promise<Packed<'DriveFile'>>; - public async pack( - src: DriveFile['id'] | DriveFile, - options?: PackOptions - ): Promise<Packed<'DriveFile'> | null> { - const opts = Object.assign({ - detail: false, - self: false - }, options); - - const file = typeof src === 'object' ? src : await this.findOne(src); - if (file == null) return null; - - const meta = await fetchMeta(); - - return await awaitAll({ - id: file.id, - createdAt: file.createdAt.toISOString(), - name: file.name, - type: file.type, - md5: file.md5, - size: file.size, - isSensitive: file.isSensitive, - blurhash: file.blurhash, - properties: file.properties, - url: opts.self ? file.url : this.getPublicUrl(file, false, meta), - thumbnailUrl: this.getPublicUrl(file, true, meta), - comment: file.comment, - folderId: file.folderId, - folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, { - detail: true - }) : null, - userId: opts.withUser ? file.userId : null, - user: (opts.withUser && file.userId) ? Users.pack(file.userId) : null - }); - } - - public async packMany( - files: (DriveFile['id'] | DriveFile)[], - options?: PackOptions - ) { - const items = await Promise.all(files.map(f => this.pack(f, options))); - return items.filter(x => x != null); - } -} - -export const packedDriveFileSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - example: 'lenna.jpg' - }, - type: { - type: 'string' as const, - optional: false as const, nullable: false as const, - example: 'image/jpeg' - }, - md5: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'md5', - example: '15eca7fba0480996e2245f5185bf39f2' - }, - size: { - type: 'number' as const, - optional: false as const, nullable: false as const, - example: 51469 - }, - isSensitive: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - blurhash: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - properties: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - width: { - type: 'number' as const, - optional: true as const, nullable: false as const, - example: 1280 - }, - height: { - type: 'number' as const, - optional: true as const, nullable: false as const, - example: 720 - }, - avgColor: { - type: 'string' as const, - optional: true as const, nullable: false as const, - example: 'rgb(40,65,87)' - } - } - }, - url: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'url', - }, - thumbnailUrl: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'url', - }, - comment: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - folderId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - folder: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'DriveFolder' as const, - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - user: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'User' as const, - } - }, -}; diff --git a/src/models/repositories/drive-folder.ts b/src/models/repositories/drive-folder.ts deleted file mode 100644 index 8ef6f01b5d..0000000000 --- a/src/models/repositories/drive-folder.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { DriveFolders, DriveFiles } from '../index'; -import { DriveFolder } from '@/models/entities/drive-folder'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(DriveFolder) -export class DriveFolderRepository extends Repository<DriveFolder> { - public validateFolderName(name: string): boolean { - return ( - (name.trim().length > 0) && - (name.length <= 200) - ); - } - - public async pack( - src: DriveFolder['id'] | DriveFolder, - options?: { - detail: boolean - } - ): Promise<Packed<'DriveFolder'>> { - const opts = Object.assign({ - detail: false - }, options); - - const folder = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: folder.id, - createdAt: folder.createdAt.toISOString(), - name: folder.name, - parentId: folder.parentId, - - ...(opts.detail ? { - foldersCount: DriveFolders.count({ - parentId: folder.id - }), - filesCount: DriveFiles.count({ - folderId: folder.id - }), - - ...(folder.parentId ? { - parent: this.pack(folder.parentId, { - detail: true - }) - } : {}) - } : {}) - }); - } -} - -export const packedDriveFolderSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - foldersCount: { - type: 'number' as const, - optional: true as const, nullable: false as const, - }, - filesCount: { - type: 'number' as const, - optional: true as const, nullable: false as const, - }, - parentId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - parent: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'DriveFolder' as const, - }, - }, -}; diff --git a/src/models/repositories/emoji.ts b/src/models/repositories/emoji.ts deleted file mode 100644 index 7985c27aba..0000000000 --- a/src/models/repositories/emoji.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Emoji } from '@/models/entities/emoji'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(Emoji) -export class EmojiRepository extends Repository<Emoji> { - public async pack( - src: Emoji['id'] | Emoji, - ): Promise<Packed<'Emoji'>> { - const emoji = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: emoji.id, - aliases: emoji.aliases, - name: emoji.name, - category: emoji.category, - host: emoji.host, - url: emoji.url, - }; - } - - public packMany( - emojis: any[], - ) { - return Promise.all(emojis.map(x => this.pack(x))); - } -} - -export const packedEmojiSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - aliases: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - category: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - host: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - url: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - } -}; diff --git a/src/models/repositories/federation-instance.ts b/src/models/repositories/federation-instance.ts deleted file mode 100644 index 4b70971ecf..0000000000 --- a/src/models/repositories/federation-instance.ts +++ /dev/null @@ -1,106 +0,0 @@ -import config from '@/config/index'; - -export const packedFederationInstanceSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - }, - caughtAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time' - }, - host: { - type: 'string' as const, - optional: false as const, nullable: false as const, - example: 'misskey.example.com' - }, - usersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - notesCount: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - followingCount: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - followersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - driveUsage: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - driveFiles: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - latestRequestSentAt: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'date-time' - }, - lastCommunicatedAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time' - }, - isNotResponding: { - type: 'boolean' as const, - optional: false as const, nullable: false as const - }, - isSuspended: { - type: 'boolean' as const, - optional: false as const, nullable: false as const - }, - softwareName: { - type: 'string' as const, - optional: false as const, nullable: true as const, - example: 'misskey' - }, - softwareVersion: { - type: 'string' as const, - optional: false as const, nullable: true as const, - example: config.version - }, - openRegistrations: { - type: 'boolean' as const, - optional: false as const, nullable: true as const, - example: true - }, - name: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - description: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - maintainerName: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - maintainerEmail: { - type: 'string' as const, - optional: false as const, nullable: true as const - }, - iconUrl: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'url' - }, - infoUpdatedAt: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'date-time' - } - } -}; diff --git a/src/models/repositories/follow-request.ts b/src/models/repositories/follow-request.ts deleted file mode 100644 index d6ee58e235..0000000000 --- a/src/models/repositories/follow-request.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { FollowRequest } from '@/models/entities/follow-request'; -import { Users } from '../index'; -import { User } from '@/models/entities/user'; - -@EntityRepository(FollowRequest) -export class FollowRequestRepository extends Repository<FollowRequest> { - public async pack( - src: FollowRequest['id'] | FollowRequest, - me?: { id: User['id'] } | null | undefined - ) { - const request = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: request.id, - follower: await Users.pack(request.followerId, me), - followee: await Users.pack(request.followeeId, me), - }; - } -} diff --git a/src/models/repositories/following.ts b/src/models/repositories/following.ts deleted file mode 100644 index b1f716069f..0000000000 --- a/src/models/repositories/following.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../index'; -import { Following } from '@/models/entities/following'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; -import { User } from '@/models/entities/user'; - -type LocalFollowerFollowing = Following & { - followerHost: null; - followerInbox: null; - followerSharedInbox: null; -}; - -type RemoteFollowerFollowing = Following & { - followerHost: string; - followerInbox: string; - followerSharedInbox: string; -}; - -type LocalFolloweeFollowing = Following & { - followeeHost: null; - followeeInbox: null; - followeeSharedInbox: null; -}; - -type RemoteFolloweeFollowing = Following & { - followeeHost: string; - followeeInbox: string; - followeeSharedInbox: string; -}; - -@EntityRepository(Following) -export class FollowingRepository extends Repository<Following> { - public isLocalFollower(following: Following): following is LocalFollowerFollowing { - return following.followerHost == null; - } - - public isRemoteFollower(following: Following): following is RemoteFollowerFollowing { - return following.followerHost != null; - } - - public isLocalFollowee(following: Following): following is LocalFolloweeFollowing { - return following.followeeHost == null; - } - - public isRemoteFollowee(following: Following): following is RemoteFolloweeFollowing { - return following.followeeHost != null; - } - - public async pack( - src: Following['id'] | Following, - me?: { id: User['id'] } | null | undefined, - opts?: { - populateFollowee?: boolean; - populateFollower?: boolean; - } - ): Promise<Packed<'Following'>> { - const following = typeof src === 'object' ? src : await this.findOneOrFail(src); - - if (opts == null) opts = {}; - - return await awaitAll({ - id: following.id, - createdAt: following.createdAt.toISOString(), - followeeId: following.followeeId, - followerId: following.followerId, - followee: opts.populateFollowee ? Users.pack(following.followee || following.followeeId, me, { - detail: true - }) : undefined, - follower: opts.populateFollower ? Users.pack(following.follower || following.followerId, me, { - detail: true - }) : undefined, - }); - } - - public packMany( - followings: any[], - me?: { id: User['id'] } | null | undefined, - opts?: { - populateFollowee?: boolean; - populateFollower?: boolean; - } - ) { - return Promise.all(followings.map(x => this.pack(x, me, opts))); - } -} - -export const packedFollowingSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - followeeId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - followee: { - type: 'object' as const, - optional: true as const, nullable: false as const, - ref: 'User' as const, - }, - followerId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - follower: { - type: 'object' as const, - optional: true as const, nullable: false as const, - ref: 'User' as const, - }, - } -}; diff --git a/src/models/repositories/gallery-like.ts b/src/models/repositories/gallery-like.ts deleted file mode 100644 index 79123e5eec..0000000000 --- a/src/models/repositories/gallery-like.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { GalleryLike } from '@/models/entities/gallery-like'; -import { GalleryPosts } from '../index'; - -@EntityRepository(GalleryLike) -export class GalleryLikeRepository extends Repository<GalleryLike> { - public async pack( - src: GalleryLike['id'] | GalleryLike, - me?: any - ) { - const like = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: like.id, - post: await GalleryPosts.pack(like.post || like.postId, me), - }; - } - - public packMany( - likes: any[], - me: any - ) { - return Promise.all(likes.map(x => this.pack(x, me))); - } -} diff --git a/src/models/repositories/gallery-post.ts b/src/models/repositories/gallery-post.ts deleted file mode 100644 index 4f666ff252..0000000000 --- a/src/models/repositories/gallery-post.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { GalleryPost } from '@/models/entities/gallery-post'; -import { Packed } from '@/misc/schema'; -import { Users, DriveFiles, GalleryLikes } from '../index'; -import { awaitAll } from '@/prelude/await-all'; -import { User } from '@/models/entities/user'; - -@EntityRepository(GalleryPost) -export class GalleryPostRepository extends Repository<GalleryPost> { - public async pack( - src: GalleryPost['id'] | GalleryPost, - me?: { id: User['id'] } | null | undefined, - ): Promise<Packed<'GalleryPost'>> { - const meId = me ? me.id : null; - const post = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: post.id, - createdAt: post.createdAt.toISOString(), - updatedAt: post.updatedAt.toISOString(), - userId: post.userId, - user: Users.pack(post.user || post.userId, me), - title: post.title, - description: post.description, - fileIds: post.fileIds, - files: DriveFiles.packMany(post.fileIds), - tags: post.tags.length > 0 ? post.tags : undefined, - isSensitive: post.isSensitive, - likedCount: post.likedCount, - isLiked: meId ? await GalleryLikes.findOne({ postId: post.id, userId: meId }).then(x => x != null) : undefined, - }); - } - - public packMany( - posts: GalleryPost[], - me?: { id: User['id'] } | null | undefined, - ) { - return Promise.all(posts.map(x => this.pack(x, me))); - } -} - -export const packedGalleryPostSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - updatedAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - title: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - description: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: false as const, nullable: false as const, - }, - fileIds: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - files: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'DriveFile' as const, - } - }, - tags: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - } - }, - isSensitive: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - } -}; diff --git a/src/models/repositories/games/reversi/game.ts b/src/models/repositories/games/reversi/game.ts deleted file mode 100644 index 9adb386fa9..0000000000 --- a/src/models/repositories/games/reversi/game.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { User } from '@/models/entities/user'; -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../../../index'; -import { ReversiGame } from '@/models/entities/games/reversi/game'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(ReversiGame) -export class ReversiGameRepository extends Repository<ReversiGame> { - public async pack( - src: ReversiGame['id'] | ReversiGame, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean - } - ): Promise<Packed<'ReversiGame'>> { - const opts = Object.assign({ - detail: true - }, options); - - const game = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: game.id, - createdAt: game.createdAt.toISOString(), - startedAt: game.startedAt && game.startedAt.toISOString(), - isStarted: game.isStarted, - isEnded: game.isEnded, - form1: game.form1, - form2: game.form2, - user1Accepted: game.user1Accepted, - user2Accepted: game.user2Accepted, - user1Id: game.user1Id, - user2Id: game.user2Id, - user1: await Users.pack(game.user1Id, me), - user2: await Users.pack(game.user2Id, me), - winnerId: game.winnerId, - winner: game.winnerId ? await Users.pack(game.winnerId, me) : null, - surrendered: game.surrendered, - black: game.black, - bw: game.bw, - isLlotheo: game.isLlotheo, - canPutEverywhere: game.canPutEverywhere, - loopedBoard: game.loopedBoard, - ...(opts.detail ? { - logs: game.logs.map(log => ({ - at: log.at.toISOString(), - color: log.color, - pos: log.pos - })), - map: game.map, - } : {}) - }; - } -} - -export const packedReversiGameSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - startedAt: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'date-time', - }, - isStarted: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - isEnded: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - form1: { - type: 'any' as const, - optional: false as const, nullable: true as const, - }, - form2: { - type: 'any' as const, - optional: false as const, nullable: true as const, - }, - user1Accepted: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - user2Accepted: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - user1Id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - user2Id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - user1: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - user2: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - winnerId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - winner: { - type: 'object' as const, - optional: false as const, nullable: true as const, - ref: 'User' as const, - }, - surrendered: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - black: { - type: 'number' as const, - optional: false as const, nullable: true as const, - }, - bw: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - isLlotheo: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - canPutEverywhere: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - loopedBoard: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - logs: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'object' as const, - optional: true as const, nullable: false as const, - properties: { - at: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - color: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - pos: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - } - } - }, - map: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - } - } - } -}; diff --git a/src/models/repositories/games/reversi/matching.ts b/src/models/repositories/games/reversi/matching.ts deleted file mode 100644 index b4515800df..0000000000 --- a/src/models/repositories/games/reversi/matching.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { ReversiMatching } from '@/models/entities/games/reversi/matching'; -import { Users } from '../../../index'; -import { awaitAll } from '@/prelude/await-all'; -import { User } from '@/models/entities/user'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(ReversiMatching) -export class ReversiMatchingRepository extends Repository<ReversiMatching> { - public async pack( - src: ReversiMatching['id'] | ReversiMatching, - me: { id: User['id'] } - ): Promise<Packed<'ReversiMatching'>> { - const matching = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: matching.id, - createdAt: matching.createdAt.toISOString(), - parentId: matching.parentId, - parent: Users.pack(matching.parentId, me, { - detail: true - }), - childId: matching.childId, - child: Users.pack(matching.childId, me, { - detail: true - }) - }); - } -} - -export const packedReversiMatchingSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - parentId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - parent: { - type: 'object' as const, - optional: false as const, nullable: true as const, - ref: 'User' as const, - }, - childId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - child: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - } -}; diff --git a/src/models/repositories/hashtag.ts b/src/models/repositories/hashtag.ts deleted file mode 100644 index d52f6ba7c6..0000000000 --- a/src/models/repositories/hashtag.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Hashtag } from '@/models/entities/hashtag'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(Hashtag) -export class HashtagRepository extends Repository<Hashtag> { - public async pack( - src: Hashtag, - ): Promise<Packed<'Hashtag'>> { - return { - tag: src.name, - mentionedUsersCount: src.mentionedUsersCount, - mentionedLocalUsersCount: src.mentionedLocalUsersCount, - mentionedRemoteUsersCount: src.mentionedRemoteUsersCount, - attachedUsersCount: src.attachedUsersCount, - attachedLocalUsersCount: src.attachedLocalUsersCount, - attachedRemoteUsersCount: src.attachedRemoteUsersCount, - }; - } - - public packMany( - hashtags: Hashtag[], - ) { - return Promise.all(hashtags.map(x => this.pack(x))); - } -} - -export const packedHashtagSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - tag: { - type: 'string' as const, - optional: false as const, nullable: false as const, - example: 'misskey', - }, - mentionedUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - mentionedLocalUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - mentionedRemoteUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - attachedUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - attachedLocalUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - attachedRemoteUsersCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - } -}; diff --git a/src/models/repositories/messaging-message.ts b/src/models/repositories/messaging-message.ts deleted file mode 100644 index abdff63689..0000000000 --- a/src/models/repositories/messaging-message.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { MessagingMessage } from '@/models/entities/messaging-message'; -import { Users, DriveFiles, UserGroups } from '../index'; -import { Packed } from '@/misc/schema'; -import { User } from '@/models/entities/user'; - -@EntityRepository(MessagingMessage) -export class MessagingMessageRepository extends Repository<MessagingMessage> { - public validateText(text: string): boolean { - return text.trim().length <= 1000 && text.trim() != ''; - } - - public async pack( - src: MessagingMessage['id'] | MessagingMessage, - me?: { id: User['id'] } | null | undefined, - options?: { - populateRecipient?: boolean, - populateGroup?: boolean, - } - ): Promise<Packed<'MessagingMessage'>> { - const opts = options || { - populateRecipient: true, - populateGroup: true, - }; - - const message = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: message.id, - createdAt: message.createdAt.toISOString(), - text: message.text, - userId: message.userId, - user: await Users.pack(message.user || message.userId, me), - recipientId: message.recipientId, - recipient: message.recipientId && opts.populateRecipient ? await Users.pack(message.recipient || message.recipientId, me) : undefined, - groupId: message.groupId, - group: message.groupId && opts.populateGroup ? await UserGroups.pack(message.group || message.groupId) : undefined, - fileId: message.fileId, - file: message.fileId ? await DriveFiles.pack(message.fileId) : null, - isRead: message.isRead, - reads: message.reads, - }; - } -} - -export const packedMessagingMessageSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: true as const, nullable: false as const, - }, - text: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - fileId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - }, - file: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'DriveFile' as const, - }, - recipientId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - }, - recipient: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'User' as const, - }, - groupId: { - type: 'string' as const, - optional: false as const, nullable: true as const, - format: 'id', - }, - group: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'UserGroup' as const, - }, - isRead: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - reads: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - }, -}; diff --git a/src/models/repositories/moderation-logs.ts b/src/models/repositories/moderation-logs.ts deleted file mode 100644 index c7df3afdc9..0000000000 --- a/src/models/repositories/moderation-logs.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../index'; -import { ModerationLog } from '@/models/entities/moderation-log'; -import { awaitAll } from '@/prelude/await-all'; - -@EntityRepository(ModerationLog) -export class ModerationLogRepository extends Repository<ModerationLog> { - public async pack( - src: ModerationLog['id'] | ModerationLog, - ) { - const log = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: log.id, - createdAt: log.createdAt, - type: log.type, - info: log.info, - userId: log.userId, - user: Users.pack(log.user || log.userId, null, { - detail: true - }), - }); - } - - public packMany( - reports: any[], - ) { - return Promise.all(reports.map(x => this.pack(x))); - } -} diff --git a/src/models/repositories/muting.ts b/src/models/repositories/muting.ts deleted file mode 100644 index 869afd3c4e..0000000000 --- a/src/models/repositories/muting.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Users } from '../index'; -import { Muting } from '@/models/entities/muting'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; -import { User } from '@/models/entities/user'; - -@EntityRepository(Muting) -export class MutingRepository extends Repository<Muting> { - public async pack( - src: Muting['id'] | Muting, - me?: { id: User['id'] } | null | undefined - ): Promise<Packed<'Muting'>> { - const muting = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return await awaitAll({ - id: muting.id, - createdAt: muting.createdAt.toISOString(), - muteeId: muting.muteeId, - mutee: Users.pack(muting.muteeId, me, { - detail: true - }) - }); - } - - public packMany( - mutings: any[], - me: { id: User['id'] } - ) { - return Promise.all(mutings.map(x => this.pack(x, me))); - } -} - -export const packedMutingSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - muteeId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - mutee: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - } -}; diff --git a/src/models/repositories/note-favorite.ts b/src/models/repositories/note-favorite.ts deleted file mode 100644 index 47586a9116..0000000000 --- a/src/models/repositories/note-favorite.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { NoteFavorite } from '@/models/entities/note-favorite'; -import { Notes } from '../index'; -import { User } from '@/models/entities/user'; - -@EntityRepository(NoteFavorite) -export class NoteFavoriteRepository extends Repository<NoteFavorite> { - public async pack( - src: NoteFavorite['id'] | NoteFavorite, - me?: { id: User['id'] } | null | undefined - ) { - const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: favorite.id, - createdAt: favorite.createdAt, - noteId: favorite.noteId, - note: await Notes.pack(favorite.note || favorite.noteId, me), - }; - } - - public packMany( - favorites: any[], - me: { id: User['id'] } - ) { - return Promise.all(favorites.map(x => this.pack(x, me))); - } -} - -export const packedNoteFavoriteSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - note: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Note' as const, - }, - noteId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - }, -}; diff --git a/src/models/repositories/note-reaction.ts b/src/models/repositories/note-reaction.ts deleted file mode 100644 index 5d86065526..0000000000 --- a/src/models/repositories/note-reaction.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { NoteReaction } from '@/models/entities/note-reaction'; -import { Notes, Users } from '../index'; -import { Packed } from '@/misc/schema'; -import { convertLegacyReaction } from '@/misc/reaction-lib'; -import { User } from '@/models/entities/user'; - -@EntityRepository(NoteReaction) -export class NoteReactionRepository extends Repository<NoteReaction> { - public async pack( - src: NoteReaction['id'] | NoteReaction, - me?: { id: User['id'] } | null | undefined, - options?: { - withNote: boolean; - }, - ): Promise<Packed<'NoteReaction'>> { - const opts = Object.assign({ - withNote: false, - }, options); - - const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: reaction.id, - createdAt: reaction.createdAt.toISOString(), - user: await Users.pack(reaction.userId, me), - type: convertLegacyReaction(reaction.reaction), - ...(opts.withNote ? { - note: await Notes.pack(reaction.noteId, me), - } : {}) - }; - } -} - -export const packedNoteReactionSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - user: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' as const, - }, - type: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - }, -}; diff --git a/src/models/repositories/note.ts b/src/models/repositories/note.ts deleted file mode 100644 index 0f00c34c9c..0000000000 --- a/src/models/repositories/note.ts +++ /dev/null @@ -1,512 +0,0 @@ -import { EntityRepository, Repository, In } from 'typeorm'; -import * as mfm from 'mfm-js'; -import { Note } from '@/models/entities/note'; -import { User } from '@/models/entities/user'; -import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index'; -import { Packed } from '@/misc/schema'; -import { nyaize } from '@/misc/nyaize'; -import { awaitAll } from '@/prelude/await-all'; -import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib'; -import { NoteReaction } from '@/models/entities/note-reaction'; -import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis'; - -@EntityRepository(Note) -export class NoteRepository extends Repository<Note> { - public validateCw(x: string) { - return x.trim().length <= 100; - } - - public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise<boolean> { - // visibility が specified かつ自分が指定されていなかったら非表示 - if (note.visibility === 'specified') { - if (meId == null) { - return false; - } else if (meId === note.userId) { - return true; - } else { - // 指定されているかどうか - const specified = note.visibleUserIds.some((id: any) => meId === id); - - if (specified) { - return true; - } else { - return false; - } - } - } - - // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 - if (note.visibility === 'followers') { - if (meId == null) { - return false; - } else if (meId === note.userId) { - return true; - } else if (note.reply && (meId === note.reply.userId)) { - // 自分の投稿に対するリプライ - return true; - } else if (note.mentions && note.mentions.some(id => meId === id)) { - // 自分へのメンション - return true; - } else { - // フォロワーかどうか - const following = await Followings.findOne({ - followeeId: note.userId, - followerId: meId - }); - - if (following == null) { - return false; - } else { - return true; - } - } - } - - return true; - } - - private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) { - // TODO: isVisibleForMe を使うようにしても良さそう(型違うけど) - let hide = false; - - // visibility が specified かつ自分が指定されていなかったら非表示 - if (packedNote.visibility === 'specified') { - if (meId == null) { - hide = true; - } else if (meId === packedNote.userId) { - hide = false; - } else { - // 指定されているかどうか - const specified = packedNote.visibleUserIds!.some((id: any) => meId === id); - - if (specified) { - hide = false; - } else { - hide = true; - } - } - } - - // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 - if (packedNote.visibility === 'followers') { - if (meId == null) { - hide = true; - } else if (meId === packedNote.userId) { - hide = false; - } else if (packedNote.reply && (meId === packedNote.reply.userId)) { - // 自分の投稿に対するリプライ - hide = false; - } else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { - // 自分へのメンション - hide = false; - } else { - // フォロワーかどうか - const following = await Followings.findOne({ - followeeId: packedNote.userId, - followerId: meId - }); - - if (following == null) { - hide = true; - } else { - hide = false; - } - } - } - - if (hide) { - packedNote.visibleUserIds = undefined; - packedNote.fileIds = []; - packedNote.files = []; - packedNote.text = null; - packedNote.poll = undefined; - packedNote.cw = null; - packedNote.isHidden = true; - } - } - - public async pack( - src: Note['id'] | Note, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean; - skipHide?: boolean; - _hint_?: { - myReactions: Map<Note['id'], NoteReaction | null>; - }; - } - ): Promise<Packed<'Note'>> { - const opts = Object.assign({ - detail: true, - skipHide: false - }, options); - - const meId = me ? me.id : null; - const note = typeof src === 'object' ? src : await this.findOneOrFail(src); - const host = note.userHost; - - async function populatePoll() { - const poll = await Polls.findOneOrFail(note.id); - const choices = poll.choices.map(c => ({ - text: c, - votes: poll.votes[poll.choices.indexOf(c)], - isVoted: false - })); - - if (poll.multiple) { - const votes = await PollVotes.find({ - userId: meId!, - noteId: note.id - }); - - const myChoices = votes.map(v => v.choice); - for (const myChoice of myChoices) { - choices[myChoice].isVoted = true; - } - } else { - const vote = await PollVotes.findOne({ - userId: meId!, - noteId: note.id - }); - - if (vote) { - choices[vote.choice].isVoted = true; - } - } - - return { - multiple: poll.multiple, - expiresAt: poll.expiresAt, - choices - }; - } - - async function populateMyReaction() { - if (options?._hint_?.myReactions) { - const reaction = options._hint_.myReactions.get(note.id); - if (reaction) { - return convertLegacyReaction(reaction.reaction); - } else if (reaction === null) { - return undefined; - } - // 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない - } - - const reaction = await NoteReactions.findOne({ - userId: meId!, - noteId: note.id, - }); - - if (reaction) { - return convertLegacyReaction(reaction.reaction); - } - - return undefined; - } - - let text = note.text; - - if (note.name && (note.url || note.uri)) { - text = `【${note.name}】\n${(note.text || '').trim()}\n\n${note.url || note.uri}`; - } - - const channel = note.channelId - ? note.channel - ? note.channel - : await Channels.findOne(note.channelId) - : null; - - const reactionEmojiNames = Object.keys(note.reactions).filter(x => x?.startsWith(':')).map(x => decodeReaction(x).reaction).map(x => x.replace(/:/g, '')); - - const packed = await awaitAll({ - id: note.id, - createdAt: note.createdAt.toISOString(), - userId: note.userId, - user: Users.pack(note.user || note.userId, me, { - detail: false, - }), - text: text, - cw: note.cw, - visibility: note.visibility, - localOnly: note.localOnly || undefined, - visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined, - viaMobile: note.viaMobile || undefined, - renoteCount: note.renoteCount, - repliesCount: note.repliesCount, - reactions: convertLegacyReactions(note.reactions), - tags: note.tags.length > 0 ? note.tags : undefined, - emojis: populateEmojis(note.emojis.concat(reactionEmojiNames), host), - fileIds: note.fileIds, - files: DriveFiles.packMany(note.fileIds), - replyId: note.replyId, - renoteId: note.renoteId, - channelId: note.channelId || undefined, - channel: channel ? { - id: channel.id, - name: channel.name, - } : undefined, - mentions: note.mentions.length > 0 ? note.mentions : undefined, - uri: note.uri || undefined, - url: note.url || undefined, - - ...(opts.detail ? { - reply: note.replyId ? this.pack(note.reply || note.replyId, me, { - detail: false, - _hint_: options?._hint_ - }) : undefined, - - renote: note.renoteId ? this.pack(note.renote || note.renoteId, me, { - detail: true, - _hint_: options?._hint_ - }) : undefined, - - poll: note.hasPoll ? populatePoll() : undefined, - - ...(meId ? { - myReaction: populateMyReaction() - } : {}) - } : {}) - }); - - if (packed.user.isCat && packed.text) { - const tokens = packed.text ? mfm.parse(packed.text) : []; - mfm.inspect(tokens, node => { - if (node.type === 'text') { - // TODO: quoteなtextはskip - node.props.text = nyaize(node.props.text); - } - }); - packed.text = mfm.toString(tokens); - } - - if (!opts.skipHide) { - await this.hideNote(packed, meId); - } - - return packed; - } - - public async packMany( - notes: Note[], - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean; - skipHide?: boolean; - } - ) { - if (notes.length === 0) return []; - - const meId = me ? me.id : null; - const myReactionsMap = new Map<Note['id'], NoteReaction | null>(); - if (meId) { - const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); - const targets = [...notes.map(n => n.id), ...renoteIds]; - const myReactions = await NoteReactions.find({ - userId: meId, - noteId: In(targets), - }); - - for (const target of targets) { - myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null); - } - } - - await prefetchEmojis(aggregateNoteEmojis(notes)); - - return await Promise.all(notes.map(n => this.pack(n, me, { - ...options, - _hint_: { - myReactions: myReactionsMap - } - }))); - } -} - -export const packedNoteSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - text: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - cw: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: false as const, nullable: false as const, - }, - replyId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - renoteId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - reply: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'Note' as const, - }, - renote: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'Note' as const, - }, - viaMobile: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - isHidden: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - visibility: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - mentions: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - visibleUserIds: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - fileIds: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - files: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'DriveFile' as const, - } - }, - tags: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - } - }, - poll: { - type: 'object' as const, - optional: true as const, nullable: true as const, - }, - channelId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - channel: { - type: 'object' as const, - optional: true as const, nullable: true as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - name: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - }, - }, - }, - localOnly: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - emojis: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - url: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - }, - }, - }, - reactions: { - type: 'object' as const, - optional: false as const, nullable: false as const, - }, - renoteCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - repliesCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - uri: { - type: 'string' as const, - optional: true as const, nullable: false as const, - }, - url: { - type: 'string' as const, - optional: true as const, nullable: false as const, - }, - - myReaction: { - type: 'object' as const, - optional: true as const, nullable: true as const, - }, - }, -}; diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts deleted file mode 100644 index d1cf9b087e..0000000000 --- a/src/models/repositories/notification.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { EntityRepository, In, Repository } from 'typeorm'; -import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '../index'; -import { Notification } from '@/models/entities/notification'; -import { awaitAll } from '@/prelude/await-all'; -import { Packed } from '@/misc/schema'; -import { Note } from '@/models/entities/note'; -import { NoteReaction } from '@/models/entities/note-reaction'; -import { User } from '@/models/entities/user'; -import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis'; -import { notificationTypes } from '@/types'; - -@EntityRepository(Notification) -export class NotificationRepository extends Repository<Notification> { - public async pack( - src: Notification['id'] | Notification, - options: { - _hintForEachNotes_?: { - myReactions: Map<Note['id'], NoteReaction | null>; - }; - } - ): Promise<Packed<'Notification'>> { - const notification = typeof src === 'object' ? src : await this.findOneOrFail(src); - const token = notification.appAccessTokenId ? await AccessTokens.findOneOrFail(notification.appAccessTokenId) : null; - - return await awaitAll({ - id: notification.id, - createdAt: notification.createdAt.toISOString(), - type: notification.type, - isRead: notification.isRead, - userId: notification.notifierId, - user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null, - ...(notification.type === 'mention' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - } : {}), - ...(notification.type === 'reply' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - } : {}), - ...(notification.type === 'renote' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - } : {}), - ...(notification.type === 'quote' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - } : {}), - ...(notification.type === 'reaction' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - reaction: notification.reaction - } : {}), - ...(notification.type === 'pollVote' ? { - note: Notes.pack(notification.note || notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_ - }), - choice: notification.choice - } : {}), - ...(notification.type === 'groupInvited' ? { - invitation: UserGroupInvitations.pack(notification.userGroupInvitationId!), - } : {}), - ...(notification.type === 'app' ? { - body: notification.customBody, - header: notification.customHeader || token?.name, - icon: notification.customIcon || token?.iconUrl, - } : {}), - }); - } - - public async packMany( - notifications: Notification[], - meId: User['id'] - ) { - if (notifications.length === 0) return []; - - const notes = notifications.filter(x => x.note != null).map(x => x.note!); - const noteIds = notes.map(n => n.id); - const myReactionsMap = new Map<Note['id'], NoteReaction | null>(); - const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); - const targets = [...noteIds, ...renoteIds]; - const myReactions = await NoteReactions.find({ - userId: meId, - noteId: In(targets), - }); - - for (const target of targets) { - myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null); - } - - await prefetchEmojis(aggregateNoteEmojis(notes)); - - return await Promise.all(notifications.map(x => this.pack(x, { - _hintForEachNotes_: { - myReactions: myReactionsMap - } - }))); - } -} - -export const packedNotificationSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - isRead: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - }, - type: { - type: 'string' as const, - optional: false as const, nullable: false as const, - enum: [...notificationTypes], - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: true as const, nullable: true as const, - }, - userId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - }, - note: { - type: 'object' as const, - ref: 'Note' as const, - optional: true as const, nullable: true as const, - }, - reaction: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - choice: { - type: 'number' as const, - optional: true as const, nullable: true as const, - }, - invitation: { - type: 'object' as const, - optional: true as const, nullable: true as const, - }, - body: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - header: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - icon: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - } -}; diff --git a/src/models/repositories/page-like.ts b/src/models/repositories/page-like.ts deleted file mode 100644 index 28f34254d9..0000000000 --- a/src/models/repositories/page-like.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { PageLike } from '@/models/entities/page-like'; -import { Pages } from '../index'; -import { User } from '@/models/entities/user'; - -@EntityRepository(PageLike) -export class PageLikeRepository extends Repository<PageLike> { - public async pack( - src: PageLike['id'] | PageLike, - me?: { id: User['id'] } | null | undefined - ) { - const like = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: like.id, - page: await Pages.pack(like.page || like.pageId, me), - }; - } - - public packMany( - likes: any[], - me: { id: User['id'] } - ) { - return Promise.all(likes.map(x => this.pack(x, me))); - } -} diff --git a/src/models/repositories/page.ts b/src/models/repositories/page.ts deleted file mode 100644 index 3a3642d7ec..0000000000 --- a/src/models/repositories/page.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Page } from '@/models/entities/page'; -import { Packed } from '@/misc/schema'; -import { Users, DriveFiles, PageLikes } from '../index'; -import { awaitAll } from '@/prelude/await-all'; -import { DriveFile } from '@/models/entities/drive-file'; -import { User } from '@/models/entities/user'; - -@EntityRepository(Page) -export class PageRepository extends Repository<Page> { - public async pack( - src: Page['id'] | Page, - me?: { id: User['id'] } | null | undefined, - ): Promise<Packed<'Page'>> { - const meId = me ? me.id : null; - const page = typeof src === 'object' ? src : await this.findOneOrFail(src); - - const attachedFiles: Promise<DriveFile | undefined>[] = []; - const collectFile = (xs: any[]) => { - for (const x of xs) { - if (x.type === 'image') { - attachedFiles.push(DriveFiles.findOne({ - id: x.fileId, - userId: page.userId - })); - } - if (x.children) { - collectFile(x.children); - } - } - }; - collectFile(page.content); - - // 後方互換性のため - let migrated = false; - const migrate = (xs: any[]) => { - for (const x of xs) { - if (x.type === 'input') { - if (x.inputType === 'text') { - x.type = 'textInput'; - } - if (x.inputType === 'number') { - x.type = 'numberInput'; - if (x.default) x.default = parseInt(x.default, 10); - } - migrated = true; - } - if (x.children) { - migrate(x.children); - } - } - }; - migrate(page.content); - if (migrated) { - this.update(page.id, { - content: page.content - }); - } - - return await awaitAll({ - id: page.id, - createdAt: page.createdAt.toISOString(), - updatedAt: page.updatedAt.toISOString(), - userId: page.userId, - user: Users.pack(page.user || page.userId, me), // { detail: true } すると無限ループするので注意 - content: page.content, - variables: page.variables, - title: page.title, - name: page.name, - summary: page.summary, - hideTitleWhenPinned: page.hideTitleWhenPinned, - alignCenter: page.alignCenter, - font: page.font, - script: page.script, - eyeCatchingImageId: page.eyeCatchingImageId, - eyeCatchingImage: page.eyeCatchingImageId ? await DriveFiles.pack(page.eyeCatchingImageId) : null, - attachedFiles: DriveFiles.packMany(await Promise.all(attachedFiles)), - likedCount: page.likedCount, - isLiked: meId ? await PageLikes.findOne({ pageId: page.id, userId: meId }).then(x => x != null) : undefined, - }); - } - - public packMany( - pages: Page[], - me?: { id: User['id'] } | null | undefined, - ) { - return Promise.all(pages.map(x => this.pack(x, me))); - } -} - -export const packedPageSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - updatedAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - title: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - summary: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - content: { - type: 'array' as const, - optional: false as const, nullable: false as const, - }, - variables: { - type: 'array' as const, - optional: false as const, nullable: false as const, - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: false as const, nullable: false as const, - }, - } -}; diff --git a/src/models/repositories/queue.ts b/src/models/repositories/queue.ts deleted file mode 100644 index 161751ddc8..0000000000 --- a/src/models/repositories/queue.ts +++ /dev/null @@ -1,30 +0,0 @@ -export const packedQueueCountSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - waiting: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - active: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - completed: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - failed: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - delayed: { - type: 'number' as const, - optional: false as const, nullable: false as const - }, - paused: { - type: 'number' as const, - optional: false as const, nullable: false as const - } - } -}; diff --git a/src/models/repositories/relay.ts b/src/models/repositories/relay.ts deleted file mode 100644 index 72ead899f1..0000000000 --- a/src/models/repositories/relay.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Relay } from '@/models/entities/relay'; - -@EntityRepository(Relay) -export class RelayRepository extends Repository<Relay> { -} diff --git a/src/models/repositories/signin.ts b/src/models/repositories/signin.ts deleted file mode 100644 index f375f9b5c0..0000000000 --- a/src/models/repositories/signin.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { Signin } from '@/models/entities/signin'; - -@EntityRepository(Signin) -export class SigninRepository extends Repository<Signin> { - public async pack( - src: Signin, - ) { - return src; - } -} diff --git a/src/models/repositories/user-group-invitation.ts b/src/models/repositories/user-group-invitation.ts deleted file mode 100644 index 638603d6ea..0000000000 --- a/src/models/repositories/user-group-invitation.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { UserGroupInvitation } from '@/models/entities/user-group-invitation'; -import { UserGroups } from '../index'; - -@EntityRepository(UserGroupInvitation) -export class UserGroupInvitationRepository extends Repository<UserGroupInvitation> { - public async pack( - src: UserGroupInvitation['id'] | UserGroupInvitation, - ) { - const invitation = typeof src === 'object' ? src : await this.findOneOrFail(src); - - return { - id: invitation.id, - group: await UserGroups.pack(invitation.userGroup || invitation.userGroupId), - }; - } - - public packMany( - invitations: any[], - ) { - return Promise.all(invitations.map(x => this.pack(x))); - } -} diff --git a/src/models/repositories/user-group.ts b/src/models/repositories/user-group.ts deleted file mode 100644 index b38a2fb50d..0000000000 --- a/src/models/repositories/user-group.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { UserGroup } from '@/models/entities/user-group'; -import { UserGroupJoinings } from '../index'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(UserGroup) -export class UserGroupRepository extends Repository<UserGroup> { - public async pack( - src: UserGroup['id'] | UserGroup, - ): Promise<Packed<'UserGroup'>> { - const userGroup = typeof src === 'object' ? src : await this.findOneOrFail(src); - - const users = await UserGroupJoinings.find({ - userGroupId: userGroup.id - }); - - return { - id: userGroup.id, - createdAt: userGroup.createdAt.toISOString(), - name: userGroup.name, - ownerId: userGroup.userId, - userIds: users.map(x => x.userId) - }; - } -} - -export const packedUserGroupSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - ownerId: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - }, - userIds: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - } - }, - }, -}; diff --git a/src/models/repositories/user-list.ts b/src/models/repositories/user-list.ts deleted file mode 100644 index 331c278e6f..0000000000 --- a/src/models/repositories/user-list.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { EntityRepository, Repository } from 'typeorm'; -import { UserList } from '@/models/entities/user-list'; -import { UserListJoinings } from '../index'; -import { Packed } from '@/misc/schema'; - -@EntityRepository(UserList) -export class UserListRepository extends Repository<UserList> { - public async pack( - src: UserList['id'] | UserList, - ): Promise<Packed<'UserList'>> { - const userList = typeof src === 'object' ? src : await this.findOneOrFail(src); - - const users = await UserListJoinings.find({ - userListId: userList.id - }); - - return { - id: userList.id, - createdAt: userList.createdAt.toISOString(), - name: userList.name, - userIds: users.map(x => x.userId) - }; - } -} - -export const packedUserListSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - userIds: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - } - }, - }, -}; diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts deleted file mode 100644 index fc0860970c..0000000000 --- a/src/models/repositories/user.ts +++ /dev/null @@ -1,659 +0,0 @@ -import $ from 'cafy'; -import { EntityRepository, Repository, In, Not } from 'typeorm'; -import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; -import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index'; -import config from '@/config/index'; -import { Packed } from '@/misc/schema'; -import { awaitAll } from '@/prelude/await-all'; -import { populateEmojis } from '@/misc/populate-emojis'; -import { getAntennas } from '@/misc/antenna-cache'; -import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const'; - -@EntityRepository(User) -export class UserRepository extends Repository<User> { - public async getRelation(me: User['id'], target: User['id']) { - const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([ - Followings.findOne({ - followerId: me, - followeeId: target - }), - Followings.findOne({ - followerId: target, - followeeId: me - }), - FollowRequests.findOne({ - followerId: me, - followeeId: target - }), - FollowRequests.findOne({ - followerId: target, - followeeId: me - }), - Blockings.findOne({ - blockerId: me, - blockeeId: target - }), - Blockings.findOne({ - blockerId: target, - blockeeId: me - }), - Mutings.findOne({ - muterId: me, - muteeId: target - }) - ]); - - return { - id: target, - isFollowing: following1 != null, - hasPendingFollowRequestFromYou: followReq1 != null, - hasPendingFollowRequestToYou: followReq2 != null, - isFollowed: following2 != null, - isBlocking: toBlocking != null, - isBlocked: fromBlocked != null, - isMuted: mute != null - }; - } - - public async getHasUnreadMessagingMessage(userId: User['id']): Promise<boolean> { - const mute = await Mutings.find({ - muterId: userId - }); - - const joinings = await UserGroupJoinings.find({ userId: userId }); - - const groupQs = Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder('message') - .where(`message.groupId = :groupId`, { groupId: j.userGroupId }) - .andWhere('message.userId != :userId', { userId: userId }) - .andWhere('NOT (:userId = ANY(message.reads))', { userId: userId }) - .andWhere('message.createdAt > :joinedAt', { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない - .getOne().then(x => x != null))); - - const [withUser, withGroups] = await Promise.all([ - MessagingMessages.count({ - where: { - recipientId: userId, - isRead: false, - ...(mute.length > 0 ? { userId: Not(In(mute.map(x => x.muteeId))) } : {}), - }, - take: 1 - }).then(count => count > 0), - groupQs - ]); - - return withUser || withGroups.some(x => x); - } - - public async getHasUnreadAnnouncement(userId: User['id']): Promise<boolean> { - const reads = await AnnouncementReads.find({ - userId: userId - }); - - const count = await Announcements.count(reads.length > 0 ? { - id: Not(In(reads.map(read => read.announcementId))) - } : {}); - - return count > 0; - } - - public async getHasUnreadAntenna(userId: User['id']): Promise<boolean> { - const myAntennas = (await getAntennas()).filter(a => a.userId === userId); - - const unread = myAntennas.length > 0 ? await AntennaNotes.findOne({ - antennaId: In(myAntennas.map(x => x.id)), - read: false - }) : null; - - return unread != null; - } - - public async getHasUnreadChannel(userId: User['id']): Promise<boolean> { - const channels = await ChannelFollowings.find({ followerId: userId }); - - const unread = channels.length > 0 ? await NoteUnreads.findOne({ - userId: userId, - noteChannelId: In(channels.map(x => x.followeeId)), - }) : null; - - return unread != null; - } - - public async getHasUnreadNotification(userId: User['id']): Promise<boolean> { - const mute = await Mutings.find({ - muterId: userId - }); - const mutedUserIds = mute.map(m => m.muteeId); - - const count = await Notifications.count({ - where: { - notifieeId: userId, - ...(mutedUserIds.length > 0 ? { notifierId: Not(In(mutedUserIds)) } : {}), - isRead: false - }, - take: 1 - }); - - return count > 0; - } - - public async getHasPendingReceivedFollowRequest(userId: User['id']): Promise<boolean> { - const count = await FollowRequests.count({ - followeeId: userId - }); - - return count > 0; - } - - public getOnlineStatus(user: User): string { - if (user.hideOnlineStatus) return 'unknown'; - if (user.lastActiveDate == null) return 'unknown'; - const elapsed = Date.now() - user.lastActiveDate.getTime(); - return ( - elapsed < USER_ONLINE_THRESHOLD ? 'online' : - elapsed < USER_ACTIVE_THRESHOLD ? 'active' : - 'offline' - ); - } - - public getAvatarUrl(user: User): string { - if (user.avatarUrl) { - return user.avatarUrl; - } else { - return `${config.url}/random-avatar/${user.id}`; - } - } - - public async pack( - src: User['id'] | User, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean, - includeSecrets?: boolean, - } - ): Promise<Packed<'User'>> { - const opts = Object.assign({ - detail: false, - includeSecrets: false - }, options); - - const user = typeof src === 'object' ? src : await this.findOneOrFail(src); - const meId = me ? me.id : null; - - const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; - const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin') - .where('pin.userId = :userId', { userId: user.id }) - .innerJoinAndSelect('pin.note', 'note') - .orderBy('pin.id', 'DESC') - .getMany() : []; - const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null; - - const followingCount = profile == null ? null : - (profile.ffVisibility === 'public') || (meId === user.id) ? user.followingCount : - (profile.ffVisibility === 'followers') && (relation!.isFollowing) ? user.followingCount : - null; - - const followersCount = profile == null ? null : - (profile.ffVisibility === 'public') || (meId === user.id) ? user.followersCount : - (profile.ffVisibility === 'followers') && (relation!.isFollowing) ? user.followersCount : - null; - - const falsy = opts.detail ? false : undefined; - - const packed = { - id: user.id, - name: user.name, - username: user.username, - host: user.host, - avatarUrl: this.getAvatarUrl(user), - avatarBlurhash: user.avatarBlurhash, - avatarColor: null, // 後方互換性のため - isAdmin: user.isAdmin || falsy, - isModerator: user.isModerator || falsy, - isBot: user.isBot || falsy, - isCat: user.isCat || falsy, - instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { - name: instance.name, - softwareName: instance.softwareName, - softwareVersion: instance.softwareVersion, - iconUrl: instance.iconUrl, - faviconUrl: instance.faviconUrl, - themeColor: instance.themeColor, - } : undefined) : undefined, - emojis: populateEmojis(user.emojis, user.host), - onlineStatus: this.getOnlineStatus(user), - - ...(opts.detail ? { - url: profile!.url, - uri: user.uri, - createdAt: user.createdAt.toISOString(), - updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, - lastFetchedAt: user.lastFetchedAt?.toISOString(), - bannerUrl: user.bannerUrl, - bannerBlurhash: user.bannerBlurhash, - bannerColor: null, // 後方互換性のため - isLocked: user.isLocked, - isModerator: user.isModerator || falsy, - isSilenced: user.isSilenced || falsy, - isSuspended: user.isSuspended || falsy, - description: profile!.description, - location: profile!.location, - birthday: profile!.birthday, - lang: profile!.lang, - fields: profile!.fields, - followersCount: followersCount || 0, - followingCount: followingCount || 0, - notesCount: user.notesCount, - pinnedNoteIds: pins.map(pin => pin.noteId), - pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), me, { - detail: true - }), - pinnedPageId: profile!.pinnedPageId, - pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null, - publicReactions: profile!.publicReactions, - ffVisibility: profile!.ffVisibility, - twoFactorEnabled: profile!.twoFactorEnabled, - usePasswordLessLogin: profile!.usePasswordLessLogin, - securityKeys: profile!.twoFactorEnabled - ? UserSecurityKeys.count({ - userId: user.id - }).then(result => result >= 1) - : false, - } : {}), - - ...(opts.detail && meId === user.id ? { - avatarId: user.avatarId, - bannerId: user.bannerId, - injectFeaturedNote: profile!.injectFeaturedNote, - receiveAnnouncementEmail: profile!.receiveAnnouncementEmail, - alwaysMarkNsfw: profile!.alwaysMarkNsfw, - carefulBot: profile!.carefulBot, - autoAcceptFollowed: profile!.autoAcceptFollowed, - noCrawle: profile!.noCrawle, - isExplorable: user.isExplorable, - isDeleted: user.isDeleted, - hideOnlineStatus: user.hideOnlineStatus, - hasUnreadSpecifiedNotes: NoteUnreads.count({ - where: { userId: user.id, isSpecified: true }, - take: 1 - }).then(count => count > 0), - hasUnreadMentions: NoteUnreads.count({ - where: { userId: user.id, isMentioned: true }, - take: 1 - }).then(count => count > 0), - hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id), - hasUnreadAntenna: this.getHasUnreadAntenna(user.id), - hasUnreadChannel: this.getHasUnreadChannel(user.id), - hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(user.id), - hasUnreadNotification: this.getHasUnreadNotification(user.id), - hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), - integrations: profile!.integrations, - mutedWords: profile!.mutedWords, - mutingNotificationTypes: profile!.mutingNotificationTypes, - emailNotificationTypes: profile!.emailNotificationTypes, - } : {}), - - ...(opts.includeSecrets ? { - email: profile!.email, - emailVerified: profile!.emailVerified, - securityKeysList: profile!.twoFactorEnabled - ? UserSecurityKeys.find({ - where: { - userId: user.id - }, - select: ['id', 'name', 'lastUsed'] - }) - : [] - } : {}), - - ...(relation ? { - isFollowing: relation.isFollowing, - isFollowed: relation.isFollowed, - hasPendingFollowRequestFromYou: relation.hasPendingFollowRequestFromYou, - hasPendingFollowRequestToYou: relation.hasPendingFollowRequestToYou, - isBlocking: relation.isBlocking, - isBlocked: relation.isBlocked, - isMuted: relation.isMuted, - } : {}) - }; - - return await awaitAll(packed); - } - - public packMany( - users: (User['id'] | User)[], - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean, - includeSecrets?: boolean, - } - ) { - return Promise.all(users.map(u => this.pack(u, me, options))); - } - - public isLocalUser(user: User): user is ILocalUser; - public isLocalUser<T extends { host: User['host'] }>(user: T): user is T & { host: null; }; - public isLocalUser(user: User | { host: User['host'] }): boolean { - return user.host == null; - } - - public isRemoteUser(user: User): user is IRemoteUser; - public isRemoteUser<T extends { host: User['host'] }>(user: T): user is T & { host: string; }; - public isRemoteUser(user: User | { host: User['host'] }): boolean { - return !this.isLocalUser(user); - } - - //#region Validators - public validateLocalUsername = $.str.match(/^\w{1,20}$/); - public validatePassword = $.str.min(1); - public validateName = $.str.min(1).max(50); - public validateDescription = $.str.min(1).max(500); - public validateLocation = $.str.min(1).max(50); - public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/); - //#endregion -} - -export const packedUserSchema = { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - id: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - name: { - type: 'string' as const, - nullable: true as const, optional: false as const, - example: '藍' - }, - username: { - type: 'string' as const, - nullable: false as const, optional: false as const, - example: 'ai' - }, - host: { - type: 'string' as const, - nullable: true as const, optional: false as const, - example: 'misskey.example.com' - }, - avatarUrl: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: false as const, - }, - avatarBlurhash: { - type: 'any' as const, - nullable: true as const, optional: false as const, - }, - avatarColor: { - type: 'any' as const, - nullable: true as const, optional: false as const, - default: null - }, - isAdmin: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - isModerator: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - isBot: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - isCat: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - emojis: { - type: 'array' as const, - nullable: false as const, optional: false as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - name: { - type: 'string' as const, - nullable: false as const, optional: false as const - }, - url: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'url' - }, - } - } - }, - url: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: true as const, - }, - createdAt: { - type: 'string' as const, - nullable: false as const, optional: true as const, - format: 'date-time', - }, - updatedAt: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'date-time', - }, - bannerUrl: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: true as const, - }, - bannerBlurhash: { - type: 'any' as const, - nullable: true as const, optional: true as const, - }, - bannerColor: { - type: 'any' as const, - nullable: true as const, optional: true as const, - default: null - }, - isLocked: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - isSuspended: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - example: false - }, - description: { - type: 'string' as const, - nullable: true as const, optional: true as const, - example: 'Hi masters, I am Ai!' - }, - location: { - type: 'string' as const, - nullable: true as const, optional: true as const, - }, - birthday: { - type: 'string' as const, - nullable: true as const, optional: true as const, - example: '2018-03-12' - }, - fields: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - name: { - type: 'string' as const, - nullable: false as const, optional: false as const - }, - value: { - type: 'string' as const, - nullable: false as const, optional: false as const - } - }, - maxLength: 4 - } - }, - followersCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - followingCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - notesCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - pinnedNoteIds: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - } - }, - pinnedNotes: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - ref: 'Note' as const, - } - }, - pinnedPageId: { - type: 'string' as const, - nullable: true as const, optional: true as const - }, - pinnedPage: { - type: 'object' as const, - nullable: true as const, optional: true as const, - ref: 'Page' as const, - }, - twoFactorEnabled: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - usePasswordLessLogin: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - securityKeys: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - avatarId: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'id' - }, - bannerId: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'id' - }, - autoWatch: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - injectFeaturedNote: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - alwaysMarkNsfw: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - carefulBot: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - autoAcceptFollowed: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - hasUnreadSpecifiedNotes: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadMentions: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadAnnouncement: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadAntenna: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadChannel: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadMessagingMessage: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadNotification: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasPendingReceivedFollowRequest: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - integrations: { - type: 'object' as const, - nullable: false as const, optional: true as const - }, - mutedWords: { - type: 'array' as const, - nullable: false as const, optional: true as const - }, - mutingNotificationTypes: { - type: 'array' as const, - nullable: false as const, optional: true as const - }, - isFollowing: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - hasPendingFollowRequestFromYou: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - hasPendingFollowRequestToYou: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isFollowed: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isBlocking: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isBlocked: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isMuted: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - } - }, -}; |