2015-10-07 12:47:57 +03:00
|
|
|
'use strict';
|
|
|
|
import SwaggerParser from 'swagger-parser';
|
2015-10-09 10:50:02 +03:00
|
|
|
import JsonPointer from './JsonPointer';
|
2015-10-18 19:32:11 +03:00
|
|
|
import {methods as swaggerMethods} from './swagger-defs';
|
2015-10-07 12:47:57 +03:00
|
|
|
|
2015-10-27 20:44:08 +03:00
|
|
|
export default class SchemaManager {
|
2015-10-07 12:47:57 +03:00
|
|
|
constructor() {
|
|
|
|
if (SchemaManager.prototype._instance) {
|
|
|
|
return SchemaManager.prototype._instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
SchemaManager.prototype._instance = this;
|
|
|
|
|
|
|
|
this._schema = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
static instance() {
|
|
|
|
return new SchemaManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
load(url) {
|
|
|
|
let promise = new Promise((resolve, reject) => {
|
|
|
|
this._schema = {};
|
|
|
|
|
2015-11-04 23:18:34 +03:00
|
|
|
SwaggerParser.bundle(url, {http: {withCredentials: false}})
|
2015-10-07 12:47:57 +03:00
|
|
|
.then(
|
|
|
|
(schema) => {
|
|
|
|
this._schema = schema;
|
|
|
|
resolve(this._schema);
|
2015-11-17 01:03:09 +03:00
|
|
|
this.init();
|
2015-10-07 12:47:57 +03:00
|
|
|
},
|
|
|
|
(err) => reject(err)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
|
2015-11-17 01:03:09 +03:00
|
|
|
/* calculate common used values */
|
|
|
|
init() {
|
2015-11-17 02:14:55 +03:00
|
|
|
this.apiUrl = this._schema.schemes[0] + '://' + this._schema.host + this._schema.basePath;
|
2015-11-29 18:14:18 +03:00
|
|
|
if (this.apiUrl.endsWith('/')) {
|
|
|
|
this.apiUrl = this.apiUrl.substr(0, this.apiUrl.length - 1);
|
|
|
|
}
|
2015-11-17 01:03:09 +03:00
|
|
|
}
|
|
|
|
|
2015-10-07 12:47:57 +03:00
|
|
|
get schema() {
|
|
|
|
// TODO: consider returning promise
|
|
|
|
return this._schema;
|
|
|
|
}
|
|
|
|
|
2015-10-08 23:21:51 +03:00
|
|
|
byPointer(pointer) {
|
2015-10-10 16:01:41 +03:00
|
|
|
let res = null;
|
|
|
|
try {
|
|
|
|
res = JsonPointer.get(this._schema, pointer);
|
|
|
|
} catch(e) {/*skip*/ }
|
|
|
|
return res;
|
2015-10-07 12:47:57 +03:00
|
|
|
}
|
2015-10-08 23:21:51 +03:00
|
|
|
|
2015-10-25 14:26:38 +03:00
|
|
|
resolveRefs(obj) {
|
|
|
|
Object.keys(obj).forEach(key => {
|
|
|
|
if (obj[key].$ref) {
|
|
|
|
obj[key] = this.byPointer(obj[key].$ref);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
getMethodParams(methodPtr, resolveRefs) {
|
|
|
|
/* inject JsonPointer into array elements */
|
|
|
|
function injectPointers(array, root) {
|
|
|
|
if (!array) return array;
|
|
|
|
return array.map((element, idx) => {
|
|
|
|
element._pointer = JsonPointer.join(root, idx);
|
|
|
|
return element;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
//get path params
|
|
|
|
let ptr = JsonPointer.dirName(methodPtr, 2) + '/parameters';
|
|
|
|
let pathParams = this.byPointer(ptr);
|
|
|
|
if (Array.isArray(pathParams)) {
|
|
|
|
pathParams = injectPointers(pathParams, ptr);
|
|
|
|
} else if (pathParams && pathParams.$ref) {
|
|
|
|
pathParams = injectPointers(this.byPointer(pathParams.$ref), pathParams.$ref);
|
|
|
|
} else {
|
|
|
|
pathParams = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
let methodParams = injectPointers(this.byPointer(methodPtr), methodPtr) || [];
|
|
|
|
if (resolveRefs) {
|
|
|
|
methodParams = this.resolveRefs(methodParams);
|
2015-11-04 23:39:46 +03:00
|
|
|
pathParams = this.resolveRefs(pathParams);
|
2015-10-25 14:26:38 +03:00
|
|
|
}
|
|
|
|
return methodParams.concat(pathParams);
|
|
|
|
}
|
|
|
|
|
2015-11-17 02:34:13 +03:00
|
|
|
getTagsMap() {
|
|
|
|
let tags = this._schema.tags || [];
|
|
|
|
var tagsMap = {};
|
|
|
|
for (let tag of tags) {
|
|
|
|
tagsMap[tag.name] = {
|
|
|
|
description: tag.description,
|
2015-12-12 14:49:22 +03:00
|
|
|
'x-traitTag': tag['x-traitTag'] || false
|
2015-11-17 02:34:13 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return tagsMap;
|
|
|
|
}
|
|
|
|
|
2015-10-18 19:32:11 +03:00
|
|
|
/* returns ES6 Map */
|
|
|
|
buildMenuTree() {
|
|
|
|
let tag2MethodMapping = new Map();
|
2015-10-29 00:22:12 +03:00
|
|
|
|
2015-11-04 23:39:05 +03:00
|
|
|
let definedTags = this._schema.tags || [];
|
2015-10-29 00:22:12 +03:00
|
|
|
// add tags into map to preserve order
|
|
|
|
for (let tag of definedTags) {
|
2015-10-30 10:41:42 +03:00
|
|
|
tag2MethodMapping.set(tag.name, {
|
|
|
|
'description': tag.description,
|
2015-12-01 01:29:01 +03:00
|
|
|
'x-traitTag': tag['x-traitTag'],
|
2015-10-30 10:41:42 +03:00
|
|
|
'methods': []
|
|
|
|
});
|
2015-10-29 00:22:12 +03:00
|
|
|
}
|
|
|
|
|
2015-10-18 19:32:11 +03:00
|
|
|
let paths = this._schema.paths;
|
|
|
|
for (let path of Object.keys(paths)) {
|
|
|
|
let methods = Object.keys(paths[path]).filter((k) => swaggerMethods.has(k));
|
|
|
|
for (let method of methods) {
|
|
|
|
let methodInfo = paths[path][method];
|
|
|
|
let tags = methodInfo.tags;
|
|
|
|
|
|
|
|
//TODO: mb need to do something cleverer
|
|
|
|
if (!tags || !tags.length) {
|
|
|
|
tags = ['[Other]'];
|
|
|
|
}
|
|
|
|
let methodPointer = JsonPointer.compile(['paths', path, method]);
|
|
|
|
let methodSummary = methodInfo.summary;
|
|
|
|
for (let tag of tags) {
|
2015-10-29 00:22:12 +03:00
|
|
|
let tagDetails = tag2MethodMapping.get(tag);
|
|
|
|
if (!tagDetails) {
|
|
|
|
tagDetails = {};
|
|
|
|
tag2MethodMapping.set(tag, tagDetails);
|
2015-10-18 19:32:11 +03:00
|
|
|
}
|
2015-12-01 01:29:01 +03:00
|
|
|
if (tagDetails['x-traitTag']) continue;
|
2015-10-30 12:48:36 +03:00
|
|
|
if (!tagDetails.methods) tagDetails.methods = [];
|
2015-10-29 00:22:12 +03:00
|
|
|
tagDetails.methods.push({pointer: methodPointer, summary: methodSummary});
|
2015-10-18 19:32:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return tag2MethodMapping;
|
|
|
|
}
|
|
|
|
|
2015-10-07 12:47:57 +03:00
|
|
|
}
|