UNPKG

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