Merge remote-tracking branch 'mi-dev/develop' into emoji-request

This commit is contained in:
mattyatea 2023-10-16 21:01:02 +09:00
commit c59a31375e
No known key found for this signature in database
GPG Key ID: 068E54E2C33BEF9A
196 changed files with 607 additions and 712 deletions

View File

@ -15,13 +15,13 @@
## 2023.x.x (unreleased) ## 2023.x.x (unreleased)
### General ### General
- - Feat: アンテナでローカルの投稿のみ収集できるようになりました
### Client ### Client
- Enhance: TLの返信表示オプションを記憶するように - Enhance: TLの返信表示オプションを記憶するように
### Server ### Server
- - Enhance: ストリーミングAPIのパフォーマンスを向上
## 2023.10.1 ## 2023.10.1
### General ### General
@ -42,6 +42,7 @@
### NOTE ### NOTE
- 2023.9.2で導入されたノート編集機能はクオリティの高い実装が困難であることが判明したため撤回されました - 2023.9.2で導入されたノート編集機能はクオリティの高い実装が困難であることが判明したため撤回されました
- アップデートを行うと、タイムラインが一時的にリセットされます - アップデートを行うと、タイムラインが一時的にリセットされます
- アンテナ内のノートも含む
- ソフトミュート設定はクライアントではなくサーバー側に保存されるようになったため、アップデートを行うとソフトミュートの設定がリセットされます - ソフトミュート設定はクライアントではなくサーバー側に保存されるようになったため、アップデートを行うとソフトミュートの設定がリセットされます
### Changes ### Changes

View File

@ -0,0 +1,144 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class DeleteCreatedAt1697420555911 {
name = 'DeleteCreatedAt1697420555911'
async up(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_02878d441ceae15ce060b73daf"`);
await queryRunner.query(`DROP INDEX "public"."IDX_c8dfad3b72196dd1d6b5db168a"`);
await queryRunner.query(`DROP INDEX "public"."IDX_e11e649824a45d8ed01d597fd9"`);
await queryRunner.query(`DROP INDEX "public"."IDX_db2098070b2b5a523c58181f74"`);
await queryRunner.query(`DROP INDEX "public"."IDX_048a757923ed8b157e9895da53"`);
await queryRunner.query(`DROP INDEX "public"."IDX_1129c2ef687fc272df040bafaa"`);
await queryRunner.query(`DROP INDEX "public"."IDX_118ec703e596086fc4515acb39"`);
await queryRunner.query(`DROP INDEX "public"."IDX_b9a354f7941c1e779f3b33aea6"`);
await queryRunner.query(`DROP INDEX "public"."IDX_71cb7b435b7c0d4843317e7e16"`);
await queryRunner.query(`DROP INDEX "public"."IDX_11e71f2511589dcc8a4d3214f9"`);
await queryRunner.query(`DROP INDEX "public"."IDX_735a5544f9249d412255f47f95"`);
await queryRunner.query(`DROP INDEX "public"."IDX_582f8fab771a9040a12961f3e7"`);
await queryRunner.query(`DROP INDEX "public"."IDX_8f1a239bd077c8864a20c62c2c"`);
await queryRunner.query(`DROP INDEX "public"."IDX_f86d57fbca33c7a4e6897490cc"`);
await queryRunner.query(`DROP INDEX "public"."IDX_d1259a2c2b7bb413ff449e8711"`);
await queryRunner.query(`DROP INDEX "public"."IDX_fbb4297c927a9b85e9cefa2eb1"`);
await queryRunner.query(`DROP INDEX "public"."IDX_0fb627e1c2f753262a74f0562d"`);
await queryRunner.query(`DROP INDEX "public"."IDX_149d2e44785707548c82999b01"`);
await queryRunner.query(`ALTER TABLE "drive_folder" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "drive_file" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "app" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "announcement_read" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user_list" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "auth_session" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "blocking" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "channel" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "channel_favorite" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "clip" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "clip_favorite" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "following" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "follow_request" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "gallery_post" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "gallery_like" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "moderation_log" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "muting" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "renote_muting" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "note_favorite" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "note_reaction" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "note_thread_muting" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "page_like" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "password_reset_request" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "poll_vote" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "promo_read" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "registration_ticket" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "signin" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "sw_subscription" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user_list_favorite" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user_list_membership" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user_note_pining" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "user_pending" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "webhook" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "role_assignment" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "flash" DROP COLUMN "createdAt"`);
await queryRunner.query(`ALTER TABLE "flash_like" DROP COLUMN "createdAt"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "flash_like" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "flash" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "role_assignment" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "role" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "webhook" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user_pending" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user_note_pining" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user_list_membership" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user_list_favorite" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "sw_subscription" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "signin" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "registry_item" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "registration_ticket" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "promo_read" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "poll_vote" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "password_reset_request" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "page_like" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "page" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "note_thread_muting" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "note_reaction" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "note_favorite" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "renote_muting" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "muting" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "moderation_log" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "gallery_like" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "gallery_post" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "follow_request" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "following" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "clip_favorite" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "note" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "clip" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "channel_favorite" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "channel_following" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "channel" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "blocking" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "auth_session" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "antenna" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user_list" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "announcement_read" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "announcement" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "ad" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "access_token" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "app" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "user" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "drive_file" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`ALTER TABLE "drive_folder" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
await queryRunner.query(`CREATE INDEX "IDX_149d2e44785707548c82999b01" ON "flash" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_0fb627e1c2f753262a74f0562d" ON "poll_vote" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_fbb4297c927a9b85e9cefa2eb1" ON "page" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_d1259a2c2b7bb413ff449e8711" ON "renote_muting" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_f86d57fbca33c7a4e6897490cc" ON "muting" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_8f1a239bd077c8864a20c62c2c" ON "gallery_post" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_582f8fab771a9040a12961f3e7" ON "following" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_735a5544f9249d412255f47f95" ON "channel_favorite" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_11e71f2511589dcc8a4d3214f9" ON "channel_following" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_71cb7b435b7c0d4843317e7e16" ON "channel" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_b9a354f7941c1e779f3b33aea6" ON "blocking" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_118ec703e596086fc4515acb39" ON "announcement" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_1129c2ef687fc272df040bafaa" ON "ad" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_048a757923ed8b157e9895da53" ON "app" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_db2098070b2b5a523c58181f74" ON "abuse_user_report" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_e11e649824a45d8ed01d597fd9" ON "user" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_c8dfad3b72196dd1d6b5db168a" ON "drive_file" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_02878d441ceae15ce060b73daf" ON "drive_folder" ("createdAt") `);
}
}

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class AntennaLocalOnly1697436246389 {
name = 'AntennaLocalOnly1697436246389'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "antenna" ADD "localOnly" boolean NOT NULL DEFAULT false`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "localOnly"`);
}
}

View File

