Skip to content

Commit

Permalink
Add support for flattening complex json structures
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan José committed Nov 22, 2016
1 parent 1b948cb commit c622c61
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 13 deletions.
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,44 @@ Then, any request that reaches the server and matches one of the directories and
Dafuq translates any parameter on the request to command line flags with double dash `--`. The request fields searched for parmeters and its override order is as follows (upper means it will prevail in case of name clashing):
* Multipart files
* Multipart form fields
* Body fields
* Body fields: Can be URL encoded or JSON. Multilevel object structures will be flattened full path key
* URL params: (parts of the url that start with `:`)
* Query Params
* Headers: (the ones starting with `X-Arg-`)

```
POST /hello/john?age=12&male HTTP/1.1
Content-Type: application/x-www-form-urlencoded
POST /hello/john?age=25&male HTTP/1.1
Content-Type: application/json
Content-Length: 100
X-Arg-username: jhon78
surname=wick&profession=killer
{
"surname": "wick",
"profession": "killer",
"confirmedKills": [
"target1",
"target2"
],
"ammo": {
"usp": 12
"ump": 25
}
}
```
would be equivalent to the following command
```
./hello/\:name/get.sh \
--name john \
--surname wick \
--username username \
--age 12 \
--male \
--profession killer
--name "john" \
--surname "wick" \
--username "jhon78" \
--age "25" \
--male \
--profession "killer" \
--confirmedKills.0 "target1" \
--confirmedKills.1 "target2" \
--ammo.usp "12" \
--ammo.ump "25"
```

### Recieving Files
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"express": "^4.14.0",
"glob": "^7.0.5",
"multer": "^1.2.0",
"traverse": "^0.6.6",
"yargs": "^5.0.0"
},
"devDependencies": {
Expand Down
14 changes: 11 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const fs = require('fs')
, child_process = require('child_process')
, debug = require('debug')
, glob = require('glob')
, traverse = require('traverse')
, express = require('express')
, multer = require('multer')
, bodyParser = require('body-parser')
Expand Down Expand Up @@ -131,12 +132,19 @@ function buildCommandFlags(req) {
return files
}, {})

const flags = Object.assign({}, headerFlags, req.query, req.params, req.body, uploadFlags)
// Flatten the body
const body = traverse(req.body).reduce(function(b, val) {
if (this.notRoot && this.isLeaf)
b[this.path.join('.')] = val
return b
}, {})

const flags = Object.assign({}, headerFlags, req.query, req.params, body, uploadFlags)
Object.keys(flags).forEach(function(flagName) {
let flagValue = flags[flagName]
cmdFlags += ` --${flagName}`
if (flagValue) {
flagValue = flagValue
if (flagValue !== undefined) {
flagValue = String(flagValue)
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
cmdFlags += ` "${flagValue}"`
Expand Down
10 changes: 10 additions & 0 deletions test/commands/json/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node
var traverse = require('traverse')
var argv = require('yargs')
.argv;

traverse(argv).forEach(function(x) {
if (this.notRoot && this.isLeaf && [ '_', '$0' ].indexOf(this.path[0]) < 0) {
console.log(this.path.join('.') + ':' + x)
}
})
31 changes: 31 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -618,4 +618,35 @@ describe('Arguments', () => {
.expect(res => res.body.result.should.be.equal('Hello Sarah \\"Connor\\"'))
.end(done)
})

it('should pass complex json as flattened paths', (done) => {
const body = {
names: [
'Sarah',
'Arnold'
],
surnames: [
'Connor',
'Swacheneger'
],
films: {
'terminator': 9
}
}
const expectedBody = [
'names.0:Sarah',
'names.1:Arnold',
'surnames.0:Connor',
'surnames.1:Swacheneger',
'films.terminator:9'
].join('\n')

request(app)
.post('/json')
.send(body)
.expect(200)
.expect('Content-Type', /json/)
.expect(res => res.body.result.should.be.equal(expectedBody))
.end(done)
})
})

0 comments on commit c622c61

Please sign in to comment.