diff --git a/package.json b/package.json index 51cf823a9..aef3a1bf4 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "config": "node ./init.js", "start": "node ./built/index.js", + "swagger": "node ./swagger.js", "build": "gulp build", "rebuild": "gulp rebuild", "clean": "gulp clean", @@ -124,6 +125,7 @@ "sortablejs": "1.5.0-rc1", "subdomain": "1.2.0", "summaly": "1.2.7", + "swagger-jsdoc": "^1.8.4", "syuilo-password-strength": "0.0.1", "syuilo-transformify": "0.1.2", "tcp-port-used": "0.1.2", diff --git a/src/api/endpoints/app/create.js b/src/api/endpoints/app/create.js index d83062c8e..9ce98b197 100644 --- a/src/api/endpoints/app/create.js +++ b/src/api/endpoints/app/create.js @@ -7,6 +7,59 @@ import rndstr from 'rndstr'; import App from '../../models/app'; import serialize from '../../serializers/app'; +/** + * @swagger + * /app/create: + * post: + * summary: Create an application + * parameters: + * - $ref: "#/parameters/AccessToken" + * - + * name: name_id + * description: Application unique name + * in: formData + * required: true + * type: string + * - + * name: name + * description: Application name + * in: formData + * required: true + * type: string + * - + * name: description + * description: Application description + * in: formData + * required: true + * type: string + * - + * name: permission + * description: Permissions that application has + * in: formData + * required: true + * type: array + * items: + * type: string + * collectionFormat: csv + * - + * name: callback_url + * description: URL called back after authentication + * in: formData + * required: false + * type: string + * + * responses: + * 200: + * description: Created application's information + * schema: + * $ref: "#/definitions/Application" + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Create an app * diff --git a/src/api/endpoints/app/name_id/available.js b/src/api/endpoints/app/name_id/available.js index 179925dce..e101e0637 100644 --- a/src/api/endpoints/app/name_id/available.js +++ b/src/api/endpoints/app/name_id/available.js @@ -5,6 +5,35 @@ */ import App from '../../../models/app'; +/** + * @swagger + * /app/name_id/available: + * post: + * summary: Check available name_id on creation an application + * parameters: + * - + * name: name_id + * description: Application unique name + * in: formData + * required: true + * type: string + * + * responses: + * 200: + * description: Success + * schema: + * type: object + * properties: + * available: + * description: Whether name_id is available + * type: boolean + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Check available name_id of app * diff --git a/src/api/endpoints/app/show.js b/src/api/endpoints/app/show.js index 8d12f9aeb..2b651d53a 100644 --- a/src/api/endpoints/app/show.js +++ b/src/api/endpoints/app/show.js @@ -7,6 +7,36 @@ import * as mongo from 'mongodb'; import App from '../../models/app'; import serialize from '../../serializers/app'; +/** + * @swagger + * /app/show: + * post: + * summary: Show an application's information + * description: Require app_id or name_id + * parameters: + * - + * name: app_id + * description: Application ID + * in: formData + * type: string + * - + * name: name_id + * description: Application unique name + * in: formData + * type: string + * + * responses: + * 200: + * description: Success + * schema: + * $ref: "#/definitions/Application" + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Show an app * diff --git a/src/api/endpoints/auth/accept.js b/src/api/endpoints/auth/accept.js index 110a0897d..131a0e561 100644 --- a/src/api/endpoints/auth/accept.js +++ b/src/api/endpoints/auth/accept.js @@ -9,6 +9,29 @@ import App from '../../models/app'; import AuthSess from '../../models/auth-session'; import AccessToken from '../../models/access-token'; +/** + * @swagger + * /auth/accept: + * post: + * summary: Accept a session + * parameters: + * - $ref: "#/parameters/NativeToken" + * - + * name: token + * description: Session Token + * in: formData + * required: true + * type: string + * responses: + * 204: + * description: OK + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Accept * diff --git a/src/api/endpoints/auth/session/generate.js b/src/api/endpoints/auth/session/generate.js index bb49cf090..f67209eee 100644 --- a/src/api/endpoints/auth/session/generate.js +++ b/src/api/endpoints/auth/session/generate.js @@ -7,6 +7,37 @@ import * as uuid from 'uuid'; import App from '../../../models/app'; import AuthSess from '../../../models/auth-session'; +/** + * @swagger + * /auth/session/generate: + * post: + * summary: Generate a session + * parameters: + * - + * name: app_secret + * description: App Secret + * in: formData + * required: true + * type: string + * + * responses: + * 200: + * description: OK + * schema: + * type: object + * properties: + * token: + * type: string + * description: Session Token + * url: + * type: string + * description: Authentication form's URL + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Generate a session * diff --git a/src/api/endpoints/auth/session/show.js b/src/api/endpoints/auth/session/show.js index 67160c699..e161d9e57 100644 --- a/src/api/endpoints/auth/session/show.js +++ b/src/api/endpoints/auth/session/show.js @@ -6,6 +6,46 @@ import AuthSess from '../../../models/auth-session'; import serialize from '../../../serializers/auth-session'; +/** + * @swagger + * /auth/session/show: + * post: + * summary: Show a session information + * parameters: + * - + * name: token + * description: Session Token + * in: formData + * required: true + * type: string + * + * responses: + * 200: + * description: OK + * schema: + * type: object + * properties: + * created_at: + * type: string + * format: date-time + * description: Date and time of the session creation + * app_id: + * type: string + * description: Application ID + * token: + * type: string + * description: Session Token + * user_id: + * type: string + * description: ID of user who create the session + * app: + * $ref: "#/definitions/Application" + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Show a session * diff --git a/src/api/endpoints/auth/session/userkey.js b/src/api/endpoints/auth/session/userkey.js index f85a720ea..9905d7d84 100644 --- a/src/api/endpoints/auth/session/userkey.js +++ b/src/api/endpoints/auth/session/userkey.js @@ -8,6 +8,42 @@ import AuthSess from '../../../models/auth-session'; import AccessToken from '../../../models/access-token'; import serialize from '../../../serializers/user'; +/** + * @swagger + * /auth/session/userkey: + * post: + * summary: Get a access token(userkey) + * parameters: + * - + * name: app_secret + * description: App Secret + * in: formData + * required: true + * type: string + * - + * name: token + * description: Session Token + * in: formData + * required: true + * type: string + * + * responses: + * 200: + * description: OK + * schema: + * type: object + * properties: + * userkey: + * type: string + * description: Access Token + * user: + * $ref: "#/definitions/User" + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Generate a session * diff --git a/src/api/endpoints/meta.js b/src/api/endpoints/meta.js index acbe43a54..88e7f64dd 100644 --- a/src/api/endpoints/meta.js +++ b/src/api/endpoints/meta.js @@ -6,6 +6,33 @@ import prominence from 'prominence'; import git from 'git-last-commit'; +/** + * @swagger + * /meta: + * post: + * summary: Show the misskey's information + * responses: + * 200: + * description: Success + * schema: + * type: object + * properties: + * maintainer: + * description: maintainer's name + * type: string + * commit: + * description: latest commit's hash + * type: string + * secure: + * description: whether the server supports secure protcols + * type: boolean + * + * default: + * description: Failed + * schema: + * $ref: "#/definitions/Error" + */ + /** * Show core info * diff --git a/swagger.js b/swagger.js new file mode 100644 index 000000000..0cfd2fff0 --- /dev/null +++ b/swagger.js @@ -0,0 +1,229 @@ +'use strict' + +const swaggerJSDoc = require('swagger-jsdoc'); +const fs = require('fs'); +const yaml = require('js-yaml'); + +const apiRoot = './src/api/endpoints'; +const files = [ + 'meta.js', + //app + 'app/show.js', + 'app/create.js', + 'app/name_id/available.js', + //auth + 'auth/accept.js', + //auth/session + 'auth/session/generate.js', + 'auth/session/show.js', + 'auth/session/userkey.js', +]; + +const defaultSwagger = { + "swagger": "2.0", + "info": { + "title": "Misskey API", + "version": "aoi" + }, + "host": "api.misskey.xyz", + "schemes": [ + "https" + ], + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json" + ], + + "parameters": { + "AccessToken": { + "name": "i", + "description": "Access Token", + "in": "formData", + "required": true, + "type": "string" + }, + + "NativeToken": { + "name": "i", + "description": "Native Access Token", + "in": "formData", + "required": true, + "type": "string", + "pattern": "^\!.+" + } + }, + + "definitions": { + "Error": { + "type": "object", + "properties": { + "error": { + "type": "string", + "description": "Error message" + } + } + }, + "User": { + "type": "object", + "required": [ + "created_at", + "followers_count", + "following_count", + "id", + "liked_count", + "likes_count", + "name", + "posts_count", + "username" + ], + "properties": { + "avatar_id": { + "type": "string", + "description": "アバターに設定しているドライブのファイルのID" + }, + "avatar_url": { + "type": "string", + "description": "アバターURL" + }, + "banner_id": { + "type": "string", + "description": "バナーに設定しているドライブのファイルのID" + }, + "banner_url": { + "type": "string", + "description": "バナーURL" + }, + "bio": { + "type": "string", + "description": "プロフィール" + }, + "birthday": { + "type": "string", + "format": "date", + "description": "誕生日" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "アカウント作成日時" + }, + "drive_capacity": { + "type": "integer", + "description": "ドライブの最大容量" + }, + "followers_count": { + "type": "integer", + "description": "フォロワー数" + }, + "following_count": { + "type": "integer", + "description": "フォロー数" + }, + "id": { + "type": "string", + "description": "ユーザーID" + }, + "is_followed": { + "type": "boolean", + "description": "フォローされているか" + }, + "is_following": { + "type": "boolean", + "description": "フォローしているか" + }, + "liked_count": { + "type": "integer", + "description": "投稿にいいねされた数" + }, + "likes_count": { + "type": "integer", + "description": "投稿にいいねした数" + }, + "location": { + "type": "string", + "description": "場所" + }, + "name": { + "type": "string", + "description": "ニックネーム" + }, + "posts_count": { + "type": "integer", + "description": "投稿数" + }, + "username": { + "type": "string", + "description": "ユーザー名" + } + } + }, + "Application": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "description": "アプリケーションの作成日時" + }, + "user_id": { + "type": "string", + "description": "アプリケーションを作成したユーザーのID" + }, + "name": { + "type": "string", + "description": "アプリケーションの名前" + }, + "name_id": { + "type": "string", + "description": "アプリケーションのユニークな名前" + }, + "description": { + "type": "string", + "description": "アプリケーションの説明" + }, + "permission": { + "type": "array", + "items": { + "type": "string" + }, + "description": "アプリケーションの持つ権限一覧" + }, + "callback_url": { + "type": "string", + "description": "コールバックURL" + }, + "id": { + "type": "string", + "description": "アプリケーションID" + }, + "icon_url": { + "type": "string", + "description": "アプリケーションのアイコンのURL" + } + } + } + }, + "securityDefinitions": {}, + "tags": [] +}; + +var options = { + swaggerDefinition: defaultSwagger, + apis: [] +}; +options.apis = files.map(c => {return `${apiRoot}/${c}`;}); + +if(fs.existsSync('.config/config.yml')){ + var config = yaml.safeLoad(fs.readFileSync('./.config/config.yml', 'utf8')); + options.swaggerDefinition.host = `api.${config.url.match(/\:\/\/(.+)$/)[1]}`; + options.swaggerDefinition.schemes = config.https.enable ? + ['https'] : + ['http']; +} + +var swaggerSpec = swaggerJSDoc(options); + +fs.writeFileSync('api-docs.json', JSON.stringify(swaggerSpec)); +