@ -180,13 +180,13 @@ export class AccountMoveService {
{ muteeId: dst.id, expiresAt: IsNull() }, { muteeId: dst.id, expiresAt: IsNull() },
).then(mutings => mutings.map(muting => muting.muterId)); ).then(mutings => mutings.map(muting => muting.muterId));
const newMutings: Map<string, { muterId: string; muteeId: string; createdAt: Date; expiresAt: Date | null; }> = new Map(); const newMutings: Map<string, { muterId: string; muteeId: string; expiresAt: Date | null; }> = new Map();
// 重複しないようにIDを生成 // 重複しないようにIDを生成
const genId = (): string => { const genId = (): string => {
let id: string; let id: string;
do { do {
id = this.idService.genId(); id = this.idService.gen();
} while (newMutings.has(id)); } while (newMutings.has(id));
return id; return id;
}; };
@ -194,7 +194,6 @@ export class AccountMoveService {
if (existingMutingsMuterUserIds.includes(muting.muterId)) continue; // skip if already muted indefinitely if (existingMutingsMuterUserIds.includes(muting.muterId)) continue; // skip if already muted indefinitely
newMutings.set(genId(), { newMutings.set(genId(), {
...muting, ...muting,
createdAt: new Date(),
muteeId: dst.id, muteeId: dst.id,
}); });
} }
@ -228,20 +227,19 @@ export class AccountMoveService {
}, },
}).then(memberships => memberships.map(membership => membership.userListId)); }).then(memberships => memberships.map(membership => membership.userListId));
const newMemberships: Map<string, { createdAt: Date; userId: string; userListId: string; userListUserId: string; }> = new Map(); const newMemberships: Map<string, { userId: string; userListId: string; userListUserId: string; }> = new Map();
// 重複しないようにIDを生成 // 重複しないようにIDを生成
const genId = (): string => { const genId = (): string => {
let id: string; let id: string;
do { do {
id = this.idService.genId(); id = this.idService.gen();
} while (newMemberships.has(id)); } while (newMemberships.has(id));
return id; return id;
}; };
for (const membership of oldMemberships) { for (const membership of oldMemberships) {
if (existingUserListIds.includes(membership.userListId)) continue; // skip if dst exists in this user's list if (existingUserListIds.includes(membership.userListId)) continue; // skip if dst exists in this user's list
newMemberships.set(genId(), { newMemberships.set(genId(), {
createdAt: new Date(),
userId: dst.id, userId: dst.id,
userListId: membership.userListId, userListId: membership.userListId,
userListUserId: membership.userListUserId, userListUserId: membership.userListUserId,

View File

@ -53,7 +53,7 @@ export class AnnouncementService {
})) }))
.andWhere(new Brackets(qb => { .andWhere(new Brackets(qb => {
qb.orWhere('announcement.forExistingUsers = false'); qb.orWhere('announcement.forExistingUsers = false');
qb.orWhere('announcement.createdAt > :createdAt', { createdAt: user.createdAt }); qb.orWhere('announcement.id > :userId', { userId: user.id });
})) }))
.andWhere(`announcement.id NOT IN (${ readsQuery.getQuery() })`); .andWhere(`announcement.id NOT IN (${ readsQuery.getQuery() })`);
@ -65,8 +65,7 @@ export class AnnouncementService {
@bindThis @bindThis
public async create(values: Partial<MiAnnouncement>, moderator?: MiUser): Promise<{ raw: MiAnnouncement; packed: Packed<'Announcement'> }> { public async create(values: Partial<MiAnnouncement>, moderator?: MiUser): Promise<{ raw: MiAnnouncement; packed: Packed<'Announcement'> }> {
const announcement = await this.announcementsRepository.insert({ const announcement = await this.announcementsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
updatedAt: null, updatedAt: null,
title: values.title, title: values.title,
text: values.text, text: values.text,
@ -179,8 +178,7 @@ export class AnnouncementService {
public async read(user: MiUser, announcementId: MiAnnouncement['id']): Promise<void> { public async read(user: MiUser, announcementId: MiAnnouncement['id']): Promise<void> {
try { try {
await this.announcementReadsRepository.insert({ await this.announcementReadsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
announcementId: announcementId, announcementId: announcementId,
userId: user.id, userId: user.id,
}); });
@ -204,7 +202,7 @@ export class AnnouncementService {
const reads = me ? (options?.reads ?? await this.getReads(me.id)) : []; const reads = me ? (options?.reads ?? await this.getReads(me.id)) : [];
return announcements.map(announcement => ({ return announcements.map(announcement => ({
id: announcement.id, id: announcement.id,
createdAt: announcement.createdAt.toISOString(), createdAt: this.idService.parse(announcement.id).date.toISOString(),
updatedAt: announcement.updatedAt?.toISOString() ?? null, updatedAt: announcement.updatedAt?.toISOString() ?? null,
text: announcement.text, text: announcement.text,
title: announcement.title, title: announcement.title,

View File

@ -57,14 +57,12 @@ export class AntennaService implements OnApplicationShutdown {
case 'antennaCreated': case 'antennaCreated':
this.antennas.push({ this.antennas.push({
...body, ...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt), lastUsedAt: new Date(body.lastUsedAt),
}); });
break; break;
case 'antennaUpdated': case 'antennaUpdated':
this.antennas[this.antennas.findIndex(a => a.id === body.id)] = { this.antennas[this.antennas.findIndex(a => a.id === body.id)] = {
...body, ...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt), lastUsedAt: new Date(body.lastUsedAt),
}; };
break; break;
@ -100,6 +98,8 @@ export class AntennaService implements OnApplicationShutdown {
if (note.visibility === 'specified') return false; if (note.visibility === 'specified') return false;
if (note.visibility === 'followers') return false; if (note.visibility === 'followers') return false;
if (antenna.localOnly && noteUser.host != null) return false;
if (!antenna.withReplies && note.replyId != null) return false; if (!antenna.withReplies && note.replyId != null) return false;
if (antenna.src === 'home') { if (antenna.src === 'home') {

View File

@ -46,8 +46,7 @@ export class ClipService {
} }
const clip = await this.clipsRepository.insert({ const clip = await this.clipsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
userId: me.id, userId: me.id,
name: name, name: name,
isPublic: isPublic, isPublic: isPublic,
@ -109,7 +108,7 @@ export class ClipService {
try { try {
await this.clipNotesRepository.insert({ await this.clipNotesRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
noteId: noteId, noteId: noteId,
clipId: clip.id, clipId: clip.id,
}); });

View File

@ -52,8 +52,7 @@ export class CreateSystemUserService {
if (exist) throw new Error('the user is already exists'); if (exist) throw new Error('the user is already exists');
account = await transactionalEntityManager.insert(MiUser, { account = await transactionalEntityManager.insert(MiUser, {
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
username: username, username: username,
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
host: null, host: null,

View File

@ -68,7 +68,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][]; roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][];
}, moderator?: MiUser): Promise<MiEmoji> { }, moderator?: MiUser): Promise<MiEmoji> {
const emoji = await this.emojisRepository.insert({ const emoji = await this.emojisRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
updatedAt: new Date(), updatedAt: new Date(),
name: data.name, name: data.name,
category: data.category, category: data.category,

View File

@ -564,8 +564,7 @@ export class DriveService {
const folder = await fetchFolder(); const folder = await fetchFolder();
let file = new MiDriveFile(); let file = new MiDriveFile();
file.id = this.idService.genId(); file.id = this.idService.gen();
file.createdAt = new Date();
file.userId = user ? user.id : null; file.userId = user ? user.id : null;
file.userHost = user ? user.host : null; file.userHost = user ? user.host : null;
file.folderId = folder !== null ? folder.id : null; file.folderId = folder !== null ? folder.id : null;

View File

@ -56,7 +56,7 @@ export class FederatedInstanceService implements OnApplicationShutdown {
if (index == null) { if (index == null) {
const i = await this.instancesRepository.insert({ const i = await this.instancesRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
host, host,
firstRetrievedAt: new Date(), firstRetrievedAt: new Date(),
}).then(x => this.instancesRepository.findOneByOrFail(x.identifiers[0])); }).then(x => this.instancesRepository.findOneByOrFail(x.identifiers[0]));

View File

@ -120,7 +120,7 @@ export class HashtagService {
} else { } else {
if (isUserAttached) { if (isUserAttached) {
this.hashtagsRepository.insert({ this.hashtagsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
name: tag, name: tag,
mentionedUserIds: [], mentionedUserIds: [],
mentionedUsersCount: 0, mentionedUsersCount: 0,
@ -137,7 +137,7 @@ export class HashtagService {
} as MiHashtag); } as MiHashtag);
} else { } else {
this.hashtagsRepository.insert({ this.hashtagsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
name: tag, name: tag,
mentionedUserIds: [user.id], mentionedUserIds: [user.id],
mentionedUsersCount: 1, mentionedUsersCount: 1,

View File

@ -26,17 +26,21 @@ export class IdService {
this.method = config.id.toLowerCase(); this.method = config.id.toLowerCase();
} }
/**
* IDを生成します()
* @param time
*/
@bindThis @bindThis
public genId(date?: Date): string { public gen(time?: number): string {
if (!date || (date > new Date())) date = new Date(); const t = (!time || (time > Date.now())) ? Date.now() : time;
switch (this.method) { switch (this.method) {
case 'aid': return genAid(date); case 'aid': return genAid(t);
case 'aidx': return genAidx(date); case 'aidx': return genAidx(t);
case 'meid': return genMeid(date); case 'meid': return genMeid(t);
case 'meidg': return genMeidg(date); case 'meidg': return genMeidg(t);
case 'ulid': return ulid(date.getTime()); case 'ulid': return ulid(t);
case 'objectid': return genObjectId(date); case 'objectid': return genObjectId(t);
default: throw new Error('unrecognized id generation method'); default: throw new Error('unrecognized id generation method');
} }
} }

View File

@ -24,8 +24,7 @@ export class ModerationLogService {
@bindThis @bindThis
public async log<T extends typeof moderationLogTypes[number]>(moderator: { id: MiUser['id'] }, type: T, info?: ModerationLogPayloads[T]) { public async log<T extends typeof moderationLogTypes[number]>(moderator: { id: MiUser['id'] }, type: T, info?: ModerationLogPayloads[T]) {
await this.moderationLogsRepository.insert({ await this.moderationLogsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
userId: moderator.id, userId: moderator.id,
type: type, type: type,
info: (info as any) ?? {}, info: (info as any) ?? {},

View File

@ -55,6 +55,7 @@ import { MetaService } from '@/core/MetaService.js';
import { SearchService } from '@/core/SearchService.js'; import { SearchService } from '@/core/SearchService.js';
import { FeaturedService } from '@/core/FeaturedService.js'; import { FeaturedService } from '@/core/FeaturedService.js';
import { RedisTimelineService } from '@/core/RedisTimelineService.js'; import { RedisTimelineService } from '@/core/RedisTimelineService.js';
import { nyaize } from '@/misc/nyaize.js';
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
@ -221,9 +222,11 @@ export class NoteCreateService implements OnApplicationShutdown {
id: MiUser['id']; id: MiUser['id'];
username: MiUser['username']; username: MiUser['username'];
host: MiUser['host']; host: MiUser['host'];
createdAt: MiUser['createdAt'];
isBot: MiUser['isBot']; isBot: MiUser['isBot'];
isCat: MiUser['isCat'];
}, data: Option, silent = false): Promise<MiNote> { }, data: Option, silent = false): Promise<MiNote> {
let patsedText: mfm.MfmNode[] | null = null;
// チャンネル外にリプライしたら対象のスコープに合わせる // チャンネル外にリプライしたら対象のスコープに合わせる
// (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで)
if (data.reply && data.channel && data.reply.channelId !== data.channel.id) { if (data.reply && data.channel && data.reply.channelId !== data.channel.id) {
@ -302,6 +305,25 @@ export class NoteCreateService implements OnApplicationShutdown {
data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH); data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH);
} }
data.text = data.text.trim(); data.text = data.text.trim();
if (user.isCat) {
patsedText = patsedText ?? mfm.parse(data.text);
function nyaizeNode(node: mfm.MfmNode) {
if (node.type === 'quote') return;
if (node.type === 'text') {
node.props.text = nyaize(node.props.text);
}
if (node.children) {
for (const child of node.children) {
nyaizeNode(child);
}
}
}
for (const node of patsedText) {
nyaizeNode(node);
}
data.text = mfm.toString(patsedText);
}
} else { } else {
data.text = null; data.text = null;
} }
@ -312,7 +334,7 @@ export class NoteCreateService implements OnApplicationShutdown {
// Parse MFM if needed // Parse MFM if needed
if (!tags || !emojis || !mentionedUsers) { if (!tags || !emojis || !mentionedUsers) {
const tokens = data.text ? mfm.parse(data.text)! : []; const tokens = patsedText ?? (data.text ? mfm.parse(data.text)! : []);
const cwTokens = data.cw ? mfm.parse(data.cw)! : []; const cwTokens = data.cw ? mfm.parse(data.cw)! : [];
const choiceTokens = data.poll && data.poll.choices const choiceTokens = data.poll && data.poll.choices
? concat(data.poll.choices.map(choice => mfm.parse(choice)!)) ? concat(data.poll.choices.map(choice => mfm.parse(choice)!))
@ -360,8 +382,7 @@ export class NoteCreateService implements OnApplicationShutdown {
@bindThis @bindThis
private async insertNote(user: { id: MiUser['id']; host: MiUser['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) { private async insertNote(user: { id: MiUser['id']; host: MiUser['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) {
const insert = new MiNote({ const insert = new MiNote({
id: this.idService.genId(data.createdAt!), id: this.idService.gen(data.createdAt?.getTime()),
createdAt: data.createdAt!,
fileIds: data.files ? data.files.map(file => file.id) : [], fileIds: data.files ? data.files.map(file => file.id) : [],
replyId: data.reply ? data.reply.id : null, replyId: data.reply ? data.reply.id : null,
renoteId: data.renote ? data.renote.id : null, renoteId: data.renote ? data.renote.id : null,
@ -460,7 +481,6 @@ export class NoteCreateService implements OnApplicationShutdown {
id: MiUser['id']; id: MiUser['id'];
username: MiUser['username']; username: MiUser['username'];
host: MiUser['host']; host: MiUser['host'];
createdAt: MiUser['createdAt'];
isBot: MiUser['isBot']; isBot: MiUser['isBot'];
}, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) { }, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) {
const meta = await this.metaService.fetch(); const meta = await this.metaService.fetch();
@ -554,7 +574,7 @@ export class NoteCreateService implements OnApplicationShutdown {
} }
// Pack the note // Pack the note
const noteObj = await this.noteEntityService.pack(note); const noteObj = await this.noteEntityService.pack(note, null, { skipHide: true });
this.globalEventService.publishNotesStream(noteObj); this.globalEventService.publishNotesStream(noteObj);

View File

@ -71,8 +71,7 @@ export class NotePiningService {
} }
await this.userNotePiningsRepository.insert({ await this.userNotePiningsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
userId: user.id, userId: user.id,
noteId: note.id, noteId: note.id,
} as MiUserNotePining); } as MiUserNotePining);

View File

@ -57,7 +57,7 @@ export class NoteReadService implements OnApplicationShutdown {
if (isThreadMuted) return; if (isThreadMuted) return;
const unread = { const unread = {
id: this.idService.genId(), id: this.idService.gen(),
noteId: note.id, noteId: note.id,
userId: userId, userId: userId,
isSpecified: params.isSpecified, isSpecified: params.isSpecified,

View File

@ -125,7 +125,7 @@ export class NotificationService implements OnApplicationShutdown {
} }
const notification = { const notification = {
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(), createdAt: new Date(),
type: type, type: type,
notifierId: notifierId, notifierId: notifierId,

View File

@ -72,10 +72,8 @@ export class PollService {
throw new Error('already voted'); throw new Error('already voted');
} }
// Create vote
await this.pollVotesRepository.insert({ await this.pollVotesRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
noteId: note.id, noteId: note.id,
userId: user.id, userId: user.id,
choice: choice, choice: choice,

View File

@ -52,14 +52,14 @@ export class QueryService {
q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId }); q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId });
q.orderBy(`${q.alias}.id`, 'DESC'); q.orderBy(`${q.alias}.id`, 'DESC');
} else if (sinceDate && untilDate) { } else if (sinceDate && untilDate) {
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.genId(new Date(sinceDate)) }); q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.genId(new Date(untilDate)) }); q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.gen(untilDate) });
q.orderBy(`${q.alias}.id`, 'DESC'); q.orderBy(`${q.alias}.id`, 'DESC');
} else if (sinceDate) { } else if (sinceDate) {
q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.genId(new Date(sinceDate)) }); q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: this.idService.gen(sinceDate) });
q.orderBy(`${q.alias}.id`, 'ASC'); q.orderBy(`${q.alias}.id`, 'ASC');
} else if (untilDate) { } else if (untilDate) {
q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.genId(new Date(untilDate)) }); q.andWhere(`${q.alias}.id < :untilId`, { untilId: this.idService.gen(untilDate) });
q.orderBy(`${q.alias}.id`, 'DESC'); q.orderBy(`${q.alias}.id`, 'DESC');
} else { } else {
q.orderBy(`${q.alias}.id`, 'DESC'); q.orderBy(`${q.alias}.id`, 'DESC');

View File

@ -153,8 +153,7 @@ export class ReactionService {
} }
const record: MiNoteReaction = { const record: MiNoteReaction = {
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
noteId: note.id, noteId: note.id,
userId: user.id, userId: user.id,
reaction, reaction,

View File

@ -54,7 +54,7 @@ export class RelayService {
@bindThis @bindThis
public async addRelay(inbox: string): Promise<MiRelay> { public async addRelay(inbox: string): Promise<MiRelay> {
const relay = await this.relaysRepository.insert({ const relay = await this.relaysRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
inbox, inbox,
status: 'requesting', status: 'requesting',
}).then(x => this.relaysRepository.findOneByOrFail(x.identifiers[0])); }).then(x => this.relaysRepository.findOneByOrFail(x.identifiers[0]));

View File

@ -127,7 +127,6 @@ export class RoleService implements OnApplicationShutdown {
if (cached) { if (cached) {
cached.push({ cached.push({
...body, ...body,
createdAt: new Date(body.createdAt),
updatedAt: new Date(body.updatedAt), updatedAt: new Date(body.updatedAt),
lastUsedAt: new Date(body.lastUsedAt), lastUsedAt: new Date(body.lastUsedAt),
}); });
@ -141,7 +140,6 @@ export class RoleService implements OnApplicationShutdown {
if (i > -1) { if (i > -1) {
cached[i] = { cached[i] = {
...body, ...body,
createdAt: new Date(body.createdAt),
updatedAt: new Date(body.updatedAt), updatedAt: new Date(body.updatedAt),
lastUsedAt: new Date(body.lastUsedAt), lastUsedAt: new Date(body.lastUsedAt),
}; };
@ -161,7 +159,6 @@ export class RoleService implements OnApplicationShutdown {
if (cached) { if (cached) {
cached.push({ cached.push({
...body, ...body,
createdAt: new Date(body.createdAt),
expiresAt: body.expiresAt ? new Date(body.expiresAt) : null, expiresAt: body.expiresAt ? new Date(body.expiresAt) : null,
}); });
} }
@ -200,10 +197,10 @@ export class RoleService implements OnApplicationShutdown {
return this.userEntityService.isRemoteUser(user); return this.userEntityService.isRemoteUser(user);
} }
case 'createdLessThan': { case 'createdLessThan': {
return user.createdAt.getTime() > (Date.now() - (value.sec * 1000)); return this.idService.parse(user.id).date.getTime() > (Date.now() - (value.sec * 1000));
} }
case 'createdMoreThan': { case 'createdMoreThan': {
return user.createdAt.getTime() < (Date.now() - (value.sec * 1000)); return this.idService.parse(user.id).date.getTime() < (Date.now() - (value.sec * 1000));
} }
case 'followersLessThanOrEq': { case 'followersLessThanOrEq': {
return user.followersCount <= value.value; return user.followersCount <= value.value;
@ -385,7 +382,7 @@ export class RoleService implements OnApplicationShutdown {
@bindThis @bindThis
public async assign(userId: MiUser['id'], roleId: MiRole['id'], expiresAt: Date | null = null, moderator?: MiUser): Promise<void> { public async assign(userId: MiUser['id'], roleId: MiRole['id'], expiresAt: Date | null = null, moderator?: MiUser): Promise<void> {
const now = new Date(); const now = Date.now();
const role = await this.rolesRepository.findOneByOrFail({ id: roleId }); const role = await this.rolesRepository.findOneByOrFail({ id: roleId });
@ -395,7 +392,7 @@ export class RoleService implements OnApplicationShutdown {
}); });
if (existing) { if (existing) {
if (existing.expiresAt && (existing.expiresAt.getTime() < now.getTime())) { if (existing.expiresAt && (existing.expiresAt.getTime() < now)) {
await this.roleAssignmentsRepository.delete({ await this.roleAssignmentsRepository.delete({
roleId: roleId, roleId: roleId,
userId: userId, userId: userId,
@ -406,8 +403,7 @@ export class RoleService implements OnApplicationShutdown {
} }
const created = await this.roleAssignmentsRepository.insert({ const created = await this.roleAssignmentsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(now),
createdAt: now,
expiresAt: expiresAt, expiresAt: expiresAt,
roleId: roleId, roleId: roleId,
userId: userId, userId: userId,
@ -488,8 +484,7 @@ export class RoleService implements OnApplicationShutdown {
public async create(values: Partial<MiRole>, moderator?: MiUser): Promise<MiRole> { public async create(values: Partial<MiRole>, moderator?: MiUser): Promise<MiRole> {
const date = new Date(); const date = new Date();
const created = await this.rolesRepository.insert({ const created = await this.rolesRepository.insert({
id: this.idService.genId(), id: this.idService.gen(date.getTime()),
createdAt: date,
updatedAt: date, updatedAt: date,
lastUsedAt: date, lastUsedAt: date,
name: values.name, name: values.name,

View File

@ -131,7 +131,7 @@ export class SearchService {
await this.meilisearchNoteIndex?.addDocuments([{ await this.meilisearchNoteIndex?.addDocuments([{
id: note.id, id: note.id,
createdAt: note.createdAt.getTime(), createdAt: this.idService.parse(note.id).date.getTime(),
userId: note.userId, userId: note.userId,
userHost: note.userHost, userHost: note.userHost,
channelId: note.channelId, channelId: note.channelId,

View File

@ -120,8 +120,7 @@ export class SignupService {
if (exist) throw new Error(' the username is already used'); if (exist) throw new Error(' the username is already used');
account = await transactionalEntityManager.save(new MiUser({ account = await transactionalEntityManager.save(new MiUser({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
username: username, username: username,
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
host: this.utilityService.toPunyNullable(host), host: this.utilityService.toPunyNullable(host),

View File

@ -68,8 +68,7 @@ export class UserBlockingService implements OnModuleInit {
]); ]);
const blocking = { const blocking = {
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
blocker, blocker,
blockerId: blocker.id, blockerId: blocker.id,
blockee, blockee,

View File

@ -205,8 +205,7 @@ export class UserFollowingService implements OnModuleInit {
let alreadyFollowed = false as boolean; let alreadyFollowed = false as boolean;
await this.followingsRepository.insert({ await this.followingsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
followerId: follower.id, followerId: follower.id,
followeeId: followee.id, followeeId: followee.id,
@ -488,8 +487,7 @@ export class UserFollowingService implements OnModuleInit {
if (blocked) throw new Error('blocked'); if (blocked) throw new Error('blocked');
const followRequest = await this.followRequestsRepository.insert({ const followRequest = await this.followRequestsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
followerId: follower.id, followerId: follower.id,
followeeId: followee.id, followeeId: followee.id,
requestId, requestId,

View File

@ -93,8 +93,7 @@ export class UserListService implements OnApplicationShutdown {
} }
await this.userListMembershipsRepository.insert({ await this.userListMembershipsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
userId: target.id, userId: target.id,
userListId: list.id, userListId: list.id,
userListUserId: list.userId, userListUserId: list.userId,

View File

@ -26,8 +26,7 @@ export class UserMutingService {
@bindThis @bindThis
public async mute(user: MiUser, target: MiUser, expiresAt: Date | null = null): Promise<void> { public async mute(user: MiUser, target: MiUser, expiresAt: Date | null = null): Promise<void> {
await this.mutingsRepository.insert({ await this.mutingsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
expiresAt: expiresAt ?? null, expiresAt: expiresAt ?? null,
muterId: user.id, muterId: user.id,
muteeId: target.id, muteeId: target.id,

View File

@ -51,7 +51,6 @@ export class WebhookService implements OnApplicationShutdown {
if (body.active) { if (body.active) {
this.webhooks.push({ this.webhooks.push({
...body, ...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
}); });
} }
@ -62,13 +61,11 @@ export class WebhookService implements OnApplicationShutdown {
if (i > -1) { if (i > -1) {
this.webhooks[i] = { this.webhooks[i] = {
...body, ...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
}; };
} else { } else {
this.webhooks.push({ this.webhooks.push({
...body, ...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null, latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
}); });
} }

View File

@ -514,8 +514,7 @@ export class ApInboxService {
if (users.length < 1) return 'skip'; if (users.length < 1) return 'skip';
await this.abuseUserReportsRepository.insert({ await this.abuseUserReportsRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
createdAt: new Date(),
targetUserId: users[0].id, targetUserId: users[0].id,
targetUserHost: users[0].host, targetUserHost: users[0].host,
reporterId: actor.id, reporterId: actor.id,

View File

@ -27,6 +27,7 @@ import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFil
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { isNotNull } from '@/misc/is-not-null.js'; import { isNotNull } from '@/misc/is-not-null.js';
import { IdService } from '@/core/IdService.js';
import { LdSignatureService } from './LdSignatureService.js'; import { LdSignatureService } from './LdSignatureService.js';
import { ApMfmService } from './ApMfmService.js'; import { ApMfmService } from './ApMfmService.js';
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js'; import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';
@ -59,6 +60,7 @@ export class ApRendererService {
private userKeypairService: UserKeypairService, private userKeypairService: UserKeypairService,
private apMfmService: ApMfmService, private apMfmService: ApMfmService,
private mfmService: MfmService, private mfmService: MfmService,
private idService: IdService,
) { ) {
} }
@ -105,7 +107,7 @@ export class ApRendererService {
id: `${this.config.url}/notes/${note.id}/activity`, id: `${this.config.url}/notes/${note.id}/activity`,
actor: this.userEntityService.genLocalUserUri(note.userId), actor: this.userEntityService.genLocalUserUri(note.userId),
type: 'Announce', type: 'Announce',
published: note.createdAt.toISOString(), published: this.idService.parse(note.id).date.toISOString(),
to, to,
cc, cc,
object, object,
@ -137,7 +139,7 @@ export class ApRendererService {
id: `${this.config.url}/notes/${note.id}/activity`, id: `${this.config.url}/notes/${note.id}/activity`,
actor: this.userEntityService.genLocalUserUri(note.userId), actor: this.userEntityService.genLocalUserUri(note.userId),
type: 'Create', type: 'Create',
published: note.createdAt.toISOString(), published: this.idService.parse(note.id).date.toISOString(),
object, object,
}; };
@ -437,7 +439,7 @@ export class ApRendererService {
}, },
_misskey_quote: quote, _misskey_quote: quote,
quoteUrl: quote, quoteUrl: quote,
published: note.createdAt.toISOString(), published: this.idService.parse(note.id).date.toISOString(),
to, to,
cc, cc,
inReplyTo, inReplyTo,

View File

@ -386,7 +386,7 @@ export class ApNoteService {
this.logger.info(`register emoji host=${host}, name=${name}`); this.logger.info(`register emoji host=${host}, name=${name}`);
return await this.emojisRepository.insert({ return await this.emojisRepository.insert({
id: this.idService.genId(), id: this.idService.gen(),
host, host,
name, name,
uri: tag.id, uri: tag.id,

View File

@ -295,10 +295,9 @@ export class ApPersonService implements OnModuleInit {
// Start transaction // Start transaction
await this.db.transaction(async transactionalEntityManager => { await this.db.transaction(async transactionalEntityManager => {
user = await transactionalEntityManager.save(new MiUser({ user = await transactionalEntityManager.save(new MiUser({
id: this.idService.genId(), id: this.idService.gen(),
avatarId: null, avatarId: null,
bannerId: null, bannerId: null,
createdAt: new Date(),
lastFetchedAt: new Date(), lastFetchedAt: new Date(),
name: truncate(person.name, nameLength), name: truncate(person.name, nameLength),
isLocked: person.manuallyApprovesFollowers, isLocked: person.manuallyApprovesFollowers,
@ -607,8 +606,7 @@ export class ApPersonService implements OnModuleInit {
for (const note of featuredNotes.filter((note): note is MiNote => note != null)) { for (const note of featuredNotes.filter((note): note is MiNote => note != null)) {
td -= 1000; td -= 1000;
transactionalEntityManager.insert(MiUserNotePining, { transactionalEntityManager.insert(MiUserNotePining, {
id: this.idService.genId(new Date(Date.now() + td)), id: this.idService.gen(Date.now() + td),
createdAt: new Date(),
userId: user.id, userId: user.id,
noteId: note.id, noteId: note.id,
}); });

View File

@ -9,6 +9,7 @@ import { AppLockService } from '@/core/AppLockService.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import Chart from '../core.js'; import Chart from '../core.js';
import { ChartLoggerService } from '../ChartLoggerService.js'; import { ChartLoggerService } from '../ChartLoggerService.js';
import { name, schema } from './entities/active-users.js'; import { name, schema } from './entities/active-users.js';
@ -29,6 +30,7 @@ export default class ActiveUsersChart extends Chart<typeof schema> { // eslint-d
private appLockService: AppLockService, private appLockService: AppLockService,
private chartLoggerService: ChartLoggerService, private chartLoggerService: ChartLoggerService,
private idService: IdService,
) { ) {
super(db, (k) => appLockService.getChartInsertLock(k), chartLoggerService.logger, name, schema); super(db, (k) => appLockService.getChartInsertLock(k), chartLoggerService.logger, name, schema);
} }
@ -42,20 +44,21 @@ export default class ActiveUsersChart extends Chart<typeof schema> { // eslint-d
} }
@bindThis @bindThis
public async read(user: { id: MiUser['id'], host: null, createdAt: MiUser['createdAt'] }): Promise<void> { public async read(user: { id: MiUser['id'], host: null }): Promise<void> {
const createdAt = this.idService.parse(user.id).date;
await this.commit({ await this.commit({
'read': [user.id], 'read': [user.id],
'registeredWithinWeek': (Date.now() - user.createdAt.getTime() < week) ? [user.id] : [], 'registeredWithinWeek': (Date.now() - createdAt.getTime() < week) ? [user.id] : [],
'registeredWithinMonth': (Date.now() - user.createdAt.getTime() < month) ? [user.id] : [], 'registeredWithinMonth': (Date.now() - createdAt.getTime() < month) ? [user.id] : [],
'registeredWithinYear': (Date.now() - user.createdAt.getTime() < year) ? [user.id] : [], 'registeredWithinYear': (Date.now() - createdAt.getTime() < year) ? [user.id] : [],
'registeredOutsideWeek': (Date.now() - user.createdAt.getTime() > week) ? [user.id] : [], 'registeredOutsideWeek': (Date.now() - createdAt.getTime() > week) ? [user.id] : [],
'registeredOutsideMonth': (Date.now() - user.createdAt.getTime() > month) ? [user.id] : [], 'registeredOutsideMonth': (Date.now() - createdAt.getTime() > month) ? [user.id] : [],
'registeredOutsideYear': (Date.now() - user.createdAt.getTime() > year) ? [user.id] : [], 'registeredOutsideYear': (Date.now() - createdAt.getTime() > year) ? [user.id] : [],
}); });
} }
@bindThis @bindThis
public async write(user: { id: MiUser['id'], host: null, createdAt: MiUser['createdAt'] }): Promise<void> { public async write(user: { id: MiUser['id'], host: null }): Promise<void> {
await this.commit({ await this.commit({
'write': [user.id], 'write': [user.id],
}); });

View File

@ -9,6 +9,7 @@ import type { AbuseUserReportsRepository } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js'; import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -18,6 +19,7 @@ export class AbuseUserReportEntityService {
private abuseUserReportsRepository: AbuseUserReportsRepository, private abuseUserReportsRepository: AbuseUserReportsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -29,7 +31,7 @@ export class AbuseUserReportEntityService {
return await awaitAll({ return await awaitAll({
id: report.id, id: report.id,
createdAt: report.createdAt.toISOString(), createdAt: this.idService.parse(report.id).date.toISOString(),
comment: report.comment, comment: report.comment,
resolved: report.resolved, resolved: report.resolved,
reporterId: report.reporterId, reporterId: report.reporterId,

View File

@ -9,12 +9,15 @@ import type { AntennasRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js'; import type { Packed } from '@/misc/json-schema.js';
import type { MiAntenna } from '@/models/Antenna.js'; import type { MiAntenna } from '@/models/Antenna.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
@Injectable() @Injectable()
export class AntennaEntityService { export class AntennaEntityService {
constructor( constructor(
@Inject(DI.antennasRepository) @Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository, private antennasRepository: AntennasRepository,
private idService: IdService,
) { ) {
} }
@ -26,7 +29,7 @@ export class AntennaEntityService {
return { return {
id: antenna.id, id: antenna.id,
createdAt: antenna.createdAt.toISOString(), createdAt: this.idService.parse(antenna.id).date.toISOString(),
name: antenna.name, name: antenna.name,
keywords: antenna.keywords, keywords: antenna.keywords,
excludeKeywords: antenna.excludeKeywords, excludeKeywords: antenna.excludeKeywords,
@ -34,6 +37,7 @@ export class AntennaEntityService {
userListId: antenna.userListId, userListId: antenna.userListId,
users: antenna.users, users: antenna.users,
caseSensitive: antenna.caseSensitive, caseSensitive: antenna.caseSensitive,
localOnly: antenna.localOnly,
notify: antenna.notify, notify: antenna.notify,
withReplies: antenna.withReplies, withReplies: antenna.withReplies,
withFile: antenna.withFile, withFile: antenna.withFile,

View File

@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { MiBlocking } from '@/models/Blocking.js'; import type { MiBlocking } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -20,6 +21,7 @@ export class BlockingEntityService {
private blockingsRepository: BlockingsRepository, private blockingsRepository: BlockingsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -32,7 +34,7 @@ export class BlockingEntityService {
return await awaitAll({ return await awaitAll({
id: blocking.id, id: blocking.id,
createdAt: blocking.createdAt.toISOString(), createdAt: this.idService.parse(blocking.id).date.toISOString(),
blockeeId: blocking.blockeeId, blockeeId: blocking.blockeeId,
blockee: this.userEntityService.pack(blocking.blockeeId, me, { blockee: this.userEntityService.pack(blocking.blockeeId, me, {
detail: true, detail: true,

View File

@ -11,6 +11,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiChannel } from '@/models/Channel.js'; import type { MiChannel } from '@/models/Channel.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { DriveFileEntityService } from './DriveFileEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js';
import { NoteEntityService } from './NoteEntityService.js'; import { NoteEntityService } from './NoteEntityService.js';
import { In } from 'typeorm'; import { In } from 'typeorm';
@ -38,6 +39,7 @@ export class ChannelEntityService {
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private driveFileEntityService: DriveFileEntityService, private driveFileEntityService: DriveFileEntityService,
private idService: IdService,
) { ) {
} }
@ -81,7 +83,7 @@ export class ChannelEntityService {
return { return {
id: channel.id, id: channel.id,
createdAt: channel.createdAt.toISOString(), createdAt: this.idService.parse(channel.id).date.toISOString(),
lastNotedAt: channel.lastNotedAt ? channel.lastNotedAt.toISOString() : null, lastNotedAt: channel.lastNotedAt ? channel.lastNotedAt.toISOString() : null,
name: channel.name, name: channel.name,
description: channel.description, description: channel.description,

View File

@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/Blocking.js'; import type { } from '@/models/Blocking.js';
import type { MiClip } from '@/models/Clip.js'; import type { MiClip } from '@/models/Clip.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -23,6 +24,7 @@ export class ClipEntityService {
private clipFavoritesRepository: ClipFavoritesRepository, private clipFavoritesRepository: ClipFavoritesRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -36,7 +38,7 @@ export class ClipEntityService {
return await awaitAll({ return await awaitAll({
id: clip.id, id: clip.id,
createdAt: clip.createdAt.toISOString(), createdAt: this.idService.parse(clip.id).date.toISOString(),
lastClippedAt: clip.lastClippedAt ? clip.lastClippedAt.toISOString() : null, lastClippedAt: clip.lastClippedAt ? clip.lastClippedAt.toISOString() : null,
userId: clip.userId, userId: clip.userId,
user: this.userEntityService.pack(clip.user ?? clip.userId), user: this.userEntityService.pack(clip.user ?? clip.userId),

View File

@ -17,6 +17,7 @@ import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { isMimeImage } from '@/misc/is-mime-image.js'; import { isMimeImage } from '@/misc/is-mime-image.js';
import { isNotNull } from '@/misc/is-not-null.js'; import { isNotNull } from '@/misc/is-not-null.js';
import { IdService } from '@/core/IdService.js';
import { UtilityService } from '../UtilityService.js'; import { UtilityService } from '../UtilityService.js';
import { VideoProcessingService } from '../VideoProcessingService.js'; import { VideoProcessingService } from '../VideoProcessingService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@ -44,6 +45,7 @@ export class DriveFileEntityService {
private utilityService: UtilityService, private utilityService: UtilityService,
private driveFolderEntityService: DriveFolderEntityService, private driveFolderEntityService: DriveFolderEntityService,
private videoProcessingService: VideoProcessingService, private videoProcessingService: VideoProcessingService,
private idService: IdService,
) { ) {
} }
@ -196,7 +198,7 @@ export class DriveFileEntityService {
return await awaitAll<Packed<'DriveFile'>>({ return await awaitAll<Packed<'DriveFile'>>({
id: file.id, id: file.id,
createdAt: file.createdAt.toISOString(), createdAt: this.idService.parse(file.id).date.toISOString(),
name: file.name, name: file.name,
type: file.type, type: file.type,
md5: file.md5, md5: file.md5,
@ -231,7 +233,7 @@ export class DriveFileEntityService {
return await awaitAll<Packed<'DriveFile'>>({ return await awaitAll<Packed<'DriveFile'>>({
id: file.id, id: file.id,
createdAt: file.createdAt.toISOString(), createdAt: this.idService.parse(file.id).date.toISOString(),
name: file.name, name: file.name,
type: file.type, type: file.type,
md5: file.md5, md5: file.md5,

View File

@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/Blocking.js'; import type { } from '@/models/Blocking.js';
import type { MiDriveFolder } from '@/models/DriveFolder.js'; import type { MiDriveFolder } from '@/models/DriveFolder.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
@Injectable() @Injectable()
export class DriveFolderEntityService { export class DriveFolderEntityService {
@ -20,6 +21,8 @@ export class DriveFolderEntityService {
@Inject(DI.driveFilesRepository) @Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository, private driveFilesRepository: DriveFilesRepository,
private idService: IdService,
) { ) {
} }
@ -38,7 +41,7 @@ export class DriveFolderEntityService {
return await awaitAll({ return await awaitAll({
id: folder.id, id: folder.id,
createdAt: folder.createdAt.toISOString(), createdAt: this.idService.parse(folder.id).date.toISOString(),
name: folder.name, name: folder.name,
parentId: folder.parentId, parentId: folder.parentId,

View File

@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiFlash } from '@/models/Flash.js'; import type { MiFlash } from '@/models/Flash.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -24,6 +25,7 @@ export class FlashEntityService {
private flashLikesRepository: FlashLikesRepository, private flashLikesRepository: FlashLikesRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -37,7 +39,7 @@ export class FlashEntityService {
return await awaitAll({ return await awaitAll({
id: flash.id, id: flash.id,
createdAt: flash.createdAt.toISOString(), createdAt: this.idService.parse(flash.id).date.toISOString(),
updatedAt: flash.updatedAt.toISOString(), updatedAt: flash.updatedAt.toISOString(),
userId: flash.userId, userId: flash.userId,
user: this.userEntityService.pack(flash.user ?? flash.userId, me), // { detail: true } すると無限ループするので注意 user: this.userEntityService.pack(flash.user ?? flash.userId, me), // { detail: true } すると無限ループするので注意

View File

@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiFollowing } from '@/models/Following.js'; import type { MiFollowing } from '@/models/Following.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
type LocalFollowerFollowing = MiFollowing & { type LocalFollowerFollowing = MiFollowing & {
@ -45,6 +46,7 @@ export class FollowingEntityService {
private followingsRepository: FollowingsRepository, private followingsRepository: FollowingsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -83,7 +85,7 @@ export class FollowingEntityService {
return await awaitAll({ return await awaitAll({
id: following.id, id: following.id,
createdAt: following.createdAt.toISOString(), createdAt: this.idService.parse(following.id).date.toISOString(),
followeeId: following.followeeId, followeeId: following.followeeId,
followerId: following.followerId, followerId: following.followerId,
followee: opts.populateFollowee ? this.userEntityService.pack(following.followee ?? following.followeeId, me, { followee: opts.populateFollowee ? this.userEntityService.pack(following.followee ?? following.followeeId, me, {

View File

@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiGalleryPost } from '@/models/GalleryPost.js'; import type { MiGalleryPost } from '@/models/GalleryPost.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
import { DriveFileEntityService } from './DriveFileEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js';
@ -26,6 +27,7 @@ export class GalleryPostEntityService {
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private driveFileEntityService: DriveFileEntityService, private driveFileEntityService: DriveFileEntityService,
private idService: IdService,
) { ) {
} }
@ -39,7 +41,7 @@ export class GalleryPostEntityService {
return await awaitAll({ return await awaitAll({
id: post.id, id: post.id,
createdAt: post.createdAt.toISOString(), createdAt: this.idService.parse(post.id).date.toISOString(),
updatedAt: post.updatedAt.toISOString(), updatedAt: post.updatedAt.toISOString(),
userId: post.userId, userId: post.userId,
user: this.userEntityService.pack(post.user ?? post.userId, me), user: this.userEntityService.pack(post.user ?? post.userId, me),

View File

@ -11,6 +11,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiRegistrationTicket } from '@/models/RegistrationTicket.js'; import type { MiRegistrationTicket } from '@/models/RegistrationTicket.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -20,6 +21,7 @@ export class InviteCodeEntityService {
private registrationTicketsRepository: RegistrationTicketsRepository, private registrationTicketsRepository: RegistrationTicketsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -39,7 +41,7 @@ export class InviteCodeEntityService {
id: target.id, id: target.id,
code: target.code, code: target.code,
expiresAt: target.expiresAt ? target.expiresAt.toISOString() : null, expiresAt: target.expiresAt ? target.expiresAt.toISOString() : null,
createdAt: target.createdAt.toISOString(), createdAt: this.idService.parse(target.id).date.toISOString(),
createdBy: target.createdBy ? await this.userEntityService.pack(target.createdBy, me) : null, createdBy: target.createdBy ? await this.userEntityService.pack(target.createdBy, me) : null,
usedBy: target.usedBy ? await this.userEntityService.pack(target.usedBy, me) : null, usedBy: target.usedBy ? await this.userEntityService.pack(target.usedBy, me) : null,
usedAt: target.usedAt ? target.usedAt.toISOString() : null, usedAt: target.usedAt ? target.usedAt.toISOString() : null,

View File

@ -10,6 +10,7 @@ import { awaitAll } from '@/misc/prelude/await-all.js';
import type { } from '@/models/Blocking.js'; import type { } from '@/models/Blocking.js';
import type { MiModerationLog } from '@/models/ModerationLog.js'; import type { MiModerationLog } from '@/models/ModerationLog.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -19,6 +20,7 @@ export class ModerationLogEntityService {
private moderationLogsRepository: ModerationLogsRepository, private moderationLogsRepository: ModerationLogsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -30,7 +32,7 @@ export class ModerationLogEntityService {
return await awaitAll({ return await awaitAll({
id: log.id, id: log.id,
createdAt: log.createdAt.toISOString(), createdAt: this.idService.parse(log.id).date.toISOString(),
type: log.type, type: log.type,
info: log.info, info: log.info,
userId: log.userId, userId: log.userId,

View File

@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiMuting } from '@/models/Muting.js'; import type { MiMuting } from '@/models/Muting.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -21,6 +22,7 @@ export class MutingEntityService {
private mutingsRepository: MutingsRepository, private mutingsRepository: MutingsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -33,7 +35,7 @@ export class MutingEntityService {
return await awaitAll({ return await awaitAll({
id: muting.id, id: muting.id,
createdAt: muting.createdAt.toISOString(), createdAt: this.idService.parse(muting.id).date.toISOString(),
expiresAt: muting.expiresAt ? muting.expiresAt.toISOString() : null, expiresAt: muting.expiresAt ? muting.expiresAt.toISOString() : null,
muteeId: muting.muteeId, muteeId: muting.muteeId,
mutee: this.userEntityService.pack(muting.muteeId, me, { mutee: this.userEntityService.pack(muting.muteeId, me, {

View File

@ -5,11 +5,9 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { In } from 'typeorm'; import { In } from 'typeorm';
import * as mfm from 'mfm-js';
import { ModuleRef } from '@nestjs/core'; import { ModuleRef } from '@nestjs/core';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Packed } from '@/misc/json-schema.js'; import type { Packed } from '@/misc/json-schema.js';
import { nyaize } from '@/misc/nyaize.js';
import { awaitAll } from '@/misc/prelude/await-all.js'; import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js'; import type { MiNote } from '@/models/Note.js';
@ -18,6 +16,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepos
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { isNotNull } from '@/misc/is-not-null.js'; import { isNotNull } from '@/misc/is-not-null.js';
import { DebounceLoader } from '@/misc/loader.js'; import { DebounceLoader } from '@/misc/loader.js';
import { IdService } from '@/core/IdService.js';
import type { OnModuleInit } from '@nestjs/common'; import type { OnModuleInit } from '@nestjs/common';
import type { CustomEmojiService } from '../CustomEmojiService.js'; import type { CustomEmojiService } from '../CustomEmojiService.js';
import type { ReactionService } from '../ReactionService.js'; import type { ReactionService } from '../ReactionService.js';
@ -30,6 +29,7 @@ export class NoteEntityService implements OnModuleInit {
private driveFileEntityService: DriveFileEntityService; private driveFileEntityService: DriveFileEntityService;
private customEmojiService: CustomEmojiService; private customEmojiService: CustomEmojiService;
private reactionService: ReactionService; private reactionService: ReactionService;
private idService: IdService;
private noteLoader = new DebounceLoader(this.findNoteOrFail); private noteLoader = new DebounceLoader(this.findNoteOrFail);
constructor( constructor(
@ -68,6 +68,7 @@ export class NoteEntityService implements OnModuleInit {
this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService'); this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService');
this.customEmojiService = this.moduleRef.get('CustomEmojiService'); this.customEmojiService = this.moduleRef.get('CustomEmojiService');
this.reactionService = this.moduleRef.get('ReactionService'); this.reactionService = this.moduleRef.get('ReactionService');
this.idService = this.moduleRef.get('IdService');
} }
@bindThis @bindThis
@ -169,11 +170,11 @@ export class NoteEntityService implements OnModuleInit {
} }
@bindThis @bindThis
private async populateMyReaction(note: MiNote, meId: MiUser['id'], _hint_?: { public async populateMyReaction(noteId: MiNote['id'], meId: MiUser['id'], _hint_?: {
myReactions: Map<MiNote['id'], MiNoteReaction | null>; myReactions: Map<MiNote['id'], MiNoteReaction | null>;
}) { }) {
if (_hint_?.myReactions) { if (_hint_?.myReactions) {
const reaction = _hint_.myReactions.get(note.id); const reaction = _hint_.myReactions.get(noteId);
if (reaction) { if (reaction) {
return this.reactionService.convertLegacyReaction(reaction.reaction); return this.reactionService.convertLegacyReaction(reaction.reaction);
} else if (reaction === null) { } else if (reaction === null) {
@ -182,14 +183,14 @@ export class NoteEntityService implements OnModuleInit {
// 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない // 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない
} }
// パフォーマンスのためノートが作成されてから1秒以上経っていない場合はリアクションを取得しない // パフォーマンスのためノートが作成されてから2秒以上経っていない場合はリアクションを取得しない
if (note.createdAt.getTime() + 1000 > Date.now()) { if (this.idService.parse(noteId).date.getTime() + 2000 > Date.now()) {
return undefined; return undefined;
} }
const reaction = await this.noteReactionsRepository.findOneBy({ const reaction = await this.noteReactionsRepository.findOneBy({
userId: meId, userId: meId,
noteId: note.id, noteId: noteId,
}); });
if (reaction) { if (reaction) {
@ -309,7 +310,7 @@ export class NoteEntityService implements OnModuleInit {
const packed: Packed<'Note'> = await awaitAll({ const packed: Packed<'Note'> = await awaitAll({
id: note.id, id: note.id,
createdAt: note.createdAt.toISOString(), createdAt: this.idService.parse(note.id).date.toISOString(),
userId: note.userId, userId: note.userId,
user: this.userEntityService.pack(note.user ?? note.userId, me, { user: this.userEntityService.pack(note.user ?? note.userId, me, {
detail: false, detail: false,
@ -357,30 +358,11 @@ export class NoteEntityService implements OnModuleInit {
poll: note.hasPoll ? this.populatePoll(note, meId) : undefined, poll: note.hasPoll ? this.populatePoll(note, meId) : undefined,
...(meId ? { ...(meId ? {
myReaction: this.populateMyReaction(note, meId, options?._hint_), myReaction: this.populateMyReaction(note.id, meId, options?._hint_),
} : {}), } : {}),
} : {}), } : {}),
}); });
if (packed.user.isCat && packed.text) {
const tokens = packed.text ? mfm.parse(packed.text) : [];
function nyaizeNode(node: mfm.MfmNode) {
if (node.type === 'quote') return;
if (node.type === 'text') {
node.props.text = nyaize(node.props.text);
}
if (node.children) {
for (const child of node.children) {
nyaizeNode(child);
}
}
}
for (const node of tokens) {
nyaizeNode(node);
}
packed.text = mfm.toString(tokens);
}
if (!opts.skipHide) { if (!opts.skipHide) {
await this.hideNote(packed, meId); await this.hideNote(packed, meId);
} }
@ -403,8 +385,9 @@ export class NoteEntityService implements OnModuleInit {
const myReactionsMap = new Map<MiNote['id'], MiNoteReaction | null>(); const myReactionsMap = new Map<MiNote['id'], MiNoteReaction | null>();
if (meId) { if (meId) {
const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!);
// パフォーマンスのためートが作成されてから1秒以上経っていない場合はリアクションを取得しない // パフォーマンスのためートが作成されてから2秒以上経っていない場合はリアクションを取得しない
const targets = [...notes.filter(n => n.createdAt.getTime() + 1000 < Date.now()).map(n => n.id), ...renoteIds]; const oldId = this.idService.gen(Date.now() - 2000);
const targets = [...notes.filter(n => n.id < oldId).map(n => n.id), ...renoteIds];
const myReactions = await this.noteReactionsRepository.findBy({ const myReactions = await this.noteReactionsRepository.findBy({
userId: meId, userId: meId,
noteId: In(targets), noteId: In(targets),

View File

@ -10,6 +10,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiNoteFavorite } from '@/models/NoteFavorite.js'; import type { MiNoteFavorite } from '@/models/NoteFavorite.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { NoteEntityService } from './NoteEntityService.js'; import { NoteEntityService } from './NoteEntityService.js';
@Injectable() @Injectable()
@ -19,6 +20,7 @@ export class NoteFavoriteEntityService {
private noteFavoritesRepository: NoteFavoritesRepository, private noteFavoritesRepository: NoteFavoritesRepository,
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private idService: IdService,
) { ) {
} }
@ -31,7 +33,7 @@ export class NoteFavoriteEntityService {
return { return {
id: favorite.id, id: favorite.id,
createdAt: favorite.createdAt.toISOString(), createdAt: this.idService.parse(favorite.id).date.toISOString(),
noteId: favorite.noteId, noteId: favorite.noteId,
note: await this.noteEntityService.pack(favorite.note ?? favorite.noteId, me), note: await this.noteEntityService.pack(favorite.note ?? favorite.noteId, me),
}; };

View File

@ -8,6 +8,7 @@ import { DI } from '@/di-symbols.js';
import type { NoteReactionsRepository } from '@/models/_.js'; import type { NoteReactionsRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js'; import type { Packed } from '@/misc/json-schema.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import type { OnModuleInit } from '@nestjs/common'; import type { OnModuleInit } from '@nestjs/common';
import type { } from '@/models/Blocking.js'; import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
@ -22,6 +23,7 @@ export class NoteReactionEntityService implements OnModuleInit {
private userEntityService: UserEntityService; private userEntityService: UserEntityService;
private noteEntityService: NoteEntityService; private noteEntityService: NoteEntityService;
private reactionService: ReactionService; private reactionService: ReactionService;
private idService: IdService;
constructor( constructor(
private moduleRef: ModuleRef, private moduleRef: ModuleRef,
@ -32,6 +34,7 @@ export class NoteReactionEntityService implements OnModuleInit {
//private userEntityService: UserEntityService, //private userEntityService: UserEntityService,
//private noteEntityService: NoteEntityService, //private noteEntityService: NoteEntityService,
//private reactionService: ReactionService, //private reactionService: ReactionService,
//private idService: IdService,
) { ) {
} }
@ -39,6 +42,7 @@ export class NoteReactionEntityService implements OnModuleInit {
this.userEntityService = this.moduleRef.get('UserEntityService'); this.userEntityService = this.moduleRef.get('UserEntityService');
this.noteEntityService = this.moduleRef.get('NoteEntityService'); this.noteEntityService = this.moduleRef.get('NoteEntityService');
this.reactionService = this.moduleRef.get('ReactionService'); this.reactionService = this.moduleRef.get('ReactionService');
this.idService = this.moduleRef.get('IdService');
} }
@bindThis @bindThis
@ -57,7 +61,7 @@ export class NoteReactionEntityService implements OnModuleInit {
return { return {
id: reaction.id, id: reaction.id,
createdAt: reaction.createdAt.toISOString(), createdAt: this.idService.parse(reaction.id).date.toISOString(),
user: await this.userEntityService.pack(reaction.user ?? reaction.userId, me), user: await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
type: this.reactionService.convertLegacyReaction(reaction.reaction), type: this.reactionService.convertLegacyReaction(reaction.reaction),
...(opts.withNote ? { ...(opts.withNote ? {

View File

@ -13,6 +13,7 @@ import type { MiUser } from '@/models/User.js';
import type { MiPage } from '@/models/Page.js'; import type { MiPage } from '@/models/Page.js';
import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiDriveFile } from '@/models/DriveFile.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
import { DriveFileEntityService } from './DriveFileEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js';
@ -30,6 +31,7 @@ export class PageEntityService {
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private driveFileEntityService: DriveFileEntityService, private driveFileEntityService: DriveFileEntityService,
private idService: IdService,
) { ) {
} }
@ -85,7 +87,7 @@ export class PageEntityService {
return await awaitAll({ return await awaitAll({
id: page.id, id: page.id,
createdAt: page.createdAt.toISOString(), createdAt: this.idService.parse(page.id).date.toISOString(),
updatedAt: page.updatedAt.toISOString(), updatedAt: page.updatedAt.toISOString(),
userId: page.userId, userId: page.userId,
user: this.userEntityService.pack(page.user ?? page.userId, me), // { detail: true } すると無限ループするので注意 user: this.userEntityService.pack(page.user ?? page.userId, me), // { detail: true } すると無限ループするので注意

View File

@ -12,6 +12,7 @@ import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { MiRenoteMuting } from '@/models/RenoteMuting.js'; import type { MiRenoteMuting } from '@/models/RenoteMuting.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -21,6 +22,7 @@ export class RenoteMutingEntityService {
private renoteMutingsRepository: RenoteMutingsRepository, private renoteMutingsRepository: RenoteMutingsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -33,7 +35,7 @@ export class RenoteMutingEntityService {
return await awaitAll({ return await awaitAll({
id: muting.id, id: muting.id,
createdAt: muting.createdAt.toISOString(), createdAt: this.idService.parse(muting.id).date.toISOString(),
muteeId: muting.muteeId, muteeId: muting.muteeId,
mutee: this.userEntityService.pack(muting.muteeId, me, { mutee: this.userEntityService.pack(muting.muteeId, me, {
detail: true, detail: true,

View File

@ -12,6 +12,7 @@ import type { MiUser } from '@/models/User.js';
import type { MiRole } from '@/models/Role.js'; import type { MiRole } from '@/models/Role.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js';
import { IdService } from '@/core/IdService.js';
@Injectable() @Injectable()
export class RoleEntityService { export class RoleEntityService {
@ -21,6 +22,8 @@ export class RoleEntityService {
@Inject(DI.roleAssignmentsRepository) @Inject(DI.roleAssignmentsRepository)
private roleAssignmentsRepository: RoleAssignmentsRepository, private roleAssignmentsRepository: RoleAssignmentsRepository,
private idService: IdService,
) { ) {
} }
@ -51,7 +54,7 @@ export class RoleEntityService {
return await awaitAll({ return await awaitAll({
id: role.id, id: role.id,
createdAt: role.createdAt.toISOString(), createdAt: this.idService.parse(role.id).date.toISOString(),
updatedAt: role.updatedAt.toISOString(), updatedAt: role.updatedAt.toISOString(),
name: role.name, name: role.name,
description: role.description, description: role.description,

View File

@ -20,6 +20,7 @@ import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { IdService } from '@/core/IdService.js';
import type { OnModuleInit } from '@nestjs/common'; import type { OnModuleInit } from '@nestjs/common';
import type { AnnouncementService } from '../AnnouncementService.js'; import type { AnnouncementService } from '../AnnouncementService.js';
import type { CustomEmojiService } from '../CustomEmojiService.js'; import type { CustomEmojiService } from '../CustomEmojiService.js';
@ -60,6 +61,7 @@ export class UserEntityService implements OnModuleInit {
private announcementService: AnnouncementService; private announcementService: AnnouncementService;
private roleService: RoleService; private roleService: RoleService;
private federatedInstanceService: FederatedInstanceService; private federatedInstanceService: FederatedInstanceService;
private idService: IdService;
constructor( constructor(
private moduleRef: ModuleRef, private moduleRef: ModuleRef,
@ -111,13 +113,6 @@ export class UserEntityService implements OnModuleInit {
@Inject(DI.userMemosRepository) @Inject(DI.userMemosRepository)
private userMemosRepository: UserMemoRepository, private userMemosRepository: UserMemoRepository,
//private noteEntityService: NoteEntityService,
//private driveFileEntityService: DriveFileEntityService,
//private pageEntityService: PageEntityService,
//private customEmojiService: CustomEmojiService,
//private antennaService: AntennaService,
//private roleService: RoleService,
) { ) {
} }
@ -130,6 +125,7 @@ export class UserEntityService implements OnModuleInit {
this.announcementService = this.moduleRef.get('AnnouncementService'); this.announcementService = this.moduleRef.get('AnnouncementService');
this.roleService = this.moduleRef.get('RoleService'); this.roleService = this.moduleRef.get('RoleService');
this.federatedInstanceService = this.moduleRef.get('FederatedInstanceService'); this.federatedInstanceService = this.moduleRef.get('FederatedInstanceService');
this.idService = this.moduleRef.get('IdService');
} }
//#region Validators //#region Validators
@ -364,7 +360,7 @@ export class UserEntityService implements OnModuleInit {
? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null))) ? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
.then(xs => xs.length === 0 ? null : xs.filter(x => x != null) as string[]) .then(xs => xs.length === 0 ? null : xs.filter(x => x != null) as string[])
: null, : null,
createdAt: user.createdAt.toISOString(), createdAt: this.idService.parse(user.id).date.toISOString(),
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null, lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
bannerUrl: user.bannerUrl, bannerUrl: user.bannerUrl,

View File

@ -10,6 +10,7 @@ import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/Blocking.js'; import type { } from '@/models/Blocking.js';
import type { MiUserList } from '@/models/UserList.js'; import type { MiUserList } from '@/models/UserList.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from './UserEntityService.js'; import { UserEntityService } from './UserEntityService.js';
@Injectable() @Injectable()
@ -22,6 +23,7 @@ export class UserListEntityService {
private userListMembershipsRepository: UserListMembershipsRepository, private userListMembershipsRepository: UserListMembershipsRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
) { ) {
} }
@ -37,7 +39,7 @@ export class UserListEntityService {
return { return {
id: userList.id, id: userList.id,
createdAt: userList.createdAt.toISOString(), createdAt: this.idService.parse(userList.id).date.toISOString(),
name: userList.name, name: userList.name,
userIds: users.map(x => x.userId), userIds: users.map(x => x.userId),
isPublic: userList.isPublic, isPublic: userList.isPublic,
@ -50,7 +52,7 @@ export class UserListEntityService {
) { ) {
return Promise.all(memberships.map(async x => ({ return Promise.all(memberships.map(async x => ({
id: x.id, id: x.id,
createdAt: x.createdAt.toISOString(), createdAt: this.idService.parse(x.id).date.toISOString(),
userId: x.userId, userId: x.userId,
user: await this.userEntityService.pack(x.userId), user: await this.userEntityService.pack(x.userId),
withReplies: x.withReplies, withReplies: x.withReplies,

View File

@ -24,8 +24,7 @@ function getNoise(): string {
return counter.toString(36).padStart(2, '0').slice(-2); return counter.toString(36).padStart(2, '0').slice(-2);
} }
export function genAid(date: Date): string { export function genAid(t: number): string {
const t = date.getTime();
if (isNaN(t)) throw new Error('Failed to create AID: Invalid Date'); if (isNaN(t)) throw new Error('Failed to create AID: Invalid Date');
counter++; counter++;
return getTime(t) + getNoise(); return getTime(t) + getNoise();

View File

@ -31,8 +31,7 @@ function getNoise(): string {
return counter.toString(36).padStart(NOISE_LENGTH, '0').slice(-NOISE_LENGTH); return counter.toString(36).padStart(NOISE_LENGTH, '0').slice(-NOISE_LENGTH);
} }
export function genAidx(date: Date): string { export function genAidx(t: number): string {
const t = date.getTime();
if (isNaN(t)) throw new Error('Failed to create AIDX: Invalid Date'); if (isNaN(t)) throw new Error('Failed to create AIDX: Invalid Date');
counter++; counter++;
return getTime(t) + nodeId + getNoise(); return getTime(t) + nodeId + getNoise();

View File

@ -29,8 +29,8 @@ function getRandom() {
return str; return str;
} }
export function genMeid(date: Date): string { export function genMeid(t: number): string {
return getTime(date.getTime()) + getRandom(); return getTime(t) + getRandom();
} }
export function parseMeid(id: string): { date: Date; } { export function parseMeid(id: string): { date: Date; } {

View File

@ -29,8 +29,8 @@ function getRandom() {
return str; return str;
} }
export function genMeidg(date: Date): string { export function genMeidg(t: number): string {
return 'g' + getTime(date.getTime()) + getRandom(); return 'g' + getTime(t) + getRandom();
} }
export function parseMeidg(id: string): { date: Date; } { export function parseMeidg(id: string): { date: Date; } {

View File

@ -29,8 +29,8 @@ function getRandom() {
return str; return str;
} }
export function genObjectId(date: Date): string { export function genObjectId(t: number): string {
return getTime(date.getTime()) + getRandom(); return getTime(t) + getRandom();
} }
export function parseObjectId(id: string): { date: Date; } { export function parseObjectId(id: string): { date: Date; } {

View File

@ -12,12 +12,6 @@ export class MiAbuseUserReport {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AbuseUserReport.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public targetUserId: MiUser['id']; public targetUserId: MiUser['id'];

View File

@ -13,11 +13,6 @@ export class MiAccessToken {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the AccessToken.',
})
public createdAt: Date;
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
nullable: true, nullable: true,
}) })

View File

@ -11,12 +11,6 @@ export class MiAd {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Ad.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The expired date of the Ad.', comment: 'The expired date of the Ad.',

View File

@ -12,12 +12,6 @@ export class MiAnnouncement {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Announcement.',
})
public createdAt: Date;
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the Announcement.', comment: 'The updated date of the Announcement.',
nullable: true, nullable: true,

View File

@ -14,11 +14,6 @@ export class MiAnnouncementRead {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the AnnouncementRead.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -13,11 +13,6 @@ export class MiAntenna {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the Antenna.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone') @Column('timestamp with time zone')
public lastUsedAt: Date; public lastUsedAt: Date;
@ -98,4 +93,9 @@ export class MiAntenna {
default: true, default: true,
}) })
public isActive: boolean; public isActive: boolean;
@Column('boolean', {
default: false,
})
public localOnly: boolean;
} }

View File

@ -12,12 +12,6 @@ export class MiApp {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the App.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -13,11 +13,6 @@ export class MiAuthSession {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the AuthSession.',
})
public createdAt: Date;
@Index() @Index()
@Column('varchar', { @Column('varchar', {
length: 128, length: 128,

View File

@ -13,12 +13,6 @@ export class MiBlocking {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Blocking.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -13,12 +13,6 @@ export class MiChannel {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Channel.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
nullable: true, nullable: true,

View File

@ -14,12 +14,6 @@ export class MiChannelFavorite {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ChannelFavorite.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -14,12 +14,6 @@ export class MiChannelFollowing {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ChannelFollowing.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -12,11 +12,6 @@ export class MiClip {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the Clip.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
nullable: true, nullable: true,

View File

@ -14,9 +14,6 @@ export class MiClipFavorite {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -14,12 +14,6 @@ export class MiDriveFile {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the DriveFile.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -12,12 +12,6 @@ export class MiDriveFolder {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the DriveFolder.',
})
public createdAt: Date;
@Column('varchar', { @Column('varchar', {
length: 128, length: 128,
comment: 'The name of the DriveFolder.', comment: 'The name of the DriveFolder.',

View File

@ -12,12 +12,6 @@ export class MiFlash {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Flash.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the Flash.', comment: 'The updated date of the Flash.',

View File

@ -14,9 +14,6 @@ export class MiFlashLike {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -13,11 +13,6 @@ export class MiFollowRequest {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the FollowRequest.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -14,12 +14,6 @@ export class MiFollowing {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Following.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -14,9 +14,6 @@ export class MiGalleryLike {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -13,12 +13,6 @@ export class MiGalleryPost {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the GalleryPost.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the GalleryPost.', comment: 'The updated date of the GalleryPost.',

View File

@ -12,11 +12,6 @@ export class MiModerationLog {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the ModerationLog.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -13,12 +13,6 @@ export class MiMuting {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Muting.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
nullable: true, nullable: true,

View File

@ -18,11 +18,6 @@ export class MiNote {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the Note.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -14,11 +14,6 @@ export class MiNoteFavorite {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the NoteFavorite.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -14,11 +14,6 @@ export class MiNoteReaction {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the NoteReaction.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -13,10 +13,6 @@ export class MiNoteThreadMuting {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -14,12 +14,6 @@ export class MiPage {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Page.',
})
public createdAt: Date;
@Index() @Index()
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the Page.', comment: 'The updated date of the Page.',

View File

@ -14,9 +14,6 @@ export class MiPageLike {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -12,9 +12,6 @@ export class MiPasswordResetRequest {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index({ unique: true }) @Index({ unique: true })
@Column('varchar', { @Column('varchar', {
length: 256, length: 256,

View File

@ -14,12 +14,6 @@ export class MiPollVote {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the PollVote.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -14,11 +14,6 @@ export class MiPromoRead {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the PromoRead.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

View File

@ -23,9 +23,6 @@ export class MiRegistrationTicket {
}) })
public expiresAt: Date | null; public expiresAt: Date | null;
@Column('timestamp with time zone')
public createdAt: Date;
@ManyToOne(type => MiUser, { @ManyToOne(type => MiUser, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
}) })

View File

@ -13,11 +13,6 @@ export class MiRegistryItem {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the RegistryItem.',
})
public createdAt: Date;
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the RegistryItem.', comment: 'The updated date of the RegistryItem.',
}) })

View File

@ -13,12 +13,6 @@ export class MiRenoteMuting {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Muting.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -89,11 +89,6 @@ export class MiRole {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the Role.',
})
public createdAt: Date;
@Column('timestamp with time zone', { @Column('timestamp with time zone', {
comment: 'The updated date of the Role.', comment: 'The updated date of the Role.',
}) })

View File

@ -14,11 +14,6 @@ export class MiRoleAssignment {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the RoleAssignment.',
})
public createdAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),

View File

@ -12,11 +12,6 @@ export class MiSignin {
@PrimaryColumn(id()) @PrimaryColumn(id())
public id: string; public id: string;
@Column('timestamp with time zone', {
comment: 'The created date of the Signin.',
})
public createdAt: Date;
@Index() @Index()
@Column(id()) @Column(id())
public userId: MiUser['id']; public userId: MiUser['id'];

Some files were not shown because too many files have changed in this diff Show More