From 35a0b920d8b406ef3297b379c1cdba8373578c2a Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 12:12:53 +0300 Subject: [PATCH 1/6] support for HTTP POST, PUT and DELETE parameter passing via request body instead of GET parameters --- app.js | 54 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/app.js b/app.js index aed37b47..24bbe943 100755 --- a/app.js +++ b/app.js @@ -314,9 +314,13 @@ function processRequest(req, res, next) { host: baseHostUrl, port: baseHostPort, method: httpMethod, - path: apiConfig.publicPath + methodURL + ((paramString.length > 0) ? '?' + paramString : "") + path: apiConfig.publicPath + methodURL// + ((paramString.length > 0) ? '?' + paramString : "") }; + if (['POST','DELETE','PUT'].indexOf(httpMethod) !== -1) { + var requestBody = query.stringify(params); + } + if (apiConfig.oauth) { console.log('Using OAuth'); @@ -442,7 +446,6 @@ function processRequest(req, res, next) { switch (httpMethod) { case 'GET': - console.log(resource); oa.get(resource, '', '',cb); break; case 'PUT': @@ -467,6 +470,10 @@ function processRequest(req, res, next) { function unsecuredCall() { console.log('Unsecured Call'); + if (['POST','PUT','DELETE'].indexOf(httpMethod) === -1) { + options.path += ((paramString.length > 0) ? '?' + paramString : ""); + } + // Add API Key to params, if any. if (apiKey != '' && apiKey != 'undefined' && apiKey != undefined) { if (options.path.indexOf('?') !== -1) { @@ -514,7 +521,16 @@ function processRequest(req, res, next) { } if (!options.headers['Content-Length']) { - options.headers['Content-Length'] = 0; + if (requestBody) { + options.headers['Content-Length'] = requestBody.length; + } + else { + options.headers['Content-Length'] = 0; + } + } + + if (requestBody) { + options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; } if (config.debug) { @@ -524,6 +540,7 @@ function processRequest(req, res, next) { // API Call. response is the response from the API, res is the response we will send back to the user. var apiCall = http.request(options, function(response) { response.setEncoding('utf-8'); + if (config.debug) { console.log('HEADERS: ' + JSON.stringify(response.headers)); console.log('STATUS CODE: ' + response.statusCode); @@ -573,7 +590,12 @@ function processRequest(req, res, next) { }; }); - apiCall.end(); + if (requestBody) { + apiCall.end(requestBody, 'utf-8'); + } + else { + apiCall.end(); + } } } @@ -582,18 +604,18 @@ function processRequest(req, res, next) { app.dynamicHelpers({ session: function(req, res) { // If api wasn't passed in as a parameter, check the path to see if it's there - if (!req.params.api) { - pathName = req.url.replace('/',''); - // Is it a valid API - if there's a config file we can assume so - fs.stat('public/data/' + pathName + '.json', function (error, stats) { - if (stats) { - req.params.api = pathName; - } - }); - } - // If the cookie says we're authed for this particular API, set the session to authed as well + if (!req.params.api) { + pathName = req.url.replace('/',''); + // Is it a valid API - if there's a config file we can assume so + fs.stat('public/data/' + pathName + '.json', function (error, stats) { + if (stats) { + req.params.api = pathName; + } + }); + } + // If the cookie says we're authed for this particular API, set the session to authed as well if (req.params.api && req.session[req.params.api] && req.session[req.params.api]['authed']) { - req.session['authed'] = true; + req.session['authed'] = true; } return req.session; @@ -664,4 +686,4 @@ if (!module.parent) { var port = process.env.PORT || config.port; app.listen(port); console.log("Express server listening on port %d", app.address().port); -} +} \ No newline at end of file From 38de2c4817d1da94e2224420b576aead616eca70 Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 12:15:06 +0300 Subject: [PATCH 2/6] sync dynamicHelpers section as per recent changes to iodocs master branch --- app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app.js b/app.js index 24bbe943..16935cb2 100755 --- a/app.js +++ b/app.js @@ -599,6 +599,7 @@ function processRequest(req, res, next) { } } + // Dynamic Helpers // Passes variables to the view app.dynamicHelpers({ From 6769277031aa0de7212e0825d2252df4dfccbae1 Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 12:17:59 +0300 Subject: [PATCH 3/6] sync dynamicHelpers section as per recent changes to iodocs master branch --- app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app.js b/app.js index 16935cb2..a7e8819d 100755 --- a/app.js +++ b/app.js @@ -446,6 +446,7 @@ function processRequest(req, res, next) { switch (httpMethod) { case 'GET': + console.log(resource); oa.get(resource, '', '',cb); break; case 'PUT': From e3ebdaadc51f2764a80b7e31a62957a79b4ce18d Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 12:19:24 +0300 Subject: [PATCH 4/6] sync dynamicHelpers section as per recent changes to iodocs master branch --- app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app.js b/app.js index a7e8819d..fa45d9dc 100755 --- a/app.js +++ b/app.js @@ -642,6 +642,7 @@ app.dynamicHelpers({ } }) + // // Routes // From 2f7b489bac38678d072fd2e4db4e7d9cc594a78e Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 15:50:59 +0300 Subject: [PATCH 5/6] support for EnumeratedDescription to better describe enumerated property values --- README.md | 11 +++++++++-- views/api.jade | 8 +++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 745dd7ed..6655ba7a 100644 --- a/README.md +++ b/README.md @@ -379,6 +379,11 @@ You should look at the *./public/data/* directory for examples. "sugarbombs", "frostedteeth" ], + "EnumeratedDescription": { + "fruitscoops": "Fruit Scoops (packed with fruit goodness)", + "sugarbombs": "Sugar Bombs (filled with sugar)", + "frostedteeth": "Frosted Teeth (sugar coating)" + }, "Description":"The type of cereal desired" }, { @@ -425,9 +430,11 @@ Line: 24. "EnumeratedList" key value is an array of enumerated values that will render a drop-down (select box) on the form. -25. Each value in the list is a string. +25. "EnumeratedDescription" key value is an object of enumerated values as keys, and their descriptions as values that will be displayed below the Description. -35. "Type" key value is *boolean* that will render a drop-down (select box) on the form for *true* and *false*. +26. Each value in the list is a string. + +27. "Type" key value is *boolean* that will render a drop-down (select box) on the form for *true* and *false*. SUPPORT ======= diff --git a/views/api.jade b/views/api.jade index ae5d28c4..97f5a9fe 100644 --- a/views/api.jade +++ b/views/api.jade @@ -120,7 +120,13 @@ ul - else input(name='params[' + parameter.Name + ']', value=parameter.Default, placeholder=className) td.type=parameter.Type - td.description=parameter.Description || 'No description' + td.description + p=parameter.Description || 'No description' + - if (parameter.Type =='enumerated' && parameter.EnumeratedDescription) + dl.clearfix + - each description, choice in parameter.EnumeratedDescription + dt #{choice} + dd #{description} - if (method.headers && method.headers.length > 0) div.headers h4.title From 3f1e4c89c6f7c0a422d2adbafdaa9af0958a6299 Mon Sep 17 00:00:00 2001 From: Martin Tajur Date: Thu, 28 Jun 2012 15:55:15 +0300 Subject: [PATCH 6/6] adding additional style rules for enumeratedDescription definition list --- public/stylesheets/style.css | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 3484766f..d9bc0e29 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -737,6 +737,28 @@ li { zoom: 1; } +dl { + display: block; + margin-bottom: 10px; + font-weight: normal; +} +dt { + width: 30%; + border-top: 1px rgba(0,0,0,.2) solid; + padding-top: 5px; + margin-top: 5px; + display: block; + float: left; +} +dd { + width: 70%; + border-top: 1px rgba(0,0,0,.2) solid; + padding-top: 5px; + margin-top: 5px; + display: block; + float: left; +} + @media print { * { background: transparent !important;