refactor: PackedHoge型をPacked<'Hoge'>型に書き換える (#7792)

* packedNotificationSchemaを更新

* read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加

* fix

* add header, choice, invitation

* test

* fix

* yatta

* remove no longer needed "as PackedUser/PackedNote"

* clean up

* add simple-schema

* fix lint

* define items in full Schema

* revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736

* user packとnote packの型不整合を修正

* add prelude/types.ts

* emoji

* signin

* game

* matching

* fix

* add emoji schema

* add reversiGame

* add reversiMatching

* remove signin schema (use Signin entity)

* add Packed type

* note-reaction

* user

* user-group

* user-list

* note

* app, messaging-message

* notification

* drive-file

* drive-folder

* following

* muting

* blocking

* hashtag

* page

* app (with modifying schema)

* import user?

* channel

* antenna

* clip

* gallery-post

* emoji

* Packed

* reversi-matching

* add changelog

* add changelog

* revert fix
This commit is contained in:
tamaina 2021-09-22 22:35:55 +09:00 committed by GitHub
parent 96c40021b9
commit dbdb0df0a9
35 changed files with 312 additions and 122 deletions

View File

@ -21,6 +21,8 @@
- UIの改善 - UIの改善
- MFMにsparklesエフェクトを追加 - MFMにsparklesエフェクトを追加
- 非ログイン自は更新ダイアログを出さないように - 非ログイン自は更新ダイアログを出さないように
- refactor: PackedHoge型をPacked<'Hoge'>型に書き換える
- refactor: スキーマのないpack関数にスキーマを定義
### Bugfixes ### Bugfixes
- アカウントデータのエクスポート/インポート処理ができない問題を修正 - アカウントデータのエクスポート/インポート処理ができない問題を修正

View File

@ -3,13 +3,13 @@ import { Note } from '@/models/entities/note';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { UserListJoinings, UserGroupJoinings } from '@/models/index'; import { UserListJoinings, UserGroupJoinings } from '@/models/index';
import { getFullApAccount } from './convert-host'; import { getFullApAccount } from './convert-host';
import { PackedNote } from '../models/repositories/note';
import { parseAcct } from '@/misc/acct'; import { parseAcct } from '@/misc/acct';
import { Packed } from './schema';
/** /**
* noteUserFollowers / antennaUserFollowing * noteUserFollowers / antennaUserFollowing
*/ */
export async function checkHitAntenna(antenna: Antenna, note: (Note | PackedNote), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> { export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> {
if (note.visibility === 'specified') return false; if (note.visibility === 'specified') return false;
if (note.visibility === 'followers') { if (note.visibility === 'followers') {

View File

@ -21,6 +21,9 @@ import { packedClipSchema } from '@/models/repositories/clip';
import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance'; import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance';
import { packedQueueCountSchema } from '@/models/repositories/queue'; import { packedQueueCountSchema } from '@/models/repositories/queue';
import { packedGalleryPostSchema } from '@/models/repositories/gallery-post'; import { packedGalleryPostSchema } from '@/models/repositories/gallery-post';
import { packedEmojiSchema } from '@/models/repositories/emoji';
import { packedReversiGameSchema } from '@/models/repositories/games/reversi/game';
import { packedReversiMatchingSchema } from '@/models/repositories/games/reversi/matching';
export const refs = { export const refs = {
User: packedUserSchema, User: packedUserSchema,
@ -45,8 +48,13 @@ export const refs = {
Clip: packedClipSchema, Clip: packedClipSchema,
FederationInstance: packedFederationInstanceSchema, FederationInstance: packedFederationInstanceSchema,
GalleryPost: packedGalleryPostSchema, GalleryPost: packedGalleryPostSchema,
Emoji: packedEmojiSchema,
ReversiGame: packedReversiGameSchema,
ReversiMatching: packedReversiMatchingSchema,
}; };
export type Packed<x extends keyof typeof refs> = ObjType<(typeof refs[x])['properties']>;
export interface Schema extends SimpleSchema { export interface Schema extends SimpleSchema {
items?: Schema; items?: Schema;
properties?: Obj; properties?: Obj;
@ -92,7 +100,7 @@ export type SchemaType<p extends Schema> =
p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> : p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> :
p['type'] extends 'object' ? ( p['type'] extends 'object' ? (
p['ref'] extends keyof typeof refs p['ref'] extends keyof typeof refs
? NullOrUndefined<p, SchemaType<typeof refs[p['ref']]>> ? NullOrUndefined<p, Packed<p['ref']>>
: NullOrUndefined<p, ObjType<NonNullable<p['properties']>>> : NullOrUndefined<p, ObjType<NonNullable<p['properties']>>>
) : ) :
p['type'] extends 'any' ? NullOrUndefined<p, any> : p['type'] extends 'any' ? NullOrUndefined<p, any> :

View File

@ -1,15 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Antenna } from '@/models/entities/antenna'; import { Antenna } from '@/models/entities/antenna';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { AntennaNotes, UserGroupJoinings } from '../index'; import { AntennaNotes, UserGroupJoinings } from '../index';
export type PackedAntenna = SchemaType<typeof packedAntennaSchema>;
@EntityRepository(Antenna) @EntityRepository(Antenna)
export class AntennaRepository extends Repository<Antenna> { export class AntennaRepository extends Repository<Antenna> {
public async pack( public async pack(
src: Antenna['id'] | Antenna, src: Antenna['id'] | Antenna,
): Promise<PackedAntenna> { ): Promise<Packed<'Antenna'>> {
const antenna = typeof src === 'object' ? src : await this.findOneOrFail(src); const antenna = typeof src === 'object' ? src : await this.findOneOrFail(src);
const hasUnreadNote = (await AntennaNotes.findOne({ antennaId: antenna.id, read: false })) != null; const hasUnreadNote = (await AntennaNotes.findOne({ antennaId: antenna.id, read: false })) != null;

View File

@ -1,9 +1,8 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { App } from '@/models/entities/app'; import { App } from '@/models/entities/app';
import { AccessTokens } from '../index'; import { AccessTokens } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { User } from '../entities/user';
export type PackedApp = SchemaType<typeof packedAppSchema>;
@EntityRepository(App) @EntityRepository(App)
export class AppRepository extends Repository<App> { export class AppRepository extends Repository<App> {
@ -15,7 +14,7 @@ export class AppRepository extends Repository<App> {
includeSecret?: boolean, includeSecret?: boolean,
includeProfileImageIds?: boolean includeProfileImageIds?: boolean
} }
): Promise<PackedApp> { ): Promise<Packed<'App'>> {
const opts = Object.assign({ const opts = Object.assign({
detail: false, detail: false,
includeSecret: false, includeSecret: false,
@ -52,13 +51,9 @@ export const packedAppSchema = {
type: 'string' as const, type: 'string' as const,
optional: false as const, nullable: false as const optional: false as const, nullable: false as const
}, },
createdAt: { callbackUrl: {
type: 'string' as const, type: 'string' as const,
optional: false as const, nullable: false as const optional: false as const, nullable: true as const
},
lastUsedAt: {
type: 'string' as const,
optional: false as const, nullable: false as const
}, },
permission: { permission: {
type: 'array' as const, type: 'array' as const,

View File

@ -2,17 +2,15 @@ import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../index'; import { Users } from '../index';
import { Blocking } from '@/models/entities/blocking'; import { Blocking } from '@/models/entities/blocking';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
@EntityRepository(Blocking) @EntityRepository(Blocking)
export class BlockingRepository extends Repository<Blocking> { export class BlockingRepository extends Repository<Blocking> {
public async pack( public async pack(
src: Blocking['id'] | Blocking, src: Blocking['id'] | Blocking,
me?: { id: User['id'] } | null | undefined me?: { id: User['id'] } | null | undefined
): Promise<PackedBlocking> { ): Promise<Packed<'Blocking'>> {
const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src); const blocking = typeof src === 'object' ? src : await this.findOneOrFail(src);
return await awaitAll({ return await awaitAll({

View File

@ -1,17 +1,15 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Channel } from '@/models/entities/channel'; import { Channel } from '@/models/entities/channel';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { DriveFiles, ChannelFollowings, NoteUnreads } from '../index'; import { DriveFiles, ChannelFollowings, NoteUnreads } from '../index';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedChannel = SchemaType<typeof packedChannelSchema>;
@EntityRepository(Channel) @EntityRepository(Channel)
export class ChannelRepository extends Repository<Channel> { export class ChannelRepository extends Repository<Channel> {
public async pack( public async pack(
src: Channel['id'] | Channel, src: Channel['id'] | Channel,
me?: { id: User['id'] } | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedChannel> { ): Promise<Packed<'Channel'>> {
const channel = typeof src === 'object' ? src : await this.findOneOrFail(src); const channel = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? me.id : null; const meId = me ? me.id : null;

View File

@ -1,16 +1,14 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Clip } from '@/models/entities/clip'; import { Clip } from '@/models/entities/clip';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { Users } from '../index'; import { Users } from '../index';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
export type PackedClip = SchemaType<typeof packedClipSchema>;
@EntityRepository(Clip) @EntityRepository(Clip)
export class ClipRepository extends Repository<Clip> { export class ClipRepository extends Repository<Clip> {
public async pack( public async pack(
src: Clip['id'] | Clip, src: Clip['id'] | Clip,
): Promise<PackedClip> { ): Promise<Packed<'Clip'>> {
const clip = typeof src === 'object' ? src : await this.findOneOrFail(src); const clip = typeof src === 'object' ? src : await this.findOneOrFail(src);
return await awaitAll({ return await awaitAll({

View File

@ -4,14 +4,12 @@ import { Users, DriveFolders } from '../index';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { toPuny } from '@/misc/convert-host'; import { toPuny } from '@/misc/convert-host';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import config from '@/config/index'; import config from '@/config/index';
import { query, appendQuery } from '@/prelude/url'; import { query, appendQuery } from '@/prelude/url';
import { Meta } from '@/models/entities/meta'; import { Meta } from '@/models/entities/meta';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
export type PackedDriveFile = SchemaType<typeof packedDriveFileSchema>;
type PackOptions = { type PackOptions = {
detail?: boolean, detail?: boolean,
self?: boolean, self?: boolean,
@ -99,12 +97,12 @@ export class DriveFileRepository extends Repository<DriveFile> {
return parseInt(sum, 10) || 0; return parseInt(sum, 10) || 0;
} }
public async pack(src: DriveFile['id'], options?: PackOptions): Promise<PackedDriveFile | null>; public async pack(src: DriveFile['id'], options?: PackOptions): Promise<Packed<'DriveFile'> | null>;
public async pack(src: DriveFile, options?: PackOptions): Promise<PackedDriveFile>; public async pack(src: DriveFile, options?: PackOptions): Promise<Packed<'DriveFile'>>;
public async pack( public async pack(
src: DriveFile['id'] | DriveFile, src: DriveFile['id'] | DriveFile,
options?: PackOptions options?: PackOptions
): Promise<PackedDriveFile | null> { ): Promise<Packed<'DriveFile'> | null> {
const opts = Object.assign({ const opts = Object.assign({
detail: false, detail: false,
self: false self: false

View File

@ -2,9 +2,7 @@ import { EntityRepository, Repository } from 'typeorm';
import { DriveFolders, DriveFiles } from '../index'; import { DriveFolders, DriveFiles } from '../index';
import { DriveFolder } from '@/models/entities/drive-folder'; import { DriveFolder } from '@/models/entities/drive-folder';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
export type PackedDriveFolder = SchemaType<typeof packedDriveFolderSchema>;
@EntityRepository(DriveFolder) @EntityRepository(DriveFolder)
export class DriveFolderRepository extends Repository<DriveFolder> { export class DriveFolderRepository extends Repository<DriveFolder> {
@ -20,7 +18,7 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
options?: { options?: {
detail: boolean detail: boolean
} }
): Promise<PackedDriveFolder> { ): Promise<Packed<'DriveFolder'>> {
const opts = Object.assign({ const opts = Object.assign({
detail: false detail: false
}, options); }, options);

View File

@ -1,11 +1,12 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Emoji } from '@/models/entities/emoji'; import { Emoji } from '@/models/entities/emoji';
import { Packed } from '@/misc/schema';
@EntityRepository(Emoji) @EntityRepository(Emoji)
export class EmojiRepository extends Repository<Emoji> { export class EmojiRepository extends Repository<Emoji> {
public async pack( public async pack(
src: Emoji['id'] | Emoji, src: Emoji['id'] | Emoji,
) { ): Promise<Packed<'Emoji'>> {
const emoji = typeof src === 'object' ? src : await this.findOneOrFail(src); const emoji = typeof src === 'object' ? src : await this.findOneOrFail(src);
return { return {
@ -24,3 +25,41 @@ export class EmojiRepository extends Repository<Emoji> {
return Promise.all(emojis.map(x => this.pack(x))); return Promise.all(emojis.map(x => this.pack(x)));
} }
} }
export const packedEmojiSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
aliases: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
category: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
host: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
url: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
}
};

View File

@ -2,7 +2,7 @@ import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../index'; import { Users } from '../index';
import { Following } from '@/models/entities/following'; import { Following } from '@/models/entities/following';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
type LocalFollowerFollowing = Following & { type LocalFollowerFollowing = Following & {
@ -29,8 +29,6 @@ type RemoteFolloweeFollowing = Following & {
followeeSharedInbox: string; followeeSharedInbox: string;
}; };
export type PackedFollowing = SchemaType<typeof packedFollowingSchema>;
@EntityRepository(Following) @EntityRepository(Following)
export class FollowingRepository extends Repository<Following> { export class FollowingRepository extends Repository<Following> {
public isLocalFollower(following: Following): following is LocalFollowerFollowing { public isLocalFollower(following: Following): following is LocalFollowerFollowing {
@ -56,7 +54,7 @@ export class FollowingRepository extends Repository<Following> {
populateFollowee?: boolean; populateFollowee?: boolean;
populateFollower?: boolean; populateFollower?: boolean;
} }
): Promise<PackedFollowing> { ): Promise<Packed<'Following'>> {
const following = typeof src === 'object' ? src : await this.findOneOrFail(src); const following = typeof src === 'object' ? src : await this.findOneOrFail(src);
if (opts == null) opts = {}; if (opts == null) opts = {};

View File

@ -1,18 +1,16 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { GalleryPost } from '@/models/entities/gallery-post'; import { GalleryPost } from '@/models/entities/gallery-post';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { Users, DriveFiles, GalleryLikes } from '../index'; import { Users, DriveFiles, GalleryLikes } from '../index';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedGalleryPost = SchemaType<typeof packedGalleryPostSchema>;
@EntityRepository(GalleryPost) @EntityRepository(GalleryPost)
export class GalleryPostRepository extends Repository<GalleryPost> { export class GalleryPostRepository extends Repository<GalleryPost> {
public async pack( public async pack(
src: GalleryPost['id'] | GalleryPost, src: GalleryPost['id'] | GalleryPost,
me?: { id: User['id'] } | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedGalleryPost> { ): Promise<Packed<'GalleryPost'>> {
const meId = me ? me.id : null; const meId = me ? me.id : null;
const post = typeof src === 'object' ? src : await this.findOneOrFail(src); const post = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -2,6 +2,7 @@ import { User } from '@/models/entities/user';
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../../../index'; import { Users } from '../../../index';
import { ReversiGame } from '@/models/entities/games/reversi/game'; import { ReversiGame } from '@/models/entities/games/reversi/game';
import { Packed } from '@/misc/schema';
@EntityRepository(ReversiGame) @EntityRepository(ReversiGame)
export class ReversiGameRepository extends Repository<ReversiGame> { export class ReversiGameRepository extends Repository<ReversiGame> {
@ -11,7 +12,7 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
options?: { options?: {
detail?: boolean detail?: boolean
} }
) { ): Promise<Packed<'ReversiGame'>> {
const opts = Object.assign({ const opts = Object.assign({
detail: true detail: true
}, options); }, options);
@ -20,8 +21,8 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
return { return {
id: game.id, id: game.id,
createdAt: game.createdAt, createdAt: game.createdAt.toISOString(),
startedAt: game.startedAt, startedAt: game.startedAt && game.startedAt.toISOString(),
isStarted: game.isStarted, isStarted: game.isStarted,
isEnded: game.isEnded, isEnded: game.isEnded,
form1: game.form1, form1: game.form1,
@ -41,9 +42,150 @@ export class ReversiGameRepository extends Repository<ReversiGame> {
canPutEverywhere: game.canPutEverywhere, canPutEverywhere: game.canPutEverywhere,
loopedBoard: game.loopedBoard, loopedBoard: game.loopedBoard,
...(opts.detail ? { ...(opts.detail ? {
logs: game.logs, logs: game.logs.map(log => ({
at: log.at.toISOString(),
color: log.color,
pos: log.pos
})),
map: game.map, map: game.map,
} : {}) } : {})
}; };
} }
} }
export const packedReversiGameSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
startedAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'date-time',
},
isStarted: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
isEnded: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
form1: {
type: 'any' as const,
optional: false as const, nullable: true as const,
},
form2: {
type: 'any' as const,
optional: false as const, nullable: true as const,
},
user1Accepted: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
user2Accepted: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
user1Id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
user2Id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
user1: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
user2: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
winnerId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
winner: {
type: 'object' as const,
optional: false as const, nullable: true as const,
ref: 'User' as const,
},
surrendered: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
black: {
type: 'number' as const,
optional: false as const, nullable: true as const,
},
bw: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
isLlotheo: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
canPutEverywhere: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
loopedBoard: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
logs: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'object' as const,
optional: true as const, nullable: false as const,
properties: {
at: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
color: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
pos: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
}
}
},
map: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
}
}
}
};

View File

@ -3,18 +3,19 @@ import { ReversiMatching } from '@/models/entities/games/reversi/matching';
import { Users } from '../../../index'; import { Users } from '../../../index';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { Packed } from '@/misc/schema';
@EntityRepository(ReversiMatching) @EntityRepository(ReversiMatching)
export class ReversiMatchingRepository extends Repository<ReversiMatching> { export class ReversiMatchingRepository extends Repository<ReversiMatching> {
public async pack( public async pack(
src: ReversiMatching['id'] | ReversiMatching, src: ReversiMatching['id'] | ReversiMatching,
me: { id: User['id'] } me: { id: User['id'] }
) { ): Promise<Packed<'ReversiMatching'>> {
const matching = typeof src === 'object' ? src : await this.findOneOrFail(src); const matching = typeof src === 'object' ? src : await this.findOneOrFail(src);
return await awaitAll({ return await awaitAll({
id: matching.id, id: matching.id,
createdAt: matching.createdAt, createdAt: matching.createdAt.toISOString(),
parentId: matching.parentId, parentId: matching.parentId,
parent: Users.pack(matching.parentId, me, { parent: Users.pack(matching.parentId, me, {
detail: true detail: true
@ -26,3 +27,43 @@ export class ReversiMatchingRepository extends Repository<ReversiMatching> {
}); });
} }
} }
export const packedReversiMatchingSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
parentId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
parent: {
type: 'object' as const,
optional: false as const, nullable: true as const,
ref: 'User' as const,
},
childId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
child: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
}
};

View File

@ -1,14 +1,12 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Hashtag } from '@/models/entities/hashtag'; import { Hashtag } from '@/models/entities/hashtag';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
export type PackedHashtag = SchemaType<typeof packedHashtagSchema>;
@EntityRepository(Hashtag) @EntityRepository(Hashtag)
export class HashtagRepository extends Repository<Hashtag> { export class HashtagRepository extends Repository<Hashtag> {
public async pack( public async pack(
src: Hashtag, src: Hashtag,
): Promise<PackedHashtag> { ): Promise<Packed<'Hashtag'>> {
return { return {
tag: src.name, tag: src.name,
mentionedUsersCount: src.mentionedUsersCount, mentionedUsersCount: src.mentionedUsersCount,

View File

@ -1,11 +1,9 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { MessagingMessage } from '@/models/entities/messaging-message'; import { MessagingMessage } from '@/models/entities/messaging-message';
import { Users, DriveFiles, UserGroups } from '../index'; import { Users, DriveFiles, UserGroups } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>;
@EntityRepository(MessagingMessage) @EntityRepository(MessagingMessage)
export class MessagingMessageRepository extends Repository<MessagingMessage> { export class MessagingMessageRepository extends Repository<MessagingMessage> {
public validateText(text: string): boolean { public validateText(text: string): boolean {
@ -19,7 +17,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
populateRecipient?: boolean, populateRecipient?: boolean,
populateGroup?: boolean, populateGroup?: boolean,
} }
): Promise<PackedMessagingMessage> { ): Promise<Packed<'MessagingMessage'>> {
const opts = options || { const opts = options || {
populateRecipient: true, populateRecipient: true,
populateGroup: true, populateGroup: true,

View File

@ -2,17 +2,15 @@ import { EntityRepository, Repository } from 'typeorm';
import { Users } from '../index'; import { Users } from '../index';
import { Muting } from '@/models/entities/muting'; import { Muting } from '@/models/entities/muting';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedMuting = SchemaType<typeof packedMutingSchema>;
@EntityRepository(Muting) @EntityRepository(Muting)
export class MutingRepository extends Repository<Muting> { export class MutingRepository extends Repository<Muting> {
public async pack( public async pack(
src: Muting['id'] | Muting, src: Muting['id'] | Muting,
me?: { id: User['id'] } | null | undefined me?: { id: User['id'] } | null | undefined
): Promise<PackedMuting> { ): Promise<Packed<'Muting'>> {
const muting = typeof src === 'object' ? src : await this.findOneOrFail(src); const muting = typeof src === 'object' ? src : await this.findOneOrFail(src);
return await awaitAll({ return await awaitAll({

View File

@ -1,18 +1,16 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { NoteReaction } from '@/models/entities/note-reaction'; import { NoteReaction } from '@/models/entities/note-reaction';
import { Users } from '../index'; import { Users } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { convertLegacyReaction } from '@/misc/reaction-lib'; import { convertLegacyReaction } from '@/misc/reaction-lib';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
@EntityRepository(NoteReaction) @EntityRepository(NoteReaction)
export class NoteReactionRepository extends Repository<NoteReaction> { export class NoteReactionRepository extends Repository<NoteReaction> {
public async pack( public async pack(
src: NoteReaction['id'] | NoteReaction, src: NoteReaction['id'] | NoteReaction,
me?: { id: User['id'] } | null | undefined me?: { id: User['id'] } | null | undefined
): Promise<PackedNoteReaction> { ): Promise<Packed<'NoteReaction'>> {
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src); const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);
return { return {

View File

@ -3,15 +3,13 @@ import * as mfm from 'mfm-js';
import { Note } from '@/models/entities/note'; import { Note } from '@/models/entities/note';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index'; import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { nyaize } from '@/misc/nyaize'; import { nyaize } from '@/misc/nyaize';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib'; import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib';
import { NoteReaction } from '@/models/entities/note-reaction'; import { NoteReaction } from '@/models/entities/note-reaction';
import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis'; import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis';
export type PackedNote = SchemaType<typeof packedNoteSchema>;
@EntityRepository(Note) @EntityRepository(Note)
export class NoteRepository extends Repository<Note> { export class NoteRepository extends Repository<Note> {
public validateCw(x: string) { public validateCw(x: string) {
@ -67,7 +65,7 @@ export class NoteRepository extends Repository<Note> {
return true; return true;
} }
private async hideNote(packedNote: PackedNote, meId: User['id'] | null) { private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) {
// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど) // TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
let hide = false; let hide = false;
@ -137,7 +135,7 @@ export class NoteRepository extends Repository<Note> {
myReactions: Map<Note['id'], NoteReaction | null>; myReactions: Map<Note['id'], NoteReaction | null>;
}; };
} }
): Promise<PackedNote> { ): Promise<Packed<'Note'>> {
const opts = Object.assign({ const opts = Object.assign({
detail: true, detail: true,
skipHide: false skipHide: false

View File

@ -2,15 +2,13 @@ import { EntityRepository, In, Repository } from 'typeorm';
import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '../index'; import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '../index';
import { Notification } from '@/models/entities/notification'; import { Notification } from '@/models/entities/notification';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { Note } from '@/models/entities/note'; import { Note } from '@/models/entities/note';
import { NoteReaction } from '@/models/entities/note-reaction'; import { NoteReaction } from '@/models/entities/note-reaction';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis'; import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis';
import { notificationTypes } from '@/types'; import { notificationTypes } from '@/types';
export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
@EntityRepository(Notification) @EntityRepository(Notification)
export class NotificationRepository extends Repository<Notification> { export class NotificationRepository extends Repository<Notification> {
public async pack( public async pack(
@ -20,7 +18,7 @@ export class NotificationRepository extends Repository<Notification> {
myReactions: Map<Note['id'], NoteReaction | null>; myReactions: Map<Note['id'], NoteReaction | null>;
}; };
} }
): Promise<PackedNotification> { ): Promise<Packed<'Notification'>> {
const notification = typeof src === 'object' ? src : await this.findOneOrFail(src); const notification = typeof src === 'object' ? src : await this.findOneOrFail(src);
const token = notification.appAccessTokenId ? await AccessTokens.findOneOrFail(notification.appAccessTokenId) : null; const token = notification.appAccessTokenId ? await AccessTokens.findOneOrFail(notification.appAccessTokenId) : null;

View File

@ -1,19 +1,17 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { Page } from '@/models/entities/page'; import { Page } from '@/models/entities/page';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { Users, DriveFiles, PageLikes } from '../index'; import { Users, DriveFiles, PageLikes } from '../index';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { DriveFile } from '@/models/entities/drive-file'; import { DriveFile } from '@/models/entities/drive-file';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
export type PackedPage = SchemaType<typeof packedPageSchema>;
@EntityRepository(Page) @EntityRepository(Page)
export class PageRepository extends Repository<Page> { export class PageRepository extends Repository<Page> {
public async pack( public async pack(
src: Page['id'] | Page, src: Page['id'] | Page,
me?: { id: User['id'] } | null | undefined, me?: { id: User['id'] } | null | undefined,
): Promise<PackedPage> { ): Promise<Packed<'Page'>> {
const meId = me ? me.id : null; const meId = me ? me.id : null;
const page = typeof src === 'object' ? src : await this.findOneOrFail(src); const page = typeof src === 'object' ? src : await this.findOneOrFail(src);

View File

@ -1,15 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { UserGroup } from '@/models/entities/user-group'; import { UserGroup } from '@/models/entities/user-group';
import { UserGroupJoinings } from '../index'; import { UserGroupJoinings } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
export type PackedUserGroup = SchemaType<typeof packedUserGroupSchema>;
@EntityRepository(UserGroup) @EntityRepository(UserGroup)
export class UserGroupRepository extends Repository<UserGroup> { export class UserGroupRepository extends Repository<UserGroup> {
public async pack( public async pack(
src: UserGroup['id'] | UserGroup, src: UserGroup['id'] | UserGroup,
): Promise<PackedUserGroup> { ): Promise<Packed<'UserGroup'>> {
const userGroup = typeof src === 'object' ? src : await this.findOneOrFail(src); const userGroup = typeof src === 'object' ? src : await this.findOneOrFail(src);
const users = await UserGroupJoinings.find({ const users = await UserGroupJoinings.find({

View File

@ -1,15 +1,13 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { UserList } from '@/models/entities/user-list'; import { UserList } from '@/models/entities/user-list';
import { UserListJoinings } from '../index'; import { UserListJoinings } from '../index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
export type PackedUserList = SchemaType<typeof packedUserListSchema>;
@EntityRepository(UserList) @EntityRepository(UserList)
export class UserListRepository extends Repository<UserList> { export class UserListRepository extends Repository<UserList> {
public async pack( public async pack(
src: UserList['id'] | UserList, src: UserList['id'] | UserList,
): Promise<PackedUserList> { ): Promise<Packed<'UserList'>> {
const userList = typeof src === 'object' ? src : await this.findOneOrFail(src); const userList = typeof src === 'object' ? src : await this.findOneOrFail(src);
const users = await UserListJoinings.find({ const users = await UserListJoinings.find({

View File

@ -3,14 +3,12 @@ import { EntityRepository, Repository, In, Not } from 'typeorm';
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; import { User, ILocalUser, IRemoteUser } from '@/models/entities/user';
import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index'; import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index';
import config from '@/config/index'; import config from '@/config/index';
import { SchemaType } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { awaitAll } from '@/prelude/await-all'; import { awaitAll } from '@/prelude/await-all';
import { populateEmojis } from '@/misc/populate-emojis'; import { populateEmojis } from '@/misc/populate-emojis';
import { getAntennas } from '@/misc/antenna-cache'; import { getAntennas } from '@/misc/antenna-cache';
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const'; import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const';
export type PackedUser = SchemaType<typeof packedUserSchema>;
@EntityRepository(User) @EntityRepository(User)
export class UserRepository extends Repository<User> { export class UserRepository extends Repository<User> {
public async getRelation(me: User['id'], target: User['id']) { public async getRelation(me: User['id'], target: User['id']) {
@ -164,7 +162,7 @@ export class UserRepository extends Repository<User> {
detail?: boolean, detail?: boolean,
includeSecrets?: boolean, includeSecrets?: boolean,
} }
): Promise<PackedUser> { ): Promise<Packed<'User'>> {
const opts = Object.assign({ const opts = Object.assign({
detail: false, detail: false,
includeSecrets: false includeSecrets: false

View File

@ -3,8 +3,8 @@ import Channel from '../channel';
import { Notes, Users } from '@/models/index'; import { Notes, Users } from '@/models/index';
import { isMutedUserRelated } from '@/misc/is-muted-user-related'; import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { PackedNote } from '@/models/repositories/note';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'channel'; public readonly chName = 'channel';
@ -25,7 +25,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
if (note.channelId !== this.channelId) return; if (note.channelId !== this.channelId) return;
// リプライなら再pack // リプライなら再pack

View File

@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel'; import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index'; import { Notes } from '@/models/index';
import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute'; import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'globalTimeline'; public readonly chName = 'globalTimeline';
@ -24,7 +24,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null) return; if (note.channelId != null) return;

View File

@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
import { isMutedUserRelated } from '@/misc/is-muted-user-related'; import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel'; import Channel from '../channel';
import { Notes } from '@/models/index'; import { Notes } from '@/models/index';
import { PackedNote } from '@/models/repositories/note';
import { normalizeForSearch } from '@/misc/normalize-for-search'; import { normalizeForSearch } from '@/misc/normalize-for-search';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'hashtag'; public readonly chName = 'hashtag';
@ -23,7 +23,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : []; const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : [];
const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag)))); const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag))));
if (!matched) return; if (!matched) return;

View File

@ -2,9 +2,9 @@ import autobind from 'autobind-decorator';
import { isMutedUserRelated } from '@/misc/is-muted-user-related'; import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel'; import Channel from '../channel';
import { Notes } from '@/models/index'; import { Notes } from '@/models/index';
import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute'; import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'homeTimeline'; public readonly chName = 'homeTimeline';
@ -18,7 +18,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
if (note.channelId) { if (note.channelId) {
if (!this.followingChannels.has(note.channelId)) return; if (!this.followingChannels.has(note.channelId)) return;
} else { } else {

View File

@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel'; import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index'; import { Notes } from '@/models/index';
import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute'; import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'hybridTimeline'; public readonly chName = 'hybridTimeline';
@ -22,7 +22,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
// チャンネルの投稿ではなく、自分自身の投稿 または // チャンネルの投稿ではなく、自分自身の投稿 または
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または // チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
// チャンネルの投稿ではなく、全体公開のローカルの投稿 または // チャンネルの投稿ではなく、全体公開のローカルの投稿 または

View File

@ -3,9 +3,9 @@ import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import Channel from '../channel'; import Channel from '../channel';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
import { Notes } from '@/models/index'; import { Notes } from '@/models/index';
import { PackedNote } from '@/models/repositories/note';
import { checkWordMute } from '@/misc/check-word-mute'; import { checkWordMute } from '@/misc/check-word-mute';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'localTimeline'; public readonly chName = 'localTimeline';
@ -24,7 +24,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
if (note.user.host !== null) return; if (note.user.host !== null) return;
if (note.visibility !== 'public') return; if (note.visibility !== 'public') return;
if (note.channelId != null && !this.followingChannels.has(note.channelId)) return; if (note.channelId != null && !this.followingChannels.has(note.channelId)) return;

View File

@ -3,8 +3,8 @@ import Channel from '../channel';
import { Notes, UserListJoinings, UserLists } from '@/models/index'; import { Notes, UserListJoinings, UserLists } from '@/models/index';
import { isMutedUserRelated } from '@/misc/is-muted-user-related'; import { isMutedUserRelated } from '@/misc/is-muted-user-related';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { PackedNote } from '@/models/repositories/note';
import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; import { isBlockerUserRelated } from '@/misc/is-blocker-user-related';
import { Packed } from '@/misc/schema';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'userList'; public readonly chName = 'userList';
@ -47,7 +47,7 @@ export default class extends Channel {
} }
@autobind @autobind
private async onNote(note: PackedNote) { private async onNote(note: Packed<'Note'>) {
if (!this.listUsers.includes(note.userId)) return; if (!this.listUsers.includes(note.userId)) return;
if (['followers', 'specified'].includes(note.visibility)) { if (['followers', 'specified'].includes(note.visibility)) {

View File

@ -14,7 +14,7 @@ import { AccessToken } from '@/models/entities/access-token';
import { UserProfile } from '@/models/entities/user-profile'; import { UserProfile } from '@/models/entities/user-profile';
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream'; import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream';
import { UserGroup } from '@/models/entities/user-group'; import { UserGroup } from '@/models/entities/user-group';
import { PackedNote } from '@/models/repositories/note'; import { Packed } from '@/misc/schema';
/** /**
* Main stream connection * Main stream connection
@ -31,7 +31,7 @@ export default class Connection {
public subscriber: EventEmitter; public subscriber: EventEmitter;
private channels: Channel[] = []; private channels: Channel[] = [];
private subscribingNotes: any = {}; private subscribingNotes: any = {};
private cachedNotes: PackedNote[] = []; private cachedNotes: Packed<'Note'>[] = [];
constructor( constructor(
wsConnection: websocket.connection, wsConnection: websocket.connection,
@ -150,8 +150,8 @@ export default class Connection {
} }
@autobind @autobind
public cacheNote(note: PackedNote) { public cacheNote(note: Packed<'Note'>) {
const add = (note: PackedNote) => { const add = (note: Packed<'Note'>) => {
const existIndex = this.cachedNotes.findIndex(n => n.id === note.id); const existIndex = this.cachedNotes.findIndex(n => n.id === note.id);
if (existIndex > -1) { if (existIndex > -1) {
this.cachedNotes[existIndex] = note; this.cachedNotes[existIndex] = note;

View File

@ -6,15 +6,15 @@ import { Not, IsNull, In } from 'typeorm';
import { Channel } from '@/models/entities/channel'; import { Channel } from '@/models/entities/channel';
import { checkHitAntenna } from '@/misc/check-hit-antenna'; import { checkHitAntenna } from '@/misc/check-hit-antenna';
import { getAntennas } from '@/misc/antenna-cache'; import { getAntennas } from '@/misc/antenna-cache';
import { PackedNote } from '@/models/repositories/note';
import { readNotificationByQuery } from '@/server/api/common/read-notification'; import { readNotificationByQuery } from '@/server/api/common/read-notification';
import { Packed } from '@/misc/schema';
/** /**
* Mark notes as read * Mark notes as read
*/ */
export default async function( export default async function(
userId: User['id'], userId: User['id'],
notes: (Note | PackedNote)[], notes: (Note | Packed<'Note'>)[],
info?: { info?: {
following: Set<User['id']>; following: Set<User['id']>;
followingChannels: Set<Channel['id']>; followingChannels: Set<Channel['id']>;
@ -34,10 +34,10 @@ export default async function(
})).map(x => x.followeeId)); })).map(x => x.followeeId));
const myAntennas = (await getAntennas()).filter(a => a.userId === userId); const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
const readMentions: (Note | PackedNote)[] = []; const readMentions: (Note | Packed<'Note'>)[] = [];
const readSpecifiedNotes: (Note | PackedNote)[] = []; const readSpecifiedNotes: (Note | Packed<'Note'>)[] = [];
const readChannelNotes: (Note | PackedNote)[] = []; const readChannelNotes: (Note | Packed<'Note'>)[] = [];
const readAntennaNotes: (Note | PackedNote)[] = []; const readAntennaNotes: (Note | Packed<'Note'>)[] = [];
for (const note of notes) { for (const note of notes) {
if (note.mentions && note.mentions.includes(userId)) { if (note.mentions && note.mentions.includes(userId)) {

View File

@ -2,11 +2,10 @@ import * as push from 'web-push';
import config from '@/config/index'; import config from '@/config/index';
import { SwSubscriptions } from '@/models/index'; import { SwSubscriptions } from '@/models/index';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
import { PackedNotification } from '../models/repositories/notification'; import { Packed } from '@/misc/schema';
import { PackedMessagingMessage } from '../models/repositories/messaging-message';
type notificationType = 'notification' | 'unreadMessagingMessage'; type notificationType = 'notification' | 'unreadMessagingMessage';
type notificationBody = PackedNotification | PackedMessagingMessage; type notificationBody = Packed<'Notification'> | Packed<'MessagingMessage'>;
export default async function(userId: string, type: notificationType, body: notificationBody) { export default async function(userId: string, type: notificationType, body: notificationBody) {
const meta = await fetchMeta(); const meta = await fetchMeta();