diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2018-07-07 02:55:52 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-07 02:55:52 +0900 |
| commit | d5bad25c63f1b1d095da8b523dc02be471d7071a (patch) | |
| tree | 381ce23594925e56ba09c16de076932193f35b47 /src/server/api/endpoints/notes | |
| parent | Merge pull request #1846 from syuilo/l10n_master (diff) | |
| parent | w (diff) | |
| download | sharkey-d5bad25c63f1b1d095da8b523dc02be471d7071a.tar.gz sharkey-d5bad25c63f1b1d095da8b523dc02be471d7071a.tar.bz2 sharkey-d5bad25c63f1b1d095da8b523dc02be471d7071a.zip | |
Merge pull request #1854 from syuilo/apis
:v:
Diffstat (limited to 'src/server/api/endpoints/notes')
21 files changed, 298 insertions, 203 deletions
diff --git a/src/server/api/endpoints/notes/conversation.ts b/src/server/api/endpoints/notes/conversation.ts index b2bc6a2e72..e47b977279 100644 --- a/src/server/api/endpoints/notes/conversation.ts +++ b/src/server/api/endpoints/notes/conversation.ts @@ -5,17 +5,17 @@ import { ILocalUser } from '../../../../models/user'; /** * Show conversation of a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Lookup note diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts index 64f3b5ce26..45fc77503e 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -1,68 +1,126 @@ import $ from 'cafy'; import ID from '../../../../cafy-id'; import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note'; import User, { ILocalUser, IUser } from '../../../../models/user'; -import DriveFile from '../../../../models/drive-file'; +import DriveFile, { IDriveFile } from '../../../../models/drive-file'; import create from '../../../../services/note/create'; import { IApp } from '../../../../models/app'; +import getParams from '../../get-params'; -/** - * Create a note - */ -module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => { - // Get 'visibility' parameter - const [visibility = 'public', visibilityErr] = $.str.optional().or(['public', 'home', 'followers', 'specified', 'private']).get(params.visibility); - if (visibilityErr) return rej('invalid visibility'); +export const meta = { + name: 'notes/create', - // Get 'visibleUserIds' parameter - const [visibleUserIds, visibleUserIdsErr] = $.arr($.type(ID)).optional().unique().min(1).get(params.visibleUserIds); - if (visibleUserIdsErr) return rej('invalid visibleUserIds'); + desc: { + ja: '投稿します。' + }, - let visibleUsers: IUser[] = []; - if (visibleUserIds !== undefined) { - visibleUsers = await Promise.all(visibleUserIds.map(id => User.findOne({ - _id: id - }))); - } + params: { + visibility: $.str.optional.or(['public', 'home', 'followers', 'specified', 'private']).note({ + default: 'public', + desc: { + ja: '投稿の公開範囲' + } + }), - // Get 'text' parameter - const [text = null, textErr] = $.str.optional().nullable().pipe(isValidText).get(params.text); - if (textErr) return rej('invalid text'); + visibleUserIds: $.arr($.type(ID)).optional.unique().min(1).note({ + desc: { + ja: '(投稿の公開範囲が specified の場合)投稿を閲覧できるユーザー' + } + }), + + text: $.str.optional.nullable.pipe(isValidText).note({ + default: null, + desc: { + ja: '投稿内容' + } + }), + + cw: $.str.optional.nullable.pipe(isValidCw).note({ + desc: { + ja: 'コンテンツの警告。このパラメータを指定すると設定したテキストで投稿のコンテンツを隠す事が出来ます。' + } + }), - // Get 'cw' parameter - const [cw, cwErr] = $.str.optional().nullable().pipe(isValidCw).get(params.cw); - if (cwErr) return rej('invalid cw'); + viaMobile: $.bool.optional.note({ + default: false, + desc: { + ja: 'モバイルデバイスからの投稿か否か。' + } + }), - // Get 'viaMobile' parameter - const [viaMobile = false, viaMobileErr] = $.bool.optional().get(params.viaMobile); - if (viaMobileErr) return rej('invalid viaMobile'); + geo: $.obj({ + coordinates: $.arr().length(2) + .item(0, $.num.range(-180, 180)) + .item(1, $.num.range(-90, 90)), + altitude: $.num.nullable, + accuracy: $.num.nullable, + altitudeAccuracy: $.num.nullable, + heading: $.num.nullable.range(0, 360), + speed: $.num.nullable + }).optional.nullable.strict().note({ + desc: { + ja: '位置情報' + }, + ref: 'geo' + }), - // Get 'tags' parameter - const [tags = [], tagsErr] = $.arr($.str.range(1, 32)).optional().unique().get(params.tags); - if (tagsErr) return rej('invalid tags'); + mediaIds: $.arr($.type(ID)).optional.unique().range(1, 4).note({ + desc: { + ja: '添付するメディア' + } + }), - // Get 'geo' parameter - const [geo, geoErr] = $.obj.optional().nullable().strict() - .have('coordinates', $.arr().length(2) - .item(0, $.num.range(-180, 180)) - .item(1, $.num.range(-90, 90))) - .have('altitude', $.num.nullable()) - .have('accuracy', $.num.nullable()) - .have('altitudeAccuracy', $.num.nullable()) - .have('heading', $.num.nullable().range(0, 360)) - .have('speed', $.num.nullable()) - .get(params.geo); - if (geoErr) return rej('invalid geo'); + renoteId: $.type(ID).optional.note({ + desc: { + ja: 'Renote対象' + } + }), - // Get 'mediaIds' parameter - const [mediaIds, mediaIdsErr] = $.arr($.type(ID)).optional().unique().range(1, 4).get(params.mediaIds); - if (mediaIdsErr) return rej('invalid mediaIds'); + poll: $.obj({ + choices: $.arr($.str) + .unique() + .range(2, 10) + .each(c => c.length > 0 && c.length < 50) + }).optional.strict().note({ + desc: { + ja: 'アンケート' + }, + ref: 'poll' + }) + }, - let files = []; - if (mediaIds !== undefined) { + res: { + type: 'object', + object: { + createdNote: { + type: 'entity(Note)', + desc: { + ja: '作成した投稿' + } + } + } + } +}; + +/** + * Create a note + */ +export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); + + let visibleUsers: IUser[] = []; + if (ps.visibleUserIds !== undefined) { + visibleUsers = await Promise.all(ps.visibleUserIds.map(id => User.findOne({ + _id: id + }))); + } + + let files: IDriveFile[] = []; + if (ps.mediaIds !== undefined) { // Fetch files // forEach だと途中でエラーなどがあっても return できないので // 敢えて for を使っています。 - for (const mediaId of mediaIds) { + for (const mediaId of ps.mediaIds) { // Fetch file // SELECT _id const entity = await DriveFile.findOne({ @@ -80,15 +138,11 @@ module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async files = null; } - // Get 'renoteId' parameter - const [renoteId, renoteIdErr] = $.type(ID).optional().get(params.renoteId); - if (renoteIdErr) return rej('invalid renoteId'); - let renote: INote = null; - if (renoteId !== undefined) { + if (ps.renoteId !== undefined) { // Fetch renote to note renote = await Note.findOne({ - _id: renoteId + _id: ps.renoteId }); if (renote == null) { @@ -99,7 +153,7 @@ module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async } // Get 'replyId' parameter - const [replyId, replyIdErr] = $.type(ID).optional().get(params.replyId); + const [replyId, replyIdErr] = $.type(ID).optional.get(params.replyId); if (replyIdErr) return rej('invalid replyId'); let reply: INote = null; @@ -119,17 +173,8 @@ module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async } } - // Get 'poll' parameter - const [poll, pollErr] = $.obj.optional().strict() - .have('choices', $.arr($.str) - .unique() - .range(2, 10) - .each(c => c.length > 0 && c.length < 50)) - .get(params.poll); - if (pollErr) return rej('invalid poll'); - - if (poll) { - (poll as any).choices = (poll as any).choices.map((choice: string, i: number) => ({ + if (ps.poll) { + (ps.poll as any).choices = (ps.poll as any).choices.map((choice: string, i: number) => ({ id: i, // IDを付与 text: choice.trim(), votes: 0 @@ -137,7 +182,7 @@ module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async } // テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー - if ((text === undefined || text === null) && files === null && renote === null && poll === undefined) { + if ((ps.text === undefined || ps.text === null) && files === null && renote === null && ps.poll === undefined) { return rej('text, mediaIds, renoteId or poll is required'); } @@ -145,17 +190,16 @@ module.exports = (params: any, user: ILocalUser, app: IApp) => new Promise(async const note = await create(user, { createdAt: new Date(), media: files, - poll, - text, + poll: ps.poll, + text: ps.text, reply, renote, - cw, - tags, + cw: ps.cw, app, - viaMobile, - visibility, + viaMobile: ps.viaMobile, + visibility: ps.visibility, visibleUsers, - geo + geo: ps.geo }); const noteObj = await pack(note, user); diff --git a/src/server/api/endpoints/notes/delete.ts b/src/server/api/endpoints/notes/delete.ts index 70bcdbaab9..49907e4449 100644 --- a/src/server/api/endpoints/notes/delete.ts +++ b/src/server/api/endpoints/notes/delete.ts @@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../models/user'; /** * Delete a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/src/server/api/endpoints/notes/favorites/create.ts index 23f7ac5f8d..9ec75dbba6 100644 --- a/src/server/api/endpoints/notes/favorites/create.ts +++ b/src/server/api/endpoints/notes/favorites/create.ts @@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../../models/user'; /** * Favorite a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/src/server/api/endpoints/notes/favorites/delete.ts index 7d2d2b4cb5..f9916905bf 100644 --- a/src/server/api/endpoints/notes/favorites/delete.ts +++ b/src/server/api/endpoints/notes/favorites/delete.ts @@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../../models/user'; /** * Unfavorite a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts index 24ffdbcba7..6de83ddad0 100644 --- a/src/server/api/endpoints/notes/global-timeline.ts +++ b/src/server/api/endpoints/notes/global-timeline.ts @@ -7,25 +7,25 @@ import { ILocalUser } from '../../../../models/user'; /** * Get timeline of global */ -module.exports = async (params: any, user: ILocalUser) => { +export default async (params: any, user: ILocalUser) => { // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) throw 'invalid limit param'; // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); + const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); if (sinceIdErr) throw 'invalid sinceId param'; // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); + const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); if (untilIdErr) throw 'invalid untilId param'; // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $.num.optional().get(params.sinceDate); + const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); if (sinceDateErr) throw 'invalid sinceDate param'; // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $.num.optional().get(params.untilDate); + const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); if (untilDateErr) throw 'invalid untilDate param'; // Check if only one of sinceId, untilId, sinceDate, untilDate specified @@ -34,7 +34,7 @@ module.exports = async (params: any, user: ILocalUser) => { } // Get 'mediaOnly' parameter - const [mediaOnly, mediaOnlyErr] = $.bool.optional().get(params.mediaOnly); + const [mediaOnly, mediaOnlyErr] = $.bool.optional.get(params.mediaOnly); if (mediaOnlyErr) throw 'invalid mediaOnly param'; // ミュートしているユーザーを取得 diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts index 48490638d2..3e96877c74 100644 --- a/src/server/api/endpoints/notes/local-timeline.ts +++ b/src/server/api/endpoints/notes/local-timeline.ts @@ -7,25 +7,25 @@ import { ILocalUser } from '../../../../models/user'; /** * Get timeline of local */ -module.exports = async (params: any, user: ILocalUser) => { +export default async (params: any, user: ILocalUser) => { // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) throw 'invalid limit param'; // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); + const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); if (sinceIdErr) throw 'invalid sinceId param'; // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); + const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); if (untilIdErr) throw 'invalid untilId param'; // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $.num.optional().get(params.sinceDate); + const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); if (sinceDateErr) throw 'invalid sinceDate param'; // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $.num.optional().get(params.untilDate); + const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); if (untilDateErr) throw 'invalid untilDate param'; // Check if only one of sinceId, untilId, sinceDate, untilDate specified @@ -34,7 +34,7 @@ module.exports = async (params: any, user: ILocalUser) => { } // Get 'mediaOnly' parameter - const [mediaOnly, mediaOnlyErr] = $.bool.optional().get(params.mediaOnly); + const [mediaOnly, mediaOnlyErr] = $.bool.optional.get(params.mediaOnly); if (mediaOnlyErr) throw 'invalid mediaOnly param'; // ミュートしているユーザーを取得 diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts index 45511603af..82e3371ffa 100644 --- a/src/server/api/endpoints/notes/mentions.ts +++ b/src/server/api/endpoints/notes/mentions.ts @@ -7,22 +7,22 @@ import { ILocalUser } from '../../../../models/user'; /** * Get mentions of myself */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'following' parameter const [following = false, followingError] = - $.bool.optional().get(params.following); + $.bool.optional.get(params.following); if (followingError) return rej('invalid following param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); + const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); if (sinceIdErr) return rej('invalid sinceId param'); // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); + const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); 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 640140c3d1..f448bb66fc 100644 --- a/src/server/api/endpoints/notes/polls/recommendation.ts +++ b/src/server/api/endpoints/notes/polls/recommendation.ts @@ -6,13 +6,13 @@ import { ILocalUser } from '../../../../../models/user'; /** * Get recommended polls */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Get votes diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts index 72ac6bb202..b86d319b37 100644 --- a/src/server/api/endpoints/notes/polls/vote.ts +++ b/src/server/api/endpoints/notes/polls/vote.ts @@ -10,7 +10,7 @@ import { ILocalUser } from '../../../../../models/user'; /** * Vote poll of a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts index d3b2d43432..5e15ed3ec6 100644 --- a/src/server/api/endpoints/notes/reactions.ts +++ b/src/server/api/endpoints/notes/reactions.ts @@ -6,21 +6,21 @@ import { ILocalUser } from '../../../../models/user'; /** * Show reactions of a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Get 'sort' parameter - const [sort = 'desc', sortError] = $.str.optional().or('desc asc').get(params.sort); + const [sort = 'desc', sortError] = $.str.optional.or('desc asc').get(params.sort); if (sortError) return rej('invalid sort param'); // Lookup note diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts index 33e457e308..8b22e53225 100644 --- a/src/server/api/endpoints/notes/reactions/create.ts +++ b/src/server/api/endpoints/notes/reactions/create.ts @@ -3,22 +3,40 @@ import Note from '../../../../../models/note'; import create from '../../../../../services/note/reaction/create'; import { validateReaction } from '../../../../../models/note-reaction'; import { ILocalUser } from '../../../../../models/user'; +import getParams from '../../../get-params'; + +export const meta = { + name: 'notes/reactions/create', + + desc: { + ja: '投稿にリアクションします。' + }, + + params: { + noteId: $.type(ID).note({ + desc: { + ja: '対象の投稿' + } + }), + + reaction: $.str.pipe(validateReaction.ok).note({ + desc: { + ja: 'リアクションの種類' + } + }) + } +}; /** * React to a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { - // Get 'noteId' parameter - const [noteId, noteIdErr] = $.type(ID).get(params.noteId); - if (noteIdErr) return rej('invalid noteId param'); - - // Get 'reaction' parameter - const [reaction, reactionErr] = $.str.pipe(validateReaction.ok).get(params.reaction); - if (reactionErr) return rej('invalid reaction param'); +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); // Fetch reactee const note = await Note.findOne({ - _id: noteId + _id: ps.noteId }); if (note === null) { @@ -26,7 +44,7 @@ module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) } try { - await create(user, note, reaction); + await create(user, note, ps.reaction); } catch (e) { rej(e); } diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts index 1f2d662511..81671751a0 100644 --- a/src/server/api/endpoints/notes/reactions/delete.ts +++ b/src/server/api/endpoints/notes/reactions/delete.ts @@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../../models/user'; /** * Unreact to a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts index 4aaf1d322b..baefde3159 100644 --- a/src/server/api/endpoints/notes/replies.ts +++ b/src/server/api/endpoints/notes/replies.ts @@ -5,17 +5,17 @@ import { ILocalUser } from '../../../../models/user'; /** * Get replies of a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Lookup note diff --git a/src/server/api/endpoints/notes/reposts.ts b/src/server/api/endpoints/notes/reposts.ts index ea3f174e1a..118e684a87 100644 --- a/src/server/api/endpoints/notes/reposts.ts +++ b/src/server/api/endpoints/notes/reposts.ts @@ -5,21 +5,21 @@ import { ILocalUser } from '../../../../models/user'; /** * Show a renotes of a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); + const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); if (sinceIdErr) return rej('invalid sinceId param'); // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); + const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); 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 20c628b84d..badaa7afc0 100644 --- a/src/server/api/endpoints/notes/search.ts +++ b/src/server/api/endpoints/notes/search.ts @@ -5,17 +5,17 @@ import { ILocalUser } from '../../../../models/user'; import { pack } from '../../../../models/note'; import es from '../../../../db/elasticsearch'; -module.exports = (params: any, me: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { // Get 'query' parameter const [query, queryError] = $.str.get(params.query); if (queryError) return rej('invalid query param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 30).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 30).get(params.limit); if (limitErr) return rej('invalid limit param'); es.search({ diff --git a/src/server/api/endpoints/notes/search_by_tag.ts b/src/server/api/endpoints/notes/search_by_tag.ts index 9be7cfffb6..a6fcae5932 100644 --- a/src/server/api/endpoints/notes/search_by_tag.ts +++ b/src/server/api/endpoints/notes/search_by_tag.ts @@ -8,65 +8,65 @@ import { pack } from '../../../../models/note'; /** * Search notes by tag */ -module.exports = (params: any, me: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { // Get 'tag' parameter const [tag, tagError] = $.str.get(params.tag); if (tagError) return rej('invalid tag param'); // Get 'includeUserIds' parameter - const [includeUserIds = [], includeUserIdsErr] = $.arr($.type(ID)).optional().get(params.includeUserIds); + const [includeUserIds = [], includeUserIdsErr] = $.arr($.type(ID)).optional.get(params.includeUserIds); if (includeUserIdsErr) return rej('invalid includeUserIds param'); // Get 'excludeUserIds' parameter - const [excludeUserIds = [], excludeUserIdsErr] = $.arr($.type(ID)).optional().get(params.excludeUserIds); + const [excludeUserIds = [], excludeUserIdsErr] = $.arr($.type(ID)).optional.get(params.excludeUserIds); if (excludeUserIdsErr) return rej('invalid excludeUserIds param'); // Get 'includeUserUsernames' parameter - const [includeUserUsernames = [], includeUserUsernamesErr] = $.arr($.str).optional().get(params.includeUserUsernames); + const [includeUserUsernames = [], includeUserUsernamesErr] = $.arr($.str).optional.get(params.includeUserUsernames); if (includeUserUsernamesErr) return rej('invalid includeUserUsernames param'); // Get 'excludeUserUsernames' parameter - const [excludeUserUsernames = [], excludeUserUsernamesErr] = $.arr($.str).optional().get(params.excludeUserUsernames); + const [excludeUserUsernames = [], excludeUserUsernamesErr] = $.arr($.str).optional.get(params.excludeUserUsernames); if (excludeUserUsernamesErr) return rej('invalid excludeUserUsernames param'); // Get 'following' parameter - const [following = null, followingErr] = $.bool.optional().nullable().get(params.following); + const [following = null, followingErr] = $.bool.optional.nullable.get(params.following); if (followingErr) return rej('invalid following param'); // Get 'mute' parameter - const [mute = 'mute_all', muteErr] = $.str.optional().get(params.mute); + const [mute = 'mute_all', muteErr] = $.str.optional.get(params.mute); if (muteErr) return rej('invalid mute param'); // Get 'reply' parameter - const [reply = null, replyErr] = $.bool.optional().nullable().get(params.reply); + const [reply = null, replyErr] = $.bool.optional.nullable.get(params.reply); if (replyErr) return rej('invalid reply param'); // Get 'renote' parameter - const [renote = null, renoteErr] = $.bool.optional().nullable().get(params.renote); + const [renote = null, renoteErr] = $.bool.optional.nullable.get(params.renote); if (renoteErr) return rej('invalid renote param'); // Get 'media' parameter - const [media = null, mediaErr] = $.bool.optional().nullable().get(params.media); + const [media = null, mediaErr] = $.bool.optional.nullable.get(params.media); if (mediaErr) return rej('invalid media param'); // Get 'poll' parameter - const [poll = null, pollErr] = $.bool.optional().nullable().get(params.poll); + const [poll = null, pollErr] = $.bool.optional.nullable.get(params.poll); if (pollErr) return rej('invalid poll param'); // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $.num.optional().get(params.sinceDate); + const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); if (sinceDateErr) throw 'invalid sinceDate param'; // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $.num.optional().get(params.untilDate); + const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); if (untilDateErr) throw 'invalid untilDate param'; // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 30).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 30).get(params.limit); if (limitErr) return rej('invalid limit param'); if (includeUserUsernames != null) { diff --git a/src/server/api/endpoints/notes/show.ts b/src/server/api/endpoints/notes/show.ts index 1ba7145996..0a27494962 100644 --- a/src/server/api/endpoints/notes/show.ts +++ b/src/server/api/endpoints/notes/show.ts @@ -5,7 +5,7 @@ import { ILocalUser } from '../../../../models/user'; /** * Show a note */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'noteId' parameter const [noteId, noteIdErr] = $.type(ID).get(params.noteId); if (noteIdErr) return rej('invalid noteId param'); diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts index 18c0acd379..43194c78c0 100644 --- a/src/server/api/endpoints/notes/timeline.ts +++ b/src/server/api/endpoints/notes/timeline.ts @@ -4,47 +4,80 @@ import Mute from '../../../../models/mute'; import { getFriends } from '../../common/get-friends'; import { pack } from '../../../../models/note'; import { ILocalUser } from '../../../../models/user'; +import getParams from '../../get-params'; -/** - * Get timeline of myself - */ -module.exports = async (params: any, user: ILocalUser) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); - if (limitErr) throw 'invalid limit param'; +export const meta = { + name: 'notes/timeline', - // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); - if (sinceIdErr) throw 'invalid sinceId param'; + desc: { + ja: 'タイムラインを取得します。' + }, - // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); - if (untilIdErr) throw 'invalid untilId param'; + params: { + limit: $.num.optional.range(1, 100).note({ + default: 10, + desc: { + ja: '最大数' + } + }), - // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $.num.optional().get(params.sinceDate); - if (sinceDateErr) throw 'invalid sinceDate param'; + sinceId: $.type(ID).optional.note({ + desc: { + ja: '指定すると、この投稿を基点としてより新しい投稿を取得します' + } + }), - // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $.num.optional().get(params.untilDate); - if (untilDateErr) throw 'invalid untilDate param'; + untilId: $.type(ID).optional.note({ + desc: { + ja: '指定すると、この投稿を基点としてより古い投稿を取得します' + } + }), - // 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'; - } + sinceDate: $.num.optional.note({ + desc: { + ja: '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + } + }), - // Get 'includeMyRenotes' parameter - const [includeMyRenotes = true, includeMyRenotesErr] = $.bool.optional().get(params.includeMyRenotes); - if (includeMyRenotesErr) throw 'invalid includeMyRenotes param'; + untilDate: $.num.optional.note({ + desc: { + ja: '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + } + }), - // Get 'includeRenotedMyNotes' parameter - const [includeRenotedMyNotes = true, includeRenotedMyNotesErr] = $.bool.optional().get(params.includeRenotedMyNotes); - if (includeRenotedMyNotesErr) throw 'invalid includeRenotedMyNotes param'; + includeMyRenotes: $.bool.optional.note({ + default: true, + desc: { + ja: '自分の行ったRenoteを含めるかどうか' + } + }), - // Get 'mediaOnly' parameter - const [mediaOnly, mediaOnlyErr] = $.bool.optional().get(params.mediaOnly); - if (mediaOnlyErr) throw 'invalid mediaOnly param'; + includeRenotedMyNotes: $.bool.optional.note({ + default: true, + desc: { + ja: 'Renoteされた自分の投稿を含めるかどうか' + } + }), + + mediaOnly: $.bool.optional.note({ + desc: { + ja: 'true にすると、メディアが添付された投稿だけ取得します' + } + }), + } +}; + +/** + * Get timeline of myself + */ +export default async (params: any, user: ILocalUser) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) throw psErr; + + // Check if only one of sinceId, untilId, sinceDate, untilDate specified + if ([ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate].filter(x => x != null).length > 1) { + throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; + } const [followings, mutedUserIds] = await Promise.all([ // フォローを取得 @@ -107,7 +140,7 @@ module.exports = async (params: any, user: ILocalUser) => { // つまり、「『自分の投稿かつRenote』ではない」を「『自分の投稿ではない』または『Renoteではない』」と表現します。 // for details: https://en.wikipedia.org/wiki/De_Morgan%27s_laws - if (includeMyRenotes === false) { + if (ps.includeMyRenotes === false) { query.$and.push({ $or: [{ userId: { $ne: user._id } @@ -123,7 +156,7 @@ module.exports = async (params: any, user: ILocalUser) => { }); } - if (includeRenotedMyNotes === false) { + if (ps.includeRenotedMyNotes === false) { query.$and.push({ $or: [{ '_renote.userId': { $ne: user._id } @@ -139,29 +172,29 @@ module.exports = async (params: any, user: ILocalUser) => { }); } - if (mediaOnly) { + if (ps.mediaOnly) { query.$and.push({ mediaIds: { $exists: true, $ne: [] } }); } - if (sinceId) { + if (ps.sinceId) { sort._id = 1; query._id = { - $gt: sinceId + $gt: ps.sinceId }; - } else if (untilId) { + } else if (ps.untilId) { query._id = { - $lt: untilId + $lt: ps.untilId }; - } else if (sinceDate) { + } else if (ps.sinceDate) { sort._id = 1; query.createdAt = { - $gt: new Date(sinceDate) + $gt: new Date(ps.sinceDate) }; - } else if (untilDate) { + } else if (ps.untilDate) { query.createdAt = { - $lt: new Date(untilDate) + $lt: new Date(ps.untilDate) }; } //#endregion @@ -169,7 +202,7 @@ module.exports = async (params: any, user: ILocalUser) => { // Issue query const timeline = await Note .find(query, { - limit: limit, + limit: ps.limit, sort: sort }); diff --git a/src/server/api/endpoints/notes/trend.ts b/src/server/api/endpoints/notes/trend.ts index 9c0a1bb112..ae66234c0b 100644 --- a/src/server/api/endpoints/notes/trend.ts +++ b/src/server/api/endpoints/notes/trend.ts @@ -6,29 +6,29 @@ import { ILocalUser } from '../../../../models/user'; /** * Get trend notes */ -module.exports = (params: any, user: ILocalUser) => new Promise(async (res, rej) => { +export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => { // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - const [offset = 0, offsetErr] = $.num.optional().min(0).get(params.offset); + const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); if (offsetErr) return rej('invalid offset param'); // Get 'reply' parameter - const [reply, replyErr] = $.bool.optional().get(params.reply); + const [reply, replyErr] = $.bool.optional.get(params.reply); if (replyErr) return rej('invalid reply param'); // Get 'renote' parameter - const [renote, renoteErr] = $.bool.optional().get(params.renote); + const [renote, renoteErr] = $.bool.optional.get(params.renote); if (renoteErr) return rej('invalid renote param'); // Get 'media' parameter - const [media, mediaErr] = $.bool.optional().get(params.media); + const [media, mediaErr] = $.bool.optional.get(params.media); if (mediaErr) return rej('invalid media param'); // Get 'poll' parameter - const [poll, pollErr] = $.bool.optional().get(params.poll); + const [poll, pollErr] = $.bool.optional.get(params.poll); if (pollErr) return rej('invalid poll param'); const query = { diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts index 8aa800b712..8a59857392 100644 --- a/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/src/server/api/endpoints/notes/user-list-timeline.ts @@ -8,25 +8,25 @@ import { ILocalUser } from '../../../../models/user'; /** * Get timeline of a user list */ -module.exports = async (params: any, user: ILocalUser) => { +export default async (params: any, user: ILocalUser) => { // Get 'limit' parameter - const [limit = 10, limitErr] = $.num.optional().range(1, 100).get(params.limit); + const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); if (limitErr) throw 'invalid limit param'; // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $.type(ID).optional().get(params.sinceId); + const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); if (sinceIdErr) throw 'invalid sinceId param'; // Get 'untilId' parameter - const [untilId, untilIdErr] = $.type(ID).optional().get(params.untilId); + const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); if (untilIdErr) throw 'invalid untilId param'; // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $.num.optional().get(params.sinceDate); + const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); if (sinceDateErr) throw 'invalid sinceDate param'; // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $.num.optional().get(params.untilDate); + const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); if (untilDateErr) throw 'invalid untilDate param'; // Check if only one of sinceId, untilId, sinceDate, untilDate specified @@ -35,15 +35,15 @@ module.exports = async (params: any, user: ILocalUser) => { } // Get 'includeMyRenotes' parameter - const [includeMyRenotes = true, includeMyRenotesErr] = $.bool.optional().get(params.includeMyRenotes); + const [includeMyRenotes = true, includeMyRenotesErr] = $.bool.optional.get(params.includeMyRenotes); if (includeMyRenotesErr) throw 'invalid includeMyRenotes param'; // Get 'includeRenotedMyNotes' parameter - const [includeRenotedMyNotes = true, includeRenotedMyNotesErr] = $.bool.optional().get(params.includeRenotedMyNotes); + const [includeRenotedMyNotes = true, includeRenotedMyNotesErr] = $.bool.optional.get(params.includeRenotedMyNotes); if (includeRenotedMyNotesErr) throw 'invalid includeRenotedMyNotes param'; // Get 'mediaOnly' parameter - const [mediaOnly, mediaOnlyErr] = $.bool.optional().get(params.mediaOnly); + const [mediaOnly, mediaOnlyErr] = $.bool.optional.get(params.mediaOnly); if (mediaOnlyErr) throw 'invalid mediaOnly param'; // Get 'listId' parameter |