api-explorer
Version:
Easily create an interactive documentation for your RESTful API
374 lines (328 loc) • 12.9 kB
JavaScript
;
var APP_NAME = "apiExplorer";
var APP_NAME_CONTROLLERS = APP_NAME + ".controllers";
var APP_NAME_SERVICES = APP_NAME + ".services";
var APP_NAME_FILTERS = APP_NAME + ".filters";
var APP_NAME_DIRECTIVES = APP_NAME + ".directives";
// Declare app level module which depends on filters, and services
angular.module(APP_NAME, [
'ngRoute',
'ngResource',
'ui.bootstrap',
APP_NAME_FILTERS,
APP_NAME_SERVICES,
APP_NAME_DIRECTIVES,
APP_NAME_CONTROLLERS
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/explorer', {templateUrl: 'partials/explorer.html', controller: 'ExplorerController'});
$routeProvider.otherwise({redirectTo: '/explorer'});
}]);
//Modules declarations
angular.module(APP_NAME_CONTROLLERS, []);
angular.module(APP_NAME_SERVICES, []);
angular.module(APP_NAME_FILTERS, []);
angular.module(APP_NAME_DIRECTIVES, []);
;
angular.module(APP_NAME_CONTROLLERS).controller('ExplorerController', [
'$scope', 'ApiInfo', "Resources", "WaitingService", "AlertService", "ExplorerService",
function($scope, ApiInfo, Resources, WaitingService, AlertService, ExplorerService) {
//init
var waitingService = new WaitingService();
var alertService = new AlertService($scope.$parent);
$scope.isResourceCollapsed = [];
$scope.isMethodCollapsed = [];
$scope.apiInfo = ApiInfo.get();
$scope.resources = Resources.query(handleResources);
$scope.callMethod = function(method) {
var execution = {
apiInfo: $scope.apiInfo,
method: method
};
waitingService.start();
ExplorerService.execute(execution, function (result) {
$scope.result = result;
waitingService.stop();
});
$scope.lastMethod = method;
};
$scope.getLabelForMethod = function(method) {
var labels = {
get: "info",
post: "success",
"delete": "danger",
"put": "warning"
};
return labels[method];
};
$scope.hasExampleValue = function(parameters) {
return ExplorerService.hasExampleValue(parameters);
};
$scope.useExampleValues = function(parameters) {
ExplorerService.replaceExampleValues(parameters);
};
function handleResources(resources) {
for(var i=0; i<resources.length; i++) {
$scope.isResourceCollapsed[i] = true;
$scope.isMethodCollapsed[i] = [];
var methods = resources[i].methods;
for(var j=0; j<methods.length; j++) {
$scope.isMethodCollapsed[i][j] = true;
useFirstEnumIfRequired(methods[j].parameters);
}
}
}
function useFirstEnumIfRequired(parameters) {
if(parameters) {
for (var i = 0; i < parameters.length; i++) {
if(parameters[i].type == "enum" && parameters[i].required) {
parameters[i].value = parameters[i].values[0];
}
}
}
}
}]);
;
angular.module(APP_NAME_CONTROLLERS).controller('IndexController', ['$scope', '$location',
function($scope, $location) {
$scope.isActive = function(route) {
return route === $location.path();
}
}]);
angular.module(APP_NAME_SERVICES).factory("ExplorerService", ['$http', '$location',
function ($http, $location) {
return {
hasExampleValue: function(parameters) {
if(!parameters) return false;
for(var i=0; i<parameters.length; i++) {
if(parameters[i].exampleValue)
return true;
}
return false;
},
replaceExampleValues: function(parameters) {
if(parameters) {
for(var i=0; i<parameters.length; i++) {
if(parameters[i].type == "object")
parameters[i].stringValue = angular.toJson(parameters[i].exampleValue);
else
parameters[i].value = parameters[i].exampleValue;
}
}
},
execute: function(info, callback) {
var url = info.apiInfo.url + info.method.path;
url = getPath(info.method.parameters, url);
var body = createBody();
var verbFunction = $http[info.method.verb];
switch(info.method.verb) {
case "get":
verbFunction(url).success(handleResponse).error(handleResponse);
break;
case "post":
verbFunction(url, body).success(handleResponse).error(handleResponse);
break;
case "put":
verbFunction(url, body).success(handleResponse).error(handleResponse);
break;
case "delete":
verbFunction(url).success(handleResponse).error(handleResponse);
break;
}
function handleResponse (data, status, headers, config) {
callback({url: url, result: data.data ? data.data : data, body: body});
}
function createBody() {
var body = undefined;
var parameters = info.method.parameters;
if(parameters) {
for (var i = 0; i < parameters.length; i++) {
if (parameters[i].parameterType == "body" && parameters[i].value !== undefined) {
if (body === undefined)
body = {};
body[parameters[i].name] = parameters[i].value;
}
}
}
return body;
}
},
getApiUrl: function() {
return $location.absUrl().split('#')[0] + "api/";
}
};
function getPath(parameters, path) {
var queryParametersAdded = 0;
if(parameters) {
for (var i = 0; i < parameters.length; i++) {
if (parameters[i].value !== undefined) {
if (parameters[i].parameterType == "query") {
path = addQueryParameter(path, parameters[i].name, parameters[i].value, queryParametersAdded);
queryParametersAdded++;
} else if (parameters[i].parameterType == "id") {
path = path.replace("{" + parameters[i].name + "}", parameters[i].value);
}
}
}
}
return path;
function addQueryParameter(path, varName, varValue, parametersAdded) {
var charAdd = "&";
if(parametersAdded === 0)
charAdd = "?";
return path + charAdd + varName + "=" + varValue;
}
}
}
]);
;
angular.module(APP_NAME_SERVICES).factory('ApiInfo', ['ResourceFactory', 'ExplorerService',
function(ResourceFactory, ExplorerService) {
var resourcesInfo = {
name : "apiInfo",
apiUrl : ExplorerService.getApiUrl()
};
return ResourceFactory.createResource(resourcesInfo);
}]);
;
angular.module(APP_NAME_SERVICES).factory('Resources', ['ResourceFactory', 'ExplorerService',
function(ResourceFactory, ExplorerService) {
var resourcesInfo = {
name : "resources",
idField: "name",
apiUrl : ExplorerService.getApiUrl()
};
return ResourceFactory.createResource(resourcesInfo);
}]);
;
angular.module(APP_NAME_SERVICES).factory('AlertService', ["$timeout",
function($timeout) {
var AlertService = function(scope, scopeCloseDelay) {
this.scope = scope;
this.scopeCloseDelay = scopeCloseDelay ? scopeCloseDelay : 8000;
this.initializeScope();
};
AlertService.prototype.add = function(msg, type) {
var scope = this.scope;
if(!type)
type = "danger";
scope.alerts.push({type:type, "message":msg});
$timeout(function() {
scope.closeAlert(scope.alerts.length - 1);
}, this.scopeCloseDelay);
};
AlertService.prototype.initializeScope = function() {
var scope = this.scope;
if(scope.alerts == null)
scope.alerts = [];
if(scope.closeAlert == null) {
scope.closeAlert = function(index) {
scope.alerts.splice(index, 1);
};
}
};
return AlertService;
}]);
;
angular.module(APP_NAME_SERVICES).factory('ResourceFactory', ['$resource',
function($resource) {
return {
createResource : function(resourceInfo) {
var idField = resourceInfo.idField;
var apiUrl = resourceInfo.apiUrl + resourceInfo.name + "/:" + idField;
var paramFieldInfo = {};
paramFieldInfo[idField] = '@' + idField;
var resource = $resource(apiUrl, {}, {
update: {method:'PUT', params:paramFieldInfo}
});
resource.getFromAvailable = function(availableResources, resourceId) {
if(availableResources == null)
return null;
for(var i=0; i<availableResources.length; i++) {
if(availableResources[i] != null && availableResources[i][idField] == resourceId)
return availableResources[i];
}
};
return resource;
}
}
}]);
;
angular.module(APP_NAME_SERVICES).factory('util', [
function() {
var copy = function(obj) {
switch(typeof obj) {
default:
return obj;
case "object":
if(Array.isArray(obj)) {
return obj.slice(0);
} else {
var obj2 = {};
for (var attr in obj) {
obj2[attr] = copy(obj[attr]);
}
return obj2;
}
}
};
return {
escapeStr : function(str) {
if(!str) return "";
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
},
copy : copy,
guessType : function(str) {
var firstChar = str.substr(0, 1);
switch(firstChar) {
case "[":
case "{":
return "json";
case "<":
return "xml";
}
}
}
}]);
;
angular.module(APP_NAME_SERVICES).factory('WaitingService', ['$modal',
function($modal) {
var WaitingService = function() {
};
WaitingService.prototype.start = function(message) {
var self = this;
if(!message) message = "Processing";
this.modalInstance = $modal.open({
templateUrl: 'templates/modal-waiting.html',
controller : function($scope) {
self.scope = $scope;
$scope.message = message;
$scope.closeModal = function() {
$scope.$close();
}
}
});
};
WaitingService.prototype.setMessage = function(message) {
if(this.scope)
this.scope.message = message;
};
WaitingService.prototype.stop = function() {
var self = this;
try {
this.modalInstance.close();
} catch(e) {
// console.log("crash"); #lol
setTimeout(function () {
self.modalInstance.close();
}, 1000);
} finally {
this.scope = null;
}
};
return WaitingService;
}]);