Skip to content

Commit e7e408c

Browse files
committed
Add clj-http implementation
1 parent e3d61a9 commit e7e408c

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

src/targets/clojure/clj_http.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* @description
3+
* HTTP code snippet generator for Clojure using clj-http.
4+
*
5+
* @author
6+
* @tggreene
7+
*
8+
* for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
9+
*/
10+
11+
'use strict'
12+
13+
var CodeBuilder = require('../../helpers/code-builder')
14+
15+
class Keyword {
16+
constructor (name) {
17+
this.name = `:${name}`
18+
}
19+
20+
toString () {
21+
return this.name
22+
}
23+
}
24+
25+
class ClojureFile {
26+
constructor (path) {
27+
this.path = `(clojure.java.io/file "${path}")`
28+
}
29+
30+
toString () {
31+
return this.path
32+
}
33+
}
34+
35+
var jsType = x => (typeof x !== 'undefined')
36+
? x.constructor.name.toLowerCase()
37+
: null
38+
39+
var objEmpty = x => (jsType(x) !== 'object')
40+
? false
41+
: Object.keys(x).length === 0
42+
43+
var filterEmpty = function (m) {
44+
Object.keys(m)
45+
.filter(x => objEmpty(m[x]))
46+
.forEach(x => delete m[x])
47+
return m
48+
}
49+
50+
var padBlock = function (x, s) {
51+
var padding = [...Array(x)].map(() => ' ').join('')
52+
return s.replace(/\n/g, `\n${padding}`)
53+
}
54+
55+
var jsToEdn = function (js) {
56+
switch (jsType(js)) {
57+
default: // 'number' 'boolean'
58+
return js.toString()
59+
case 'string':
60+
return `"${js.replace(/\"/g, '\\"')}"`
61+
case 'clojurefile':
62+
return js.toString()
63+
case 'keyword':
64+
return js.toString()
65+
case 'null':
66+
return 'nil'
67+
case 'regexp':
68+
return `#"${js.source}"`
69+
case 'object': // simple vertical format
70+
var obj = Object.keys(js)
71+
.reduce((acc, key) => {
72+
var val = padBlock(key.length + 2, jsToEdn(js[key]))
73+
return `${acc}:${key} ${val}\n `
74+
}, '')
75+
.trim()
76+
return `{${padBlock(1, obj)}}`
77+
case 'array': // simple horizontal format
78+
var arr = js.reduce((acc, val) => `${acc} ${jsToEdn(val)}`, '').trim()
79+
return `[${padBlock(1, arr)}]`
80+
}
81+
}
82+
83+
module.exports = function (source, options) {
84+
var code = new CodeBuilder(options)
85+
var methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options']
86+
87+
if (methods.indexOf(source.method.toLowerCase()) === -1) {
88+
return code.push('Method not supported').join()
89+
}
90+
91+
var params = {headers: source.allHeaders,
92+
'query-params': source.queryObj}
93+
94+
switch (source.postData.mimeType) {
95+
case 'application/json':
96+
params['content-type'] = new Keyword('json')
97+
params['form-params'] = source.postData.jsonObj
98+
delete params.headers['content-type']
99+
break
100+
case 'application/x-www-form-urlencoded':
101+
params['form-params'] = source.postData.paramsObj
102+
delete params.headers['content-type']
103+
break
104+
case 'text/plain':
105+
params.body = source.postData.text
106+
delete params.headers['content-type']
107+
break
108+
case 'multipart/form-data':
109+
params.multipart = source.postData.params.map(x => {
110+
if (x.fileName && !x.value) {
111+
return {name: x.name,
112+
content: new ClojureFile(x.fileName)}
113+
} else {
114+
return {name: x.name,
115+
content: x.value}
116+
}
117+
})
118+
delete params.headers['content-type']
119+
break
120+
}
121+
122+
switch (params.headers.accept) {
123+
case 'application/json':
124+
params.accept = new Keyword('json')
125+
delete params.headers.accept
126+
break
127+
}
128+
129+
code.push('(require \'[clj-http.client :as client])\n')
130+
131+
if (objEmpty(filterEmpty(params))) {
132+
code.push('(client/%s "%s")', source.method.toLowerCase(), source.url)
133+
} else {
134+
code.push('(client/%s "%s" %s)', source.method.toLowerCase(), source.url, padBlock(11 + source.method.length + source.url.length, jsToEdn(filterEmpty(params))))
135+
}
136+
137+
return code.join()
138+
}
139+
140+
module.exports.info = {
141+
key: 'clj_http',
142+
title: 'clj-http',
143+
link: 'https://github.com/dakrone/clj-http',
144+
description: 'An idiomatic clojure http client wrapping the apache client.'
145+
}

src/targets/clojure/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'
2+
3+
module.exports = {
4+
info: {
5+
key: 'clojure',
6+
title: 'Clojure',
7+
extname: '.clj',
8+
default: 'clj_http'
9+
},
10+
11+
clj_http: require('./clj_http')
12+
}

0 commit comments

Comments
 (0)