Skip to content

Commit

Permalink
Merge pull request #82 from tggreene/add-clojure-generator
Browse files Browse the repository at this point in the history
Add clojure generator
  • Loading branch information
Ahmad Nassri committed Mar 14, 2017
2 parents 016bdba + 63c6345 commit 6cb8486
Show file tree
Hide file tree
Showing 19 changed files with 239 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"bin": "bin/httpsnippet",
"keywords": [
"api",
"clojure",
"csharp",
"curl",
"go",
Expand Down
151 changes: 151 additions & 0 deletions src/targets/clojure/clj_http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* @description
* HTTP code snippet generator for Clojure using clj-http.
*
* @author
* @tggreene
*
* for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
*/

'use strict'

var CodeBuilder = require('../../helpers/code-builder')

var Keyword = function (name) {
this.name = name
}

Keyword.prototype.toString = function () {
return ':' + this.name
}

var File = function (path) {
this.path = path
}

File.prototype.toString = function () {
return '(clojure.java.io/file "' + this.path + '")'
}

var jsType = function (x) {
return (typeof x !== 'undefined')
? x.constructor.name.toLowerCase()
: null
}

var objEmpty = function (x) {
return (jsType(x) === 'object')
? Object.keys(x).length === 0
: false
}

var filterEmpty = function (m) {
Object.keys(m)
.filter(function (x) { return objEmpty(m[x]) })
.forEach(function (x) { delete m[x] })
return m
}

var padBlock = function (x, s) {
var padding = Array.apply(null, Array(x))
.map(function (_) {
return ' '
})
.join('')
return s.replace(/\n/g, '\n' + padding)
}

var jsToEdn = function (js) {
switch (jsType(js)) {
default: // 'number' 'boolean'
return js.toString()
case 'string':
return '"' + js.replace(/\"/g, '\\"') + '"'
case 'file':
return js.toString()
case 'keyword':
return js.toString()
case 'null':
return 'nil'
case 'regexp':
return '#"' + js.source + '"'
case 'object': // simple vertical format
var obj = Object.keys(js)
.reduce(function (acc, key) {
var val = padBlock(key.length + 2, jsToEdn(js[key]))
return acc + ':' + key + ' ' + val + '\n '
}, '')
.trim()
return '{' + padBlock(1, obj) + '}'
case 'array': // simple horizontal format
var arr = js.reduce(function (acc, val) {
return acc + ' ' + jsToEdn(val)
}, '').trim()
return '[' + padBlock(1, arr) + ']'
}
}

module.exports = function (source, options) {
var code = new CodeBuilder(options)
var methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options']

if (methods.indexOf(source.method.toLowerCase()) === -1) {
return code.push('Method not supported').join()
}

var params = {headers: source.allHeaders,
'query-params': source.queryObj}

switch (source.postData.mimeType) {
case 'application/json':
params['content-type'] = new Keyword('json')
params['form-params'] = source.postData.jsonObj
delete params.headers['content-type']
break
case 'application/x-www-form-urlencoded':
params['form-params'] = source.postData.paramsObj
delete params.headers['content-type']
break
case 'text/plain':
params.body = source.postData.text
delete params.headers['content-type']
break
case 'multipart/form-data':
params.multipart = source.postData.params.map(function (x) {
if (x.fileName && !x.value) {
return {name: x.name,
content: new File(x.fileName)}
} else {
return {name: x.name,
content: x.value}
}
})
delete params.headers['content-type']
break
}

switch (params.headers.accept) {
case 'application/json':
params.accept = new Keyword('json')
delete params.headers.accept
break
}

code.push('(require \'[clj-http.client :as client])\n')

if (objEmpty(filterEmpty(params))) {
code.push('(client/%s "%s")', source.method.toLowerCase(), source.url)
} else {
code.push('(client/%s "%s" %s)', source.method.toLowerCase(), source.url, padBlock(11 + source.method.length + source.url.length, jsToEdn(filterEmpty(params))))
}

return code.join()
}

module.exports.info = {
key: 'clj_http',
title: 'clj-http',
link: 'https://github.com/dakrone/clj-http',
description: 'An idiomatic clojure http client wrapping the apache client.'
}
12 changes: 12 additions & 0 deletions src/targets/clojure/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

module.exports = {
info: {
key: 'clojure',
title: 'Clojure',
extname: '.clj',
default: 'clj_http'
},

clj_http: require('./clj_http')
}
1 change: 1 addition & 0 deletions src/targets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module.exports = {
c: require('./c'),
clojure: require('./clojure'),
csharp: require('./csharp'),
go: require('./go'),
java: require('./java'),
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/available-targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@
}
]
},
{
"key": "clojure",
"title": "Clojure",
"extname": ".clj",
"default": "clj_http",
"clients": [
{
"key": "clj_http",
"title": "clj-http",
"link": "https://github.com/dakrone/clj-http",
"description": "An idiomatic clojure http client wrapping the apache client."
}
]
},
{
"key": "c",
"title": "C",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:form-params {:foo "bar"
:hello "world"}})
9 changes: 9 additions & 0 deletions test/fixtures/output/clojure/clj_http/application-json.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:content-type :json
:form-params {:number 1
:string "f\"oo"
:arr [1 2 3]
:nested {:a "b"}
:arr_mix [1 "a" {:arr_mix_nested {}}]
:boolean false}})
3 changes: 3 additions & 0 deletions test/fixtures/output/clojure/clj_http/cookies.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:headers {:cookie "foo=bar; bar=baz"}})
1 change: 1 addition & 0 deletions test/fixtures/output/clojure/clj_http/custom-method.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Method not supported
8 changes: 8 additions & 0 deletions test/fixtures/output/clojure/clj_http/full.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:headers {:cookie "foo=bar; bar=baz"}
:query-params {:foo ["bar" "baz"]
:baz "abc"
:key "value"}
:form-params {:foo "bar"}
:accept :json})
4 changes: 4 additions & 0 deletions test/fixtures/output/clojure/clj_http/headers.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(require '[clj-http.client :as client])

(client/get "http://mockbin.com/har" {:headers {:x-foo "Bar"}
:accept :json})
3 changes: 3 additions & 0 deletions test/fixtures/output/clojure/clj_http/https.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(require '[clj-http.client :as client])

(client/get "https://mockbin.com/har")
4 changes: 4 additions & 0 deletions test/fixtures/output/clojure/clj_http/multipart-data.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:multipart [{:name "foo"
:content "Hello World"}]})
4 changes: 4 additions & 0 deletions test/fixtures/output/clojure/clj_http/multipart-file.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:multipart [{:name "foo"
:content (clojure.java.io/file "test/fixtures/files/hello.txt")}]})
4 changes: 4 additions & 0 deletions test/fixtures/output/clojure/clj_http/multipart-form-data.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:multipart [{:name "foo"
:content "bar"}]})
5 changes: 5 additions & 0 deletions test/fixtures/output/clojure/clj_http/query.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(require '[clj-http.client :as client])

(client/get "http://mockbin.com/har" {:query-params {:foo ["bar" "baz"]
:baz "abc"
:key "value"}})
3 changes: 3 additions & 0 deletions test/fixtures/output/clojure/clj_http/short.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(require '[clj-http.client :as client])

(client/get "http://mockbin.com/har")
3 changes: 3 additions & 0 deletions test/fixtures/output/clojure/clj_http/text-plain.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(require '[clj-http.client :as client])

(client/post "http://mockbin.com/har" {:body "Hello World"})
5 changes: 5 additions & 0 deletions test/targets/clojure/clj_http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict'

require('should')

module.exports = function (snippet, fixtures) {}

0 comments on commit 6cb8486

Please sign in to comment.