kopia lustrzana https://github.com/c9/core
128 wiersze
4.7 KiB
JavaScript
128 wiersze
4.7 KiB
JavaScript
define(function(require, exports, module) {
|
|
"use strict";
|
|
|
|
var assert = require("assert");
|
|
var format = require("util").format;
|
|
var join = require("path").join;
|
|
|
|
module.exports = createClient;
|
|
createClient.buildApi = buildApi;
|
|
|
|
function createClient(endpoint, options, callback) {
|
|
if (!callback)
|
|
return createClient(endpoint, {}, options);
|
|
|
|
var baseUrl = options.baseUrl || endpoint.split("/").slice(0, -1).join("/");
|
|
var request = options.request || require("./http_node" + "" /* hide this module from the packager */);
|
|
|
|
function rest(path, requestOptions, callback) {
|
|
var url = baseUrl + path;
|
|
if (!requestOptions.query) requestOptions.query = {};
|
|
if (options.accessToken)
|
|
requestOptions.query.access_token = options.accessToken;
|
|
|
|
if (options.username) {
|
|
requestOptions.username = options.username;
|
|
requestOptions.password = options.password;
|
|
}
|
|
|
|
request(url, requestOptions, callback);
|
|
}
|
|
|
|
request(endpoint, {}, function(err, description, data) {
|
|
if (err) return callback(err);
|
|
|
|
var client = buildApi(description, rest);
|
|
callback(null, client);
|
|
});
|
|
}
|
|
|
|
function buildApi(description, rest) {
|
|
var api = createSection(description, rest, "/");
|
|
return api;
|
|
}
|
|
|
|
function createSection(description, rest, path) {
|
|
var section = {};
|
|
if (description.sections) {
|
|
description.sections.forEach(function(sectionDesc) {
|
|
assert(sectionDesc.name, "API section has no name");
|
|
assert(!section[sectionDesc.name], format("Section with name '%s' already exists", sectionDesc.name));
|
|
console.log("section", sectionDesc.name)
|
|
section[sectionDesc.name] = createSection(sectionDesc, rest, join(path, sectionDesc.name));
|
|
});
|
|
}
|
|
|
|
if (description.routes) {
|
|
description.routes.forEach(function(route) {
|
|
var name = route.name || route.method;
|
|
assert(!section[name], format("Route with name '%s' already exists", name));
|
|
|
|
section[name] = createRoute(route, rest, path);
|
|
});
|
|
}
|
|
|
|
return section;
|
|
}
|
|
|
|
function createRoute(route, rest, path) {
|
|
return function request(options, requestOptions, callback) {
|
|
if (arguments.length == 1) return request({}, {}, arguments[0]);
|
|
if (arguments.length == 2) return request(arguments[0], {}, arguments[1]);
|
|
|
|
// check for required arguments
|
|
for (var key in route.params) {
|
|
var param = route.params[key];
|
|
if (!param.optional && !options.hasOwnProperty(key)) {
|
|
return callback(new TypeError(format("Missing required parameter '%s'", key)));
|
|
}
|
|
}
|
|
|
|
// check for additional arguments
|
|
for (var key in options) {
|
|
if (!route.params[key]) {
|
|
return callback(new TypeError(format("Argument '%s' is not supported by the API", key)));
|
|
}
|
|
}
|
|
|
|
// TODO verify types
|
|
// TODO serialize arguments
|
|
|
|
// fill in parameters
|
|
path = join(path, route.route.replace(/\/:([\w\.\-\_]+)(\*?)/g, function(match, key, wildcard) {
|
|
if (wildcard) return "";
|
|
return options[key].toString();
|
|
}));
|
|
|
|
// populate query string
|
|
var query = {};
|
|
for (var key in route.params) {
|
|
if (route.params[key].source !== "query") continue;
|
|
if (!options.hasOwnProperty(key)) continue;
|
|
|
|
query[key] = options[key];
|
|
}
|
|
// options passed in have higher prio
|
|
for (var key in requestOptions.query || {}) {
|
|
query[key] = requestOptions.query[key];
|
|
}
|
|
|
|
// populate body
|
|
var body = {};
|
|
for (var key in route.params) {
|
|
if (route.params[key].source !== "body") continue;
|
|
if (!options.hasOwnProperty(key)) continue;
|
|
|
|
body[key] = options[key];
|
|
}
|
|
|
|
requestOptions.contentType = "application/json";
|
|
requestOptions.query = query;
|
|
if (Object.keys(body).length)
|
|
requestOptions.body = body;
|
|
|
|
// do request
|
|
rest(path, requestOptions, callback);
|
|
};
|
|
}
|
|
}); |