From 5b6641003139606d54e3b8646b156d4fcd05b9d5 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 14 Dec 2017 22:36:04 +0900
Subject: [PATCH] :v:

---
 src/web/docs/api/endpoints/gulpfile.ts       | 39 +++++++++++++++-----
 src/web/docs/api/endpoints/posts/create.yaml | 21 +++++------
 src/web/docs/api/endpoints/view.pug          |  6 ++-
 3 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/src/web/docs/api/endpoints/gulpfile.ts b/src/web/docs/api/endpoints/gulpfile.ts
index a2c3944709..e375447c55 100644
--- a/src/web/docs/api/endpoints/gulpfile.ts
+++ b/src/web/docs/api/endpoints/gulpfile.ts
@@ -14,7 +14,8 @@ import config from './../../../../conf';
 
 const parseParam = param => {
 	const id = param.type.match(/^id\((.+?)\)/);
-	const object = param.type.match(/^object\((.+?)\)/);
+	const entity = param.type.match(/^entity\((.+?)\)/);
+	const isObject = /^object/.test(param.type);
 	const isArray = /\[\]$/.test(param.type);
 	if (id) {
 		param.kind = 'id';
@@ -24,18 +25,40 @@ const parseParam = param => {
 			param.type += '[]';
 		}
 	}
-	if (object) {
-		param.kind = 'object';
+	if (entity) {
+		param.kind = 'entity';
 		param.type = 'object';
-		param.def = object[1];
+		param.entity = entity[1];
 		if (isArray) {
 			param.type += '[]';
 		}
 	}
+	if (isObject) {
+		param.kind = 'object';
+	}
 
 	return param;
 };
 
+const extractDefs = params => {
+	const defs = [];
+
+	params.forEach(param => {
+		if (param.def) {
+			defs.push({
+				name: param.defName,
+				params: param.def.map(p => parseParam(p))
+			});
+
+			const childDefs = extractDefs(param.def);
+
+			defs.concat(childDefs);
+		}
+	});
+
+	return defs;
+};
+
 gulp.task('doc:endpoints', () => {
 	glob('./src/web/docs/api/endpoints/**/*.yaml', (globErr, files) => {
 		if (globErr) {
@@ -50,11 +73,9 @@ gulp.task('doc:endpoints', () => {
 				url: `${config.api_url}/${ep.endpoint}`,
 				desc: ep.desc,
 				params: ep.params.map(p => parseParam(p)),
-				paramDefs: Object.keys(ep.paramDefs).map(key => ({
-					name: key,
-					params: ep.paramDefs[key].map(p => parseParam(p))
-				})),
-				res: ep.res.map(p => parseParam(p))
+				paramDefs: extractDefs(ep.params),
+				res: ep.res.map(p => parseParam(p)),
+				resDefs: extractDefs(ep.res)
 			};
 			pug.renderFile('./src/web/docs/api/endpoints/view.pug', vars, (renderErr, html) => {
 				if (renderErr) {
diff --git a/src/web/docs/api/endpoints/posts/create.yaml b/src/web/docs/api/endpoints/posts/create.yaml
index b6613038a7..feedf4f0d2 100644
--- a/src/web/docs/api/endpoints/posts/create.yaml
+++ b/src/web/docs/api/endpoints/posts/create.yaml
@@ -7,7 +7,7 @@ desc:
 params:
   - name: "text"
     type: "string"
-    optional: false
+    optional: true
     desc:
       ja: "投稿の本文"
       en: "Text of a post"
@@ -30,20 +30,19 @@ params:
       ja: "引用する投稿"
       en: "A post you want to quote"
   - name: "poll"
-    type: "object(poll)"
+    type: "object"
     optional: true
     desc:
       ja: "投票"
       en: "A poll"
-
-paramDefs:
-  poll:
-    - name: "choices"
-      type: "string[]"
-      optional: false
-      desc:
-        ja: "投票の選択肢"
-        en: "Choices of a poll"
+    defName: "poll"
+    def:
+      - name: "choices"
+        type: "string[]"
+        optional: false
+        desc:
+          ja: "投票の選択肢"
+          en: "Choices of a poll"
 
 res:
   - name: "created_post"
diff --git a/src/web/docs/api/endpoints/view.pug b/src/web/docs/api/endpoints/view.pug
index d9de9cb74a..b7b2658a39 100644
--- a/src/web/docs/api/endpoints/view.pug
+++ b/src/web/docs/api/endpoints/view.pug
@@ -21,9 +21,13 @@ mixin table(params)
 							= ' '
 							a(href=`/docs/api/entities/${param.entity}`)= param.entity
 							| )
+						else if param.kind == 'entity'
+							| #{param.type} (
+							a(href=`/docs/api/entities/${param.entity}`)= param.entity
+							| )
 						else if param.kind == 'object'
 							| #{param.type} (
-							a(href=`#${param.def}`)= param.def
+							a(href=`#${param.defName}`)= param.defName
 							| )
 						else
 							= param.type