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
This commit is contained in:
syuilo
2019-02-23 11:20:58 +09:00
committed by GitHub
parent 68a6758302
commit 52774bbe64
173 changed files with 1091 additions and 876 deletions

View File

@ -74,7 +74,7 @@ APIはすべてリクエストのパラメータ・レスポンスともにJSON
ストリーミングAPIも提供しています。
APIリファレンスもご確認ください。
[APIリファレンス](/api-doc)もご確認ください。
### レートリミット
Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。

View File

@ -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

View File

@ -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}', `<code>${endpoint.kind}</code>`)
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')

View File

@ -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"

View File

@ -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"

View File

@ -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: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
en-US: "The your <a href='/docs/api/reactions'>reaction</a> 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: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
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: "速度。メートル / 秒数で表す。"

View File

@ -1 +0,0 @@
@import "../style"

View File

@ -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)"

View File

@ -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)

View File

@ -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

View File

@ -1,11 +0,0 @@
@import "../style"
table.props
.name
font-weight bold
.name
.type
.optional
font-family Consolas, 'Courier New', Courier, Monaco, monospace

View File

@ -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