Skip to content

Commit ec590a8

Browse files
author
Daniils Petrovs
committed
Implement Elixir HTTPoison target
1 parent 7fd160c commit ec590a8

21 files changed

Lines changed: 181 additions & 0 deletions

src/targets/elixir/httpoison.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* @description
3+
* HTTPoison Elixir HTTP client code snippet generator.
4+
*
5+
* @author
6+
* @danirukun
7+
*
8+
* For any questions or issues regarding the generated code snippet,
9+
* please open an issue mentioning the author.
10+
*/
11+
12+
'use strict'
13+
14+
const CodeBuilder = require('../../helpers/code-builder')
15+
16+
/**
17+
Converts an ES6 list of objects to an Elixir KW list
18+
*/
19+
const jsListToKwList = (jsList) => {
20+
if (jsList.length === 0) {
21+
return '[]'
22+
} else {
23+
const kwList = jsList
24+
.map(obj => `{"${obj.name}", "${obj.value}"}`)
25+
.join(', ')
26+
return `[${kwList}]`
27+
}
28+
}
29+
30+
/**
31+
Converts a list containing cookies objects into an
32+
HTTPoison `cookie` parameter argument.
33+
*/
34+
const jsCookiesToExBin = (jsCookiesList) => {
35+
if (jsCookiesList.length === 0) {
36+
return '""'
37+
} else {
38+
const exBinary = jsCookiesList
39+
.map(cookie => `${cookie.name}=${cookie.value}`)
40+
.join('; ')
41+
return `"${exBinary}"`
42+
}
43+
}
44+
45+
/**
46+
Converts a list of params to a Poison multipart form payload.
47+
*/
48+
const jsMultiPartParamsToPoisonPayload = (jsMultiParams) => {
49+
const [params] = jsMultiParams
50+
const isFileUpload = 'fileName' in params
51+
let multiPart
52+
53+
if (isFileUpload) {
54+
const { fileName, name } = params
55+
const formData = [
56+
{ name: 'name', value: name },
57+
{ name: 'filename', value: fileName }]
58+
const formDataKwList = jsListToKwList(formData)
59+
const headers = jsListToKwList([{ name: 'content-type', value: 'multipart/form-data' }])
60+
61+
multiPart = `[{:file, "${fileName}", {"form-data", ${formDataKwList}}, ${headers}}]`
62+
} else {
63+
multiPart = jsListToKwList(jsMultiParams)
64+
}
65+
66+
return `{:multipart, ${multiPart}}`
67+
}
68+
69+
const isJson = (mimeType) => {
70+
return mimeType === 'application/json'
71+
}
72+
73+
const isMultiPartForm = (mimeType) => {
74+
return mimeType === 'multipart/form-data'
75+
}
76+
77+
const escapeExString = (text) => {
78+
return `~s(${text})`
79+
}
80+
81+
module.exports = (source, _options) => {
82+
const code = new CodeBuilder()
83+
84+
const { method, headers, cookies, postData: { mimeType, params } } = source
85+
const text = `"${(source.postData.text || '')}"`
86+
const escapedText = isJson(mimeType)
87+
? escapeExString(text)
88+
: text
89+
const payload = isMultiPartForm(mimeType)
90+
? jsMultiPartParamsToPoisonPayload(params)
91+
: escapedText
92+
93+
function appendHeaders (headers) {
94+
const exHeaders = jsListToKwList(headers)
95+
96+
argPlaceholders += ', %s'
97+
poisonArgs = poisonArgs.concat([exHeaders])
98+
}
99+
100+
function appendCookies (cookies) {
101+
const exCookies = jsCookiesToExBin(cookies)
102+
const poisonOpts = `hackney: [cookie: ${exCookies}]`
103+
104+
argPlaceholders += ', %s'
105+
poisonArgs = poisonArgs.concat([poisonOpts])
106+
}
107+
108+
function appendPayload (payload) {
109+
argPlaceholders += ', %s'
110+
poisonArgs = poisonArgs.concat([payload])
111+
}
112+
113+
let argPlaceholders = ':%s, "%s"'
114+
let poisonArgs = [method.toLowerCase(), source.fullUrl]
115+
116+
appendPayload(payload)
117+
118+
if (headers.length > 0) appendHeaders(headers)
119+
if (cookies.length > 0) {
120+
if (headers.length === 0) appendHeaders([])
121+
appendCookies(cookies)
122+
}
123+
124+
code.push(`HTTPoison.request(${argPlaceholders})`, ...poisonArgs)
125+
126+
return code.join()
127+
}
128+
129+
module.exports.info = {
130+
key: 'httpoison',
131+
title: 'HTTPoison',
132+
link: 'https://github.com/edgurgel/httpoison',
133+
description: 'HTTP client for Elixir, based on HTTPotion.'
134+
}

src/targets/elixir/index.js

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

src/targets/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module.exports = {
44
c: require('./c'),
55
clojure: require('./clojure'),
66
csharp: require('./csharp'),
7+
elixir: require('./elixir'),
78
go: require('./go'),
89
http: require('./http'),
910
java: require('./java'),

test/fixtures/available-targets.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,20 @@
241241
"link": "http://ruby-doc.org/stdlib-2.2.1/libdoc/net/http/rdoc/Net/HTTP.html",
242242
"description": "Ruby HTTP client"
243243
}
244+
]
245+
},
246+
{
247+
"key": "elixir",
248+
"title": "Elixir",
249+
"extname": ".ex",
250+
"default": "httpoison",
251+
"clients": [
252+
{
253+
"key": "httpoison",
254+
"title": "HTTPoison",
255+
"link": "https://github.com/edgurgel/httpoison",
256+
"description": "HTTP client for Elixir, based on HTTPotion."
257+
}
244258
]
245259
},
246260
{
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:post, "http://mockbin.com/har", "foo=bar&hello=world", [{"content-type", "application/x-www-form-urlencoded"}])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:post, "http://mockbin.com/har", ~s("{"number":1,"string":"f\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}"), [{"content-type", "application/json"}])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:post, "http://mockbin.com/har", "", [], hackney: [cookie: "foo=bar; bar=baz"])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:propfind, "http://mockbin.com/har", "")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:post, "http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value", "foo=bar", [{"accept", "application/json"}, {"content-type", "application/x-www-form-urlencoded"}], hackney: [cookie: "foo=bar; bar=baz"])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HTTPoison.request(:get, "http://mockbin.com/har", "", [{"accept", "application/json"}, {"x-foo", "Bar"}])

0 commit comments

Comments
 (0)