From 4e15337a6467c9e0afda22ec095c181724bd5243 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 23 Feb 2019 11:20:58 +0900 Subject: [PATCH] Introduce OpenAPI specs (#4351) * wip * wip * wip * Update index.ts * Update gen-openapi-spec.ts * Update api.ja-JP.md * Fix * Improve doc * Update gen-openapi-spec.ts * Update redoc.html * Improve doc * Update gen-openapi-spec.ts * Improve doc * Update CHANGELOG.md --- CHANGELOG.md | 1 + assets/api-doc.png | 3 + package.json | 2 +- src/client/assets/redoc.html | 24 + src/docs/api.ja-JP.md | 2 +- src/docs/api/endpoints/style.styl | 40 -- src/docs/api/endpoints/view.pug | 81 --- src/docs/api/entities/drive-file.yaml | 90 ---- src/docs/api/entities/drive-folder.yaml | 41 -- src/docs/api/entities/note.yaml | 211 -------- src/docs/api/entities/style.styl | 1 - src/docs/api/entities/user.yaml | 174 ------ src/docs/api/entities/view.pug | 20 - src/docs/api/mixins.pug | 34 -- src/docs/api/style.styl | 11 - src/docs/base.pug | 11 - src/misc/cafy-id.ts | 4 +- src/server/api/api-handler.ts | 2 +- src/server/api/call.ts | 3 + src/server/api/endpoints.ts | 22 +- .../api/endpoints/admin/abuse-user-reports.ts | 2 + src/server/api/endpoints/admin/drive/files.ts | 2 + .../api/endpoints/admin/drive/show-file.ts | 2 + src/server/api/endpoints/admin/emoji/add.ts | 2 + src/server/api/endpoints/admin/emoji/list.ts | 2 + .../api/endpoints/admin/emoji/remove.ts | 2 + .../api/endpoints/admin/emoji/update.ts | 2 + .../admin/federation/remove-all-following.ts | 2 + .../admin/federation/update-instance.ts | 2 + src/server/api/endpoints/admin/invite.ts | 2 + .../api/endpoints/admin/moderators/add.ts | 2 + .../api/endpoints/admin/moderators/remove.ts | 2 + src/server/api/endpoints/admin/queue/clear.ts | 2 + .../admin/remove-abuse-user-report.ts | 2 + .../api/endpoints/admin/reset-password.ts | 2 + src/server/api/endpoints/admin/show-user.ts | 2 + src/server/api/endpoints/admin/show-users.ts | 2 + .../api/endpoints/admin/silence-user.ts | 2 + .../api/endpoints/admin/suspend-user.ts | 2 + .../api/endpoints/admin/unsilence-user.ts | 2 + .../api/endpoints/admin/unsuspend-user.ts | 2 + .../api/endpoints/admin/unverify-user.ts | 2 + src/server/api/endpoints/admin/update-meta.ts | 2 + .../api/endpoints/admin/update-remote-user.ts | 2 + src/server/api/endpoints/admin/verify-user.ts | 2 + .../api/endpoints/aggregation/hashtags.ts | 2 + src/server/api/endpoints/ap/show.ts | 2 + src/server/api/endpoints/app/create.ts | 2 + src/server/api/endpoints/app/show.ts | 2 + src/server/api/endpoints/auth/accept.ts | 2 + .../api/endpoints/auth/session/generate.ts | 2 + src/server/api/endpoints/auth/session/show.ts | 2 + .../api/endpoints/auth/session/userkey.ts | 2 + src/server/api/endpoints/blocking/create.ts | 2 + src/server/api/endpoints/blocking/delete.ts | 2 + src/server/api/endpoints/blocking/list.ts | 2 + .../api/endpoints/charts/active-users.ts | 11 +- src/server/api/endpoints/charts/drive.ts | 11 +- src/server/api/endpoints/charts/federation.ts | 11 +- src/server/api/endpoints/charts/hashtag.ts | 11 +- src/server/api/endpoints/charts/instance.ts | 11 +- src/server/api/endpoints/charts/network.ts | 11 +- src/server/api/endpoints/charts/notes.ts | 11 +- src/server/api/endpoints/charts/user/drive.ts | 11 +- .../api/endpoints/charts/user/following.ts | 11 +- src/server/api/endpoints/charts/user/notes.ts | 11 +- .../api/endpoints/charts/user/reactions.ts | 11 +- src/server/api/endpoints/charts/users.ts | 11 +- src/server/api/endpoints/drive.ts | 2 + src/server/api/endpoints/drive/files.ts | 11 +- .../endpoints/drive/files/attached_notes.ts | 2 + .../endpoints/drive/files/check_existence.ts | 2 + .../api/endpoints/drive/files/create.ts | 10 +- .../api/endpoints/drive/files/delete.ts | 2 + src/server/api/endpoints/drive/files/find.ts | 2 + src/server/api/endpoints/drive/files/show.ts | 6 + .../api/endpoints/drive/files/update.ts | 2 + .../endpoints/drive/files/upload_from_url.ts | 2 + src/server/api/endpoints/drive/folders.ts | 2 + .../api/endpoints/drive/folders/create.ts | 2 + .../api/endpoints/drive/folders/delete.ts | 2 + .../api/endpoints/drive/folders/find.ts | 2 + .../api/endpoints/drive/folders/show.ts | 2 + .../api/endpoints/drive/folders/update.ts | 2 + src/server/api/endpoints/drive/stream.ts | 2 + .../api/endpoints/federation/instances.ts | 2 + .../api/endpoints/federation/show-instance.ts | 2 + src/server/api/endpoints/following/create.ts | 2 + src/server/api/endpoints/following/delete.ts | 2 + .../endpoints/following/requests/accept.ts | 2 + .../endpoints/following/requests/cancel.ts | 2 + .../api/endpoints/following/requests/list.ts | 2 + .../endpoints/following/requests/reject.ts | 2 + .../api/endpoints/games/reversi/games.ts | 2 + .../api/endpoints/games/reversi/games/show.ts | 2 + .../games/reversi/games/surrender.ts | 2 + .../endpoints/games/reversi/invitations.ts | 2 + .../api/endpoints/games/reversi/match.ts | 2 + .../endpoints/games/reversi/match/cancel.ts | 2 + src/server/api/endpoints/hashtags/list.ts | 2 + src/server/api/endpoints/hashtags/search.ts | 2 + src/server/api/endpoints/hashtags/trend.ts | 2 + src/server/api/endpoints/hashtags/users.ts | 2 + src/server/api/endpoints/i.ts | 2 + .../i/clear-follow-request-notification.ts | 2 + src/server/api/endpoints/i/favorites.ts | 2 + src/server/api/endpoints/i/notifications.ts | 2 + src/server/api/endpoints/i/pin.ts | 2 + .../i/read_all_messaging_messages.ts | 2 + .../api/endpoints/i/read_all_unread_notes.ts | 2 + src/server/api/endpoints/i/unpin.ts | 2 + src/server/api/endpoints/i/update.ts | 2 + src/server/api/endpoints/messaging/history.ts | 2 + .../api/endpoints/messaging/messages.ts | 2 + .../endpoints/messaging/messages/create.ts | 2 + .../endpoints/messaging/messages/delete.ts | 2 + .../api/endpoints/messaging/messages/read.ts | 2 + src/server/api/endpoints/meta.ts | 2 + src/server/api/endpoints/mute/create.ts | 2 + src/server/api/endpoints/mute/delete.ts | 2 + src/server/api/endpoints/mute/list.ts | 2 + src/server/api/endpoints/my/apps.ts | 2 + src/server/api/endpoints/notes.ts | 2 + .../api/endpoints/notes/conversation.ts | 9 + src/server/api/endpoints/notes/create.ts | 4 +- src/server/api/endpoints/notes/delete.ts | 2 + .../api/endpoints/notes/favorites/create.ts | 2 + .../api/endpoints/notes/favorites/delete.ts | 2 + src/server/api/endpoints/notes/featured.ts | 11 +- .../api/endpoints/notes/global-timeline.ts | 9 + .../api/endpoints/notes/hybrid-timeline.ts | 9 + .../api/endpoints/notes/local-timeline.ts | 9 + src/server/api/endpoints/notes/mentions.ts | 11 +- .../endpoints/notes/polls/recommendation.ts | 2 + src/server/api/endpoints/notes/polls/vote.ts | 2 + src/server/api/endpoints/notes/reactions.ts | 2 + .../api/endpoints/notes/reactions/create.ts | 2 + .../api/endpoints/notes/reactions/delete.ts | 2 + src/server/api/endpoints/notes/renotes.ts | 9 + src/server/api/endpoints/notes/replies.ts | 11 +- src/server/api/endpoints/notes/search.ts | 9 + .../api/endpoints/notes/search_by_tag.ts | 11 +- src/server/api/endpoints/notes/show.ts | 6 + src/server/api/endpoints/notes/state.ts | 2 + src/server/api/endpoints/notes/timeline.ts | 11 +- .../api/endpoints/notes/user-list-timeline.ts | 9 + .../api/endpoints/notes/watching/create.ts | 2 + .../api/endpoints/notes/watching/delete.ts | 2 + .../notifications/mark_all_as_read.ts | 2 + src/server/api/endpoints/stats.ts | 2 + src/server/api/endpoints/sw/register.ts | 2 + .../api/endpoints/username/available.ts | 2 + src/server/api/endpoints/users.ts | 2 + src/server/api/endpoints/users/followers.ts | 2 + src/server/api/endpoints/users/following.ts | 2 + .../users/get_frequently_replied_users.ts | 2 + .../api/endpoints/users/lists/create.ts | 2 + .../api/endpoints/users/lists/delete.ts | 2 + src/server/api/endpoints/users/lists/list.ts | 2 + src/server/api/endpoints/users/lists/pull.ts | 2 + src/server/api/endpoints/users/lists/push.ts | 2 + src/server/api/endpoints/users/lists/show.ts | 2 + .../api/endpoints/users/lists/update.ts | 2 + src/server/api/endpoints/users/notes.ts | 9 + .../api/endpoints/users/recommendation.ts | 2 + src/server/api/endpoints/users/relation.ts | 4 +- .../api/endpoints/users/report-abuse.ts | 2 + src/server/api/endpoints/users/search.ts | 2 + src/server/api/endpoints/users/show.ts | 6 + src/server/api/error.ts | 7 +- src/server/api/gen-openapi-spec.ts | 507 ++++++++++++++++++ src/server/web/docs.ts | 129 ----- src/server/web/index.ts | 10 + 173 files changed, 1094 insertions(+), 876 deletions(-) create mode 100644 assets/api-doc.png create mode 100644 src/client/assets/redoc.html delete mode 100644 src/docs/api/endpoints/style.styl delete mode 100644 src/docs/api/endpoints/view.pug delete mode 100644 src/docs/api/entities/drive-file.yaml delete mode 100644 src/docs/api/entities/drive-folder.yaml delete mode 100644 src/docs/api/entities/note.yaml delete mode 100644 src/docs/api/entities/style.styl delete mode 100644 src/docs/api/entities/user.yaml delete mode 100644 src/docs/api/entities/view.pug delete mode 100644 src/docs/api/mixins.pug delete mode 100644 src/docs/api/style.styl create mode 100644 src/server/api/gen-openapi-spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f929f39a3..b9479bcbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ChangeLog unreleasded ---------- +* APIドキュメント刷新 * /api/v1/instance/peers 復活 * 「返信が遷移後も残り続ける問題を修正」([9beddc9](https://github.com/syuilo/misskey/commit/9beddc941a716f1322ae0b7d71d159edd642a399)) によって遷移前に返信が表示されなくなった問題を修正 * デッキモードにてユーザーのプロフィールを連続で見たとき、アクティビティや画像が前のユーザーのもののまま表示される問題を修正 diff --git a/assets/api-doc.png b/assets/api-doc.png new file mode 100644 index 000000000..47d042b70 --- /dev/null +++ b/assets/api-doc.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8f1269d35880c41bf0c40f80978baabdc0e18a7e9b0d139d5803f4197fd0e7f +size 5994 diff --git a/package.json b/package.json index 8f38b0a1a..ed14c0020 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "bcryptjs": "2.4.3", "bee-queue": "1.2.2", "bootstrap-vue": "2.0.0-rc.11", - "cafy": "14.0.1", + "cafy": "15.1.0", "chai": "4.2.0", "chai-http": "4.2.1", "chalk": "2.4.2", diff --git a/src/client/assets/redoc.html b/src/client/assets/redoc.html new file mode 100644 index 000000000..9803464cb --- /dev/null +++ b/src/client/assets/redoc.html @@ -0,0 +1,24 @@ + + + + Misskey API + + + + + + + + + + + + + diff --git a/src/docs/api.ja-JP.md b/src/docs/api.ja-JP.md index ecc80cc05..b8e84e670 100644 --- a/src/docs/api.ja-JP.md +++ b/src/docs/api.ja-JP.md @@ -74,7 +74,7 @@ APIはすべてリクエストのパラメータ・レスポンスともにJSON ストリーミングAPIも提供しています。 -APIリファレンスもご確認ください。 +[APIリファレンス](/api-doc)もご確認ください。 ### レートリミット Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。 diff --git a/src/docs/api/endpoints/style.styl b/src/docs/api/endpoints/style.styl deleted file mode 100644 index 56ad29162..000000000 --- a/src/docs/api/endpoints/style.styl +++ /dev/null @@ -1,40 +0,0 @@ -@import "../style" - -#url - padding 8px 12px 8px 8px - font-family Consolas, 'Courier New', Courier, Monaco, monospace - color #fff - background #222e40 - border-radius 4px - overflow auto - white-space nowrap - - > .method - display inline-block - margin 0 8px 0 0 - padding 0 6px - color #fff - background #17afc7 - border-radius 4px - user-select none - pointer-events none - - > .host - opacity 0.7 - -#stability - padding 8px 12px - color #fff - border-radius 4px - - &.deprecated - background #f42443 - - &.experimental - background #f2781a - - &.stable - background #3dcc90 - - > b - margin-left 4px diff --git a/src/docs/api/endpoints/view.pug b/src/docs/api/endpoints/view.pug deleted file mode 100644 index 696ec4050..000000000 --- a/src/docs/api/endpoints/view.pug +++ /dev/null @@ -1,81 +0,0 @@ -extends ../../base -include ../mixins - -block meta - link(rel="stylesheet" href="/docs/assets/api/endpoints/style.css") - -block main - h1= title - - p#url - span.method POST - span.host - = endpointUrl.host - | / - span.path= endpointUrl.path - - - var stability = endpoint.stability || 'experimental'; - p#stability(class=stability) - | Stability: - b= stability - - if endpoint.desc - p#desc= endpoint.desc[lang] || endpoint.desc['ja-JP'] - - if endpoint.requireCredential - div.ui.info: p - i.fas.fa-id-card-alt(style="margin-right: 4px") - = i18n('docs.api.endpoints.require-credential') - - if endpoint.kind - div.ui.info: p - i.fas.fa-unlock-alt(style="margin-right: 4px") - != i18n('docs.api.endpoints.require-permission').replace('{permission}', `${endpoint.kind}`) - - if endpoint.limit - div.ui.info.warn: p - i.far.fa-clock(style="margin-right: 4px") - b!= i18n('docs.api.endpoints.has-limit') - if endpoint.limit.duration - != i18n('docs.api.endpoints.duration-limit').replace('{duration}', endpoint.limit.duration).replace('{max}', endpoint.limit.max) - if endpoint.limit.minInterval - != i18n('docs.api.endpoints.min-interval-limit').replace('{interval}', endpoint.limit.minInterval) - - if params && Object.keys(params).length > 0 - section - h2= i18n('docs.api.endpoints.params') - +propTable(params) - - if paramDefs - each paramDef in paramDefs - section(id= paramDef.name) - h3= paramDef.name - +propTable(paramDef.params) - if params && Object.keys(params).length == 0 - section - h2= i18n('docs.api.endpoints.params') - p= i18n('docs.api.endpoints.no-params') - - if res - section - h2= i18n('docs.api.endpoints.res') - - if resProps - +propTable(resProps) - - if resDefs - each resDef in resDefs - section(id= resDef.name) - h3= resDef.name - +propTable(resDef.props) - else - if res.type.startsWith('entity') - a(href=`/docs/${lang}/api/entities/${kebab(res.entity)}`)= res.entity - -block footer - div.ui.info: p - i.fas.fa-info-circle(style="margin-right: 4px") - = i18n('docs.api.endpoints.generated') - p - = i18n('docs.api.endpoints.show-src') - a(href=src target="_blank")= i18n('docs.api.endpoints.show-src-link') diff --git a/src/docs/api/entities/drive-file.yaml b/src/docs/api/entities/drive-file.yaml deleted file mode 100644 index 0c2195ac0..000000000 --- a/src/docs/api/entities/drive-file.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: "DriveFile" - -desc: - ja-JP: "ドライブのファイル。" - en-US: "A file of Drive." - -props: - id: - type: "id" - optional: false - desc: - ja-JP: "ファイルID" - en-US: "The ID of this file" - - createdAt: - type: "date" - optional: false - desc: - ja-JP: "アップロード日時" - en-US: "The upload date of this file" - - userId: - type: "id(User)" - optional: false - desc: - ja-JP: "所有者ID" - en-US: "The ID of the owner of this file" - - user: - type: "entity(User)" - optional: true - desc: - ja-JP: "所有者" - en-US: "The owner of this file" - - name: - type: "string" - optional: false - desc: - ja-JP: "ファイル名" - en-US: "The name of this file" - - md5: - type: "string" - optional: false - desc: - ja-JP: "ファイルのMD5ハッシュ値" - en-US: "The md5 hash value of this file" - - type: - type: "string" - optional: false - desc: - ja-JP: "ファイルの種類" - en-US: "The type of this file" - - datasize: - type: "number" - optional: false - desc: - ja-JP: "ファイルサイズ(bytes)" - en-US: "The size of this file (bytes)" - - url: - type: "string" - optional: false - desc: - ja-JP: "ファイルのURL" - en-US: "The URL of this file" - - folderId: - type: "id(DriveFolder)" - optional: true - desc: - ja-JP: "フォルダID" - en-US: "The ID of the folder of this file" - - folder: - type: "entity(DriveFolder)" - optional: true - desc: - ja-JP: "フォルダ" - en-US: "The folder of this file" - - isSensitive: - type: "boolean" - optional: true - desc: - ja-JP: "このメディアが「閲覧注意」(NSFW)かどうか" - en-US: "Whether this media is NSFW" diff --git a/src/docs/api/entities/drive-folder.yaml b/src/docs/api/entities/drive-folder.yaml deleted file mode 100644 index e3dfd2ca0..000000000 --- a/src/docs/api/entities/drive-folder.yaml +++ /dev/null @@ -1,41 +0,0 @@ -name: "DriveFolder" - -desc: - ja-JP: "ドライブのフォルダを表します。" - en-US: "A folder of Drive." - -props: - id: - type: "id" - optional: false - desc: - ja-JP: "フォルダID" - en-US: "The ID of this folder" - - createdAt: - type: "date" - optional: false - desc: - ja-JP: "作成日時" - en-US: "The created date of this folder" - - userId: - type: "id(User)" - optional: false - desc: - ja-JP: "所有者ID" - en-US: "The ID of the owner of this folder" - - parentId: - type: "entity(DriveFolder)" - optional: false - desc: - ja-JP: "親フォルダのID (ルートなら null)" - en-US: "The ID of parent folder" - - name: - type: "string" - optional: false - desc: - ja-JP: "フォルダ名" - en-US: "The name of this folder" diff --git a/src/docs/api/entities/note.yaml b/src/docs/api/entities/note.yaml deleted file mode 100644 index ce0c5de2e..000000000 --- a/src/docs/api/entities/note.yaml +++ /dev/null @@ -1,211 +0,0 @@ -name: "Note" - -desc: - ja-JP: "投稿。" - en-US: "A note." - -props: - id: - type: "id" - optional: false - desc: - ja-JP: "投稿ID" - en-US: "The ID of this note" - - createdAt: - type: "date" - optional: false - desc: - ja-JP: "投稿日時" - en-US: "The posted date of this note" - - viaMobile: - type: "boolean" - optional: true - desc: - ja-JP: "モバイル端末から投稿したか否か(自己申告であることに留意)" - en-US: "Whether this note sent via a mobile device" - - localOnly: - type: "boolean" - optional: true - desc: - ja-JP: "ローカルのみに公開する投稿か否か" - en-US: "Whether this note is no federation" - - text: - type: "string" - optional: true - desc: - ja-JP: "投稿の本文" - en-US: "The text of this note" - - fileIds: - type: "id(DriveFile)[]" - optional: true - desc: - ja-JP: "添付されているファイルのID (なければレスポンスでは空配列)" - en-US: "The IDs of the attached files (empty array for response if no files is attached)" - - files: - type: "entity(DriveFile)[]" - optional: true - desc: - ja-JP: "添付されているファイル" - en-US: "The attached files" - - userId: - type: "id(User)" - optional: false - desc: - ja-JP: "投稿者ID" - en-US: "The ID of author of this note" - - user: - type: "entity(User)" - optional: true - desc: - ja-JP: "投稿者" - en-US: "The author of this note" - - myReaction: - type: "string" - optional: true - desc: - ja-JP: "この投稿に対する自分のリアクション" - en-US: "The your reaction of this note" - - renoteCount: - type: "number" - optional: false - desc: - ja-JP: "この投稿がRenoteされた数" - en-US: "The number of renotes for this post" - - repliesCount: - type: "number" - optional: false - desc: - ja-JP: "この投稿に返信された数" - en-US: "The number of replies to this post" - - reactionCounts: - type: "object" - optional: false - desc: - ja-JP: "リアクションをキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト" - - replyId: - type: "id(Note)" - optional: true - desc: - ja-JP: "返信した投稿のID" - en-US: "The ID of the replyed note" - - reply: - type: "entity(Note)" - optional: true - desc: - ja-JP: "返信した投稿" - en-US: "The replyed note" - - renoteId: - type: "id(Note)" - optional: true - desc: - ja-JP: "引用した投稿のID" - en-US: "The ID of the quoted note" - - renote: - type: "entity(Note)" - optional: true - desc: - ja-JP: "引用した投稿" - en-US: "The quoted note" - - poll: - type: "object" - optional: true - desc: - ja-JP: "投票" - en-US: "The poll" - - props: - choices: - type: "object[]" - optional: false - desc: - ja-JP: "投票の選択肢" - en-US: "The choices of this poll" - - props: - id: - type: "number" - optional: false - desc: - ja-JP: "選択肢ID" - en-US: "The ID of this choice" - - isVoted: - type: "boolean" - optional: true - desc: - ja-JP: "自分がこの選択肢に投票したかどうか" - en-US: "Whether you voted to this choice" - - text: - type: "string" - optional: false - desc: - ja-JP: "選択肢本文" - en-US: "The text of this choice" - - votes: - type: "number" - optional: false - desc: - ja-JP: "この選択肢に投票された数" - en-US: "The number voted for this choice" - geo: - type: "object" - optional: true - desc: - ja-JP: "位置情報" - en-US: "Geo location" - - props: - coordinates: - type: "number[]" - optional: false - desc: - ja-JP: "座標。最初に経度:-180〜180で表す。最後に緯度:-90〜90で表す。" - - altitude: - type: "number" - optional: false - desc: - ja-JP: "高度。メートル単位で表す。" - - accuracy: - type: "number" - optional: false - desc: - ja-JP: "緯度、経度の精度。メートル単位で表す。" - - altitudeAccuracy: - type: "number" - optional: false - desc: - ja-JP: "高度の精度。メートル単位で表す。" - - heading: - type: "number" - optional: false - desc: - ja-JP: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。" - - speed: - type: "number" - optional: false - desc: - ja-JP: "速度。メートル / 秒数で表す。" diff --git a/src/docs/api/entities/style.styl b/src/docs/api/entities/style.styl deleted file mode 100644 index bddf0f53a..000000000 --- a/src/docs/api/entities/style.styl +++ /dev/null @@ -1 +0,0 @@ -@import "../style" diff --git a/src/docs/api/entities/user.yaml b/src/docs/api/entities/user.yaml deleted file mode 100644 index e3755d858..000000000 --- a/src/docs/api/entities/user.yaml +++ /dev/null @@ -1,174 +0,0 @@ -name: "User" - -desc: - ja-JP: "ユーザー。" - en-US: "A user." - -props: - id: - type: "id" - optional: false - desc: - ja-JP: "ユーザーID" - en-US: "The ID of this user" - - createdAt: - type: "date" - optional: false - desc: - ja-JP: "アカウント作成日時" - en-US: "The registered date of this user" - - username: - type: "string" - optional: false - desc: - ja-JP: "ユーザー名" - en-US: "The username of this user" - - description: - type: "string" - optional: false - desc: - ja-JP: "アカウントの説明(自己紹介)" - en-US: "The description of this user" - - avatarId: - type: "id(DriveFile)" - optional: true - desc: - ja-JP: "アバターのID" - en-US: "The ID of the avatar of this user" - - avatarUrl: - type: "string" - optional: false - desc: - ja-JP: "アバターのURL" - en-US: "The URL of the avatar of this user" - - bannerId: - type: "id(DriveFile)" - optional: true - desc: - ja-JP: "バナーのID" - en-US: "The ID of the banner of this user" - - bannerUrl: - type: "string" - optional: false - desc: - ja-JP: "バナーのURL" - en-US: "The URL of the banner of this user" - - followersCount: - type: "number" - optional: false - desc: - ja-JP: "フォロワーの数" - en-US: "The number of the followers for this user" - - followingCount: - type: "number" - optional: false - desc: - ja-JP: "フォローしているユーザーの数" - en-US: "The number of the following users for this user" - - isFollowing: - type: "boolean" - optional: true - desc: - ja-JP: "自分がこのユーザーをフォローしているか" - - isFollowed: - type: "boolean" - optional: true - desc: - ja-JP: "自分がこのユーザーにフォローされているか" - - isMuted: - type: "boolean" - optional: true - desc: - ja-JP: "自分がこのユーザーをミュートしているか" - en-US: "Whether you muted this user" - - notesCount: - type: "number" - optional: false - desc: - ja-JP: "投稿の数" - en-US: "The number of the notes of this user" - - pinnedNotes: - type: "entity(Note)[]" - optional: true - desc: - ja-JP: "ピン留めされた投稿" - en-US: "The pinned note of this user" - - pinnedNoteIds: - type: "id(Note)[]" - optional: true - desc: - ja-JP: "ピン留めされた投稿のID" - en-US: "The ID of the pinned note of this user" - - host: - type: "string | null" - optional: false - desc: - ja-JP: "ホスト (例: example.com:3000)" - en-US: "Host (e.g. example.com:3000)" - - twitter: - type: "object" - optional: true - desc: - ja-JP: "連携されているTwitterアカウント情報" - en-US: "The info of the connected twitter account of this user" - - props: - userId: - type: "string" - optional: false - desc: - ja-JP: "ユーザーID" - en-US: "The user ID" - - screenName: - type: "string" - optional: false - desc: - ja-JP: "ユーザー名" - en-US: "The screen name of this user" - - isBot: - type: "boolean" - optional: true - desc: - ja-JP: "botか否か(自己申告であることに留意)" - en-US: "Whether is bot or not" - - profile: - type: "object" - optional: false - desc: - ja-JP: "プロフィール" - en-US: "The profile of this user" - - props: - location: - type: "string" - optional: true - desc: - ja-JP: "場所" - en-US: "The location of this user" - - birthday: - type: "string" - optional: true - desc: - ja-JP: "誕生日 (YYYY-MM-DD)" - en-US: "The birthday of this user (YYYY-MM-DD)" diff --git a/src/docs/api/entities/view.pug b/src/docs/api/entities/view.pug deleted file mode 100644 index 1f166d053..000000000 --- a/src/docs/api/entities/view.pug +++ /dev/null @@ -1,20 +0,0 @@ -extends ../../base -include ../mixins - -block meta - link(rel="stylesheet" href="/docs/assets/api/entities/style.css") - -block main - h1= name - - p#desc= desc[lang] || desc['ja-JP'] - - section - h2= i18n('docs.api.entities.properties') - +propTable(props) - - if propDefs - each propDef in propDefs - section(id= propDef.name) - h3= propDef.name - +propTable(propDef.props) diff --git a/src/docs/api/mixins.pug b/src/docs/api/mixins.pug deleted file mode 100644 index 563739d52..000000000 --- a/src/docs/api/mixins.pug +++ /dev/null @@ -1,34 +0,0 @@ -mixin type(prop) - i= prop.type - if prop.kind == 'id' - if prop.entity - | ( - a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity - | ID) - else - | (ID) - else if prop.kind == 'entity' - | ( - a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity - | ) - else if prop.kind == 'object' - if prop.hasDef - | ( - a(href=`#${prop.name}`)= prop.name - | ) - else if prop.kind == 'date' - | (Date) - -mixin propTable(props) - table.props - thead: tr - th= i18n('docs.api.props.name') - th= i18n('docs.api.props.type') - th= i18n('docs.api.props.description') - tbody - each prop in props - tr - td.name= prop.name - td.type - +type(prop) - td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja-JP'] : null diff --git a/src/docs/api/style.styl b/src/docs/api/style.styl deleted file mode 100644 index 3675a4da6..000000000 --- a/src/docs/api/style.styl +++ /dev/null @@ -1,11 +0,0 @@ -@import "../style" - -table.props - .name - font-weight bold - - .name - .type - .optional - font-family Consolas, 'Courier New', Courier, Monaco, monospace - diff --git a/src/docs/base.pug b/src/docs/base.pug index 41eb80a64..7d6af89de 100644 --- a/src/docs/base.pug +++ b/src/docs/base.pug @@ -17,17 +17,6 @@ html(lang= lang) ul each doc in docs li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja-JP'] - section - h2 API - ul - li Entities - ul - each entity in entities - li: a(href=`/docs/${lang}/api/entities/${kebab(entity)}`)= entity - li Endpoints - ul - each endpoint in endpoints - li: a(href=`/docs/${lang}/api/endpoints/${kebab(endpoint.name)}`)= endpoint.name main article block main diff --git a/src/misc/cafy-id.ts b/src/misc/cafy-id.ts index eb5822a7d..bc8fe4ea2 100644 --- a/src/misc/cafy-id.ts +++ b/src/misc/cafy-id.ts @@ -26,6 +26,8 @@ export type ObjectId = mongo.ObjectID; * ID */ export default class ID extends Context { + public readonly name = 'ID'; + constructor(optional = false, nullable = false) { super(optional, nullable); @@ -38,7 +40,7 @@ export default class ID extends Context { } public getType() { - return super.getType('string'); + return super.getType('String'); } public makeOptional(): ID { diff --git a/src/server/api/api-handler.ts b/src/server/api/api-handler.ts index fdfaea1ff..00af69703 100644 --- a/src/server/api/api-handler.ts +++ b/src/server/api/api-handler.ts @@ -26,7 +26,7 @@ export default (endpoint: IEndpoint, ctx: Koa.BaseContext) => new Promise((res) call(endpoint.name, user, app, body, (ctx.req as any).file).then(res => { reply(res); }).catch(e => { - reply(e.kind == 'client' ? 400 : 500, e); + reply(e.httpStatusCode ? e.httpStatusCode : e.kind == 'client' ? 400 : 500, e); }); }).catch(() => { reply(403, new ApiError({ diff --git a/src/server/api/call.ts b/src/server/api/call.ts index 106f0937b..4b3d4cfbe 100644 --- a/src/server/api/call.ts +++ b/src/server/api/call.ts @@ -21,6 +21,7 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file? message: 'No such endpoint.', code: 'NO_SUCH_ENDPOINT', id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709', + httpStatusCode: 404 }); } @@ -33,6 +34,7 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file? message: 'Credential required.', code: 'CREDENTIAL_REQUIRED', id: '1384574d-a912-4b81-8601-c7b1c4085df1', + httpStatusCode: 401 }); } @@ -63,6 +65,7 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file? message: 'Rate limit exceeded. Please try again later.', code: 'RATE_LIMIT_EXCEEDED', id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef', + httpStatusCode: 429 }); }); } diff --git a/src/server/api/endpoints.ts b/src/server/api/endpoints.ts index 6765a63e9..2873dd3c1 100644 --- a/src/server/api/endpoints.ts +++ b/src/server/api/endpoints.ts @@ -2,18 +2,30 @@ import { Context } from 'cafy'; import * as path from 'path'; import * as glob from 'glob'; +export type Param = { + validator: Context; + transform?: any; + default?: any; + desc?: { [key: string]: string }; + ref?: string; +}; + export interface IEndpointMeta { stability?: string; //'deprecated' | 'experimental' | 'stable'; desc?: { [key: string]: string }; + tags?: string[]; + params?: { + [key: string]: Param; + }; + + errors?: { [key: string]: { - validator: Context; - transform?: any; - default?: any; - desc?: { [key: string]: string }; - ref?: string; + message: string; + code: string; + id: string; }; }; diff --git a/src/server/api/endpoints/admin/abuse-user-reports.ts b/src/server/api/endpoints/admin/abuse-user-reports.ts index 602171abb..d9fe3429c 100644 --- a/src/server/api/endpoints/admin/abuse-user-reports.ts +++ b/src/server/api/endpoints/admin/abuse-user-reports.ts @@ -4,6 +4,8 @@ import Report, { packMany } from '../../../../models/abuse-user-report'; import define from '../../define'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/drive/files.ts b/src/server/api/endpoints/admin/drive/files.ts index 318b2de1b..8ed417a42 100644 --- a/src/server/api/endpoints/admin/drive/files.ts +++ b/src/server/api/endpoints/admin/drive/files.ts @@ -4,6 +4,8 @@ import define from '../../../define'; import { fallback } from '../../../../../prelude/symbol'; export const meta = { + tags: ['admin'], + requireCredential: false, requireModerator: true, diff --git a/src/server/api/endpoints/admin/drive/show-file.ts b/src/server/api/endpoints/admin/drive/show-file.ts index 9b993584e..405b6d44c 100644 --- a/src/server/api/endpoints/admin/drive/show-file.ts +++ b/src/server/api/endpoints/admin/drive/show-file.ts @@ -5,6 +5,8 @@ import DriveFile from '../../../../../models/drive-file'; import { ApiError } from '../../../error'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/emoji/add.ts b/src/server/api/endpoints/admin/emoji/add.ts index b84e9d34d..99439f89a 100644 --- a/src/server/api/endpoints/admin/emoji/add.ts +++ b/src/server/api/endpoints/admin/emoji/add.ts @@ -7,6 +7,8 @@ export const meta = { 'ja-JP': 'カスタム絵文字を追加します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/emoji/list.ts b/src/server/api/endpoints/admin/emoji/list.ts index f51a536fa..954f8f96c 100644 --- a/src/server/api/endpoints/admin/emoji/list.ts +++ b/src/server/api/endpoints/admin/emoji/list.ts @@ -7,6 +7,8 @@ export const meta = { 'ja-JP': 'カスタム絵文字を取得します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/emoji/remove.ts b/src/server/api/endpoints/admin/emoji/remove.ts index 9699a0012..4c69dffba 100644 --- a/src/server/api/endpoints/admin/emoji/remove.ts +++ b/src/server/api/endpoints/admin/emoji/remove.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': 'カスタム絵文字を削除します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/emoji/update.ts b/src/server/api/endpoints/admin/emoji/update.ts index 7d065eadd..38d90c65a 100644 --- a/src/server/api/endpoints/admin/emoji/update.ts +++ b/src/server/api/endpoints/admin/emoji/update.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': 'カスタム絵文字を更新します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/federation/remove-all-following.ts b/src/server/api/endpoints/admin/federation/remove-all-following.ts index 1a272aeb0..98afdfc2a 100644 --- a/src/server/api/endpoints/admin/federation/remove-all-following.ts +++ b/src/server/api/endpoints/admin/federation/remove-all-following.ts @@ -5,6 +5,8 @@ import User from '../../../../../models/user'; import deleteFollowing from '../../../../../services/following/delete'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/federation/update-instance.ts b/src/server/api/endpoints/admin/federation/update-instance.ts index 50eb4ba13..0d127b53b 100644 --- a/src/server/api/endpoints/admin/federation/update-instance.ts +++ b/src/server/api/endpoints/admin/federation/update-instance.ts @@ -3,6 +3,8 @@ import define from '../../../define'; import Instance from '../../../../../models/instance'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/invite.ts b/src/server/api/endpoints/admin/invite.ts index 3c2b32349..28aa30195 100644 --- a/src/server/api/endpoints/admin/invite.ts +++ b/src/server/api/endpoints/admin/invite.ts @@ -7,6 +7,8 @@ export const meta = { 'ja-JP': '招待コードを発行します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/moderators/add.ts b/src/server/api/endpoints/admin/moderators/add.ts index 58515381d..2271bcd1a 100644 --- a/src/server/api/endpoints/admin/moderators/add.ts +++ b/src/server/api/endpoints/admin/moderators/add.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark a user as moderator.' }, + tags: ['admin'], + requireCredential: true, requireAdmin: true, diff --git a/src/server/api/endpoints/admin/moderators/remove.ts b/src/server/api/endpoints/admin/moderators/remove.ts index 75627fb63..84143d3e3 100644 --- a/src/server/api/endpoints/admin/moderators/remove.ts +++ b/src/server/api/endpoints/admin/moderators/remove.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Unmark a user as moderator.' }, + tags: ['admin'], + requireCredential: true, requireAdmin: true, diff --git a/src/server/api/endpoints/admin/queue/clear.ts b/src/server/api/endpoints/admin/queue/clear.ts index 9a1e56595..f0fd00f1a 100644 --- a/src/server/api/endpoints/admin/queue/clear.ts +++ b/src/server/api/endpoints/admin/queue/clear.ts @@ -2,6 +2,8 @@ import define from '../../../define'; import { destroy } from '../../../../../queue'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/remove-abuse-user-report.ts b/src/server/api/endpoints/admin/remove-abuse-user-report.ts index c0c40c85d..fa17e2c93 100644 --- a/src/server/api/endpoints/admin/remove-abuse-user-report.ts +++ b/src/server/api/endpoints/admin/remove-abuse-user-report.ts @@ -4,6 +4,8 @@ import define from '../../define'; import AbuseUserReport from '../../../../models/abuse-user-report'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/reset-password.ts b/src/server/api/endpoints/admin/reset-password.ts index b274dc2a7..73901d835 100644 --- a/src/server/api/endpoints/admin/reset-password.ts +++ b/src/server/api/endpoints/admin/reset-password.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': '指定したユーザーのパスワードをリセットします。', }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/show-user.ts b/src/server/api/endpoints/admin/show-user.ts index 5fcf4c386..985f71a87 100644 --- a/src/server/api/endpoints/admin/show-user.ts +++ b/src/server/api/endpoints/admin/show-user.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': '指定したユーザーの情報を取得します。', }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/show-users.ts b/src/server/api/endpoints/admin/show-users.ts index 9d1c5ea98..5feb1b4fd 100644 --- a/src/server/api/endpoints/admin/show-users.ts +++ b/src/server/api/endpoints/admin/show-users.ts @@ -4,6 +4,8 @@ import define from '../../define'; import { fallback } from '../../../../prelude/symbol'; export const meta = { + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/silence-user.ts b/src/server/api/endpoints/admin/silence-user.ts index 532025563..2557d8de6 100644 --- a/src/server/api/endpoints/admin/silence-user.ts +++ b/src/server/api/endpoints/admin/silence-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Make silence a user.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/suspend-user.ts b/src/server/api/endpoints/admin/suspend-user.ts index 321c3955e..83b39fb0b 100644 --- a/src/server/api/endpoints/admin/suspend-user.ts +++ b/src/server/api/endpoints/admin/suspend-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Suspend a user.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/unsilence-user.ts b/src/server/api/endpoints/admin/unsilence-user.ts index bb039eb8d..01bf41aae 100644 --- a/src/server/api/endpoints/admin/unsilence-user.ts +++ b/src/server/api/endpoints/admin/unsilence-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Unsilence a user.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/unsuspend-user.ts b/src/server/api/endpoints/admin/unsuspend-user.ts index 4732e4436..5da35f28e 100644 --- a/src/server/api/endpoints/admin/unsuspend-user.ts +++ b/src/server/api/endpoints/admin/unsuspend-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Unsuspend a user.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/unverify-user.ts b/src/server/api/endpoints/admin/unverify-user.ts index 857cceb1e..d3ca05cb3 100644 --- a/src/server/api/endpoints/admin/unverify-user.ts +++ b/src/server/api/endpoints/admin/unverify-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark a user as unverified.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index 1fb87d0a9..46fdeff75 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -7,6 +7,8 @@ export const meta = { 'ja-JP': 'インスタンスの設定を更新します。' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/update-remote-user.ts b/src/server/api/endpoints/admin/update-remote-user.ts index 8d1db33ba..a74685912 100644 --- a/src/server/api/endpoints/admin/update-remote-user.ts +++ b/src/server/api/endpoints/admin/update-remote-user.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Update specified remote user information.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/admin/verify-user.ts b/src/server/api/endpoints/admin/verify-user.ts index 77db8e6e6..f67b6c3bf 100644 --- a/src/server/api/endpoints/admin/verify-user.ts +++ b/src/server/api/endpoints/admin/verify-user.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark a user as verified.' }, + tags: ['admin'], + requireCredential: true, requireModerator: true, diff --git a/src/server/api/endpoints/aggregation/hashtags.ts b/src/server/api/endpoints/aggregation/hashtags.ts index 6de36a1d1..978e9f64b 100644 --- a/src/server/api/endpoints/aggregation/hashtags.ts +++ b/src/server/api/endpoints/aggregation/hashtags.ts @@ -3,6 +3,8 @@ import define from '../../define'; import fetchMeta from '../../../../misc/fetch-meta'; export const meta = { + tags: ['hashtags'], + requireCredential: false, }; diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts index 8dd9f96f9..72c853790 100644 --- a/src/server/api/endpoints/ap/show.ts +++ b/src/server/api/endpoints/ap/show.ts @@ -10,6 +10,8 @@ import Resolver from '../../../../remote/activitypub/resolver'; import { ApiError } from '../../error'; export const meta = { + tags: ['federation'], + desc: { 'ja-JP': 'URIを指定してActivityPubオブジェクトを参照します。' }, diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts index ef8bd6607..67b1b8150 100644 --- a/src/server/api/endpoints/app/create.ts +++ b/src/server/api/endpoints/app/create.ts @@ -4,6 +4,8 @@ import App, { pack } from '../../../../models/app'; import define from '../../define'; export const meta = { + tags: ['app'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/app/show.ts b/src/server/api/endpoints/app/show.ts index 72755ce01..f3f5b843b 100644 --- a/src/server/api/endpoints/app/show.ts +++ b/src/server/api/endpoints/app/show.ts @@ -5,6 +5,8 @@ import define from '../../define'; import { ApiError } from '../../error'; export const meta = { + tags: ['app'], + params: { appId: { validator: $.type(ID), diff --git a/src/server/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts index 964ee6559..cedf7821f 100644 --- a/src/server/api/endpoints/auth/accept.ts +++ b/src/server/api/endpoints/auth/accept.ts @@ -8,6 +8,8 @@ import define from '../../define'; import { ApiError } from '../../error'; export const meta = { + tags: ['auth'], + requireCredential: true, secure: true, diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts index 9f0f18471..b6bfb5590 100644 --- a/src/server/api/endpoints/auth/session/generate.ts +++ b/src/server/api/endpoints/auth/session/generate.ts @@ -7,6 +7,8 @@ import define from '../../../define'; import { ApiError } from '../../../error'; export const meta = { + tags: ['auth'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/auth/session/show.ts b/src/server/api/endpoints/auth/session/show.ts index 5e9e68c2c..4287950f3 100644 --- a/src/server/api/endpoints/auth/session/show.ts +++ b/src/server/api/endpoints/auth/session/show.ts @@ -4,6 +4,8 @@ import define from '../../../define'; import { ApiError } from '../../../error'; export const meta = { + tags: ['auth'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts index 17d62886a..d4c3d7777 100644 --- a/src/server/api/endpoints/auth/session/userkey.ts +++ b/src/server/api/endpoints/auth/session/userkey.ts @@ -7,6 +7,8 @@ import define from '../../../define'; import { ApiError } from '../../../error'; export const meta = { + tags: ['auth'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/blocking/create.ts b/src/server/api/endpoints/blocking/create.ts index 71c3ed316..e723cb038 100644 --- a/src/server/api/endpoints/blocking/create.ts +++ b/src/server/api/endpoints/blocking/create.ts @@ -16,6 +16,8 @@ export const meta = { 'en-US': 'Block a user.' }, + tags: ['blocking', 'users'], + limit: { duration: ms('1hour'), max: 100 diff --git a/src/server/api/endpoints/blocking/delete.ts b/src/server/api/endpoints/blocking/delete.ts index 426d88c1c..2a9fdc5e2 100644 --- a/src/server/api/endpoints/blocking/delete.ts +++ b/src/server/api/endpoints/blocking/delete.ts @@ -16,6 +16,8 @@ export const meta = { 'en-US': 'Unblock a user.' }, + tags: ['blocking', 'users'], + limit: { duration: ms('1hour'), max: 100 diff --git a/src/server/api/endpoints/blocking/list.ts b/src/server/api/endpoints/blocking/list.ts index 088b2c488..2921f48f2 100644 --- a/src/server/api/endpoints/blocking/list.ts +++ b/src/server/api/endpoints/blocking/list.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Get blocking users.' }, + tags: ['blocking', 'account'], + requireCredential: true, kind: 'following-read', diff --git a/src/server/api/endpoints/charts/active-users.ts b/src/server/api/endpoints/charts/active-users.ts index 11f86d0ba..9dad942e0 100644 --- a/src/server/api/endpoints/charts/active-users.ts +++ b/src/server/api/endpoints/charts/active-users.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'アクティブユーザーのチャートを取得します。' }, + tags: ['charts', 'users'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/drive.ts b/src/server/api/endpoints/charts/drive.ts index 9244ef748..5438d7648 100644 --- a/src/server/api/endpoints/charts/drive.ts +++ b/src/server/api/endpoints/charts/drive.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'ドライブのチャートを取得します。' }, + tags: ['charts', 'drive'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/federation.ts b/src/server/api/endpoints/charts/federation.ts index c98c9f6cb..c7b34f101 100644 --- a/src/server/api/endpoints/charts/federation.ts +++ b/src/server/api/endpoints/charts/federation.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'フェデレーションのチャートを取得します。' }, + tags: ['charts'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/hashtag.ts b/src/server/api/endpoints/charts/hashtag.ts index 5905fdc1a..4db6e6240 100644 --- a/src/server/api/endpoints/charts/hashtag.ts +++ b/src/server/api/endpoints/charts/hashtag.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'ハッシュタグごとのチャートを取得します。' }, + tags: ['charts', 'hashtags'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -31,7 +33,14 @@ export const meta = { 'ja-JP': '対象のハッシュタグ' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/instance.ts b/src/server/api/endpoints/charts/instance.ts index e47334c7c..3fe85f086 100644 --- a/src/server/api/endpoints/charts/instance.ts +++ b/src/server/api/endpoints/charts/instance.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'インスタンスごとのチャートを取得します。' }, + tags: ['charts'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -32,7 +34,14 @@ export const meta = { 'en-US': 'Target instance host' } } - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/network.ts b/src/server/api/endpoints/charts/network.ts index fa1917f75..48b1d0f66 100644 --- a/src/server/api/endpoints/charts/network.ts +++ b/src/server/api/endpoints/charts/network.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'ネットワークのチャートを取得します。' }, + tags: ['charts'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/notes.ts b/src/server/api/endpoints/charts/notes.ts index 006a8d6e2..d254bb854 100644 --- a/src/server/api/endpoints/charts/notes.ts +++ b/src/server/api/endpoints/charts/notes.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': '投稿のチャートを取得します。' }, + tags: ['charts', 'notes'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/user/drive.ts b/src/server/api/endpoints/charts/user/drive.ts index 6383ddf2f..32645b38c 100644 --- a/src/server/api/endpoints/charts/user/drive.ts +++ b/src/server/api/endpoints/charts/user/drive.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': 'ユーザーごとのドライブのチャートを取得します。' }, + tags: ['charts', 'drive', 'users'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -34,7 +36,14 @@ export const meta = { 'en-US': 'Target user ID' } } - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/user/following.ts b/src/server/api/endpoints/charts/user/following.ts index 9443b56a4..73f0c1e4f 100644 --- a/src/server/api/endpoints/charts/user/following.ts +++ b/src/server/api/endpoints/charts/user/following.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': 'ユーザーごとのフォロー/フォロワーのチャートを取得します。' }, + tags: ['charts', 'users', 'following'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -34,7 +36,14 @@ export const meta = { 'en-US': 'Target user ID' } } - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/user/notes.ts b/src/server/api/endpoints/charts/user/notes.ts index da642fc76..6a95911b1 100644 --- a/src/server/api/endpoints/charts/user/notes.ts +++ b/src/server/api/endpoints/charts/user/notes.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': 'ユーザーごとの投稿のチャートを取得します。' }, + tags: ['charts', 'users', 'notes'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -34,7 +36,14 @@ export const meta = { 'en-US': 'Target user ID' } } - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/src/server/api/endpoints/charts/user/reactions.ts index e440b3ae3..51ff83f20 100644 --- a/src/server/api/endpoints/charts/user/reactions.ts +++ b/src/server/api/endpoints/charts/user/reactions.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': 'ユーザーごとの被リアクション数のチャートを取得します。' }, + tags: ['charts', 'users', 'reactions'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -34,7 +36,14 @@ export const meta = { 'en-US': 'Target user ID' } } - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/charts/users.ts b/src/server/api/endpoints/charts/users.ts index ea32b7afd..0b1b18bbe 100644 --- a/src/server/api/endpoints/charts/users.ts +++ b/src/server/api/endpoints/charts/users.ts @@ -9,6 +9,8 @@ export const meta = { 'ja-JP': 'ユーザーのチャートを取得します。' }, + tags: ['charts', 'users'], + params: { span: { validator: $.str.or(['day', 'hour']), @@ -24,7 +26,14 @@ export const meta = { 'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'object', + }, + }, }; export default define(meta, async (ps) => { diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts index 54afe55cb..9c4482f91 100644 --- a/src/server/api/endpoints/drive.ts +++ b/src/server/api/endpoints/drive.ts @@ -8,6 +8,8 @@ export const meta = { 'en-US': 'Get drive information.' }, + tags: ['drive', 'account'], + requireCredential: true, kind: 'drive-read' diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts index 1c12f0dc0..f108e820e 100644 --- a/src/server/api/endpoints/drive/files.ts +++ b/src/server/api/endpoints/drive/files.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Get files of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-read', @@ -38,7 +40,14 @@ export const meta = { type: { validator: $.optional.str.match(/^[a-zA-Z\/\-\*]+$/) } - } + }, + + res: { + type: 'array', + items: { + type: 'DriveFile', + }, + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/drive/files/attached_notes.ts b/src/server/api/endpoints/drive/files/attached_notes.ts index 506444b18..c1d828b05 100644 --- a/src/server/api/endpoints/drive/files/attached_notes.ts +++ b/src/server/api/endpoints/drive/files/attached_notes.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get the notes that specified file of drive attached.' }, + tags: ['drive', 'notes'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/drive/files/check_existence.ts b/src/server/api/endpoints/drive/files/check_existence.ts index aafd46fb2..12680d541 100644 --- a/src/server/api/endpoints/drive/files/check_existence.ts +++ b/src/server/api/endpoints/drive/files/check_existence.ts @@ -8,6 +8,8 @@ export const meta = { 'en-US': 'Returns whether the file with the given MD5 hash exists in the user\'s drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts index c96e4bbf1..b2979c488 100644 --- a/src/server/api/endpoints/drive/files/create.ts +++ b/src/server/api/endpoints/drive/files/create.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Upload a file to drive.' }, + tags: ['drive'], + requireCredential: true, limit: { @@ -35,7 +37,7 @@ export const meta = { }, isSensitive: { - validator: $.optional.or($.bool, $.str), + validator: $.optional.either($.bool, $.str), default: false, transform: (v: any): boolean => v === true || v === 'true', desc: { @@ -45,7 +47,7 @@ export const meta = { }, force: { - validator: $.optional.or($.bool, $.str), + validator: $.optional.either($.bool, $.str), default: false, transform: (v: any): boolean => v === true || v === 'true', desc: { @@ -54,6 +56,10 @@ export const meta = { } }, + res: { + type: 'DriveFile', + }, + errors: { invalidFileName: { message: 'Invalid file name.', diff --git a/src/server/api/endpoints/drive/files/delete.ts b/src/server/api/endpoints/drive/files/delete.ts index 2dc493efe..dd4e187fc 100644 --- a/src/server/api/endpoints/drive/files/delete.ts +++ b/src/server/api/endpoints/drive/files/delete.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Delete a file of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-write', diff --git a/src/server/api/endpoints/drive/files/find.ts b/src/server/api/endpoints/drive/files/find.ts index 6eb909b9d..0d4102a48 100644 --- a/src/server/api/endpoints/drive/files/find.ts +++ b/src/server/api/endpoints/drive/files/find.ts @@ -6,6 +6,8 @@ import define from '../../../define'; export const meta = { requireCredential: true, + tags: ['drive'], + kind: 'drive-read', params: { diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts index f844d434f..c2442c65c 100644 --- a/src/server/api/endpoints/drive/files/show.ts +++ b/src/server/api/endpoints/drive/files/show.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Get specified file of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-read', @@ -37,6 +39,10 @@ export const meta = { } }, + res: { + type: 'DriveFile', + }, + errors: { noSuchFile: { message: 'No such file.', diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts index f24cc6bcd..c8803bec3 100644 --- a/src/server/api/endpoints/drive/files/update.ts +++ b/src/server/api/endpoints/drive/files/update.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Update specified file of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-write', diff --git a/src/server/api/endpoints/drive/files/upload_from_url.ts b/src/server/api/endpoints/drive/files/upload_from_url.ts index 8d25530dd..93a9fa62f 100644 --- a/src/server/api/endpoints/drive/files/upload_from_url.ts +++ b/src/server/api/endpoints/drive/files/upload_from_url.ts @@ -10,6 +10,8 @@ export const meta = { 'ja-JP': 'ドライブに指定されたURLに存在するファイルをアップロードします。' }, + tags: ['drive'], + limit: { duration: ms('1hour'), max: 60 diff --git a/src/server/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts index 698206085..a0b972f71 100644 --- a/src/server/api/endpoints/drive/folders.ts +++ b/src/server/api/endpoints/drive/folders.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Get folders of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/drive/folders/create.ts b/src/server/api/endpoints/drive/folders/create.ts index a54c780b8..5fab0b91a 100644 --- a/src/server/api/endpoints/drive/folders/create.ts +++ b/src/server/api/endpoints/drive/folders/create.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Create a folder of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-write', diff --git a/src/server/api/endpoints/drive/folders/delete.ts b/src/server/api/endpoints/drive/folders/delete.ts index 26a71d57d..9f22bf9ea 100644 --- a/src/server/api/endpoints/drive/folders/delete.ts +++ b/src/server/api/endpoints/drive/folders/delete.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Delete specified folder of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-write', diff --git a/src/server/api/endpoints/drive/folders/find.ts b/src/server/api/endpoints/drive/folders/find.ts index 25d89f9fb..17769567a 100644 --- a/src/server/api/endpoints/drive/folders/find.ts +++ b/src/server/api/endpoints/drive/folders/find.ts @@ -4,6 +4,8 @@ import DriveFolder, { pack } from '../../../../../models/drive-folder'; import define from '../../../define'; export const meta = { + tags: ['drive'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts index 0d98158b9..033743622 100644 --- a/src/server/api/endpoints/drive/folders/show.ts +++ b/src/server/api/endpoints/drive/folders/show.ts @@ -12,6 +12,8 @@ export const meta = { 'en-US': 'Get specified folder of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/drive/folders/update.ts b/src/server/api/endpoints/drive/folders/update.ts index 585664ba0..1dc0e6387 100644 --- a/src/server/api/endpoints/drive/folders/update.ts +++ b/src/server/api/endpoints/drive/folders/update.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Update specified folder of drive.' }, + tags: ['drive'], + requireCredential: true, kind: 'drive-write', diff --git a/src/server/api/endpoints/drive/stream.ts b/src/server/api/endpoints/drive/stream.ts index d5872470f..f6586a852 100644 --- a/src/server/api/endpoints/drive/stream.ts +++ b/src/server/api/endpoints/drive/stream.ts @@ -4,6 +4,8 @@ import DriveFile, { packMany } from '../../../../models/drive-file'; import define from '../../define'; export const meta = { + tags: ['drive'], + requireCredential: true, kind: 'drive-read', diff --git a/src/server/api/endpoints/federation/instances.ts b/src/server/api/endpoints/federation/instances.ts index 34da9dff7..f81f81822 100644 --- a/src/server/api/endpoints/federation/instances.ts +++ b/src/server/api/endpoints/federation/instances.ts @@ -3,6 +3,8 @@ import define from '../../define'; import Instance from '../../../../models/instance'; export const meta = { + tags: ['federation'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/federation/show-instance.ts b/src/server/api/endpoints/federation/show-instance.ts index e443abcda..e7f68620a 100644 --- a/src/server/api/endpoints/federation/show-instance.ts +++ b/src/server/api/endpoints/federation/show-instance.ts @@ -3,6 +3,8 @@ import define from '../../define'; import Instance from '../../../../models/instance'; export const meta = { + tags: ['federation'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts index a4e68f580..81b239955 100644 --- a/src/server/api/endpoints/following/create.ts +++ b/src/server/api/endpoints/following/create.ts @@ -16,6 +16,8 @@ export const meta = { 'en-US': 'Follow a user.' }, + tags: ['following', 'users'], + limit: { duration: ms('1hour'), max: 100 diff --git a/src/server/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts index faa42cacf..8f8249b1e 100644 --- a/src/server/api/endpoints/following/delete.ts +++ b/src/server/api/endpoints/following/delete.ts @@ -16,6 +16,8 @@ export const meta = { 'en-US': 'Unfollow a user.' }, + tags: ['following', 'users'], + limit: { duration: ms('1hour'), max: 100 diff --git a/src/server/api/endpoints/following/requests/accept.ts b/src/server/api/endpoints/following/requests/accept.ts index cc42ca9c3..0975990c0 100644 --- a/src/server/api/endpoints/following/requests/accept.ts +++ b/src/server/api/endpoints/following/requests/accept.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Accept a follow request.' }, + tags: ['following', 'account'], + requireCredential: true, kind: 'following-write', diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/src/server/api/endpoints/following/requests/cancel.ts index eb3abfa3e..371f9f0ed 100644 --- a/src/server/api/endpoints/following/requests/cancel.ts +++ b/src/server/api/endpoints/following/requests/cancel.ts @@ -12,6 +12,8 @@ export const meta = { 'en-US': 'Cancel a follow request.' }, + tags: ['following', 'account'], + requireCredential: true, kind: 'following-write', diff --git a/src/server/api/endpoints/following/requests/list.ts b/src/server/api/endpoints/following/requests/list.ts index f66027764..c9bcedf92 100644 --- a/src/server/api/endpoints/following/requests/list.ts +++ b/src/server/api/endpoints/following/requests/list.ts @@ -7,6 +7,8 @@ export const meta = { 'en-US': 'Get all pending received follow requests.' }, + tags: ['following', 'account'], + requireCredential: true, kind: 'following-read' diff --git a/src/server/api/endpoints/following/requests/reject.ts b/src/server/api/endpoints/following/requests/reject.ts index 908e64acc..5e59d4bc9 100644 --- a/src/server/api/endpoints/following/requests/reject.ts +++ b/src/server/api/endpoints/following/requests/reject.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Reject a follow request.' }, + tags: ['following', 'account'], + requireCredential: true, kind: 'following-write', diff --git a/src/server/api/endpoints/games/reversi/games.ts b/src/server/api/endpoints/games/reversi/games.ts index b188ba996..e3c22c761 100644 --- a/src/server/api/endpoints/games/reversi/games.ts +++ b/src/server/api/endpoints/games/reversi/games.ts @@ -4,6 +4,8 @@ import ReversiGame, { pack } from '../../../../../models/games/reversi/game'; import define from '../../../define'; export const meta = { + tags: ['games'], + params: { limit: { validator: $.optional.num.range(1, 100), diff --git a/src/server/api/endpoints/games/reversi/games/show.ts b/src/server/api/endpoints/games/reversi/games/show.ts index d70ab8de9..766ca9011 100644 --- a/src/server/api/endpoints/games/reversi/games/show.ts +++ b/src/server/api/endpoints/games/reversi/games/show.ts @@ -6,6 +6,8 @@ import define from '../../../../define'; import { ApiError } from '../../../../error'; export const meta = { + tags: ['games'], + params: { gameId: { validator: $.type(ID), diff --git a/src/server/api/endpoints/games/reversi/games/surrender.ts b/src/server/api/endpoints/games/reversi/games/surrender.ts index 954ae07eb..446210894 100644 --- a/src/server/api/endpoints/games/reversi/games/surrender.ts +++ b/src/server/api/endpoints/games/reversi/games/surrender.ts @@ -6,6 +6,8 @@ import define from '../../../../define'; import { ApiError } from '../../../../error'; export const meta = { + tags: ['games'], + desc: { 'ja-JP': '指定したリバーシの対局で投了します。' }, diff --git a/src/server/api/endpoints/games/reversi/invitations.ts b/src/server/api/endpoints/games/reversi/invitations.ts index 034c84bdd..c20477057 100644 --- a/src/server/api/endpoints/games/reversi/invitations.ts +++ b/src/server/api/endpoints/games/reversi/invitations.ts @@ -2,6 +2,8 @@ import Matching, { pack as packMatching } from '../../../../../models/games/reve import define from '../../../define'; export const meta = { + tags: ['games'], + requireCredential: true }; diff --git a/src/server/api/endpoints/games/reversi/match.ts b/src/server/api/endpoints/games/reversi/match.ts index 6913ee13d..e66765944 100644 --- a/src/server/api/endpoints/games/reversi/match.ts +++ b/src/server/api/endpoints/games/reversi/match.ts @@ -9,6 +9,8 @@ import { ApiError } from '../../../error'; import { getUser } from '../../../common/getters'; export const meta = { + tags: ['games'], + requireCredential: true, params: { diff --git a/src/server/api/endpoints/games/reversi/match/cancel.ts b/src/server/api/endpoints/games/reversi/match/cancel.ts index 03b76babd..fb230032d 100644 --- a/src/server/api/endpoints/games/reversi/match/cancel.ts +++ b/src/server/api/endpoints/games/reversi/match/cancel.ts @@ -2,6 +2,8 @@ import Matching from '../../../../../../models/games/reversi/matching'; import define from '../../../../define'; export const meta = { + tags: ['games'], + requireCredential: true }; diff --git a/src/server/api/endpoints/hashtags/list.ts b/src/server/api/endpoints/hashtags/list.ts index bfeba1d16..5939c1019 100644 --- a/src/server/api/endpoints/hashtags/list.ts +++ b/src/server/api/endpoints/hashtags/list.ts @@ -3,6 +3,8 @@ import define from '../../define'; import Hashtag from '../../../../models/hashtag'; export const meta = { + tags: ['hashtags'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/hashtags/search.ts b/src/server/api/endpoints/hashtags/search.ts index eff50f413..ff7ca44f5 100644 --- a/src/server/api/endpoints/hashtags/search.ts +++ b/src/server/api/endpoints/hashtags/search.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': 'ハッシュタグを検索します。' }, + tags: ['hashtags'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/hashtags/trend.ts b/src/server/api/endpoints/hashtags/trend.ts index bf036642d..8b8dd7024 100644 --- a/src/server/api/endpoints/hashtags/trend.ts +++ b/src/server/api/endpoints/hashtags/trend.ts @@ -16,6 +16,8 @@ const requiredUsers = 3; // 最低何人がそのタグを投稿している必 const max = 5; export const meta = { + tags: ['hashtags'], + requireCredential: false, }; diff --git a/src/server/api/endpoints/hashtags/users.ts b/src/server/api/endpoints/hashtags/users.ts index b77bdf6aa..f589c37b8 100644 --- a/src/server/api/endpoints/hashtags/users.ts +++ b/src/server/api/endpoints/hashtags/users.ts @@ -5,6 +5,8 @@ import define from '../../define'; export const meta = { requireCredential: false, + tags: ['hashtags', 'users'], + params: { tag: { validator: $.str, diff --git a/src/server/api/endpoints/i.ts b/src/server/api/endpoints/i.ts index 7ef4ddd26..b7fe404ec 100644 --- a/src/server/api/endpoints/i.ts +++ b/src/server/api/endpoints/i.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': '自分のアカウント情報を取得します。' }, + tags: ['account'], + requireCredential: true, params: {}, diff --git a/src/server/api/endpoints/i/clear-follow-request-notification.ts b/src/server/api/endpoints/i/clear-follow-request-notification.ts index 2c656965d..38c6ec1ce 100644 --- a/src/server/api/endpoints/i/clear-follow-request-notification.ts +++ b/src/server/api/endpoints/i/clear-follow-request-notification.ts @@ -2,6 +2,8 @@ import User from '../../../../models/user'; import define from '../../define'; export const meta = { + tags: ['account', 'following'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts index b9bef38c6..7ea6f7b96 100644 --- a/src/server/api/endpoints/i/favorites.ts +++ b/src/server/api/endpoints/i/favorites.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Get favorited notes' }, + tags: ['account', 'notes', 'favorites'], + requireCredential: true, kind: 'favorites-read', diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts index 693d27996..3d038e5d3 100644 --- a/src/server/api/endpoints/i/notifications.ts +++ b/src/server/api/endpoints/i/notifications.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get notifications.' }, + tags: ['account', 'notifications'], + requireCredential: true, kind: 'account-read', diff --git a/src/server/api/endpoints/i/pin.ts b/src/server/api/endpoints/i/pin.ts index 0b6b1b0db..8d853d45c 100644 --- a/src/server/api/endpoints/i/pin.ts +++ b/src/server/api/endpoints/i/pin.ts @@ -12,6 +12,8 @@ export const meta = { 'ja-JP': '指定した投稿をピン留めします。' }, + tags: ['account', 'notes'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/i/read_all_messaging_messages.ts b/src/server/api/endpoints/i/read_all_messaging_messages.ts index 6bc6e16b4..bbbfa0d7b 100644 --- a/src/server/api/endpoints/i/read_all_messaging_messages.ts +++ b/src/server/api/endpoints/i/read_all_messaging_messages.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark all talk messages as read.' }, + tags: ['account', 'messaging'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/i/read_all_unread_notes.ts b/src/server/api/endpoints/i/read_all_unread_notes.ts index 16db17cb0..742c2d990 100644 --- a/src/server/api/endpoints/i/read_all_unread_notes.ts +++ b/src/server/api/endpoints/i/read_all_unread_notes.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark all messages as read.' }, + tags: ['account'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/i/unpin.ts b/src/server/api/endpoints/i/unpin.ts index 472e81156..184d46f2c 100644 --- a/src/server/api/endpoints/i/unpin.ts +++ b/src/server/api/endpoints/i/unpin.ts @@ -12,6 +12,8 @@ export const meta = { 'ja-JP': '指定した投稿のピン留めを解除します。' }, + tags: ['account', 'notes'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index df7da4677..22e76925b 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -20,6 +20,8 @@ export const meta = { 'en-US': 'Update myself' }, + tags: ['account'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts index e42bf79c5..0425ef021 100644 --- a/src/server/api/endpoints/messaging/history.ts +++ b/src/server/api/endpoints/messaging/history.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Show messaging history.' }, + tags: ['messaging'], + requireCredential: true, kind: 'messaging-read', diff --git a/src/server/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts index 34d3f4cfd..f1408f87f 100644 --- a/src/server/api/endpoints/messaging/messages.ts +++ b/src/server/api/endpoints/messaging/messages.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get messages of messaging.' }, + tags: ['messaging'], + requireCredential: true, kind: 'messaging-read', diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts index 7ff652629..cf32b4461 100644 --- a/src/server/api/endpoints/messaging/messages/create.ts +++ b/src/server/api/endpoints/messaging/messages/create.ts @@ -19,6 +19,8 @@ export const meta = { 'en-US': 'Create a message of messaging.' }, + tags: ['messaging'], + requireCredential: true, kind: 'messaging-write', diff --git a/src/server/api/endpoints/messaging/messages/delete.ts b/src/server/api/endpoints/messaging/messages/delete.ts index 5bc492c19..0ca12846c 100644 --- a/src/server/api/endpoints/messaging/messages/delete.ts +++ b/src/server/api/endpoints/messaging/messages/delete.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Delete a message.' }, + tags: ['messaging'], + requireCredential: true, kind: 'messaging-write', diff --git a/src/server/api/endpoints/messaging/messages/read.ts b/src/server/api/endpoints/messaging/messages/read.ts index 98f195d75..aa8ecdc4f 100644 --- a/src/server/api/endpoints/messaging/messages/read.ts +++ b/src/server/api/endpoints/messaging/messages/read.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Mark as read a message of messaging.' }, + tags: ['messaging'], + requireCredential: true, kind: 'messaging-write', diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 82769506c..07a475d4c 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Get the information of this instance.' }, + tags: ['meta'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/mute/create.ts b/src/server/api/endpoints/mute/create.ts index 3b2546176..7eaee90a0 100644 --- a/src/server/api/endpoints/mute/create.ts +++ b/src/server/api/endpoints/mute/create.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Mute a user' }, + tags: ['mute', 'users'], + requireCredential: true, kind: 'account/write', diff --git a/src/server/api/endpoints/mute/delete.ts b/src/server/api/endpoints/mute/delete.ts index 93af5834b..1a03f6371 100644 --- a/src/server/api/endpoints/mute/delete.ts +++ b/src/server/api/endpoints/mute/delete.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Unmute a user' }, + tags: ['mute', 'users'], + requireCredential: true, kind: 'account/write', diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts index 84699c237..da7189b48 100644 --- a/src/server/api/endpoints/mute/list.ts +++ b/src/server/api/endpoints/mute/list.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Get muted users.' }, + tags: ['mute', 'account'], + requireCredential: true, kind: 'account/read', diff --git a/src/server/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts index 0eeeb5f85..1a936c918 100644 --- a/src/server/api/endpoints/my/apps.ts +++ b/src/server/api/endpoints/my/apps.ts @@ -3,6 +3,8 @@ import App, { pack } from '../../../../models/app'; import define from '../../define'; export const meta = { + tags: ['account', 'app'], + desc: { 'ja-JP': '自分のアプリケーション一覧を取得します。', 'en-US': 'Get my apps' diff --git a/src/server/api/endpoints/notes.ts b/src/server/api/endpoints/notes.ts index f8d6fdd2b..b4716ac3e 100644 --- a/src/server/api/endpoints/notes.ts +++ b/src/server/api/endpoints/notes.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': '投稿を取得します。' }, + tags: ['notes'], + params: { local: { validator: $.optional.bool, diff --git a/src/server/api/endpoints/notes/conversation.ts b/src/server/api/endpoints/notes/conversation.ts index 2f08de9e8..702d8dc43 100644 --- a/src/server/api/endpoints/notes/conversation.ts +++ b/src/server/api/endpoints/notes/conversation.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Show conversation of a note.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -34,6 +36,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { noSuchNote: { message: 'No such note.', diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts index d24cd7b12..a4f262bda 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -25,6 +25,8 @@ export const meta = { 'ja-JP': '投稿します。' }, + tags: ['notes'], + requireCredential: true, limit: { @@ -175,7 +177,7 @@ export const meta = { type: 'object', props: { createdNote: { - type: 'entity(Note)', + type: 'Note', desc: { 'ja-JP': '作成した投稿' } diff --git a/src/server/api/endpoints/notes/delete.ts b/src/server/api/endpoints/notes/delete.ts index 8ca5a3bb0..399f9288d 100644 --- a/src/server/api/endpoints/notes/delete.ts +++ b/src/server/api/endpoints/notes/delete.ts @@ -15,6 +15,8 @@ export const meta = { 'en-US': 'Delete a note.' }, + tags: ['notes'], + requireCredential: true, kind: 'note-write', diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/src/server/api/endpoints/notes/favorites/create.ts index 26e3e34d5..9cde1a7dc 100644 --- a/src/server/api/endpoints/notes/favorites/create.ts +++ b/src/server/api/endpoints/notes/favorites/create.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Favorite a note.' }, + tags: ['favorites'], + requireCredential: true, kind: 'favorite-write', diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/src/server/api/endpoints/notes/favorites/delete.ts index d79a3d88c..e2c787f3b 100644 --- a/src/server/api/endpoints/notes/favorites/delete.ts +++ b/src/server/api/endpoints/notes/favorites/delete.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Unfavorite a note.' }, + tags: ['favorites'], + requireCredential: true, kind: 'favorite-write', diff --git a/src/server/api/endpoints/notes/featured.ts b/src/server/api/endpoints/notes/featured.ts index 08cc677ab..0d2187bb0 100644 --- a/src/server/api/endpoints/notes/featured.ts +++ b/src/server/api/endpoints/notes/featured.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Get featured notes.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -20,7 +22,14 @@ export const meta = { 'ja-JP': '最大数' } } - } + }, + + res: { + type: 'array', + items: { + type: 'Note', + }, + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts index 8670f8edb..b62d8e25a 100644 --- a/src/server/api/endpoints/notes/global-timeline.ts +++ b/src/server/api/endpoints/notes/global-timeline.ts @@ -12,6 +12,8 @@ export const meta = { 'ja-JP': 'グローバルタイムラインを取得します。' }, + tags: ['notes'], + params: { withFiles: { validator: $.optional.bool, @@ -51,6 +53,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { gtlDisabled: { message: 'Global timeline has been disabled.', diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index f3050caec..153436b9b 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -14,6 +14,8 @@ export const meta = { 'ja-JP': 'ハイブリッドタイムラインを取得します。' }, + tags: ['notes'], + params: { limit: { validator: $.optional.num.range(1, 100), @@ -92,6 +94,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { stlDisabled: { message: 'Social timeline has been disabled.', diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts index 44328ebed..06c6d7a53 100644 --- a/src/server/api/endpoints/notes/local-timeline.ts +++ b/src/server/api/endpoints/notes/local-timeline.ts @@ -13,6 +13,8 @@ export const meta = { 'ja-JP': 'ローカルタイムラインを取得します。' }, + tags: ['notes'], + params: { withFiles: { validator: $.optional.bool, @@ -67,6 +69,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { ltlDisabled: { message: 'Local timeline has been disabled.', diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts index 090f184f7..91333174e 100644 --- a/src/server/api/endpoints/notes/mentions.ts +++ b/src/server/api/endpoints/notes/mentions.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get mentions of myself.' }, + tags: ['notes'], + requireCredential: true, params: { @@ -39,7 +41,14 @@ export const meta = { visibility: { validator: $.optional.str, }, - } + }, + + res: { + type: 'array', + items: { + type: 'Note', + }, + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts index 61a1840b8..0a05e89c6 100644 --- a/src/server/api/endpoints/notes/polls/recommendation.ts +++ b/src/server/api/endpoints/notes/polls/recommendation.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Get recommended polls.' }, + tags: ['notes'], + requireCredential: true, params: { diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts index 00840579d..60007db13 100644 --- a/src/server/api/endpoints/notes/polls/vote.ts +++ b/src/server/api/endpoints/notes/polls/vote.ts @@ -18,6 +18,8 @@ export const meta = { 'en-US': 'Vote poll of a note.' }, + tags: ['notes'], + requireCredential: true, kind: 'vote-write', diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts index 74f22cc77..c67dd6d82 100644 --- a/src/server/api/endpoints/notes/reactions.ts +++ b/src/server/api/endpoints/notes/reactions.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Show reactions of a note.' }, + tags: ['notes', 'reactions'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts index 816c6a9c2..291e10bbd 100644 --- a/src/server/api/endpoints/notes/reactions/create.ts +++ b/src/server/api/endpoints/notes/reactions/create.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'React to a note.' }, + tags: ['reactions', 'notes'], + requireCredential: true, kind: 'reaction-write', diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts index 1afa6526f..2ccfb9329 100644 --- a/src/server/api/endpoints/notes/reactions/delete.ts +++ b/src/server/api/endpoints/notes/reactions/delete.ts @@ -12,6 +12,8 @@ export const meta = { 'en-US': 'Unreact to a note.' }, + tags: ['reactions', 'notes'], + requireCredential: true, kind: 'reaction-write', diff --git a/src/server/api/endpoints/notes/renotes.ts b/src/server/api/endpoints/notes/renotes.ts index b4c99b1f4..15dcf55dc 100644 --- a/src/server/api/endpoints/notes/renotes.ts +++ b/src/server/api/endpoints/notes/renotes.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Show a renotes of a note.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -39,6 +41,13 @@ export const meta = { } }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { noSuchNote: { message: 'No such note.', diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts index 080917f6f..c80fd7320 100644 --- a/src/server/api/endpoints/notes/replies.ts +++ b/src/server/api/endpoints/notes/replies.ts @@ -11,6 +11,8 @@ export const meta = { 'en-US': 'Get replies of a note.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -32,7 +34,14 @@ export const meta = { validator: $.optional.num.min(0), default: 0 }, - } + }, + + res: { + type: 'array', + items: { + type: 'Note', + }, + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts index 3eec2e318..edc8a1456 100644 --- a/src/server/api/endpoints/notes/search.ts +++ b/src/server/api/endpoints/notes/search.ts @@ -12,6 +12,8 @@ export const meta = { 'en-US': 'Search notes.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -30,6 +32,13 @@ export const meta = { } }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { searchingNotAvailable: { message: 'Searching not available.', diff --git a/src/server/api/endpoints/notes/search_by_tag.ts b/src/server/api/endpoints/notes/search_by_tag.ts index a4fd1903e..0030e2e37 100644 --- a/src/server/api/endpoints/notes/search_by_tag.ts +++ b/src/server/api/endpoints/notes/search_by_tag.ts @@ -11,6 +11,8 @@ export const meta = { 'ja-JP': '指定されたタグが付けられた投稿を取得します。' }, + tags: ['notes', 'hashtags'], + params: { tag: { validator: $.optional.str, @@ -100,7 +102,14 @@ export const meta = { validator: $.optional.num.range(1, 30), default: 10 }, - } + }, + + res: { + type: 'array', + items: { + type: 'Note', + }, + }, }; export default define(meta, async (ps, me) => { diff --git a/src/server/api/endpoints/notes/show.ts b/src/server/api/endpoints/notes/show.ts index f4fd06c03..6d8dc73ff 100644 --- a/src/server/api/endpoints/notes/show.ts +++ b/src/server/api/endpoints/notes/show.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get a note.' }, + tags: ['notes'], + requireCredential: false, params: { @@ -26,6 +28,10 @@ export const meta = { } }, + res: { + type: 'Note', + }, + errors: { noSuchNote: { message: 'No such note.', diff --git a/src/server/api/endpoints/notes/state.ts b/src/server/api/endpoints/notes/state.ts index 07e35480f..494480284 100644 --- a/src/server/api/endpoints/notes/state.ts +++ b/src/server/api/endpoints/notes/state.ts @@ -12,6 +12,8 @@ export const meta = { 'en-US': 'Get state of a note.' }, + tags: ['notes'], + requireCredential: true, params: { diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts index cb6900a10..9ec8070f7 100644 --- a/src/server/api/endpoints/notes/timeline.ts +++ b/src/server/api/endpoints/notes/timeline.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get timeline of myself.' }, + tags: ['notes'], + requireCredential: true, params: { @@ -91,7 +93,14 @@ export const meta = { 'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' } }, - } + }, + + res: { + type: 'array', + items: { + type: 'Note', + }, + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts index 1969b924a..45e96fbda 100644 --- a/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/src/server/api/endpoints/notes/user-list-timeline.ts @@ -14,6 +14,8 @@ export const meta = { 'en-US': 'Get timeline of a user list.' }, + tags: ['notes', 'lists'], + requireCredential: true, params: { @@ -102,6 +104,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { noSuchList: { message: 'No such list.', diff --git a/src/server/api/endpoints/notes/watching/create.ts b/src/server/api/endpoints/notes/watching/create.ts index 7361237e8..2b2de1bd3 100644 --- a/src/server/api/endpoints/notes/watching/create.ts +++ b/src/server/api/endpoints/notes/watching/create.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Watch a note.' }, + tags: ['notes'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/notes/watching/delete.ts b/src/server/api/endpoints/notes/watching/delete.ts index 33fbef570..512db793e 100644 --- a/src/server/api/endpoints/notes/watching/delete.ts +++ b/src/server/api/endpoints/notes/watching/delete.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Unwatch a note.' }, + tags: ['notes'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/notifications/mark_all_as_read.ts b/src/server/api/endpoints/notifications/mark_all_as_read.ts index 91e10b46e..e5df64828 100644 --- a/src/server/api/endpoints/notifications/mark_all_as_read.ts +++ b/src/server/api/endpoints/notifications/mark_all_as_read.ts @@ -9,6 +9,8 @@ export const meta = { 'en-US': 'Mark all notifications as read.' }, + tags: ['notifications', 'account'], + requireCredential: true, kind: 'notification-write' diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts index 43d7c4495..fa67ce25f 100644 --- a/src/server/api/endpoints/stats.ts +++ b/src/server/api/endpoints/stats.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Get the instance\'s statistics' }, + tags: ['meta'], + params: { } }; diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts index 870c13555..0b81b06ab 100644 --- a/src/server/api/endpoints/sw/register.ts +++ b/src/server/api/endpoints/sw/register.ts @@ -4,6 +4,8 @@ import define from '../../define'; import fetchMeta from '../../../../misc/fetch-meta'; export const meta = { + tags: ['account'], + requireCredential: true, params: { diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts index a651bc4d5..1d098eb39 100644 --- a/src/server/api/endpoints/username/available.ts +++ b/src/server/api/endpoints/username/available.ts @@ -4,6 +4,8 @@ import { validateUsername } from '../../../../models/user'; import define from '../../define'; export const meta = { + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts index f7e7a1001..7147a3541 100644 --- a/src/server/api/endpoints/users.ts +++ b/src/server/api/endpoints/users.ts @@ -7,6 +7,8 @@ import { getHideUserIds } from '../common/get-hide-users'; const nonnull = { $ne: null as any }; export const meta = { + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts index cb5b04762..32c75fc8d 100644 --- a/src/server/api/endpoints/users/followers.ts +++ b/src/server/api/endpoints/users/followers.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get followers of a user.' }, + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts index 04abe5f4b..3ce103621 100644 --- a/src/server/api/endpoints/users/following.ts +++ b/src/server/api/endpoints/users/following.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Get following users of a user.' }, + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users/get_frequently_replied_users.ts b/src/server/api/endpoints/users/get_frequently_replied_users.ts index 0b90e489c..6f9c746ac 100644 --- a/src/server/api/endpoints/users/get_frequently_replied_users.ts +++ b/src/server/api/endpoints/users/get_frequently_replied_users.ts @@ -9,6 +9,8 @@ import { ApiError } from '../../error'; import { getUser } from '../../common/getters'; export const meta = { + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users/lists/create.ts b/src/server/api/endpoints/users/lists/create.ts index a3d91b6c2..00d2538c9 100644 --- a/src/server/api/endpoints/users/lists/create.ts +++ b/src/server/api/endpoints/users/lists/create.ts @@ -8,6 +8,8 @@ export const meta = { 'en-US': 'Create a user list' }, + tags: ['lists'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/users/lists/delete.ts b/src/server/api/endpoints/users/lists/delete.ts index 6aaf4701d..d8faaa928 100644 --- a/src/server/api/endpoints/users/lists/delete.ts +++ b/src/server/api/endpoints/users/lists/delete.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Delete a user list' }, + tags: ['lists'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/users/lists/list.ts b/src/server/api/endpoints/users/lists/list.ts index 5bd662878..632f4e7e5 100644 --- a/src/server/api/endpoints/users/lists/list.ts +++ b/src/server/api/endpoints/users/lists/list.ts @@ -6,6 +6,8 @@ export const meta = { 'ja-JP': '自分の作成したユーザーリスト一覧を取得します。' }, + tags: ['lists', 'account'], + requireCredential: true, kind: 'account-read' diff --git a/src/server/api/endpoints/users/lists/pull.ts b/src/server/api/endpoints/users/lists/pull.ts index 7c438ff3d..0eee1975d 100644 --- a/src/server/api/endpoints/users/lists/pull.ts +++ b/src/server/api/endpoints/users/lists/pull.ts @@ -13,6 +13,8 @@ export const meta = { 'en-US': 'Remove a user to a user list.' }, + tags: ['lists', 'users'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/users/lists/push.ts b/src/server/api/endpoints/users/lists/push.ts index c63bbb6ac..6b47f9dc7 100644 --- a/src/server/api/endpoints/users/lists/push.ts +++ b/src/server/api/endpoints/users/lists/push.ts @@ -16,6 +16,8 @@ export const meta = { 'en-US': 'Add a user to a user list.' }, + tags: ['lists', 'users'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/users/lists/show.ts b/src/server/api/endpoints/users/lists/show.ts index 3bd8ce657..2f3c8889a 100644 --- a/src/server/api/endpoints/users/lists/show.ts +++ b/src/server/api/endpoints/users/lists/show.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Show a user list.' }, + tags: ['lists', 'account'], + requireCredential: true, kind: 'account-read', diff --git a/src/server/api/endpoints/users/lists/update.ts b/src/server/api/endpoints/users/lists/update.ts index 842ae189e..589769314 100644 --- a/src/server/api/endpoints/users/lists/update.ts +++ b/src/server/api/endpoints/users/lists/update.ts @@ -10,6 +10,8 @@ export const meta = { 'en-US': 'Update a user list' }, + tags: ['lists'], + requireCredential: true, kind: 'account-write', diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts index 1c5882d5b..f8942fb2d 100644 --- a/src/server/api/endpoints/users/notes.ts +++ b/src/server/api/endpoints/users/notes.ts @@ -11,6 +11,8 @@ export const meta = { 'ja-JP': '指定したユーザーのタイムラインを取得します。' }, + tags: ['users', 'notes'], + params: { userId: { validator: $.type(ID), @@ -124,6 +126,13 @@ export const meta = { }, }, + res: { + type: 'array', + items: { + type: 'Note', + }, + }, + errors: { noSuchUser: { message: 'No such user.', diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index dc37bc56b..2261ee7df 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -15,6 +15,8 @@ export const meta = { 'ja-JP': 'おすすめのユーザー一覧を取得します。' }, + tags: ['users'], + requireCredential: true, kind: 'account-read', diff --git a/src/server/api/endpoints/users/relation.ts b/src/server/api/endpoints/users/relation.ts index 5b7b4d8e4..f4121aa0d 100644 --- a/src/server/api/endpoints/users/relation.ts +++ b/src/server/api/endpoints/users/relation.ts @@ -8,11 +8,13 @@ export const meta = { 'ja-JP': 'ユーザー間のリレーションを取得します。' }, + tags: ['users'], + requireCredential: true, params: { userId: { - validator: $.or($.type(ID), $.arr($.type(ID)).unique()), + validator: $.either($.type(ID), $.arr($.type(ID)).unique()), transform: (v: any): ObjectId | ObjectId[] => Array.isArray(v) ? v.map(x => transform(x)) : transform(v), desc: { 'ja-JP': 'ユーザーID (配列でも可)' diff --git a/src/server/api/endpoints/users/report-abuse.ts b/src/server/api/endpoints/users/report-abuse.ts index 36f797f5e..0f23f8f0c 100644 --- a/src/server/api/endpoints/users/report-abuse.ts +++ b/src/server/api/endpoints/users/report-abuse.ts @@ -12,6 +12,8 @@ export const meta = { 'ja-JP': '指定したユーザーを迷惑なユーザーであると報告します。' }, + tags: ['users'], + requireCredential: true, params: { diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts index 6fd390f28..a6b50b687 100644 --- a/src/server/api/endpoints/users/search.ts +++ b/src/server/api/endpoints/users/search.ts @@ -8,6 +8,8 @@ export const meta = { 'ja-JP': 'ユーザーを検索します。' }, + tags: ['users'], + requireCredential: false, params: { diff --git a/src/server/api/endpoints/users/show.ts b/src/server/api/endpoints/users/show.ts index 4f870b8b9..4e59945eb 100644 --- a/src/server/api/endpoints/users/show.ts +++ b/src/server/api/endpoints/users/show.ts @@ -13,6 +13,8 @@ export const meta = { 'ja-JP': '指定したユーザーの情報を取得します。' }, + tags: ['users'], + requireCredential: false, params: { @@ -42,6 +44,10 @@ export const meta = { } }, + res: { + type: 'User', + }, + errors: { failedToResolveRemoteUser: { message: 'Failed to resolve remote user.', diff --git a/src/server/api/error.ts b/src/server/api/error.ts index 6b5c44cac..ca441d581 100644 --- a/src/server/api/error.ts +++ b/src/server/api/error.ts @@ -3,14 +3,16 @@ export class ApiError extends Error { public code: string; public id: string; public kind: string; + public httpStatusCode?: number; public info?: any; - constructor(e?: { message: string, code: string, id: string, kind?: 'client' | 'server' }, info?: any) { + constructor(e?: { message: string, code: string, id: string, kind?: 'client' | 'server', httpStatusCode?: number }, info?: any) { if (e == null) e = { message: 'Internal error occurred. Please contact us if the error persists.', code: 'INTERNAL_ERROR', id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac', - kind: 'server' + kind: 'server', + httpStatusCode: 500 }; super(e.message); @@ -18,6 +20,7 @@ export class ApiError extends Error { this.code = e.code; this.id = e.id; this.kind = e.kind || 'client'; + this.httpStatusCode = e.httpStatusCode; this.info = info; } } diff --git a/src/server/api/gen-openapi-spec.ts b/src/server/api/gen-openapi-spec.ts new file mode 100644 index 000000000..3b0669087 --- /dev/null +++ b/src/server/api/gen-openapi-spec.ts @@ -0,0 +1,507 @@ +import endpoints from './endpoints'; +import { Context } from 'cafy'; +import config from '../../config'; + +const basicErrors = { + '400': { + 'INVALID_PARAM': { + value: { + error: { + message: 'Invalid param.', + code: 'INVALID_PARAM', + id: '3d81ceae-475f-4600-b2a8-2bc116157532', + } + } + } + }, + '401': { + 'CREDENTIAL_REQUIRED': { + value: { + error: { + message: 'Credential required.', + code: 'CREDENTIAL_REQUIRED', + id: '1384574d-a912-4b81-8601-c7b1c4085df1', + } + } + } + }, + '403': { + 'AUTHENTICATION_FAILED': { + value: { + error: { + message: 'Authentication failed. Please ensure your token is correct.', + code: 'AUTHENTICATION_FAILED', + id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14', + } + } + } + }, + '418': { + 'I_AM_AI': { + value: { + error: { + message: 'You sent a request to Ai-chan, Misskey\'s showgirl, instead of the server.', + code: 'I_AM_AI', + id: '60c46cd1-f23a-46b1-bebe-5d2b73951a84', + } + } + } + }, + '429': { + 'RATE_LIMIT_EXCEEDED': { + value: { + error: { + message: 'Rate limit exceeded. Please try again later.', + code: 'RATE_LIMIT_EXCEEDED', + id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef', + } + } + } + }, + '500': { + 'INTERNAL_ERROR': { + value: { + error: { + message: 'Internal error occurred. Please contact us if the error persists.', + code: 'INTERNAL_ERROR', + id: '5d37dbcb-891e-41ca-a3d6-e690c97775ac', + } + } + } + } +}; + +const schemas = { + Error: { + type: 'object', + properties: { + error: { + type: 'object', + description: 'An error object.', + properties: { + code: { + type: 'string', + description: 'An error code.', + }, + message: { + type: 'string', + description: 'An error message.', + }, + id: { + type: 'string', + format: 'uuid', + description: 'An error ID. This ID is static.', + } + }, + required: ['code', 'id', 'message'] + }, + }, + required: ['error'] + }, + + User: { + type: 'object', + properties: { + id: { + type: 'string', + format: 'id', + description: 'The unique identifier for this User.' + }, + username: { + type: 'string', + description: 'The screen name, handle, or alias that this user identifies themselves with.', + example: 'ai' + }, + name: { + type: 'string', + nullable: true, + description: 'The name of the user, as they’ve defined it.', + example: '藍' + }, + host: { + type: 'string', + nullable: true, + example: 'misskey.example.com' + }, + description: { + type: 'string', + nullable: true, + description: 'The user-defined UTF-8 string describing their account.', + example: 'Hi masters, I am Ai!' + }, + createdAt: { + type: 'string', + format: 'date-time', + description: 'The date that the user account was created on Misskey.' + }, + followersCount: { + type: 'number', + description: 'The number of followers this account currently has.' + }, + followingCount: { + type: 'number', + description: 'The number of users this account is following.' + }, + notesCount: { + type: 'number', + description: 'The number of Notes (including renotes) issued by the user.' + }, + isBot: { + type: 'boolean', + description: 'Whether this account is a bot.' + }, + isCat: { + type: 'boolean', + description: 'Whether this account is a cat.' + }, + isAdmin: { + type: 'boolean', + description: 'Whether this account is the admin.' + }, + isVerified: { + type: 'boolean' + }, + isLocked: { + type: 'boolean' + }, + }, + required: ['id', 'name', 'username', 'createdAt'] + }, + + Note: { + type: 'object', + properties: { + id: { + type: 'string', + format: 'id', + description: 'The unique identifier for this Note.' + }, + createdAt: { + type: 'string', + format: 'date-time', + description: 'The date that the Note was created on Misskey.' + }, + text: { + type: 'string' + }, + cw: { + type: 'string' + }, + userId: { + type: 'string', + format: 'id', + }, + user: { + $ref: '#/components/schemas/User' + }, + replyId: { + type: 'string', + format: 'id', + }, + renoteId: { + type: 'string', + format: 'id', + }, + reply: { + $ref: '#/components/schemas/Note' + }, + renote: { + $ref: '#/components/schemas/Note' + }, + viaMobile: { + type: 'boolean' + }, + visibility: { + type: 'string' + }, + }, + required: ['id', 'userId', 'createdAt'] + }, + + DriveFile: { + type: 'object', + properties: { + id: { + type: 'string', + format: 'id', + description: 'The unique identifier for this Drive file.' + }, + createdAt: { + type: 'string', + format: 'date-time', + description: 'The date that the Drive file was created on Misskey.' + }, + name: { + type: 'string', + description: 'The file name with extension.', + example: 'lenna.jpg' + }, + type: { + type: 'string', + description: 'The MIME type of this Drive file.', + example: 'image/jpeg' + }, + md5: { + type: 'string', + format: 'md5', + description: 'The MD5 hash of this Drive file.', + example: '15eca7fba0480996e2245f5185bf39f2' + }, + datasize: { + type: 'number', + description: 'The size of this Drive file. (bytes)', + example: 51469 + }, + folderId: { + type: 'string', + format: 'id', + nullable: true, + description: 'The parent folder ID of this Drive file.', + }, + isSensitive: { + type: 'boolean', + description: 'Whether this Drive file is sensitive.', + }, + }, + required: ['id', 'createdAt', 'name', 'type', 'datasize', 'md5'] + } +}; + +export function genOpenapiSpec(lang = 'ja-JP') { + const spec = { + openapi: '3.0.0', + + info: { + version: 'v1', + title: 'Misskey API', + description: 'Misskey is a decentralized microblogging platform.', + 'x-logo': { url: '/assets/api-doc.png' } + }, + + servers: [{ + url: config.api_url + }], + + paths: {} as any, + + components: { + schemas: schemas, + + securitySchemes: { + ApiKeyAuth: { + type: 'apiKey', + in: 'body', + name: 'i' + } + } + } + }; + + function genProps(props: { [key: string]: Context & { desc: any, default: any }; }) { + const properties = {} as any; + + const kvs = Object.entries(props); + + for (const kv of kvs) { + properties[kv[0]] = genProp(kv[1], kv[1].desc, kv[1].default); + } + + return properties; + } + + function genProp(param: Context, desc?: string, _default?: any): any { + const required = param.name === 'Object' ? (param as any).props ? Object.entries((param as any).props).filter(([k, v]: any) => !v.isOptional).map(([k, v]) => k) : [] : []; + return { + description: desc, + default: _default, + ...(_default ? { default: _default } : {}), + type: param.name === 'ID' ? 'string' : param.name.toLowerCase(), + ...(param.name === 'ID' ? { example: 'xxxxxxxxxxxxxxxxxxxxxxxx', format: 'id' } : {}), + nullable: param.isNullable, + ...(param.name === 'String' ? { + ...((param as any).enum ? { enum: (param as any).enum } : {}), + ...((param as any).minLength ? { minLength: (param as any).minLength } : {}), + ...((param as any).maxLength ? { maxLength: (param as any).maxLength } : {}), + } : {}), + ...(param.name === 'Number' ? { + ...((param as any).minimum ? { minimum: (param as any).minimum } : {}), + ...((param as any).maximum ? { maximum: (param as any).maximum } : {}), + } : {}), + ...(param.name === 'Object' ? { + ...(required.length > 0 ? { required } : {}), + properties: (param as any).props ? genProps((param as any).props) : {} + } : {}), + ...(param.name === 'Array' ? { + items: (param as any).ctx ? genProp((param as any).ctx) : {} + } : {}) + }; + } + + for (const endpoint of endpoints.filter(ep => !ep.meta.secure)) { + const porops = {} as any; + const errors = {} as any; + + if (endpoint.meta.errors) { + for (const e of Object.values(endpoint.meta.errors)) { + errors[e.code] = { + value: { + error: e + } + }; + } + } + + if (endpoint.meta.params) { + for (const kv of Object.entries(endpoint.meta.params)) { + if (kv[1].desc) (kv[1].validator as any).desc = kv[1].desc[lang]; + if (kv[1].default) (kv[1].validator as any).default = kv[1].default; + porops[kv[0]] = kv[1].validator; + } + } + + const required = endpoint.meta.params ? Object.entries(endpoint.meta.params).filter(([k, v]) => !v.validator.isOptional).map(([k, v]) => k) : []; + + const resSchema = endpoint.meta.res ? renderType(endpoint.meta.res) : {}; + + function renderType(x: any) { + const res = {} as any; + + if (['User', 'Note', 'DriveFile'].includes(x.type)) { + res['$ref'] = `#/components/schemas/${x.type}`; + } else if (x.type === 'object') { + res['type'] = 'object'; + if (x.props) { + const props = {} as any; + for (const kv of Object.entries(x.props)) { + props[kv[0]] = renderType(kv[1]); + } + res['properties'] = props; + } + } else if (x.type === 'array') { + res['type'] = 'array'; + if (x.items) { + res['items'] = renderType(x.items); + } + } else { + res['type'] = x.type; + } + + return res; + } + + const info = { + summary: endpoint.name, + description: endpoint.meta.desc ? endpoint.meta.desc[lang] : 'No description provided.', + ...(endpoint.meta.tags ? { + tags: endpoint.meta.tags + } : {}), + ...(endpoint.meta.requireCredential ? { + security: [{ + ApiKeyAuth: [] + }] + } : {}), + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + ...(required.length > 0 ? { required } : {}), + properties: endpoint.meta.params ? genProps(porops) : {} + } + } + } + }, + responses: { + ...(endpoint.meta.res ? { + '200': { + description: 'OK (with results)', + content: { + 'application/json': { + schema: resSchema + } + } + } + } : { + '204': { + description: 'OK (without any results)', + } + }), + '400': { + description: 'Client error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: { ...errors, ...basicErrors['400'] } + } + } + }, + '401': { + description: 'Authentication error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['401'] + } + } + }, + '403': { + description: 'Forbiddon error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['403'] + } + } + }, + '418': { + description: 'I\'m Ai', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['418'] + } + } + }, + ...(endpoint.meta.limit ? { + '429': { + description: 'To many requests', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['429'] + } + } + } + } : {}), + '500': { + description: 'Internal server error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['500'] + } + } + }, + } + }; + + spec.paths['/' + endpoint.name] = { + post: info + }; + } + + return spec; +} diff --git a/src/server/web/docs.ts b/src/server/web/docs.ts index c0e03f914..414aac02c 100644 --- a/src/server/web/docs.ts +++ b/src/server/web/docs.ts @@ -10,11 +10,9 @@ import ms = require('ms'); import * as Router from 'koa-router'; import * as send from 'koa-send'; import * as glob from 'glob'; -import * as yaml from 'js-yaml'; import config from '../../config'; import { licenseHtml } from '../../misc/license'; import { copyright } from '../../const.json'; -import endpoints from '../api/endpoints'; import * as locales from '../../../locales'; import * as nestedProperty from 'nested-property'; @@ -33,14 +31,6 @@ async function genVars(lang: string): Promise<{ [key: string]: any }> { const cwd = path.resolve(__dirname + '/../../../') + '/'; - vars['endpoints'] = endpoints; - - const entities = glob.sync('src/docs/api/entities/**/*.yaml', { cwd }); - vars['entities'] = entities.map(x => { - const _x = yaml.safeLoad(fs.readFileSync(cwd + x, 'utf-8')); - return _x.name; - }); - const docs = glob.sync(`src/docs/**/*.${lang}.md`, { cwd }); vars['docs'] = {}; for (const x of docs) { @@ -67,82 +57,6 @@ async function genVars(lang: string): Promise<{ [key: string]: any }> { return vars; } -// WIP type -const parseParamDefinition = (key: string, x: any) => { - return Object.assign({ - name: key, - type: x.validator.getType() - }, x); -}; - -const parsePropDefinition = (key: string, prop: any) => { - const id = prop.type.match(/^id\((.+?)\)|^id/); - const entity = prop.type.match(/^entity\((.+?)\)/); - const isObject = /^object/.test(prop.type); - const isDate = /^date/.test(prop.type); - const isArray = /\[\]$/.test(prop.type); - if (id) { - prop.kind = 'id'; - prop.type = 'string'; - prop.entity = id[1]; - if (isArray) { - prop.type += '[]'; - } - } - if (entity) { - prop.kind = 'entity'; - prop.type = 'object'; - prop.entity = entity[1]; - if (isArray) { - prop.type += '[]'; - } - } - if (isObject) { - prop.kind = 'object'; - if (prop.props) { - prop.hasDef = true; - } - } - if (isDate) { - prop.kind = 'date'; - prop.type = 'string'; - if (isArray) { - prop.type += '[]'; - } - } - - if (prop.optional) { - prop.type += '?'; - } - - prop.name = key; - - return prop; -}; - -const sortParams = (params: { name: string }[]) => { - return params; -}; - -const extractPropDefRef = (props: any[]) => { - let defs: any[] = []; - - for (const [k, v] of Object.entries(props)) { - if (v.props) { - defs.push({ - name: k, - props: sortParams(Object.entries(v.props).map(([k, v]) => parsePropDefinition(k, v))) - }); - - const childDefs = extractPropDefRef(v.props); - - defs = defs.concat(childDefs); - } - } - - return sortParams(defs); -}; - const router = new Router(); router.get('/assets/*', async ctx => { @@ -152,49 +66,6 @@ router.get('/assets/*', async ctx => { }); }); -router.get('/*/api/endpoints/*', async ctx => { - const lang = getLang(ctx.params[0]); - const name = ctx.params[1]; - const ep = endpoints.find(e => e.name === name); - - const vars = { - id: `api/endpoints/${name}`, - title: name, - endpoint: ep.meta, - endpointUrl: { - host: config.api_url, - path: name - }, - // @ts-ignore - params: ep.meta.params ? sortParams(Object.entries(ep.meta.params).map(([k, v]) => parseParamDefinition(k, v))) : null, - res: ep.meta.res, - resProps: ep.meta.res && ep.meta.res.props ? sortParams(Object.entries(ep.meta.res.props).map(([k, v]) => parsePropDefinition(k, v))) : null, - resDefs: null as any, //extractPropDefRef(Object.entries(ep.res.props).map(([k, v]) => parsePropDefinition(k, v))) - src: `https://github.com/syuilo/misskey/tree/master/src/server/api/endpoints/${name}.ts` - }; - - await ctx.render('../../../../src/docs/api/endpoints/view', Object.assign(await genVars(lang), vars)); - - ctx.set('Cache-Control', 'public, max-age=300'); -}); - -router.get('/*/api/entities/*', async ctx => { - const lang = getLang(ctx.params[0]); - const entity = ctx.params[1]; - - const x = yaml.safeLoad(fs.readFileSync(path.resolve(`${__dirname}/../../../src/docs/api/entities/${entity}.yaml`), 'utf-8')); - - await ctx.render('../../../../src/docs/api/entities/view', Object.assign(await genVars(lang), { - id: `api/entities/${entity}`, - name: x.name, - desc: x.desc, - props: sortParams(Object.entries(x.props).map(([k, v]) => parsePropDefinition(k, v))), - propDefs: extractPropDefRef(x.props) - })); - - ctx.set('Cache-Control', 'public, max-age=300'); -}); - router.get('/*/*', async ctx => { const lang = getLang(ctx.params[0]); const doc = ctx.params[1]; diff --git a/src/server/web/index.ts b/src/server/web/index.ts index 589e476d6..0270dde61 100644 --- a/src/server/web/index.ts +++ b/src/server/web/index.ts @@ -21,6 +21,7 @@ import getNoteSummary from '../../misc/get-note-summary'; import fetchMeta from '../../misc/fetch-meta'; import Emoji from '../../models/emoji'; import * as pkg from '../../../package.json'; +import { genOpenapiSpec } from '../api/gen-openapi-spec'; const client = `${__dirname}/../../client/`; @@ -83,10 +84,19 @@ router.get('/manifest.json', async ctx => { // Docs router.use('/docs', docs.routes()); +router.get('/api-doc', async ctx => { + await send(ctx as any, '/assets/redoc.html', { + root: client + }); +}); // URL preview endpoint router.get('/url', require('./url-preview')); +router.get('/api.json', async ctx => { + ctx.body = genOpenapiSpec(); +}); + const getFeed = async (acct: string) => { const { username, host } = parseAcct(acct); const user = await User.findOne({