summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/notes
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api/endpoints/notes')
-rw-r--r--src/server/api/endpoints/notes/context.ts4
-rw-r--r--src/server/api/endpoints/notes/create.ts23
-rw-r--r--src/server/api/endpoints/notes/favorites/create.ts8
-rw-r--r--src/server/api/endpoints/notes/favorites/delete.ts8
-rw-r--r--src/server/api/endpoints/notes/global-timeline.ts6
-rw-r--r--src/server/api/endpoints/notes/local-timeline.ts6
-rw-r--r--src/server/api/endpoints/notes/mentions.ts6
-rw-r--r--src/server/api/endpoints/notes/polls/recommendation.ts4
-rw-r--r--src/server/api/endpoints/notes/polls/vote.ts8
-rw-r--r--src/server/api/endpoints/notes/reactions.ts4
-rw-r--r--src/server/api/endpoints/notes/reactions/create.ts4
-rw-r--r--src/server/api/endpoints/notes/reactions/delete.ts9
-rw-r--r--src/server/api/endpoints/notes/replies.ts4
-rw-r--r--src/server/api/endpoints/notes/reposts.ts8
-rw-r--r--src/server/api/endpoints/notes/search.ts10
-rw-r--r--src/server/api/endpoints/notes/show.ts4
-rw-r--r--src/server/api/endpoints/notes/timeline.ts6
-rw-r--r--src/server/api/endpoints/notes/user-list-timeline.ts179
18 files changed, 227 insertions, 74 deletions
diff --git a/src/server/api/endpoints/notes/context.ts b/src/server/api/endpoints/notes/context.ts
index 2caf742d26..309fc26447 100644
--- a/src/server/api/endpoints/notes/context.ts
+++ b/src/server/api/endpoints/notes/context.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { pack } from '../../../../models/note';
/**
@@ -13,7 +13,7 @@ import Note, { pack } from '../../../../models/note';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts
index ea1f41aae2..1824a16c24 100644
--- a/src/server/api/endpoints/notes/create.ts
+++ b/src/server/api/endpoints/notes/create.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
import { ILocalUser } from '../../../../models/user';
import Channel, { IChannel } from '../../../../models/channel';
@@ -11,11 +11,6 @@ import { IApp } from '../../../../models/app';
/**
* Create a note
- *
- * @param {any} params
- * @param {any} user
- * @param {any} app
- * @return {Promise<any>}
*/
module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'visibility' parameter
@@ -35,11 +30,11 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
if (viaMobileErr) return rej('invalid viaMobile');
// Get 'tags' parameter
- const [tags = [], tagsErr] = $(params.tags).optional.array('string').unique().eachQ(t => t.range(1, 32)).$;
+ const [tags = [], tagsErr] = $(params.tags).optional.array($().string().range(1, 32)).unique().$;
if (tagsErr) return rej('invalid tags');
// Get 'geo' parameter
- const [geo, geoErr] = $(params.geo).optional.nullable.strict.object()
+ const [geo, geoErr] = $(params.geo).optional.nullable.object(true)
.have('coordinates', $().array().length(2)
.item(0, $().number().range(-180, 180))
.item(1, $().number().range(-90, 90)))
@@ -52,7 +47,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
if (geoErr) return rej('invalid geo');
// Get 'mediaIds' parameter
- const [mediaIds, mediaIdsErr] = $(params.mediaIds).optional.array('id').unique().range(1, 4).$;
+ const [mediaIds, mediaIdsErr] = $(params.mediaIds).optional.array($().type(ID)).unique().range(1, 4).$;
if (mediaIdsErr) return rej('invalid mediaIds');
let files = [];
@@ -79,7 +74,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}
// Get 'renoteId' parameter
- const [renoteId, renoteIdErr] = $(params.renoteId).optional.id().$;
+ const [renoteId, renoteIdErr] = $(params.renoteId).optional.type(ID).$;
if (renoteIdErr) return rej('invalid renoteId');
let renote: INote = null;
@@ -100,7 +95,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}
// Get 'replyId' parameter
- const [replyId, replyIdErr] = $(params.replyId).optional.id().$;
+ const [replyId, replyIdErr] = $(params.replyId).optional.type(ID).$;
if (replyIdErr) return rej('invalid replyId');
let reply: INote = null;
@@ -121,7 +116,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}
// Get 'channelId' parameter
- const [channelId, channelIdErr] = $(params.channelId).optional.id().$;
+ const [channelId, channelIdErr] = $(params.channelId).optional.type(ID).$;
if (channelIdErr) return rej('invalid channelId');
let channel: IChannel = null;
@@ -162,8 +157,8 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}
// Get 'poll' parameter
- const [poll, pollErr] = $(params.poll).optional.strict.object()
- .have('choices', $().array('string')
+ const [poll, pollErr] = $(params.poll).optional.object(true)
+ .have('choices', $().array($().string())
.unique()
.range(2, 10)
.each(c => c.length > 0 && c.length < 50))
diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/src/server/api/endpoints/notes/favorites/create.ts
index c8e7f52426..e4c4adb9bb 100644
--- a/src/server/api/endpoints/notes/favorites/create.ts
+++ b/src/server/api/endpoints/notes/favorites/create.ts
@@ -1,20 +1,16 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Favorite from '../../../../../models/favorite';
import Note from '../../../../../models/note';
/**
* Favorite a note
- *
- * @param {any} params
- * @param {any} user
- * @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get favoritee
diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/src/server/api/endpoints/notes/favorites/delete.ts
index 92aceb343b..3c4d9a1111 100644
--- a/src/server/api/endpoints/notes/favorites/delete.ts
+++ b/src/server/api/endpoints/notes/favorites/delete.ts
@@ -1,20 +1,16 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Favorite from '../../../../../models/favorite';
import Note from '../../../../../models/note';
/**
* Unfavorite a note
- *
- * @param {any} params
- * @param {any} user
- * @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get favoritee
diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index 07e138ec54..e2a94d8a3e 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note from '../../../../models/note';
import Mute from '../../../../models/mute';
import { pack } from '../../../../models/note';
@@ -15,11 +15,11 @@ module.exports = async (params, user, app) => {
if (limitErr) throw 'invalid limit param';
// Get 'sinceId' parameter
- const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
if (sinceIdErr) throw 'invalid sinceId param';
// Get 'untilId' parameter
- const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
if (untilIdErr) throw 'invalid untilId param';
// Get 'sinceDate' parameter
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index d63528c3cd..dda83311ac 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note from '../../../../models/note';
import Mute from '../../../../models/mute';
import { pack } from '../../../../models/note';
@@ -15,11 +15,11 @@ module.exports = async (params, user, app) => {
if (limitErr) throw 'invalid limit param';
// Get 'sinceId' parameter
- const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
if (sinceIdErr) throw 'invalid sinceId param';
// Get 'untilId' parameter
- const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
if (untilIdErr) throw 'invalid untilId param';
// Get 'sinceDate' parameter
diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts
index 2d95606b3f..815cf271a2 100644
--- a/src/server/api/endpoints/notes/mentions.ts
+++ b/src/server/api/endpoints/notes/mentions.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note from '../../../../models/note';
import { getFriendIds } from '../../common/get-friends';
import { pack } from '../../../../models/note';
@@ -24,11 +24,11 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
if (limitErr) return rej('invalid limit param');
// Get 'sinceId' parameter
- const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
if (sinceIdErr) return rej('invalid sinceId param');
// Get 'untilId' parameter
- const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
if (untilIdErr) return rej('invalid untilId param');
// Check if both of sinceId and untilId is specified
diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts
index cb530ea2cf..24b0a4c803 100644
--- a/src/server/api/endpoints/notes/polls/recommendation.ts
+++ b/src/server/api/endpoints/notes/polls/recommendation.ts
@@ -7,10 +7,6 @@ import Note, { pack } from '../../../../../models/note';
/**
* Get recommended polls
- *
- * @param {any} params
- * @param {any} user
- * @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'limit' parameter
diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts
index 03d94da60d..2669c39085 100644
--- a/src/server/api/endpoints/notes/polls/vote.ts
+++ b/src/server/api/endpoints/notes/polls/vote.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Vote from '../../../../../models/poll-vote';
import Note from '../../../../../models/note';
import Watching from '../../../../../models/note-watching';
@@ -11,14 +11,10 @@ import notify from '../../../../../publishers/notify';
/**
* Vote poll of a note
- *
- * @param {any} params
- * @param {any} user
- * @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get votee
diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts
index bbff97bb0a..68ffbacd46 100644
--- a/src/server/api/endpoints/notes/reactions.ts
+++ b/src/server/api/endpoints/notes/reactions.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note from '../../../../models/note';
import Reaction, { pack } from '../../../../models/note-reaction';
@@ -14,7 +14,7 @@ import Reaction, { pack } from '../../../../models/note-reaction';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts
index 9e217cc3e0..1c21252604 100644
--- a/src/server/api/endpoints/notes/reactions/create.ts
+++ b/src/server/api/endpoints/notes/reactions/create.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Note from '../../../../../models/note';
import create from '../../../../../services/note/reaction/create';
import { validateReaction } from '../../../../../models/note-reaction';
@@ -11,7 +11,7 @@ import { validateReaction } from '../../../../../models/note-reaction';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'reaction' parameter
diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts
index b5d738b8ff..be3c1b214d 100644
--- a/src/server/api/endpoints/notes/reactions/delete.ts
+++ b/src/server/api/endpoints/notes/reactions/delete.ts
@@ -1,21 +1,16 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
import Reaction from '../../../../../models/note-reaction';
import Note from '../../../../../models/note';
-// import event from '../../../publishers/stream';
/**
* Unreact to a note
- *
- * @param {any} params
- * @param {any} user
- * @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Fetch unreactee
diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts
index 88d9ff329a..31f1bb941a 100644
--- a/src/server/api/endpoints/notes/replies.ts
+++ b/src/server/api/endpoints/notes/replies.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { pack } from '../../../../models/note';
/**
@@ -13,7 +13,7 @@ import Note, { pack } from '../../../../models/note';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
diff --git a/src/server/api/endpoints/notes/reposts.ts b/src/server/api/endpoints/notes/reposts.ts
index 9dfc2c3cb5..fe98931380 100644
--- a/src/server/api/endpoints/notes/reposts.ts
+++ b/src/server/api/endpoints/notes/reposts.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { pack } from '../../../../models/note';
/**
@@ -13,7 +13,7 @@ import Note, { pack } from '../../../../models/note';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
@@ -21,11 +21,11 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
if (limitErr) return rej('invalid limit param');
// Get 'sinceId' parameter
- const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
if (sinceIdErr) return rej('invalid sinceId param');
// Get 'untilId' parameter
- const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
if (untilIdErr) return rej('invalid untilId param');
// Check if both of sinceId and untilId is specified
diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts
index 3ff3fbbafa..021f620aa2 100644
--- a/src/server/api/endpoints/notes/search.ts
+++ b/src/server/api/endpoints/notes/search.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
const escapeRegexp = require('escape-regexp');
import Note from '../../../../models/note';
import User from '../../../../models/user';
@@ -22,19 +22,19 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
if (textError) return rej('invalid text param');
// Get 'includeUserIds' parameter
- const [includeUserIds = [], includeUserIdsErr] = $(params.includeUserIds).optional.array('id').$;
+ const [includeUserIds = [], includeUserIdsErr] = $(params.includeUserIds).optional.array($().type(ID)).$;
if (includeUserIdsErr) return rej('invalid includeUserIds param');
// Get 'excludeUserIds' parameter
- const [excludeUserIds = [], excludeUserIdsErr] = $(params.excludeUserIds).optional.array('id').$;
+ const [excludeUserIds = [], excludeUserIdsErr] = $(params.excludeUserIds).optional.array($().type(ID)).$;
if (excludeUserIdsErr) return rej('invalid excludeUserIds param');
// Get 'includeUserUsernames' parameter
- const [includeUserUsernames = [], includeUserUsernamesErr] = $(params.includeUserUsernames).optional.array('string').$;
+ const [includeUserUsernames = [], includeUserUsernamesErr] = $(params.includeUserUsernames).optional.array($().string()).$;
if (includeUserUsernamesErr) return rej('invalid includeUserUsernames param');
// Get 'excludeUserUsernames' parameter
- const [excludeUserUsernames = [], excludeUserUsernamesErr] = $(params.excludeUserUsernames).optional.array('string').$;
+ const [excludeUserUsernames = [], excludeUserUsernamesErr] = $(params.excludeUserUsernames).optional.array($().string()).$;
if (excludeUserUsernamesErr) return rej('invalid excludeUserUsernames param');
// Get 'following' parameter
diff --git a/src/server/api/endpoints/notes/show.ts b/src/server/api/endpoints/notes/show.ts
index 67cdc3038b..266e0687e9 100644
--- a/src/server/api/endpoints/notes/show.ts
+++ b/src/server/api/endpoints/notes/show.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { pack } from '../../../../models/note';
/**
@@ -13,7 +13,7 @@ import Note, { pack } from '../../../../models/note';
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
- const [noteId, noteIdErr] = $(params.noteId).id().$;
+ const [noteId, noteIdErr] = $(params.noteId).type(ID).$;
if (noteIdErr) return rej('invalid noteId param');
// Get note
diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts
index de30afea57..476d64158c 100644
--- a/src/server/api/endpoints/notes/timeline.ts
+++ b/src/server/api/endpoints/notes/timeline.ts
@@ -1,7 +1,7 @@
/**
* Module dependencies
*/
-import $ from 'cafy';
+import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note from '../../../../models/note';
import Mute from '../../../../models/mute';
import ChannelWatching from '../../../../models/channel-watching';
@@ -17,11 +17,11 @@ module.exports = async (params, user, app) => {
if (limitErr) throw 'invalid limit param';
// Get 'sinceId' parameter
- const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
if (sinceIdErr) throw 'invalid sinceId param';
// Get 'untilId' parameter
- const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
if (untilIdErr) throw 'invalid untilId param';
// Get 'sinceDate' parameter
diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts
new file mode 100644
index 0000000000..bb94fa0ab9
--- /dev/null
+++ b/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -0,0 +1,179 @@
+/**
+ * Module dependencies
+ */
+import $ from 'cafy'; import ID from '../../../../cafy-id';
+import Note from '../../../../models/note';
+import Mute from '../../../../models/mute';
+import { pack } from '../../../../models/note';
+import UserList from '../../../../models/user-list';
+
+/**
+ * Get timeline of a user list
+ */
+module.exports = async (params, user, app) => {
+ // Get 'limit' parameter
+ const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
+ if (limitErr) throw 'invalid limit param';
+
+ // Get 'sinceId' parameter
+ const [sinceId, sinceIdErr] = $(params.sinceId).optional.type(ID).$;
+ if (sinceIdErr) throw 'invalid sinceId param';
+
+ // Get 'untilId' parameter
+ const [untilId, untilIdErr] = $(params.untilId).optional.type(ID).$;
+ if (untilIdErr) throw 'invalid untilId param';
+
+ // Get 'sinceDate' parameter
+ const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$;
+ if (sinceDateErr) throw 'invalid sinceDate param';
+
+ // Get 'untilDate' parameter
+ const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$;
+ if (untilDateErr) throw 'invalid untilDate param';
+
+ // Check if only one of sinceId, untilId, sinceDate, untilDate specified
+ if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) {
+ throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
+ }
+
+ // Get 'includeMyRenotes' parameter
+ const [includeMyRenotes = true, includeMyRenotesErr] = $(params.includeMyRenotes).optional.boolean().$;
+ if (includeMyRenotesErr) throw 'invalid includeMyRenotes param';
+
+ // Get 'includeRenotedMyNotes' parameter
+ const [includeRenotedMyNotes = true, includeRenotedMyNotesErr] = $(params.includeRenotedMyNotes).optional.boolean().$;
+ if (includeRenotedMyNotesErr) throw 'invalid includeRenotedMyNotes param';
+
+ // Get 'listId' parameter
+ const [listId, listIdErr] = $(params.listId).type(ID).$;
+ if (listIdErr) throw 'invalid listId param';
+
+ const [list, mutedUserIds] = await Promise.all([
+ // リストを取得
+ // Fetch the list
+ UserList.findOne({
+ _id: listId,
+ userId: user._id
+ }),
+
+ // ミュートしているユーザーを取得
+ Mute.find({
+ muterId: user._id
+ }).then(ms => ms.map(m => m.muteeId))
+ ]);
+
+ if (list.userIds.length == 0) {
+ return [];
+ }
+
+ //#region Construct query
+ const sort = {
+ _id: -1
+ };
+
+ const listQuery = list.userIds.map(u => ({
+ userId: u,
+
+ // リプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
+ $or: [{
+ // リプライでない
+ replyId: null
+ }, { // または
+ // リプライだが返信先が投稿者自身の投稿
+ $expr: {
+ $eq: ['$_reply.userId', '$userId']
+ }
+ }, { // または
+ // リプライだが返信先が自分(フォロワー)の投稿
+ '_reply.userId': user._id
+ }, { // または
+ // 自分(フォロワー)が送信したリプライ
+ userId: user._id
+ }]
+ }));
+
+ const query = {
+ $and: [{
+ // リストに入っている人のタイムラインへの投稿
+ $or: listQuery,
+
+ // mute
+ userId: {
+ $nin: mutedUserIds
+ },
+ '_reply.userId': {
+ $nin: mutedUserIds
+ },
+ '_renote.userId': {
+ $nin: mutedUserIds
+ },
+ }]
+ } as any;
+
+ // MongoDBではトップレベルで否定ができないため、De Morganの法則を利用してクエリします。
+ // つまり、「『自分の投稿かつRenote』ではない」を「『自分の投稿ではない』または『Renoteではない』」と表現します。
+ // for details: https://en.wikipedia.org/wiki/De_Morgan%27s_laws
+
+ if (includeMyRenotes === false) {
+ query.$and.push({
+ $or: [{
+ userId: { $ne: user._id }
+ }, {
+ renoteId: null
+ }, {
+ text: { $ne: null }
+ }, {
+ mediaIds: { $ne: [] }
+ }, {
+ poll: { $ne: null }
+ }]
+ });
+ }
+
+ if (includeRenotedMyNotes === false) {
+ query.$and.push({
+ $or: [{
+ '_renote.userId': { $ne: user._id }
+ }, {
+ renoteId: null
+ }, {
+ text: { $ne: null }
+ }, {
+ mediaIds: { $ne: [] }
+ }, {
+ poll: { $ne: null }
+ }]
+ });
+ }
+
+ if (sinceId) {
+ sort._id = 1;
+ query._id = {
+ $gt: sinceId
+ };
+ } else if (untilId) {
+ query._id = {
+ $lt: untilId
+ };
+ } else if (sinceDate) {
+ sort._id = 1;
+ query.createdAt = {
+ $gt: new Date(sinceDate)
+ };
+ } else if (untilDate) {
+ query.createdAt = {
+ $lt: new Date(untilDate)
+ };
+ }
+ //#endregion
+
+ // Issue query
+ const timeline = await Note
+ .find(query, {
+ limit: limit,
+ sort: sort
+ });
+
+ // Serialize
+ return await Promise.all(timeline.map(note => pack(note, user)));
+};