/
cURLCodeGenerator.coffee
173 lines (144 loc) · 5.76 KB
/
cURLCodeGenerator.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# in API v0.2.0 and below (Paw 2.2.2 and below), require had no return value
((root) -> root.Mustache = require("mustache.js") or root.Mustache)(this)
((root) -> root.Base64 = require("Base64.js") or root.Base64)(this)
addslashes = (str) ->
("#{str}").replace(/[\\"]/g, '\\$&')
addslashes_single_quotes = (str) ->
("#{str}").replace(/\\/g, '\\$&').replace(/'/g, "\\'")
cURLCodeGenerator = ->
self = this
@headers = (request) ->
headers = request.headers
auth = null
if headers['Authorization']
auth = @auth request, headers['Authorization']
if auth
delete headers['Authorization']
return {
"has_headers": Object.keys(headers).length > 0
"header_list": ({
"header_name": addslashes_single_quotes header_name
"header_value": addslashes_single_quotes header_value
} for header_name, header_value of headers)
"auth": auth
}
@auth = (request, authHeader) ->
if self.options.useHeader
return null
match = authHeader.match(/([^\s]+)\s(.*)/) || []
scheme = match[1] || null
params = match[2] || null
if scheme == 'Basic'
try
decoded = Base64.atob(params)
catch err
return null
userpass = decoded.match(/([^:]*):?(.*)/)
return {
"username": addslashes_single_quotes(userpass[1] || ''),
"password": addslashes_single_quotes(userpass[2] || ''),
}
digestDS = request.getHeaderByName('Authorization', true)
if digestDS and digestDS.length == 1 and digestDS.getComponentAtIndex(0).type == 'com.luckymarmot.PawExtensions.DigestAuthDynamicValue'
digestDV = digestDS.getComponentAtIndex(0)
DVuser = digestDV.username
username = ''
if typeof DVuser == 'object'
username = DVuser.getEvaluatedString()
else
username = DVuser
DVpass = digestDV.password
password = ''
if typeof DVpass == 'object'
password = DVpass.getEvaluatedString()
else
password = DVpass
return {
"isDigest": true,
"username": addslashes_single_quotes(username),
"password": addslashes_single_quotes(password)
}
return null
@body = (request) ->
url_encoded_body = request.urlEncodedBody
if url_encoded_body
return {
"has_url_encoded_body":true
"url_encoded_body": ({
"name": addslashes name
"value": addslashes value
} for name, value of url_encoded_body)
}
multipart_body = request.multipartBody
if multipart_body
return {
"has_multipart_body":true
"multipart_body": ({
"name": addslashes name
"value": addslashes value
} for name, value of multipart_body)
}
json_body = request.jsonBody
if json_body?
return {
"has_raw_body_with_tabs_or_new_lines": true
"has_raw_body_without_tabs_or_new_lines": false
"raw_body": addslashes_single_quotes(JSON.stringify(json_body, null, 2))
}
raw_body = request.body
if raw_body
if raw_body.length < 5000
has_tabs_or_new_lines = (null != /\r|\n|\t/.exec(raw_body))
return {
"has_raw_body_with_tabs_or_new_lines":has_tabs_or_new_lines
"has_raw_body_without_tabs_or_new_lines":!has_tabs_or_new_lines
"raw_body": if has_tabs_or_new_lines then addslashes_single_quotes raw_body else addslashes raw_body
}
else
return {
"has_long_body":true
}
@strip_last_backslash = (string) ->
# Remove the last backslash on the last non-empty line
# We do that programatically as it's difficult to know the "last line"
# in Mustache templates
lines = string.split("\n")
for i in [(lines.length - 1)..0]
lines[i] = lines[i].replace(/\s*\\\s*$/, "")
if not lines[i].match(/^\s*$/)
break
lines.join("\n")
@generateRequest = (request) ->
view =
"request": request
"request_is_head": request.method == "HEAD"
"specify_method": request.method != "GET" && request.method != "HEAD"
"headers": @headers request
"body": @body request
# Make multi-line description.
if view.request.description
view.request.cURLDescription = view.request.description.split('\n').map((line, index) ->
return "# #{line}"
).join('\n')
else
view.request.cURLDescription = ''
template = readFile "curl.mustache"
rendered_code = Mustache.render template, view
return @strip_last_backslash rendered_code
@generate = (context, requests, options) ->
self.options = (options || {}).inputs || {}
curls = requests.map((request) ->
return self.generateRequest(request)
)
return curls.join('\n')
return
cURLCodeGenerator.identifier =
"com.luckymarmot.PawExtensions.cURLCodeGenerator"
cURLCodeGenerator.title =
"cURL"
cURLCodeGenerator.fileExtension = "sh"
cURLCodeGenerator.languageHighlighter = "bash"
cURLCodeGenerator.inputs = [
new InputField("useHeader", "do not use -u option", "Checkbox", {defaultValue: false})
]
registerCodeGenerator cURLCodeGenerator