Skip to content

Commit

Permalink
Implement issue Marak#28, replace JS based views consturction with We…
Browse files Browse the repository at this point in the history
…ld and JSOM
  • Loading branch information
syrio committed Sep 29, 2011
1 parent 78ae028 commit f2e4356
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 118 deletions.
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

1 comment on commit f2e4356

@Marak
Copy link

@Marak Marak commented on f2e4356 Mar 26, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to get this working, but I think you are missing the info.html file ( also missing jquery / weld ).

Please sign in to comment.