refactor: migrate to typeorm 3.0 (#8443)
* wip * wip * wip * Update following.ts * wip * wip * wip * Update resolve-user.ts * maxQueryExecutionTime * wip * wip
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
import { getRepository, getCustomRepository } from 'typeorm';
|
||||
import { } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
|
||||
import { Announcement } from './entities/announcement.js';
|
||||
import { AnnouncementRead } from './entities/announcement-read.js';
|
||||
import { Instance } from './entities/instance.js';
|
||||
@ -63,65 +65,65 @@ import { PasswordResetRequest } from './entities/password-reset-request.js';
|
||||
import { UserPending } from './entities/user-pending.js';
|
||||
import { InstanceRepository } from './repositories/instance.js';
|
||||
|
||||
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 = getCustomRepository(InstanceRepository);
|
||||
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 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);
|
||||
export const Announcements = db.getRepository(Announcement);
|
||||
export const AnnouncementReads = db.getRepository(AnnouncementRead);
|
||||
export const Apps = (AppRepository);
|
||||
export const Notes = (NoteRepository);
|
||||
export const NoteFavorites = (NoteFavoriteRepository);
|
||||
export const NoteWatchings = db.getRepository(NoteWatching);
|
||||
export const NoteThreadMutings = db.getRepository(NoteThreadMuting);
|
||||
export const NoteReactions = (NoteReactionRepository);
|
||||
export const NoteUnreads = db.getRepository(NoteUnread);
|
||||
export const Polls = db.getRepository(Poll);
|
||||
export const PollVotes = db.getRepository(PollVote);
|
||||
export const Users = (UserRepository);
|
||||
export const UserProfiles = db.getRepository(UserProfile);
|
||||
export const UserKeypairs = db.getRepository(UserKeypair);
|
||||
export const UserPendings = db.getRepository(UserPending);
|
||||
export const AttestationChallenges = db.getRepository(AttestationChallenge);
|
||||
export const UserSecurityKeys = db.getRepository(UserSecurityKey);
|
||||
export const UserPublickeys = db.getRepository(UserPublickey);
|
||||
export const UserLists = (UserListRepository);
|
||||
export const UserListJoinings = db.getRepository(UserListJoining);
|
||||
export const UserGroups = (UserGroupRepository);
|
||||
export const UserGroupJoinings = db.getRepository(UserGroupJoining);
|
||||
export const UserGroupInvitations = (UserGroupInvitationRepository);
|
||||
export const UserNotePinings = db.getRepository(UserNotePining);
|
||||
export const UsedUsernames = db.getRepository(UsedUsername);
|
||||
export const Followings = (FollowingRepository);
|
||||
export const FollowRequests = (FollowRequestRepository);
|
||||
export const Instances = (InstanceRepository);
|
||||
export const Emojis = (EmojiRepository);
|
||||
export const DriveFiles = (DriveFileRepository);
|
||||
export const DriveFolders = (DriveFolderRepository);
|
||||
export const Notifications = (NotificationRepository);
|
||||
export const Metas = db.getRepository(Meta);
|
||||
export const Mutings = (MutingRepository);
|
||||
export const Blockings = (BlockingRepository);
|
||||
export const SwSubscriptions = db.getRepository(SwSubscription);
|
||||
export const Hashtags = (HashtagRepository);
|
||||
export const AbuseUserReports = (AbuseUserReportRepository);
|
||||
export const RegistrationTickets = db.getRepository(RegistrationTicket);
|
||||
export const AuthSessions = (AuthSessionRepository);
|
||||
export const AccessTokens = db.getRepository(AccessToken);
|
||||
export const Signins = (SigninRepository);
|
||||
export const MessagingMessages = (MessagingMessageRepository);
|
||||
export const Pages = (PageRepository);
|
||||
export const PageLikes = (PageLikeRepository);
|
||||
export const GalleryPosts = (GalleryPostRepository);
|
||||
export const GalleryLikes = (GalleryLikeRepository);
|
||||
export const ModerationLogs = (ModerationLogRepository);
|
||||
export const Clips = (ClipRepository);
|
||||
export const ClipNotes = db.getRepository(ClipNote);
|
||||
export const Antennas = (AntennaRepository);
|
||||
export const AntennaNotes = db.getRepository(AntennaNote);
|
||||
export const PromoNotes = db.getRepository(PromoNote);
|
||||
export const PromoReads = db.getRepository(PromoRead);
|
||||
export const Relays = (RelayRepository);
|
||||
export const MutedNotes = db.getRepository(MutedNote);
|
||||
export const Channels = (ChannelRepository);
|
||||
export const ChannelFollowings = db.getRepository(ChannelFollowing);
|
||||
export const ChannelNotePinings = db.getRepository(ChannelNotePining);
|
||||
export const RegistryItems = db.getRepository(RegistryItem);
|
||||
export const Ads = db.getRepository(Ad);
|
||||
export const PasswordResetRequests = db.getRepository(PasswordResetRequest);
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Users } from '../index.js';
|
||||
import { AbuseUserReport } from '@/models/entities/abuse-user-report.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
|
||||
@EntityRepository(AbuseUserReport)
|
||||
export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
|
||||
public async pack(
|
||||
export const AbuseUserReportRepository = db.getRepository(AbuseUserReport).extend({
|
||||
async pack(
|
||||
src: AbuseUserReport['id'] | AbuseUserReport,
|
||||
) {
|
||||
const report = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const report = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: report.id,
|
||||
@ -29,11 +28,11 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
|
||||
}) : null,
|
||||
forwarded: report.forwarded,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
reports: any[],
|
||||
) {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,17 +1,16 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Antenna } from '@/models/entities/antenna.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { AntennaNotes, UserGroupJoinings } from '../index.js';
|
||||
|
||||
@EntityRepository(Antenna)
|
||||
export class AntennaRepository extends Repository<Antenna> {
|
||||
public async pack(
|
||||
export const AntennaRepository = db.getRepository(Antenna).extend({
|
||||
async pack(
|
||||
src: Antenna['id'] | Antenna,
|
||||
): Promise<Packed<'Antenna'>> {
|
||||
const antenna = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const antenna = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
const hasUnreadNote = (await AntennaNotes.findOne({ antennaId: antenna.id, read: false })) != null;
|
||||
const userGroupJoining = antenna.userGroupJoiningId ? await UserGroupJoinings.findOne(antenna.userGroupJoiningId) : null;
|
||||
const hasUnreadNote = (await AntennaNotes.findOneBy({ antennaId: antenna.id, read: false })) != null;
|
||||
const userGroupJoining = antenna.userGroupJoiningId ? await UserGroupJoinings.findOneBy({ id: antenna.userGroupJoiningId }) : null;
|
||||
|
||||
return {
|
||||
id: antenna.id,
|
||||
@ -29,5 +28,5 @@ export class AntennaRepository extends Repository<Antenna> {
|
||||
withFile: antenna.withFile,
|
||||
hasUnreadNote,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { App } from '@/models/entities/app.js';
|
||||
import { AccessTokens } from '../index.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { User } from '../entities/user.js';
|
||||
|
||||
@EntityRepository(App)
|
||||
export class AppRepository extends Repository<App> {
|
||||
public async pack(
|
||||
export const AppRepository = db.getRepository(App).extend({
|
||||
async pack(
|
||||
src: App['id'] | App,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -21,7 +20,7 @@ export class AppRepository extends Repository<App> {
|
||||
includeProfileImageIds: false,
|
||||
}, options);
|
||||
|
||||
const app = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const app = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: app.id,
|
||||
@ -30,11 +29,11 @@ export class AppRepository extends Repository<App> {
|
||||
permission: app.permission,
|
||||
...(opts.includeSecret ? { secret: app.secret } : {}),
|
||||
...(me ? {
|
||||
isAuthorized: await AccessTokens.count({
|
||||
isAuthorized: await AccessTokens.countBy({
|
||||
appId: app.id,
|
||||
userId: me.id,
|
||||
}).then(count => count > 0),
|
||||
} : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,21 +1,20 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Apps } from '../index.js';
|
||||
import { AuthSession } from '@/models/entities/auth-session.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(AuthSession)
|
||||
export class AuthSessionRepository extends Repository<AuthSession> {
|
||||
public async pack(
|
||||
export const AuthSessionRepository = db.getRepository(AuthSession).extend({
|
||||
async pack(
|
||||
src: AuthSession['id'] | AuthSession,
|
||||
me?: { id: User['id'] } | null | undefined
|
||||
) {
|
||||
const session = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const session = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: session.id,
|
||||
app: Apps.pack(session.appId, me),
|
||||
token: session.token,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,17 +1,16 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Users } from '../index.js';
|
||||
import { Blocking } from '@/models/entities/blocking.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(Blocking)
|
||||
export class BlockingRepository extends Repository<Blocking> {
|
||||
public async pack(
|
||||
export const BlockingRepository = db.getRepository(Blocking).extend({
|
||||
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);
|
||||
const blocking = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: blocking.id,
|
||||
@ -21,12 +20,12 @@ export class BlockingRepository extends Repository<Blocking> {
|
||||
detail: true,
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
blockings: any[],
|
||||
me: { id: User['id'] }
|
||||
) {
|
||||
return Promise.all(blockings.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Channel } from '@/models/entities/channel.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { DriveFiles, ChannelFollowings, NoteUnreads } from '../index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(Channel)
|
||||
export class ChannelRepository extends Repository<Channel> {
|
||||
public async pack(
|
||||
export const ChannelRepository = db.getRepository(Channel).extend({
|
||||
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 channel = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
const meId = me ? me.id : null;
|
||||
|
||||
const banner = channel.bannerId ? await DriveFiles.findOne(channel.bannerId) : null;
|
||||
const banner = channel.bannerId ? await DriveFiles.findOneBy({ id: channel.bannerId }) : null;
|
||||
|
||||
const hasUnreadNote = meId ? (await NoteUnreads.findOne({ noteChannelId: channel.id, userId: meId })) != null : undefined;
|
||||
const hasUnreadNote = meId ? (await NoteUnreads.findOneBy({ noteChannelId: channel.id, userId: meId })) != null : undefined;
|
||||
|
||||
const following = meId ? await ChannelFollowings.findOne({
|
||||
const following = meId ? await ChannelFollowings.findOneBy({
|
||||
followerId: meId,
|
||||
followeeId: channel.id,
|
||||
}) : null;
|
||||
@ -38,5 +37,5 @@ export class ChannelRepository extends Repository<Channel> {
|
||||
hasUnreadNote,
|
||||
} : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Clip } from '@/models/entities/clip.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { Users } from '../index.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
|
||||
@EntityRepository(Clip)
|
||||
export class ClipRepository extends Repository<Clip> {
|
||||
public async pack(
|
||||
export const ClipRepository = db.getRepository(Clip).extend({
|
||||
async pack(
|
||||
src: Clip['id'] | Clip,
|
||||
): Promise<Packed<'Clip'>> {
|
||||
const clip = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const clip = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: clip.id,
|
||||
@ -20,12 +19,12 @@ export class ClipRepository extends Repository<Clip> {
|
||||
description: clip.description,
|
||||
isPublic: clip.isPublic,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
clips: Clip[],
|
||||
) {
|
||||
return Promise.all(clips.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||
import { Users, DriveFolders } from '../index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
@ -16,9 +16,8 @@ type PackOptions = {
|
||||
withUser?: boolean,
|
||||
};
|
||||
|
||||
@EntityRepository(DriveFile)
|
||||
export class DriveFileRepository extends Repository<DriveFile> {
|
||||
public validateFileName(name: string): boolean {
|
||||
export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||
validateFileName(name: string): boolean {
|
||||
return (
|
||||
(name.trim().length > 0) &&
|
||||
(name.length <= 200) &&
|
||||
@ -26,9 +25,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
(name.indexOf('/') === -1) &&
|
||||
(name.indexOf('..') === -1)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
public getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
||||
getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
||||
if (file.properties.orientation != null) {
|
||||
const properties = JSON.parse(JSON.stringify(file.properties));
|
||||
if (file.properties.orientation >= 5) {
|
||||
@ -39,9 +38,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
}
|
||||
|
||||
return file.properties;
|
||||
}
|
||||
},
|
||||
|
||||
public getPublicUrl(file: DriveFile, thumbnail = false): string | null {
|
||||
getPublicUrl(file: DriveFile, thumbnail = false): string | null {
|
||||
// リモートかつメディアプロキシ
|
||||
if (file.uri != null && file.userHost != null && config.mediaProxy != null) {
|
||||
return appendQuery(config.mediaProxy, query({
|
||||
@ -62,9 +61,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
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> {
|
||||
async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise<number> {
|
||||
const id = typeof user === 'object' ? user.id : user;
|
||||
|
||||
const { sum } = await this
|
||||
@ -75,9 +74,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
},
|
||||
|
||||
public async calcDriveUsageOfHost(host: string): Promise<number> {
|
||||
async calcDriveUsageOfHost(host: string): Promise<number> {
|
||||
const { sum } = await this
|
||||
.createQueryBuilder('file')
|
||||
.where('file.userHost = :host', { host: toPuny(host) })
|
||||
@ -86,9 +85,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
},
|
||||
|
||||
public async calcDriveUsageOfLocal(): Promise<number> {
|
||||
async calcDriveUsageOfLocal(): Promise<number> {
|
||||
const { sum } = await this
|
||||
.createQueryBuilder('file')
|
||||
.where('file.userHost IS NULL')
|
||||
@ -97,9 +96,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(sum, 10) || 0;
|
||||
}
|
||||
},
|
||||
|
||||
public async calcDriveUsageOfRemote(): Promise<number> {
|
||||
async calcDriveUsageOfRemote(): Promise<number> {
|
||||
const { sum } = await this
|
||||
.createQueryBuilder('file')
|
||||
.where('file.userHost IS NOT NULL')
|
||||
@ -108,11 +107,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
.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(
|
||||
async pack(
|
||||
src: DriveFile['id'] | DriveFile,
|
||||
options?: PackOptions
|
||||
): Promise<Packed<'DriveFile'> | null> {
|
||||
@ -121,11 +118,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
self: false,
|
||||
}, options);
|
||||
|
||||
const file = typeof src === 'object' ? src : await this.findOne(src);
|
||||
const file = typeof src === 'object' ? src : await this.findOneBy({ id: src });
|
||||
if (file == null) return null;
|
||||
|
||||
const meta = await fetchMeta();
|
||||
|
||||
return await awaitAll<Packed<'DriveFile'>>({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
@ -146,13 +141,13 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
||||
userId: opts.withUser ? file.userId : null,
|
||||
user: (opts.withUser && file.userId) ? Users.pack(file.userId) : null,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public async packMany(
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { DriveFolders, DriveFiles } from '../index.js';
|
||||
import { DriveFolder } from '@/models/entities/drive-folder.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(DriveFolder)
|
||||
export class DriveFolderRepository extends Repository<DriveFolder> {
|
||||
public async pack(
|
||||
export const DriveFolderRepository = db.getRepository(DriveFolder).extend({
|
||||
async pack(
|
||||
src: DriveFolder['id'] | DriveFolder,
|
||||
options?: {
|
||||
detail: boolean
|
||||
@ -16,7 +15,7 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
|
||||
detail: false,
|
||||
}, options);
|
||||
|
||||
const folder = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const folder = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: folder.id,
|
||||
@ -25,10 +24,10 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
|
||||
parentId: folder.parentId,
|
||||
|
||||
...(opts.detail ? {
|
||||
foldersCount: DriveFolders.count({
|
||||
foldersCount: DriveFolders.countBy({
|
||||
parentId: folder.id,
|
||||
}),
|
||||
filesCount: DriveFiles.count({
|
||||
filesCount: DriveFiles.countBy({
|
||||
folderId: folder.id,
|
||||
}),
|
||||
|
||||
@ -39,5 +38,5 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
|
||||
} : {}),
|
||||
} : {}),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Emoji } from '@/models/entities/emoji.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(Emoji)
|
||||
export class EmojiRepository extends Repository<Emoji> {
|
||||
public async pack(
|
||||
export const EmojiRepository = db.getRepository(Emoji).extend({
|
||||
async pack(
|
||||
src: Emoji['id'] | Emoji,
|
||||
): Promise<Packed<'Emoji'>> {
|
||||
const emoji = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const emoji = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: emoji.id,
|
||||
@ -18,11 +17,11 @@ export class EmojiRepository extends Repository<Emoji> {
|
||||
// || emoji.originalUrl してるのは後方互換性のため
|
||||
url: emoji.publicUrl || emoji.originalUrl,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
emojis: any[],
|
||||
) {
|
||||
return Promise.all(emojis.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { FollowRequest } from '@/models/entities/follow-request.js';
|
||||
import { Users } from '../index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(FollowRequest)
|
||||
export class FollowRequestRepository extends Repository<FollowRequest> {
|
||||
public async pack(
|
||||
export const FollowRequestRepository = db.getRepository(FollowRequest).extend({
|
||||
async pack(
|
||||
src: FollowRequest['id'] | FollowRequest,
|
||||
me?: { id: User['id'] } | null | undefined
|
||||
) {
|
||||
const request = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const request = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: request.id,
|
||||
follower: await Users.pack(request.followerId, me),
|
||||
followee: await Users.pack(request.followeeId, me),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Users } from '../index.js';
|
||||
import { Following } from '@/models/entities/following.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
@ -29,25 +29,24 @@ type RemoteFolloweeFollowing = Following & {
|
||||
followeeSharedInbox: string;
|
||||
};
|
||||
|
||||
@EntityRepository(Following)
|
||||
export class FollowingRepository extends Repository<Following> {
|
||||
public isLocalFollower(following: Following): following is LocalFollowerFollowing {
|
||||
export const FollowingRepository = db.getRepository(Following).extend({
|
||||
isLocalFollower(following: Following): following is LocalFollowerFollowing {
|
||||
return following.followerHost == null;
|
||||
}
|
||||
},
|
||||
|
||||
public isRemoteFollower(following: Following): following is RemoteFollowerFollowing {
|
||||
isRemoteFollower(following: Following): following is RemoteFollowerFollowing {
|
||||
return following.followerHost != null;
|
||||
}
|
||||
},
|
||||
|
||||
public isLocalFollowee(following: Following): following is LocalFolloweeFollowing {
|
||||
isLocalFollowee(following: Following): following is LocalFolloweeFollowing {
|
||||
return following.followeeHost == null;
|
||||
}
|
||||
},
|
||||
|
||||
public isRemoteFollowee(following: Following): following is RemoteFolloweeFollowing {
|
||||
isRemoteFollowee(following: Following): following is RemoteFolloweeFollowing {
|
||||
return following.followeeHost != null;
|
||||
}
|
||||
},
|
||||
|
||||
public async pack(
|
||||
async pack(
|
||||
src: Following['id'] | Following,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
opts?: {
|
||||
@ -55,7 +54,7 @@ export class FollowingRepository extends Repository<Following> {
|
||||
populateFollower?: boolean;
|
||||
}
|
||||
): Promise<Packed<'Following'>> {
|
||||
const following = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const following = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
if (opts == null) opts = {};
|
||||
|
||||
@ -71,9 +70,9 @@ export class FollowingRepository extends Repository<Following> {
|
||||
detail: true,
|
||||
}) : undefined,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
followings: any[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
opts?: {
|
||||
@ -82,5 +81,5 @@ export class FollowingRepository extends Repository<Following> {
|
||||
}
|
||||
) {
|
||||
return Promise.all(followings.map(x => this.pack(x, me, opts)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,25 +1,24 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { GalleryLike } from '@/models/entities/gallery-like.js';
|
||||
import { GalleryPosts } from '../index.js';
|
||||
|
||||
@EntityRepository(GalleryLike)
|
||||
export class GalleryLikeRepository extends Repository<GalleryLike> {
|
||||
public async pack(
|
||||
export const GalleryLikeRepository = db.getRepository(GalleryLike).extend({
|
||||
async pack(
|
||||
src: GalleryLike['id'] | GalleryLike,
|
||||
me?: any
|
||||
) {
|
||||
const like = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const like = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: like.id,
|
||||
post: await GalleryPosts.pack(like.post || like.postId, me),
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
likes: any[],
|
||||
me: any
|
||||
) {
|
||||
return Promise.all(likes.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,18 +1,17 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { GalleryPost } from '@/models/entities/gallery-post.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { Users, DriveFiles, GalleryLikes } from '../index.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(GalleryPost)
|
||||
export class GalleryPostRepository extends Repository<GalleryPost> {
|
||||
public async pack(
|
||||
export const GalleryPostRepository = db.getRepository(GalleryPost).extend({
|
||||
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);
|
||||
const post = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: post.id,
|
||||
@ -27,14 +26,14 @@ export class GalleryPostRepository extends Repository<GalleryPost> {
|
||||
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,
|
||||
isLiked: meId ? await GalleryLikes.findOneBy({ postId: post.id, userId: meId }).then(x => x != null) : undefined,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
posts: GalleryPost[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(posts.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Hashtag } from '@/models/entities/hashtag.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(Hashtag)
|
||||
export class HashtagRepository extends Repository<Hashtag> {
|
||||
public async pack(
|
||||
export const HashtagRepository = db.getRepository(Hashtag).extend({
|
||||
async pack(
|
||||
src: Hashtag,
|
||||
): Promise<Packed<'Hashtag'>> {
|
||||
return {
|
||||
@ -16,11 +15,11 @@ export class HashtagRepository extends Repository<Hashtag> {
|
||||
attachedLocalUsersCount: src.attachedLocalUsersCount,
|
||||
attachedRemoteUsersCount: src.attachedRemoteUsersCount,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
hashtags: Hashtag[],
|
||||
) {
|
||||
return Promise.all(hashtags.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Instance } from '@/models/entities/instance.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(Instance)
|
||||
export class InstanceRepository extends Repository<Instance> {
|
||||
public async pack(
|
||||
export const InstanceRepository = db.getRepository(Instance).extend({
|
||||
async pack(
|
||||
instance: Instance,
|
||||
): Promise<Packed<'FederationInstance'>> {
|
||||
return {
|
||||
@ -29,11 +28,11 @@ export class InstanceRepository extends Repository<Instance> {
|
||||
iconUrl: instance.iconUrl,
|
||||
infoUpdatedAt: instance.infoUpdatedAt ? instance.infoUpdatedAt.toISOString() : null,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
instances: Instance[],
|
||||
) {
|
||||
return Promise.all(instances.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { MessagingMessage } from '@/models/entities/messaging-message.js';
|
||||
import { Users, DriveFiles, UserGroups } from '../index.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(MessagingMessage)
|
||||
export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
||||
public async pack(
|
||||
export const MessagingMessageRepository = db.getRepository(MessagingMessage).extend({
|
||||
async pack(
|
||||
src: MessagingMessage['id'] | MessagingMessage,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -19,7 +18,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
||||
populateGroup: true,
|
||||
};
|
||||
|
||||
const message = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const message = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: message.id,
|
||||
@ -36,5 +35,5 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
||||
isRead: message.isRead,
|
||||
reads: message.reads,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Users } from '../index.js';
|
||||
import { ModerationLog } from '@/models/entities/moderation-log.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
|
||||
@EntityRepository(ModerationLog)
|
||||
export class ModerationLogRepository extends Repository<ModerationLog> {
|
||||
public async pack(
|
||||
export const ModerationLogRepository = db.getRepository(ModerationLog).extend({
|
||||
async pack(
|
||||
src: ModerationLog['id'] | ModerationLog,
|
||||
) {
|
||||
const log = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const log = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: log.id,
|
||||
@ -20,11 +19,11 @@ export class ModerationLogRepository extends Repository<ModerationLog> {
|
||||
detail: true,
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
reports: any[],
|
||||
) {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,17 +1,16 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Users } from '../index.js';
|
||||
import { Muting } from '@/models/entities/muting.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(Muting)
|
||||
export class MutingRepository extends Repository<Muting> {
|
||||
public async pack(
|
||||
export const MutingRepository = db.getRepository(Muting).extend({
|
||||
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);
|
||||
const muting = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
id: muting.id,
|
||||
@ -22,12 +21,12 @@ export class MutingRepository extends Repository<Muting> {
|
||||
detail: true,
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
mutings: any[],
|
||||
me: { id: User['id'] }
|
||||
) {
|
||||
return Promise.all(mutings.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,15 +1,14 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { NoteFavorite } from '@/models/entities/note-favorite.js';
|
||||
import { Notes } from '../index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(NoteFavorite)
|
||||
export class NoteFavoriteRepository extends Repository<NoteFavorite> {
|
||||
public async pack(
|
||||
export const NoteFavoriteRepository = db.getRepository(NoteFavorite).extend({
|
||||
async pack(
|
||||
src: NoteFavorite['id'] | NoteFavorite,
|
||||
me?: { id: User['id'] } | null | undefined
|
||||
) {
|
||||
const favorite = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const favorite = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: favorite.id,
|
||||
@ -17,12 +16,12 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> {
|
||||
noteId: favorite.noteId,
|
||||
note: await Notes.pack(favorite.note || favorite.noteId, me),
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
favorites: any[],
|
||||
me: { id: User['id'] }
|
||||
) {
|
||||
return Promise.all(favorites.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { NoteReaction } from '@/models/entities/note-reaction.js';
|
||||
import { Notes, Users } from '../index.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { convertLegacyReaction } from '@/misc/reaction-lib.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(NoteReaction)
|
||||
export class NoteReactionRepository extends Repository<NoteReaction> {
|
||||
public async pack(
|
||||
export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
|
||||
async pack(
|
||||
src: NoteReaction['id'] | NoteReaction,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -18,7 +17,7 @@ export class NoteReactionRepository extends Repository<NoteReaction> {
|
||||
withNote: false,
|
||||
}, options);
|
||||
|
||||
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const reaction = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: reaction.id,
|
||||
@ -29,5 +28,5 @@ export class NoteReactionRepository extends Repository<NoteReaction> {
|
||||
note: await Notes.pack(reaction.note ?? reaction.noteId, me),
|
||||
} : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EntityRepository, Repository, In } from 'typeorm';
|
||||
import { In } from 'typeorm';
|
||||
import * as mfm from 'mfm-js';
|
||||
import { Note } from '@/models/entities/note.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
@ -9,10 +9,70 @@ import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib.js';
|
||||
import { NoteReaction } from '@/models/entities/note-reaction.js';
|
||||
import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis.js';
|
||||
import { db } from '@/db/postgre.js';
|
||||
|
||||
@EntityRepository(Note)
|
||||
export class NoteRepository extends Repository<Note> {
|
||||
public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise<boolean> {
|
||||
async function 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.findOneBy({
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
export const NoteRepository = db.getRepository(Note).extend({
|
||||
async isVisibleForMe(note: Note, meId: User['id'] | null): Promise<boolean> {
|
||||
// visibility が specified かつ自分が指定されていなかったら非表示
|
||||
if (note.visibility === 'specified') {
|
||||
if (meId == null) {
|
||||
@ -45,7 +105,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
return true;
|
||||
} else {
|
||||
// フォロワーかどうか
|
||||
const following = await Followings.findOne({
|
||||
const following = await Followings.findOneBy({
|
||||
followeeId: note.userId,
|
||||
followerId: meId,
|
||||
});
|
||||
@ -59,69 +119,9 @@ export class NoteRepository extends Repository<Note> {
|
||||
}
|
||||
|
||||
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(
|
||||
async pack(
|
||||
src: Note['id'] | Note,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -138,11 +138,11 @@ export class NoteRepository extends Repository<Note> {
|
||||
}, options);
|
||||
|
||||
const meId = me ? me.id : null;
|
||||
const note = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const note = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
const host = note.userHost;
|
||||
|
||||
async function populatePoll() {
|
||||
const poll = await Polls.findOneOrFail(note.id);
|
||||
const poll = await Polls.findOneByOrFail({ noteId: note.id });
|
||||
const choices = poll.choices.map(c => ({
|
||||
text: c,
|
||||
votes: poll.votes[poll.choices.indexOf(c)],
|
||||
@ -150,7 +150,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
}));
|
||||
|
||||
if (poll.multiple) {
|
||||
const votes = await PollVotes.find({
|
||||
const votes = await PollVotes.findBy({
|
||||
userId: meId!,
|
||||
noteId: note.id,
|
||||
});
|
||||
@ -160,7 +160,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
choices[myChoice].isVoted = true;
|
||||
}
|
||||
} else {
|
||||
const vote = await PollVotes.findOne({
|
||||
const vote = await PollVotes.findOneBy({
|
||||
userId: meId!,
|
||||
noteId: note.id,
|
||||
});
|
||||
@ -188,7 +188,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
// 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない
|
||||
}
|
||||
|
||||
const reaction = await NoteReactions.findOne({
|
||||
const reaction = await NoteReactions.findOneBy({
|
||||
userId: meId!,
|
||||
noteId: note.id,
|
||||
});
|
||||
@ -209,7 +209,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
const channel = note.channelId
|
||||
? note.channel
|
||||
? note.channel
|
||||
: await Channels.findOne(note.channelId)
|
||||
: await Channels.findOneBy({ id: note.channelId })
|
||||
: null;
|
||||
|
||||
const reactionEmojiNames = Object.keys(note.reactions).filter(x => x?.startsWith(':')).map(x => decodeReaction(x).reaction).map(x => x.replace(/:/g, ''));
|
||||
@ -275,13 +275,13 @@ export class NoteRepository extends Repository<Note> {
|
||||
}
|
||||
|
||||
if (!opts.skipHide) {
|
||||
await this.hideNote(packed, meId);
|
||||
await hideNote(packed, meId);
|
||||
}
|
||||
|
||||
return packed;
|
||||
}
|
||||
},
|
||||
|
||||
public async packMany(
|
||||
async packMany(
|
||||
notes: Note[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -296,7 +296,7 @@ export class NoteRepository extends Repository<Note> {
|
||||
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({
|
||||
const myReactions = await NoteReactions.findBy({
|
||||
userId: meId,
|
||||
noteId: In(targets),
|
||||
});
|
||||
@ -314,5 +314,5 @@ export class NoteRepository extends Repository<Note> {
|
||||
myReactions: myReactionsMap,
|
||||
},
|
||||
})));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EntityRepository, In, Repository } from 'typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '../index.js';
|
||||
import { Notification } from '@/models/entities/notification.js';
|
||||
import { awaitAll } from '@/prelude/await-all.js';
|
||||
@ -8,10 +8,10 @@ import { NoteReaction } from '@/models/entities/note-reaction.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis.js';
|
||||
import { notificationTypes } from '@/types.js';
|
||||
import { db } from '@/db/postgre.js';
|
||||
|
||||
@EntityRepository(Notification)
|
||||
export class NotificationRepository extends Repository<Notification> {
|
||||
public async pack(
|
||||
export const NotificationRepository = db.getRepository(Notification).extend({
|
||||
async pack(
|
||||
src: Notification['id'] | Notification,
|
||||
options: {
|
||||
_hintForEachNotes_?: {
|
||||
@ -19,8 +19,8 @@ export class NotificationRepository extends Repository<Notification> {
|
||||
};
|
||||
}
|
||||
): Promise<Packed<'Notification'>> {
|
||||
const notification = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const token = notification.appAccessTokenId ? await AccessTokens.findOneOrFail(notification.appAccessTokenId) : null;
|
||||
const notification = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
const token = notification.appAccessTokenId ? await AccessTokens.findOneByOrFail({ id: notification.appAccessTokenId }) : null;
|
||||
|
||||
return await awaitAll({
|
||||
id: notification.id,
|
||||
@ -82,9 +82,9 @@ export class NotificationRepository extends Repository<Notification> {
|
||||
icon: notification.customIcon || token?.iconUrl,
|
||||
} : {}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public async packMany(
|
||||
async packMany(
|
||||
notifications: Notification[],
|
||||
meId: User['id']
|
||||
) {
|
||||
@ -95,7 +95,7 @@ export class NotificationRepository extends Repository<Notification> {
|
||||
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({
|
||||
const myReactions = await NoteReactions.findBy({
|
||||
userId: meId,
|
||||
noteId: In(targets),
|
||||
});
|
||||
@ -111,5 +111,5 @@ export class NotificationRepository extends Repository<Notification> {
|
||||
myReactions: myReactionsMap,
|
||||
},
|
||||
})));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,26 +1,25 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { PageLike } from '@/models/entities/page-like.js';
|
||||
import { Pages } from '../index.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(PageLike)
|
||||
export class PageLikeRepository extends Repository<PageLike> {
|
||||
public async pack(
|
||||
export const PageLikeRepository = db.getRepository(PageLike).extend({
|
||||
async pack(
|
||||
src: PageLike['id'] | PageLike,
|
||||
me?: { id: User['id'] } | null | undefined
|
||||
) {
|
||||
const like = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const like = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: like.id,
|
||||
page: await Pages.pack(like.page || like.pageId, me),
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
likes: any[],
|
||||
me: { id: User['id'] }
|
||||
) {
|
||||
return Promise.all(likes.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Page } from '@/models/entities/page.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
import { Users, DriveFiles, PageLikes } from '../index.js';
|
||||
@ -6,20 +6,19 @@ import { awaitAll } from '@/prelude/await-all.js';
|
||||
import { DriveFile } from '@/models/entities/drive-file.js';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
@EntityRepository(Page)
|
||||
export class PageRepository extends Repository<Page> {
|
||||
public async pack(
|
||||
export const PageRepository = db.getRepository(Page).extend({
|
||||
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 page = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
const attachedFiles: Promise<DriveFile | undefined>[] = [];
|
||||
const collectFile = (xs: any[]) => {
|
||||
for (const x of xs) {
|
||||
if (x.type === 'image') {
|
||||
attachedFiles.push(DriveFiles.findOne({
|
||||
attachedFiles.push(DriveFiles.findOneBy({
|
||||
id: x.fileId,
|
||||
userId: page.userId,
|
||||
}));
|
||||
@ -76,14 +75,14 @@ export class PageRepository extends Repository<Page> {
|
||||
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,
|
||||
isLiked: meId ? await PageLikes.findOneBy({ pageId: page.id, userId: meId }).then(x => x != null) : undefined,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
pages: Page[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(pages.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Relay } from '@/models/entities/relay.js';
|
||||
|
||||
@EntityRepository(Relay)
|
||||
export class RelayRepository extends Repository<Relay> {
|
||||
}
|
||||
export const RelayRepository = db.getRepository(Relay).extend({
|
||||
});
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { Signin } from '@/models/entities/signin.js';
|
||||
|
||||
@EntityRepository(Signin)
|
||||
export class SigninRepository extends Repository<Signin> {
|
||||
public async pack(
|
||||
export const SigninRepository = db.getRepository(Signin).extend({
|
||||
async pack(
|
||||
src: Signin,
|
||||
) {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { UserGroupInvitation } from '@/models/entities/user-group-invitation.js';
|
||||
import { UserGroups } from '../index.js';
|
||||
|
||||
@EntityRepository(UserGroupInvitation)
|
||||
export class UserGroupInvitationRepository extends Repository<UserGroupInvitation> {
|
||||
public async pack(
|
||||
export const UserGroupInvitationRepository = db.getRepository(UserGroupInvitation).extend({
|
||||
async pack(
|
||||
src: UserGroupInvitation['id'] | UserGroupInvitation,
|
||||
) {
|
||||
const invitation = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const invitation = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: invitation.id,
|
||||
group: await UserGroups.pack(invitation.userGroup || invitation.userGroupId),
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public packMany(
|
||||
packMany(
|
||||
invitations: any[],
|
||||
) {
|
||||
return Promise.all(invitations.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { UserGroup } from '@/models/entities/user-group.js';
|
||||
import { UserGroupJoinings } from '../index.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(UserGroup)
|
||||
export class UserGroupRepository extends Repository<UserGroup> {
|
||||
public async pack(
|
||||
export const UserGroupRepository = db.getRepository(UserGroup).extend({
|
||||
async pack(
|
||||
src: UserGroup['id'] | UserGroup,
|
||||
): Promise<Packed<'UserGroup'>> {
|
||||
const userGroup = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const userGroup = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
const users = await UserGroupJoinings.find({
|
||||
const users = await UserGroupJoinings.findBy({
|
||||
userGroupId: userGroup.id,
|
||||
});
|
||||
|
||||
@ -21,5 +20,5 @@ export class UserGroupRepository extends Repository<UserGroup> {
|
||||
ownerId: userGroup.userId,
|
||||
userIds: users.map(x => x.userId),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { db } from '@/db/postgre.js';
|
||||
import { UserList } from '@/models/entities/user-list.js';
|
||||
import { UserListJoinings } from '../index.js';
|
||||
import { Packed } from '@/misc/schema.js';
|
||||
|
||||
@EntityRepository(UserList)
|
||||
export class UserListRepository extends Repository<UserList> {
|
||||
public async pack(
|
||||
export const UserListRepository = db.getRepository(UserList).extend({
|
||||
async pack(
|
||||
src: UserList['id'] | UserList,
|
||||
): Promise<Packed<'UserList'>> {
|
||||
const userList = typeof src === 'object' ? src : await this.findOneOrFail(src);
|
||||
const userList = typeof src === 'object' ? src : await this.findOneByOrFail({ id: src });
|
||||
|
||||
const users = await UserListJoinings.find({
|
||||
const users = await UserListJoinings.findBy({
|
||||
userListId: userList.id,
|
||||
});
|
||||
|
||||
@ -20,5 +19,5 @@ export class UserListRepository extends Repository<UserList> {
|
||||
name: userList.name,
|
||||
userIds: users.map(x => x.userId),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ import { getAntennas } from '@/misc/antenna-cache.js';
|
||||
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
|
||||
import { Cache } from '@/misc/cache.js';
|
||||
import { Instance } from '../entities/instance.js';
|
||||
import { db } from '@/db/postgre.js';
|
||||
|
||||
const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
|
||||
|
||||
@ -23,51 +24,69 @@ type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends bo
|
||||
|
||||
const ajv = new Ajv();
|
||||
|
||||
@EntityRepository(User)
|
||||
export class UserRepository extends Repository<User> {
|
||||
public localUsernameSchema = { type: 'string', pattern: /^\w{1,20}$/.toString().slice(1, -1) } as const;
|
||||
public passwordSchema = { type: 'string', minLength: 1 } as const;
|
||||
public nameSchema = { type: 'string', minLength: 1, maxLength: 50 } as const;
|
||||
public descriptionSchema = { type: 'string', minLength: 1, maxLength: 500 } as const;
|
||||
public locationSchema = { type: 'string', minLength: 1, maxLength: 50 } as const;
|
||||
public birthdaySchema = { type: 'string', pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1) } as const;
|
||||
const localUsernameSchema = { type: 'string', pattern: /^\w{1,20}$/.toString().slice(1, -1) } as const;
|
||||
const passwordSchema = { type: 'string', minLength: 1 } as const;
|
||||
const nameSchema = { type: 'string', minLength: 1, maxLength: 50 } as const;
|
||||
const descriptionSchema = { type: 'string', minLength: 1, maxLength: 500 } as const;
|
||||
const locationSchema = { type: 'string', minLength: 1, maxLength: 50 } as const;
|
||||
const birthdaySchema = { type: 'string', pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1) } as const;
|
||||
|
||||
function isLocalUser(user: User): user is ILocalUser;
|
||||
function isLocalUser<T extends { host: User['host'] }>(user: T): user is T & { host: null; };
|
||||
function isLocalUser(user: User | { host: User['host'] }): boolean {
|
||||
return user.host == null;
|
||||
}
|
||||
|
||||
function isRemoteUser(user: User): user is IRemoteUser;
|
||||
function isRemoteUser<T extends { host: User['host'] }>(user: T): user is T & { host: string; };
|
||||
function isRemoteUser(user: User | { host: User['host'] }): boolean {
|
||||
return !isLocalUser(user);
|
||||
}
|
||||
|
||||
export const UserRepository = db.getRepository(User).extend({
|
||||
localUsernameSchema,
|
||||
passwordSchema,
|
||||
nameSchema,
|
||||
descriptionSchema,
|
||||
locationSchema,
|
||||
birthdaySchema,
|
||||
|
||||
//#region Validators
|
||||
public validateLocalUsername = ajv.compile(this.localUsernameSchema);
|
||||
public validatePassword = ajv.compile(this.passwordSchema);
|
||||
public validateName = ajv.compile(this.nameSchema);
|
||||
public validateDescription = ajv.compile(this.descriptionSchema);
|
||||
public validateLocation = ajv.compile(this.locationSchema);
|
||||
public validateBirthday = ajv.compile(this.birthdaySchema);
|
||||
validateLocalUsername: ajv.compile(localUsernameSchema),
|
||||
validatePassword: ajv.compile(passwordSchema),
|
||||
validateName: ajv.compile(nameSchema),
|
||||
validateDescription: ajv.compile(descriptionSchema),
|
||||
validateLocation: ajv.compile(locationSchema),
|
||||
validateBirthday: ajv.compile(birthdaySchema),
|
||||
//#endregion
|
||||
|
||||
public async getRelation(me: User['id'], target: User['id']) {
|
||||
async getRelation(me: User['id'], target: User['id']) {
|
||||
const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([
|
||||
Followings.findOne({
|
||||
Followings.findOneBy({
|
||||
followerId: me,
|
||||
followeeId: target,
|
||||
}),
|
||||
Followings.findOne({
|
||||
Followings.findOneBy({
|
||||
followerId: target,
|
||||
followeeId: me,
|
||||
}),
|
||||
FollowRequests.findOne({
|
||||
FollowRequests.findOneBy({
|
||||
followerId: me,
|
||||
followeeId: target,
|
||||
}),
|
||||
FollowRequests.findOne({
|
||||
FollowRequests.findOneBy({
|
||||
followerId: target,
|
||||
followeeId: me,
|
||||
}),
|
||||
Blockings.findOne({
|
||||
Blockings.findOneBy({
|
||||
blockerId: me,
|
||||
blockeeId: target,
|
||||
}),
|
||||
Blockings.findOne({
|
||||
Blockings.findOneBy({
|
||||
blockerId: target,
|
||||
blockeeId: me,
|
||||
}),
|
||||
Mutings.findOne({
|
||||
Mutings.findOneBy({
|
||||
muterId: me,
|
||||
muteeId: target,
|
||||
}),
|
||||
@ -83,14 +102,14 @@ export class UserRepository extends Repository<User> {
|
||||
isBlocked: fromBlocked != null,
|
||||
isMuted: mute != null,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
public async getHasUnreadMessagingMessage(userId: User['id']): Promise<boolean> {
|
||||
const mute = await Mutings.find({
|
||||
async getHasUnreadMessagingMessage(userId: User['id']): Promise<boolean> {
|
||||
const mute = await Mutings.findBy({
|
||||
muterId: userId,
|
||||
});
|
||||
|
||||
const joinings = await UserGroupJoinings.find({ userId: userId });
|
||||
const joinings = await UserGroupJoinings.findBy({ userId: userId });
|
||||
|
||||
const groupQs = Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder('message')
|
||||
.where(`message.groupId = :groupId`, { groupId: j.userGroupId })
|
||||
@ -112,44 +131,44 @@ export class UserRepository extends Repository<User> {
|
||||
]);
|
||||
|
||||
return withUser || withGroups.some(x => x);
|
||||
}
|
||||
},
|
||||
|
||||
public async getHasUnreadAnnouncement(userId: User['id']): Promise<boolean> {
|
||||
const reads = await AnnouncementReads.find({
|
||||
async getHasUnreadAnnouncement(userId: User['id']): Promise<boolean> {
|
||||
const reads = await AnnouncementReads.findBy({
|
||||
userId: userId,
|
||||
});
|
||||
|
||||
const count = await Announcements.count(reads.length > 0 ? {
|
||||
const count = await Announcements.countBy(reads.length > 0 ? {
|
||||
id: Not(In(reads.map(read => read.announcementId))),
|
||||
} : {});
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
},
|
||||
|
||||
public async getHasUnreadAntenna(userId: User['id']): Promise<boolean> {
|
||||
async getHasUnreadAntenna(userId: User['id']): Promise<boolean> {
|
||||
const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
|
||||
|
||||
const unread = myAntennas.length > 0 ? await AntennaNotes.findOne({
|
||||
const unread = myAntennas.length > 0 ? await AntennaNotes.findOneBy({
|
||||
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 });
|
||||
async getHasUnreadChannel(userId: User['id']): Promise<boolean> {
|
||||
const channels = await ChannelFollowings.findBy({ followerId: userId });
|
||||
|
||||
const unread = channels.length > 0 ? await NoteUnreads.findOne({
|
||||
const unread = channels.length > 0 ? await NoteUnreads.findOneBy({
|
||||
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({
|
||||
async getHasUnreadNotification(userId: User['id']): Promise<boolean> {
|
||||
const mute = await Mutings.findBy({
|
||||
muterId: userId,
|
||||
});
|
||||
const mutedUserIds = mute.map(m => m.muteeId);
|
||||
@ -164,17 +183,17 @@ export class UserRepository extends Repository<User> {
|
||||
});
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
},
|
||||
|
||||
public async getHasPendingReceivedFollowRequest(userId: User['id']): Promise<boolean> {
|
||||
const count = await FollowRequests.count({
|
||||
async getHasPendingReceivedFollowRequest(userId: User['id']): Promise<boolean> {
|
||||
const count = await FollowRequests.countBy({
|
||||
followeeId: userId,
|
||||
});
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
},
|
||||
|
||||
public getOnlineStatus(user: User): 'unknown' | 'online' | 'active' | 'offline' {
|
||||
getOnlineStatus(user: User): 'unknown' | 'online' | 'active' | 'offline' {
|
||||
if (user.hideOnlineStatus) return 'unknown';
|
||||
if (user.lastActiveDate == null) return 'unknown';
|
||||
const elapsed = Date.now() - user.lastActiveDate.getTime();
|
||||
@ -183,22 +202,22 @@ export class UserRepository extends Repository<User> {
|
||||
elapsed < USER_ACTIVE_THRESHOLD ? 'active' :
|
||||
'offline'
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
public getAvatarUrl(user: User): string {
|
||||
getAvatarUrl(user: User): string {
|
||||
// TODO: avatarIdがあるがavatarがない(JOINされてない)場合のハンドリング
|
||||
if (user.avatar) {
|
||||
return DriveFiles.getPublicUrl(user.avatar, true) || this.getIdenticonUrl(user.id);
|
||||
} else {
|
||||
return this.getIdenticonUrl(user.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
public getIdenticonUrl(userId: User['id']): string {
|
||||
getIdenticonUrl(userId: User['id']): string {
|
||||
return `${config.url}/identicon/${userId}`;
|
||||
}
|
||||
},
|
||||
|
||||
public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>(
|
||||
async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>(
|
||||
src: User['id'] | User,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -215,11 +234,15 @@ export class UserRepository extends Repository<User> {
|
||||
|
||||
if (typeof src === 'object') {
|
||||
user = src;
|
||||
if (src.avatar === undefined && src.avatarId) src.avatar = await DriveFiles.findOne(src.avatarId) ?? null;
|
||||
if (src.banner === undefined && src.bannerId) src.banner = await DriveFiles.findOne(src.bannerId) ?? null;
|
||||
if (src.avatar === undefined && src.avatarId) src.avatar = await DriveFiles.findOneBy({ id: src.avatarId }) ?? null;
|
||||
if (src.banner === undefined && src.bannerId) src.banner = await DriveFiles.findOneBy({ id: src.bannerId }) ?? null;
|
||||
} else {
|
||||
user = await this.findOneOrFail(src, {
|
||||
relations: ['avatar', 'banner'],
|
||||
user = await this.findOneOrFail({
|
||||
where: { id: src },
|
||||
relations: {
|
||||
avatar: true,
|
||||
banner: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -232,7 +255,7 @@ export class UserRepository extends Repository<User> {
|
||||
.innerJoinAndSelect('pin.note', 'note')
|
||||
.orderBy('pin.id', 'DESC')
|
||||
.getMany() : [];
|
||||
const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null;
|
||||
const profile = opts.detail ? await UserProfiles.findOneByOrFail({ userId: user.id }) : null;
|
||||
|
||||
const followingCount = profile == null ? null :
|
||||
(profile.ffVisibility === 'public') || isMe ? user.followingCount :
|
||||
@ -258,9 +281,8 @@ export class UserRepository extends Repository<User> {
|
||||
isModerator: user.isModerator || falsy,
|
||||
isBot: user.isBot || falsy,
|
||||
isCat: user.isCat || falsy,
|
||||
// TODO: typeorm 3.0にしたら .then(x => x || null) は消せる
|
||||
instance: user.host ? userInstanceCache.fetch(user.host,
|
||||
() => Instances.findOne({ host: user.host }).then(x => x || null),
|
||||
() => Instances.findOneBy({ host: user.host! }),
|
||||
v => v != null
|
||||
).then(instance => instance ? {
|
||||
name: instance.name,
|
||||
@ -304,7 +326,7 @@ export class UserRepository extends Repository<User> {
|
||||
twoFactorEnabled: profile!.twoFactorEnabled,
|
||||
usePasswordLessLogin: profile!.usePasswordLessLogin,
|
||||
securityKeys: profile!.twoFactorEnabled
|
||||
? UserSecurityKeys.count({
|
||||
? UserSecurityKeys.countBy({
|
||||
userId: user.id,
|
||||
}).then(result => result >= 1)
|
||||
: false,
|
||||
@ -352,7 +374,11 @@ export class UserRepository extends Repository<User> {
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
select: ['id', 'name', 'lastUsed'],
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
lastUsed: true,
|
||||
},
|
||||
})
|
||||
: [],
|
||||
} : {}),
|
||||
@ -369,9 +395,9 @@ export class UserRepository extends Repository<User> {
|
||||
} as Promiseable<Packed<'User'>> as Promiseable<IsMeAndIsUserDetailed<ExpectsMe, D>>;
|
||||
|
||||
return await awaitAll(packed);
|
||||
}
|
||||
},
|
||||
|
||||
public packMany<D extends boolean = false>(
|
||||
packMany<D extends boolean = false>(
|
||||
users: (User['id'] | User)[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
@ -380,17 +406,8 @@ export class UserRepository extends Repository<User> {
|
||||
}
|
||||
): Promise<IsUserDetailed<D>[]> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
isLocalUser,
|
||||
isRemoteUser,
|
||||
});
|
||||
|
Reference in New Issue
Block a user