Refactor API (#4770)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update description.ts * wip
This commit is contained in:
parent
f31f986d66
commit
0463c6bb0f
105 changed files with 1622 additions and 808 deletions
|
@ -1,8 +1,8 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Users } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { AbuseUserReport } from '../entities/abuse-user-report';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
|
||||
@EntityRepository(AbuseUserReport)
|
||||
export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
|
||||
|
@ -17,7 +17,7 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> {
|
|||
) {
|
||||
const report = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: report.id,
|
||||
createdAt: report.createdAt,
|
||||
reporterId: report.reporterId,
|
||||
|
|
|
@ -2,6 +2,9 @@ import { EntityRepository, Repository } from 'typeorm';
|
|||
import { App } from '../entities/app';
|
||||
import { AccessTokens } from '..';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedApp = SchemaType<typeof packedAppSchema>;
|
||||
|
||||
@EntityRepository(App)
|
||||
export class AppRepository extends Repository<App> {
|
||||
|
@ -13,7 +16,7 @@ export class AppRepository extends Repository<App> {
|
|||
includeSecret?: boolean,
|
||||
includeProfileImageIds?: boolean
|
||||
}
|
||||
) {
|
||||
): Promise<PackedApp> {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
includeSecret: false,
|
||||
|
@ -37,3 +40,40 @@ export class AppRepository extends Repository<App> {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const packedAppSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this Note.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
name: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'アプリケーションの名前'
|
||||
},
|
||||
callbackUrl: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
description: 'コールバックするURL'
|
||||
},
|
||||
permission: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
}
|
||||
},
|
||||
secret: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
description: 'アプリケーションのシークレットキー'
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Apps } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { AuthSession } from '../entities/auth-session';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
|
||||
@EntityRepository(AuthSession)
|
||||
export class AuthSessionRepository extends Repository<AuthSession> {
|
||||
|
@ -12,7 +12,7 @@ export class AuthSessionRepository extends Repository<AuthSession> {
|
|||
) {
|
||||
const session = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: session.id,
|
||||
app: Apps.pack(session.appId, me),
|
||||
token: session.token
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Users } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { Blocking } from '../entities/blocking';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { SchemaType, types, bool } from '../../misc/schema';
|
||||
|
||||
export type PackedBlocking = SchemaType<typeof packedBlockingSchema>;
|
||||
|
||||
@EntityRepository(Blocking)
|
||||
export class BlockingRepository extends Repository<Blocking> {
|
||||
|
@ -16,14 +19,47 @@ export class BlockingRepository extends Repository<Blocking> {
|
|||
public async pack(
|
||||
src: Blocking['id'] | Blocking,
|
||||
me?: any
|
||||
) {
|
||||
): Promise<PackedBlocking> {
|
||||
const blocking = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: blocking.id,
|
||||
createdAt: blocking.createdAt.toISOString(),
|
||||
blockeeId: blocking.blockeeId,
|
||||
blockee: Users.pack(blocking.blockeeId, me, {
|
||||
detail: true
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedBlockingSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this blocking.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the blocking was created.'
|
||||
},
|
||||
blockeeId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
blockee: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'User',
|
||||
description: 'The blockee.'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { DriveFile } from '../entities/drive-file';
|
||||
import { Users, DriveFolders } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { User } from '../entities/user';
|
||||
import { toPuny } from '../../misc/convert-host';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedDriveFile = SchemaType<typeof packedDriveFileSchema>;
|
||||
|
||||
@EntityRepository(DriveFile)
|
||||
export class DriveFileRepository extends Repository<DriveFile> {
|
||||
|
@ -82,7 +85,7 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
|||
self?: boolean,
|
||||
withUser?: boolean,
|
||||
}
|
||||
) {
|
||||
): Promise<PackedDriveFile> {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
self: false
|
||||
|
@ -90,9 +93,9 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
|||
|
||||
const file = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
md5: file.md5,
|
||||
|
@ -109,3 +112,66 @@ export class DriveFileRepository extends Repository<DriveFile> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedDriveFileSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this Drive file.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the Drive file was created on Misskey.'
|
||||
},
|
||||
name: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The file name with extension.',
|
||||
example: 'lenna.jpg'
|
||||
},
|
||||
type: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The MIME type of this Drive file.',
|
||||
example: 'image/jpeg'
|
||||
},
|
||||
md5: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'md5',
|
||||
description: 'The MD5 hash of this Drive file.',
|
||||
example: '15eca7fba0480996e2245f5185bf39f2'
|
||||
},
|
||||
size: {
|
||||
type: types.number,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The size of this Drive file. (bytes)',
|
||||
example: 51469
|
||||
},
|
||||
url: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
format: 'url',
|
||||
description: 'The URL of this Drive file.',
|
||||
},
|
||||
folderId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
format: 'id',
|
||||
description: 'The parent folder ID of this Drive file.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
isSensitive: {
|
||||
type: types.boolean,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'Whether this Drive file is sensitive.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { DriveFolders, DriveFiles } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { DriveFolder } from '../entities/drive-folder';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { SchemaType, types, bool } from '../../misc/schema';
|
||||
|
||||
export type PackedDriveFolder = SchemaType<typeof packedDriveFolderSchema>;
|
||||
|
||||
@EntityRepository(DriveFolder)
|
||||
export class DriveFolderRepository extends Repository<DriveFolder> {
|
||||
|
@ -18,16 +21,16 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
|
|||
options?: {
|
||||
detail: boolean
|
||||
}
|
||||
): Promise<Record<string, any>> {
|
||||
): Promise<PackedDriveFolder> {
|
||||
const opts = Object.assign({
|
||||
detail: false
|
||||
}, options);
|
||||
|
||||
const folder = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: folder.id,
|
||||
createdAt: folder.createdAt,
|
||||
createdAt: folder.createdAt.toISOString(),
|
||||
name: folder.name,
|
||||
parentId: folder.parentId,
|
||||
|
||||
|
@ -48,3 +51,50 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedDriveFolderSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this Drive folder.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the Drive folder was created.'
|
||||
},
|
||||
name: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The folder name.',
|
||||
},
|
||||
foldersCount: {
|
||||
type: types.number,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
description: 'The count of child folders.',
|
||||
},
|
||||
filesCount: {
|
||||
type: types.number,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
description: 'The count of child files.',
|
||||
},
|
||||
parentId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
format: 'id',
|
||||
description: 'The parent folder ID of this folder.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
parent: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
ref: 'DriveFolder'
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Users } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { Following } from '../entities/following';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { SchemaType, types, bool } from '../../misc/schema';
|
||||
|
||||
type LocalFollowerFollowing = Following & {
|
||||
followerHost: null;
|
||||
|
@ -28,6 +29,8 @@ type RemoteFolloweeFollowing = Following & {
|
|||
followeeSharedInbox: string;
|
||||
};
|
||||
|
||||
export type PackedFollowing = SchemaType<typeof packedFollowingSchema>;
|
||||
|
||||
@EntityRepository(Following)
|
||||
export class FollowingRepository extends Repository<Following> {
|
||||
public isLocalFollower(following: Following): following is LocalFollowerFollowing {
|
||||
|
@ -64,22 +67,64 @@ export class FollowingRepository extends Repository<Following> {
|
|||
populateFollowee?: boolean;
|
||||
populateFollower?: boolean;
|
||||
}
|
||||
) {
|
||||
): Promise<PackedFollowing> {
|
||||
const following = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
if (opts == null) opts = {};
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: following.id,
|
||||
createdAt: following.createdAt,
|
||||
createdAt: following.createdAt.toISOString(),
|
||||
followeeId: following.followeeId,
|
||||
followerId: following.followerId,
|
||||
followee: opts.populateFollowee ? Users.pack(following.followee || following.followeeId, me, {
|
||||
detail: true
|
||||
}) : null,
|
||||
}) : undefined,
|
||||
follower: opts.populateFollower ? Users.pack(following.follower || following.followerId, me, {
|
||||
detail: true
|
||||
}) : null,
|
||||
}) : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedFollowingSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this following.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the following was created.'
|
||||
},
|
||||
followeeId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
followee: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
ref: 'User',
|
||||
description: 'The followee.'
|
||||
},
|
||||
followerId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
follower: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
ref: 'User',
|
||||
description: 'The follower.'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { ReversiMatching } from '../../../entities/games/reversi/matching';
|
||||
import { Users } from '../../..';
|
||||
import { ensure } from '../../../../prelude/ensure';
|
||||
import { awaitAll } from '../../../../prelude/await-all';
|
||||
|
||||
@EntityRepository(ReversiMatching)
|
||||
export class ReversiMatchingRepository extends Repository<ReversiMatching> {
|
||||
|
@ -12,7 +12,7 @@ export class ReversiMatchingRepository extends Repository<ReversiMatching> {
|
|||
) {
|
||||
const matching = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: matching.id,
|
||||
createdAt: matching.createdAt,
|
||||
parentId: matching.parentId,
|
||||
|
|
|
@ -2,6 +2,9 @@ import { EntityRepository, Repository } from 'typeorm';
|
|||
import { MessagingMessage } from '../entities/messaging-message';
|
||||
import { Users, DriveFiles } from '..';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>;
|
||||
|
||||
@EntityRepository(MessagingMessage)
|
||||
export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
||||
|
@ -15,7 +18,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
|||
options?: {
|
||||
populateRecipient: boolean
|
||||
}
|
||||
) {
|
||||
): Promise<PackedMessagingMessage> {
|
||||
const opts = options || {
|
||||
populateRecipient: true
|
||||
};
|
||||
|
@ -24,15 +27,73 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
|
|||
|
||||
return {
|
||||
id: message.id,
|
||||
createdAt: message.createdAt,
|
||||
createdAt: message.createdAt.toISOString(),
|
||||
text: message.text,
|
||||
userId: message.userId,
|
||||
user: await Users.pack(message.user || message.userId, me),
|
||||
recipientId: message.recipientId,
|
||||
recipient: opts.populateRecipient ? await Users.pack(message.recipient || message.recipientId, me) : null,
|
||||
recipient: opts.populateRecipient ? await Users.pack(message.recipient || message.recipientId, me) : undefined,
|
||||
fileId: message.fileId,
|
||||
file: message.fileId ? await DriveFiles.pack(message.fileId) : null,
|
||||
isRead: message.isRead
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const packedMessagingMessageSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this MessagingMessage.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the MessagingMessage was created.'
|
||||
},
|
||||
userId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
user: {
|
||||
type: types.object,
|
||||
ref: 'User',
|
||||
optional: bool.true, nullable: bool.false,
|
||||
},
|
||||
text: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
},
|
||||
fileId: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
format: 'id',
|
||||
},
|
||||
file: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
ref: 'DriveFile',
|
||||
},
|
||||
recipientId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
recipient: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
ref: 'User'
|
||||
},
|
||||
isRead: {
|
||||
type: types.boolean,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Users } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { Muting } from '../entities/muting';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedMuting = SchemaType<typeof packedMutingSchema>;
|
||||
|
||||
@EntityRepository(Muting)
|
||||
export class MutingRepository extends Repository<Muting> {
|
||||
|
@ -16,14 +19,47 @@ export class MutingRepository extends Repository<Muting> {
|
|||
public async pack(
|
||||
src: Muting['id'] | Muting,
|
||||
me?: any
|
||||
) {
|
||||
): Promise<PackedMuting> {
|
||||
const muting = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: muting.id,
|
||||
createdAt: muting.createdAt.toISOString(),
|
||||
muteeId: muting.muteeId,
|
||||
mutee: Users.pack(muting.muteeId, me, {
|
||||
detail: true
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedMutingSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this muting.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the muting was created.'
|
||||
},
|
||||
muteeId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
mutee: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'User',
|
||||
description: 'The mutee.'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,18 +2,54 @@ import { EntityRepository, Repository } from 'typeorm';
|
|||
import { NoteReaction } from '../entities/note-reaction';
|
||||
import { Users } from '..';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>;
|
||||
|
||||
@EntityRepository(NoteReaction)
|
||||
export class NoteReactionRepository extends Repository<NoteReaction> {
|
||||
public async pack(
|
||||
src: NoteReaction['id'] | NoteReaction,
|
||||
me?: any
|
||||
) {
|
||||
): Promise<PackedNoteReaction> {
|
||||
const reaction = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return {
|
||||
id: reaction.id,
|
||||
createdAt: reaction.createdAt.toISOString(),
|
||||
user: await Users.pack(reaction.userId, me),
|
||||
type: reaction.reaction,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const packedNoteReactionSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this reaction.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the reaction was created.'
|
||||
},
|
||||
user: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'User',
|
||||
description: 'User who performed this reaction.'
|
||||
},
|
||||
type: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The reaction type.'
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -4,8 +4,11 @@ import { User } from '../entities/user';
|
|||
import { unique, concat } from '../../prelude/array';
|
||||
import { nyaize } from '../../misc/nyaize';
|
||||
import { Emojis, Users, Apps, PollVotes, DriveFiles, NoteReactions, Followings, Polls } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { SchemaType, types, bool } from '../../misc/schema';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
|
||||
export type PackedNote = SchemaType<typeof packedNoteSchema>;
|
||||
|
||||
@EntityRepository(Note)
|
||||
export class NoteRepository extends Repository<Note> {
|
||||
|
@ -13,18 +16,18 @@ export class NoteRepository extends Repository<Note> {
|
|||
return x.trim().length <= 100;
|
||||
}
|
||||
|
||||
private async hideNote(packedNote: any, meId: User['id'] | null) {
|
||||
private async hideNote(packedNote: PackedNote, meId: User['id'] | null) {
|
||||
let hide = false;
|
||||
|
||||
// visibility が specified かつ自分が指定されていなかったら非表示
|
||||
if (packedNote.visibility == 'specified') {
|
||||
if (packedNote.visibility === 'specified') {
|
||||
if (meId == null) {
|
||||
hide = true;
|
||||
} else if (meId === packedNote.userId) {
|
||||
hide = false;
|
||||
} else {
|
||||
// 指定されているかどうか
|
||||
const specified = packedNote.visibleUserIds.some((id: any) => meId === id);
|
||||
const specified = packedNote.visibleUserIds!.some((id: any) => meId === id);
|
||||
|
||||
if (specified) {
|
||||
hide = false;
|
||||
|
@ -40,10 +43,10 @@ export class NoteRepository extends Repository<Note> {
|
|||
hide = true;
|
||||
} else if (meId === packedNote.userId) {
|
||||
hide = false;
|
||||
} else if (packedNote.reply && (meId === packedNote.reply.userId)) {
|
||||
} else if (packedNote.reply && (meId === (packedNote.reply as PackedNote).userId)) {
|
||||
// 自分の投稿に対するリプライ
|
||||
hide = false;
|
||||
} else if (packedNote.mentions && packedNote.mentions.some((id: any) => meId === id)) {
|
||||
} else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) {
|
||||
// 自分へのメンション
|
||||
hide = false;
|
||||
} else {
|
||||
|
@ -62,14 +65,13 @@ export class NoteRepository extends Repository<Note> {
|
|||
}
|
||||
|
||||
if (hide) {
|
||||
packedNote.visibleUserIds = null;
|
||||
packedNote.visibleUserIds = undefined;
|
||||
packedNote.fileIds = [];
|
||||
packedNote.files = [];
|
||||
packedNote.text = null;
|
||||
packedNote.poll = null;
|
||||
packedNote.poll = undefined;
|
||||
packedNote.cw = null;
|
||||
packedNote.tags = [];
|
||||
packedNote.geo = null;
|
||||
packedNote.geo = undefined;
|
||||
packedNote.isHidden = true;
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +94,7 @@ export class NoteRepository extends Repository<Note> {
|
|||
detail?: boolean;
|
||||
skipHide?: boolean;
|
||||
}
|
||||
): Promise<Record<string, any>> {
|
||||
): Promise<PackedNote> {
|
||||
const opts = Object.assign({
|
||||
detail: true,
|
||||
skipHide: false
|
||||
|
@ -159,9 +161,9 @@ export class NoteRepository extends Repository<Note> {
|
|||
|
||||
const reactionEmojis = unique(concat([note.emojis, Object.keys(note.reactions)]));
|
||||
|
||||
const packed = await rap({
|
||||
const packed = await awaitAll({
|
||||
id: note.id,
|
||||
createdAt: note.createdAt,
|
||||
createdAt: note.createdAt.toISOString(),
|
||||
app: note.appId ? Apps.pack(note.appId) : undefined,
|
||||
userId: note.userId,
|
||||
user: Users.pack(note.user || note.userId, meId),
|
||||
|
@ -213,3 +215,127 @@ export class NoteRepository extends Repository<Note> {
|
|||
return packed;
|
||||
}
|
||||
}
|
||||
|
||||
export const packedNoteSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this Note.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the Note was created on Misskey.'
|
||||
},
|
||||
text: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.true,
|
||||
},
|
||||
cw: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
},
|
||||
userId: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
},
|
||||
user: {
|
||||
type: types.object,
|
||||
ref: 'User',
|
||||
optional: bool.false, nullable: bool.false,
|
||||
},
|
||||
replyId: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
renoteId: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
reply: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
ref: 'Note'
|
||||
},
|
||||
renote: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
ref: 'Note'
|
||||
},
|
||||
viaMobile: {
|
||||
type: types.boolean,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
},
|
||||
isHidden: {
|
||||
type: types.boolean,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
},
|
||||
visibility: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
},
|
||||
mentions: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id'
|
||||
}
|
||||
},
|
||||
visibleUserIds: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id'
|
||||
}
|
||||
},
|
||||
fileIds: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id'
|
||||
}
|
||||
},
|
||||
files: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'DriveFile'
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
type: types.array,
|
||||
optional: bool.true, nullable: bool.false,
|
||||
items: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
}
|
||||
},
|
||||
poll: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
},
|
||||
geo: {
|
||||
type: types.object,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { EntityRepository, Repository } from 'typeorm';
|
||||
import { Users, Notes } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { Notification } from '../entities/notification';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
import { types, bool, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
|
||||
|
||||
@EntityRepository(Notification)
|
||||
export class NotificationRepository extends Repository<Notification> {
|
||||
|
@ -14,12 +17,12 @@ export class NotificationRepository extends Repository<Notification> {
|
|||
|
||||
public async pack(
|
||||
src: Notification['id'] | Notification,
|
||||
) {
|
||||
): Promise<PackedNotification> {
|
||||
const notification = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
return await rap({
|
||||
return await awaitAll({
|
||||
id: notification.id,
|
||||
createdAt: notification.createdAt,
|
||||
createdAt: notification.createdAt.toISOString(),
|
||||
type: notification.type,
|
||||
userId: notification.notifierId,
|
||||
user: Users.pack(notification.notifier || notification.notifierId),
|
||||
|
@ -46,3 +49,39 @@ export class NotificationRepository extends Repository<Notification> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const packedNotificationSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this notification.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the notification was created.'
|
||||
},
|
||||
type: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
enum: ['follow', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote'],
|
||||
description: 'The type of the notification.'
|
||||
},
|
||||
userId: {
|
||||
type: types.string,
|
||||
optional: bool.true, nullable: bool.true,
|
||||
format: 'id',
|
||||
},
|
||||
user: {
|
||||
type: types.object,
|
||||
ref: 'User',
|
||||
optional: bool.true, nullable: bool.true,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,12 +2,15 @@ import { EntityRepository, Repository } from 'typeorm';
|
|||
import { UserList } from '../entities/user-list';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import { UserListJoinings } from '..';
|
||||
import { bool, types, SchemaType } from '../../misc/schema';
|
||||
|
||||
export type PackedUserList = SchemaType<typeof packedUserListSchema>;
|
||||
|
||||
@EntityRepository(UserList)
|
||||
export class UserListRepository extends Repository<UserList> {
|
||||
public async pack(
|
||||
src: UserList['id'] | UserList,
|
||||
) {
|
||||
): Promise<PackedUserList> {
|
||||
const userList = typeof src === 'object' ? src : await this.findOne(src).then(ensure);
|
||||
|
||||
const users = await UserListJoinings.find({
|
||||
|
@ -16,8 +19,43 @@ export class UserListRepository extends Repository<UserList> {
|
|||
|
||||
return {
|
||||
id: userList.id,
|
||||
createdAt: userList.createdAt.toISOString(),
|
||||
name: userList.name,
|
||||
userIds: users.map(x => x.userId)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const packedUserListSchema = {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this UserList.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
format: 'date-time',
|
||||
description: 'The date that the UserList was created.'
|
||||
},
|
||||
name: {
|
||||
type: types.string,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
description: 'The name of the UserList.'
|
||||
},
|
||||
userIds: {
|
||||
type: types.array,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
items: {
|
||||
type: types.string,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
format: 'id',
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { EntityRepository, Repository, In } from 'typeorm';
|
||||
import { User, ILocalUser, IRemoteUser } from '../entities/user';
|
||||
import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles } from '..';
|
||||
import rap from '@prezzemolo/rap';
|
||||
import { ensure } from '../../prelude/ensure';
|
||||
import config from '../../config';
|
||||
import { SchemaType, bool, types } from '../../misc/schema';
|
||||
import { awaitAll } from '../../prelude/await-all';
|
||||
|
||||
export type PackedUser = SchemaType<typeof packedUserSchema>;
|
||||
|
||||
@EntityRepository(User)
|
||||
export class UserRepository extends Repository<User> {
|
||||
|
@ -71,7 +74,7 @@ export class UserRepository extends Repository<User> {
|
|||
includeSecrets?: boolean,
|
||||
includeHasUnreadNotes?: boolean
|
||||
}
|
||||
): Promise<Record<string, any>> {
|
||||
): Promise<PackedUser> {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
includeSecrets: false
|
||||
|
@ -86,7 +89,7 @@ export class UserRepository extends Repository<User> {
|
|||
|
||||
const falsy = opts.detail ? false : undefined;
|
||||
|
||||
return await rap({
|
||||
const packed = {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
username: user.username,
|
||||
|
@ -120,8 +123,8 @@ export class UserRepository extends Repository<User> {
|
|||
|
||||
...(opts.detail ? {
|
||||
url: profile!.url,
|
||||
createdAt: user.createdAt,
|
||||
updatedAt: user.updatedAt,
|
||||
createdAt: user.createdAt.toISOString(),
|
||||
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
|
||||
bannerUrl: user.bannerUrl,
|
||||
bannerColor: user.bannerColor,
|
||||
isLocked: user.isLocked,
|
||||
|
@ -179,7 +182,9 @@ export class UserRepository extends Repository<User> {
|
|||
isBlocked: relation.isBlocked,
|
||||
isMuted: relation.isMuted,
|
||||
} : {})
|
||||
});
|
||||
};
|
||||
|
||||
return await awaitAll(packed);
|
||||
}
|
||||
|
||||
public isLocalUser(user: User): user is ILocalUser {
|
||||
|
@ -216,3 +221,156 @@ export class UserRepository extends Repository<User> {
|
|||
}
|
||||
//#endregion
|
||||
}
|
||||
|
||||
export const packedUserSchema = {
|
||||
type: types.object,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
properties: {
|
||||
id: {
|
||||
type: types.string,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
format: 'id',
|
||||
description: 'The unique identifier for this User.',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
username: {
|
||||
type: types.string,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
description: 'The screen name, handle, or alias that this user identifies themselves with.',
|
||||
example: 'ai'
|
||||
},
|
||||
name: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.false,
|
||||
description: 'The name of the user, as they’ve defined it.',
|
||||
example: '藍'
|
||||
},
|
||||
url: {
|
||||
type: types.string,
|
||||
format: 'url',
|
||||
nullable: bool.true, optional: bool.true,
|
||||
},
|
||||
avatarUrl: {
|
||||
type: types.string,
|
||||
format: 'url',
|
||||
nullable: bool.true, optional: bool.false,
|
||||
},
|
||||
avatarColor: {
|
||||
type: types.any,
|
||||
nullable: bool.true, optional: bool.false,
|
||||
},
|
||||
bannerUrl: {
|
||||
type: types.string,
|
||||
format: 'url',
|
||||
nullable: bool.true, optional: bool.true,
|
||||
},
|
||||
bannerColor: {
|
||||
type: types.any,
|
||||
nullable: bool.true, optional: bool.true,
|
||||
},
|
||||
emojis: {
|
||||
type: types.any,
|
||||
nullable: bool.true, optional: bool.false,
|
||||
},
|
||||
host: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.false,
|
||||
example: 'misskey.example.com'
|
||||
},
|
||||
description: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.true,
|
||||
description: 'The user-defined UTF-8 string describing their account.',
|
||||
example: 'Hi masters, I am Ai!'
|
||||
},
|
||||
birthday: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.true,
|
||||
example: '2018-03-12'
|
||||
},
|
||||
createdAt: {
|
||||
type: types.string,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
format: 'date-time',
|
||||
description: 'The date that the user account was created on Misskey.'
|
||||
},
|
||||
updatedAt: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.true,
|
||||
format: 'date-time',
|
||||
},
|
||||
location: {
|
||||
type: types.string,
|
||||
nullable: bool.true, optional: bool.true,
|
||||
},
|
||||
followersCount: {
|
||||
type: types.number,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'The number of followers this account currently has.'
|
||||
},
|
||||
followingCount: {
|
||||
type: types.number,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'The number of users this account is following.'
|
||||
},
|
||||
notesCount: {
|
||||
type: types.number,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'The number of Notes (including renotes) issued by the user.'
|
||||
},
|
||||
isBot: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'Whether this account is a bot.'
|
||||
},
|
||||
pinnedNoteIds: {
|
||||
type: types.array,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
items: {
|
||||
type: types.string,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
format: 'id',
|
||||
}
|
||||
},
|
||||
pinnedNotes: {
|
||||
type: types.array,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
items: {
|
||||
type: types.object,
|
||||
nullable: bool.false, optional: bool.false,
|
||||
ref: 'Note'
|
||||
}
|
||||
},
|
||||
isCat: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'Whether this account is a cat.'
|
||||
},
|
||||
isAdmin: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'Whether this account is the admin.'
|
||||
},
|
||||
isModerator: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'Whether this account is a moderator.'
|
||||
},
|
||||
isVerified: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
},
|
||||
isLocked: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
},
|
||||
hasUnreadSpecifiedNotes: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
},
|
||||
hasUnreadMentions: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue