UNPKG

4.68 kBJavaScriptView Raw
1const _ = require("lodash");
2const jsonfile = require("jsonfile");
3const shell = require("shelljs");
4const ip = require("ip");
5const fs = require("fs");
6
7const debug = require("debug")("motif:swagger");
8
9class Swagger {
10 constructor(context) {
11 this._context = context;
12 this._config = context.config.get("swagger");
13 }
14
15 isMultipartData(params) {
16 let isMultipartData = false;
17 _.forEach(params, param => {
18 if (param.type === "file") {
19 isMultipartData = true;
20 }
21 });
22 return;
23 }
24
25 paramInfo(param, typeIn) {
26 const paramInfo = {
27 name: param.name,
28 in: typeIn,
29 description: param.description || "No description",
30 required: param.optional === true ? false : true,
31 type: param.type || "string"
32 // enums
33 };
34
35 if (_.isArray(param.enum)) {
36 paramInfo.enum = param.enum;
37 }
38
39 return paramInfo;
40 }
41
42 pathInfo(route, info, isAdmin = false) {
43 const responseType = "application/json";
44 const requestType = this.isMultipartData(route.params || [])
45 ? "multipart/form-data"
46 : "application/x-www-form-urlencoded";
47
48 const parameters = (route.params || []).map(param => {
49 const paramsTypeIn = ((route, param) => {
50 if (route.path.indexOf(":" + param.name) !== -1) {
51 return "path";
52 }
53
54 if (route.method === "put" || route.method === "post") {
55 return "formData";
56 }
57
58 return "query";
59 })(route, param);
60
61 debug("paramsTypeIn", route.path, param.name, paramsTypeIn);
62
63 return this.paramInfo(param, paramsTypeIn);
64 });
65
66 const tags = route.tags || [route.group];
67 const isAdminAPI =
68 tags.indexOf("admin") !== -1 ||
69 (route.permissions && route.permissions.indexOf("admin") !== -1);
70
71 if (!isAdmin && isAdminAPI) {
72 return null;
73 } else if (isAdmin && !isAdminAPI) {
74 return null;
75 }
76
77 const pathInfo = {
78 tags: tags,
79 summary: route.summary || "",
80 description: route.description || "No description",
81 produces: [responseType],
82 consumes: [requestType],
83 parameters: parameters,
84 responses: {
85 "200": {
86 description: "A JSON result",
87 content: {
88 "application/json": {
89 schema: {
90 $ref: "#/definitions/Result"
91 }
92 }
93 }
94 }
95 }
96 };
97
98 if (route.permissions) {
99 pathInfo["security"] = [{APIKeyHeader: []}];
100 }
101
102 info[route.method] = pathInfo;
103
104 return info;
105 }
106
107 buildPaths(routes, isAdmin = false) {
108 const routePaths = {};
109
110 _.forEach(routes, route => {
111 // if (!route.path) continue;
112 // if (!["get", "post","put","delete"].includes(route.method)) continue;
113 const routePath = ((routePath, params) => {
114 _.forEach(params, param => {
115 routePath = routePath.replace(
116 ":" + param.name,
117 "{" + param.name + "}"
118 );
119 });
120
121 return routePath;
122 })(route.routePath, route.params);
123
124 debug("routePath", routePath);
125
126 let pathInfo = this.pathInfo(route, routePaths[routePath] || {}, isAdmin);
127 if (pathInfo) {
128 routePaths[routePath] = pathInfo;
129 }
130 });
131
132 return routePaths;
133 }
134
135 buildJSON(routes, isAdmin = false) {
136 const routePaths = this.buildPaths(routes, isAdmin);
137 const host = this._config.host
138 ? this._config.host
139 : ip.address() + ":" + this._context.port;
140
141 const json = {
142 swagger: "2.0",
143 info: {
144 title: this._config.title || "Motif API",
145 description: "Auto created swagger api document by motif",
146 version: this._config.version || "0.0.0"
147 },
148 securityDefinitions: {
149 APIKeyHeader: {
150 type: "apiKey",
151 in: "header",
152 name: "x-access-token"
153 }
154 },
155 definitions: {
156 Result: {
157 type: "object",
158 properties: {
159 error: {
160 type: "string"
161 },
162 status: {
163 type: "string"
164 },
165 data: {
166 type: "object"
167 }
168 }
169 }
170 },
171 host: host,
172 basePath: "/",
173 schemes: ["http", "https"],
174 paths: routePaths
175 };
176
177 return json;
178 }
179
180 jsonWriteAsync(path, json) {
181 return new Promise((resolve, reject) => {
182 jsonfile.writeFile(path, json, function(err) {
183 if (err) {
184 console.error(`json ${path} create fail !!`);
185 return reject(err);
186 }
187 // console.log(`json ${path} create success`);
188 resolve();
189 });
190 });
191 }
192}
193
194module.exports = Swagger;