Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions examples/sample_modules/complexModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,35 @@ exports.customEcho.schema = {
}
};

exports.complexMethod = {
description: "this is a complex method",
var hello = function (options, callback){
callback(null, 'hello');
}

hello.description = "this is the hello method, calls back with a hello"

exports.complexModule = {
description: "this is a complex module",
module: 'complexModule',
compy: hello
}


exports.nestedComplexModule = {
description: "this is a highly nested complex module",
module: 'nestedComplexModule',
level1: {
foo: "bar",
la: 4,
description: "this is the level 1 method",
description: "this is the level 1 module",
module: 'level1',
level2: {
hello2: function (options, callback){
callback(null, 'hello2');
},
description: "this is the level 2 module",
module: 'level2',
hello2: hello,
level3: {
description: "this is the level 3 method",
hello3: function (options, callback){
callback(null, 'hello3');
},
module: 'level3',
description: "this is the level 3 module",
hello3: hello
},
},
}
Expand Down
4 changes: 2 additions & 2 deletions examples/standalone/server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var webservice = require('../lib/webservice'),
demoModule = require('./modules/demoModule'),
var webservice = require('../../lib/webservice'),
demoModule = require('../sample_modules/demoModule'),
colors = require('colors');

webservice.createServer(demoModule).listen(8080);
Expand Down
231 changes: 125 additions & 106 deletions lib/view.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,137 @@

/*** simple internal view server ( for documentation ) ***/

var renderRoutes = exports.renderRoutes = function( format, name, items, template ) {
// console.log(util.inspect(request.originalUrl));
var renderHtml = function( name, items, template, cb) {

var fs = require('fs'),
jsdom = require('jsdom');

var welder = {};

/* edit (by rootnot)
1. Now this function is called with response context (this refers to response object).
2. Added inspection form with iframe containing output from called methods
*/
jsdom.env(
__dirname + '/views/info.html',
[__dirname + '/views/jquery.min.js', __dirname + '/views/weld.min.js'],
function(errors, window) {

var module_html = '';

var info = [ { title: items.title, name: items.name, version: items.version } ];
window.weld(window.$('#info')[0], info);

module_html += window.$('#info-weld').html();

function welder(items) {

var html = '';

// iterate through each top-level method in the module and created a link
for(var method in items.methods) {
var m = items.methods[method];
if(typeof m == 'string'){
continue;
}

if(m.module == undefined) {

// if the module is private, ignore it
if(m.private === true) {
continue;
}

var path = "/" + method;
if(typeof m.regex !== 'undefined') {
path = m.regex;
}

var details = [ { path: path } ];


window.weld(window.$('.details')[0], details, { map: function(parent, element, key, val) {
if(key == 'path') {
window.$(element).attr('href', val);
}
}
});

var description = [ { description: m.description } ];

window.weld(window.$('.method')[0], description);

var arguments = [];

var sampleCurlArgs = '', sampleCurlJSON = {};

// parse arguments
if(m.schema) {
sampleCurlArgs = "?";
var s = m.schema;
for(var arg in s) {

// only generate sample curl syntax for required properties
if(s[arg].optional != true) {
sampleCurlArgs += (arg + "=val&");
sampleCurlJSON[arg] = "val";
}
arguments.push( { name: arg + ' ' + JSON.stringify(s[arg]) });
}
sampleCurlArgs = sampleCurlArgs.substr(0,sampleCurlArgs.length-1);
}

if (arguments.length == 0) {
arguments.push({name: '{}'});
}
window.weld(window.$('.argument')[0], arguments);

// GET
get = [ { url: '/' + method, params: 'curl -X GET ' + items.endpoint + '/' + method + sampleCurlArgs} ]
window.weld(window.$('.get')[0], get);

// POST
post = [ { url: '/' + method, params: 'curl -X POST -d "' + sampleCurlArgs.substr(1, sampleCurlArgs.length) + '" ' + items.endpoint + '/' + method,
json: 'curl -X POST -d "' + JSON.stringify(sampleCurlJSON) + '" ' + items.endpoint + '/' + method } ];
window.weld(window.$('.post')[0], post);

html += window.$('#main-weld').html();
}

if (typeof m.methods === "object" || typeof m.methods === "function") {
if(typeof m.methods === "function") {
console.log('function!');
}
if (typeof(m.endpoint) == 'undefined') {
m.endpoint = items.endpoint + '/' + m.module;
}
more_welded = welder(m);
html += more_welded;
}

}

return html;
}

module_html += welder(items);
module_html += window.$('#footer-weld').html();

cb(0, template.replace('{{body}}', module_html)); // fake mustache


});

}

var renderRoutes = exports.renderRoutes = function( format, name, items, template, cb ) {


if(format == 'json'){
return JSON.stringify(items, true, 2);
}
if(format == 'html'){
var html = '';
html += '<h1>' + items.title + '</h1>'
html += '<h3>' + items.name + '</h3>';
html += 'Version <i>' + items.version + '</i>';
html += '<h3>Available Methods</h3>';

// iterate through each top-level method in the module and created a link
for(var method in items.methods){
var m = items.methods[method];
if(typeof m == 'string'){
continue;
}
// if the module is private, ignore it
if(m.private === true){
continue;
}

// var path = "/" + method;
var path = this.request.originalUrl + method;
if(typeof m.regex !== 'undefined') {
path = m.regex;
}
html += ('<div class="member grad">');
html += ('<div class="header"><a href="'+ path +'">' + path + '</a></div>');
html += ('<div class="content">');
html += ('<div class="member grad">');
html += ('<div class="sub header">' + m.description + '</div>');

var sampleCurlArgs = '', sampleCurlJSON = {};

// parse arguments
if(m.schema){

sampleCurlArgs = "?";
html += ('<div class="content"><strong>arguments:</strong> <br/>');
var s = m.schema;
for(var arg in s){

// only generate sample curl syntax for required properties
if(s[arg].optional != true){
sampleCurlArgs += (arg + "=val&");
sampleCurlJSON[arg] = "val";
}

if(format == 'html'){
renderHtml(name, items, template, cb);
}

html += (arg + ' ' + JSON.stringify(s[arg]) + '<br/>');
}
sampleCurlArgs = sampleCurlArgs.substr(0,sampleCurlArgs.length-1);
html += ('</div>');
}

// GET
html += ('<div class="content">');
html += ('<span class="verb">GET</span> <span class="url">/'+method+'<br>');
html += ('<div class="curl">curl -X GET ' + items.endpoint + '/' + method + sampleCurlArgs + '</div>');
//html += ('<div class="descriptor">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br/></div>');
html += ('</span></div>');

// POST
html += ('<div class="content">');
html += ('<span class="verb">POST</span> <span class="url">/'+method+'<br>');
html += ('<div class="curl">curl -X POST -d "' + sampleCurlArgs.substr(1, sampleCurlArgs.length) + '" ' + items.endpoint + '/' + method + '</div>');
html += ('You can also post JSON...<br/>');
html += ('<div class="curl">curl -X POST -d "' + JSON.stringify(sampleCurlJSON) + '" ' + items.endpoint + '/' + method + '</div>');

//html += ('<div class="descriptor">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<br/></div>');
html += ('</span></div>');
html += ('</div></div>');

// form
html += ('<div class="form">');
html += ('<form method="get" action="' + items.endpoint + '/' + method + '" + target="' + method + '-output">');
for (var arg in s)
{
html += ('<div class="field">');
html += ('<label for="' + arg + '">' + arg + ': </label>');
html += ('<input type="text" id="' + method + '-' + arg + '" name="' + arg + '">');
html += ('</div>');
}
html += ('<div class="button"><input type="submit"/></div>');
html += ('</form>');
html += ('<iframe class="response" name="' + method + '-output"/>');
html += ('</div');


html += ('<span class="content">JSONP support is currently enabled. To use JSONP, append "&callback=mymethod" to any GET request</span>');
html += ('<br/><br/>');


html += ('</div>');

if (typeof m.methods === "object" || typeof m.methods === "function") {
html += renderRoutes( format, 'a', m.methods, template);
if (Object.keys(m.methods).length) {
}
}
// + '/' + method + '</a> <i>' + (items[method].description || '') + ' </i>' + '</li>');
}
html += '<h4>This page was auto-generated by <a href="http://github.com/marak/webservice.js" target="_blank">webservice.js</a></h4>'
return template.replace('{{body}}', html); // fake mustache
}
return 'error';
}

/*** simple html renderer for validator errors ***/
Expand Down