summaryrefslogtreecommitdiff
path: root/src/models
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2019-04-23 22:35:26 +0900
committerGitHub <noreply@github.com>2019-04-23 22:35:26 +0900
commit0463c6bb0f8fd32740ceb61ccce04c662272a618 (patch)
treea28cbdf6c9cdc14648b8c0e46248665a3ad7e5af /src/models
parentFix #4768 (diff)
downloadsharkey-0463c6bb0f8fd32740ceb61ccce04c662272a618.tar.gz
sharkey-0463c6bb0f8fd32740ceb61ccce04c662272a618.tar.bz2
sharkey-0463c6bb0f8fd32740ceb61ccce04c662272a618.zip
Refactor API (#4770)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update description.ts * wip
Diffstat (limited to 'src/models')
-rw-r--r--src/models/repositories/abuse-user-report.ts4
-rw-r--r--src/models/repositories/app.ts42
-rw-r--r--src/models/repositories/auth-session.ts4
-rw-r--r--src/models/repositories/blocking.ts42
-rw-r--r--src/models/repositories/drive-file.ts74
-rw-r--r--src/models/repositories/drive-folder.ts58
-rw-r--r--src/models/repositories/following.ts57
-rw-r--r--src/models/repositories/games/reversi/matching.ts4
-rw-r--r--src/models/repositories/messaging-message.ts67
-rw-r--r--src/models/repositories/muting.ts42
-rw-r--r--src/models/repositories/note-reaction.ts38
-rw-r--r--src/models/repositories/note.ts152
-rw-r--r--src/models/repositories/notification.ts47
-rw-r--r--src/models/repositories/user-list.ts40
-rw-r--r--src/models/repositories/user.ts170
15 files changed, 786 insertions, 55 deletions
diff --git a/src/models/repositories/abuse-user-report.ts b/src/models/repositories/abuse-user-report.ts
index f619d6e37f..c708b265a6 100644
--- a/src/models/repositories/abuse-user-report.ts
+++ b/src/models/repositories/abuse-user-report.ts
@@ -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,
diff --git a/src/models/repositories/app.ts b/src/models/repositories/app.ts
index fa5ebf2ac7..6562a470be 100644
--- a/src/models/repositories/app.ts
+++ b/src/models/repositories/app.ts
@@ -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: 'アプリケーションのシークレットキー'
+ }
+ },
+};
diff --git a/src/models/repositories/auth-session.ts b/src/models/repositories/auth-session.ts
index 32f7968233..a6a4d46de6 100644
--- a/src/models/repositories/auth-session.ts
+++ b/src/models/repositories/auth-session.ts
@@ -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
diff --git a/src/models/repositories/blocking.ts b/src/models/repositories/blocking.ts
index e18aa591f3..fd209bce1c 100644
--- a/src/models/repositories/blocking.ts
+++ b/src/models/repositories/blocking.ts
@@ -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.'
+ },
+ }
+};
diff --git a/src/models/repositories/drive-file.ts b/src/models/repositories/drive-file.ts
index f117b38b24..245db4b797 100644
--- a/src/models/repositories/drive-file.ts
+++ b/src/models/repositories/drive-file.ts
@@ -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.',
+ },
+ },
+};
diff --git a/src/models/repositories/drive-folder.ts b/src/models/repositories/drive-folder.ts
index ce88adefa4..ef920c4326 100644
--- a/src/models/repositories/drive-folder.ts
+++ b/src/models/repositories/drive-folder.ts
@@ -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'
+ },
+ },
+};
diff --git a/src/models/repositories/following.ts b/src/models/repositories/following.ts
index 3fff57866f..aba6527fac 100644
--- a/src/models/repositories/following.ts
+++ b/src/models/repositories/following.ts
@@ -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.'
+ },
+ }
+};
diff --git a/src/models/repositories/games/reversi/matching.ts b/src/models/repositories/games/reversi/matching.ts
index 4d99c6ef76..86c9204456 100644
--- a/src/models/repositories/games/reversi/matching.ts
+++ b/src/models/repositories/games/reversi/matching.ts
@@ -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,
diff --git a/src/models/repositories/messaging-message.ts b/src/models/repositories/messaging-message.ts
index 6659273539..33f95bbd5f 100644
--- a/src/models/repositories/messaging-message.ts
+++ b/src/models/repositories/messaging-message.ts
@@ -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,
+ },
+ },
+};
diff --git a/src/models/repositories/muting.ts b/src/models/repositories/muting.ts
index 1812e2e713..1e8135a5c9 100644
--- a/src/models/repositories/muting.ts
+++ b/src/models/repositories/muting.ts
@@ -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.'
+ },
+ }
+};
diff --git a/src/models/repositories/note-reaction.ts b/src/models/repositories/note-reaction.ts
index 28191d4ab0..85e5b6b0a1 100644
--- a/src/models/repositories/note-reaction.ts
+++ b/src/models/repositories/note-reaction.ts
@@ -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.'
+ },
+ },
+};
diff --git a/src/models/repositories/note.ts b/src/models/repositories/note.ts
index 1d2ce7a9c9..1dbfabe88d 100644
--- a/src/models/repositories/note.ts
+++ b/src/models/repositories/note.ts
@@ -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,
+ },
+ },
+};
diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts
index 4781d4c065..cf77b35a08 100644
--- a/src/models/repositories/notification.ts
+++ b/src/models/repositories/notification.ts
@@ -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,
+ },
+ }
+};
diff --git a/src/models/repositories/user-list.ts b/src/models/repositories/user-list.ts
index e591794b8b..54231c7f85 100644
--- a/src/models/repositories/user-list.ts
+++ b/src/models/repositories/user-list.ts
@@ -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',
+ }
+ },
+ },
+};
diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts
index afba15eb53..6b212203f9 100644
--- a/src/models/repositories/user.ts
+++ b/src/models/repositories/user.ts
@@ -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,
+ },
+ },
+};