Skip to content

Commit aab878b

Browse files
authored
Merge pull request #115 from particle-iot/feature/headers
feature/headers
2 parents ac9909f + 0268713 commit aab878b

File tree

7 files changed

+1925
-1198
lines changed

7 files changed

+1925
-1198
lines changed

src/Agent.js

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,36 @@ import request from 'superagent';
2121
import prefix from 'superagent-prefix';
2222

2323
export default class Agent {
24-
25-
constructor(baseUrl) {
24+
constructor(baseUrl){
2625
this.prefix = prefix(baseUrl);
2726
}
2827

29-
get(uri, auth, query, context) {
30-
return this.request({ uri, auth, method: 'get', query, context });
28+
get({ uri, auth, headers, query, context }){
29+
return this.request({ uri, method: 'get', auth, headers, query, context });
3130
}
3231

33-
head(uri, auth, query, context) {
34-
return this.request({ uri, auth, method: 'head', query, context });
32+
head({ uri, auth, headers, query, context }){
33+
return this.request({ uri, method: 'head', auth, headers, query, context });
3534
}
3635

37-
post(uri, data, auth, context) {
38-
return this.request({ uri, data, auth, method: 'post', context });
36+
post({ uri, headers, data, auth, context }){
37+
return this.request({ uri, method: 'post', auth, headers, data, context });
3938
}
4039

41-
put(uri, data, auth, context) {
42-
return this.request({ uri, data, auth, method: 'put', context });
40+
put({ uri, auth, headers, data, context }){
41+
return this.request({ uri, method: 'put', auth, headers, data, context });
4342
}
4443

45-
delete(uri, data, auth, context) {
46-
return this.request({ uri, data, auth, method: 'delete', context });
44+
delete({ uri, auth, headers, data, context }){
45+
return this.request({ uri, method: 'delete', auth, headers, data, context });
4746
}
4847

4948

5049
/**
5150
*
5251
* @param {String} uri The URI to request
5352
* @param {String} method The method used to request the URI, should be in uppercase.
53+
* @param {Object} headers Key/Value pairs like `{ 'X-FOO': 'foo', X-BAR: 'bar' }` to send as headers.
5454
* @param {String} data Arbitrary data to send as the body.
5555
* @param {Object} auth Authorization
5656
* @param {String} query Query parameters
@@ -62,22 +62,24 @@ export default class Agent {
6262
request({
6363
uri,
6464
method,
65+
headers = undefined,
6566
data = undefined,
6667
auth,
6768
query = undefined,
6869
form = undefined,
6970
files = undefined,
7071
context = undefined,
7172
raw = false
72-
}) {
73+
}){
7374
const requestFiles = this._sanitizeFiles(files);
74-
return this._request({ uri, method, data, auth, query, form, context, files: requestFiles, raw });
75+
return this._request({ uri, method, headers, data, auth, query, form, context, files: requestFiles, raw });
7576
}
7677

7778
/**
7879
*
7980
* @param {String} uri The URI to request
8081
* @param {String} method The method used to request the URI, should be in uppercase.
82+
* @param {Object} headers Key/Value pairs like `{ 'X-FOO': 'foo', X-BAR: 'bar' }` to send as headers.
8183
* @param {String} data Arbitrary data to send as the body.
8284
* @param {Object} auth Authorization
8385
* @param {String} query Query parameters
@@ -86,8 +88,8 @@ export default class Agent {
8688
* @param {Object} context the invocation context
8789
* @return {Promise} A promise. fulfilled with {body, statusCode}, rejected with { statusCode, errorDescription, error, body }
8890
*/
89-
_request({ uri, method, data, auth, query, form, files, context, raw }) {
90-
const req = this._buildRequest({ uri, method, data, auth, query, form, context, files });
91+
_request({ uri, method, headers, data, auth, query, form, files, context, raw }){
92+
const req = this._buildRequest({ uri, method, headers, data, auth, query, form, context, files });
9193

9294
if (raw){
9395
return req;
@@ -101,7 +103,7 @@ export default class Agent {
101103
* @returns {Promise} The promise to send the request and retrieve the response.
102104
* @private
103105
*/
104-
_promiseResponse(req) {
106+
_promiseResponse(req){
105107
return new Promise((fulfill, reject) => this._sendRequest(req, fulfill, reject));
106108
}
107109

@@ -113,15 +115,15 @@ export default class Agent {
113115
* @private
114116
* @returns {undefined} Nothing
115117
*/
116-
_sendRequest(request, fulfill, reject) {
118+
_sendRequest(request, fulfill, reject){
117119
request.end((error, res) => {
118120
const body = res && res.body;
119-
if (error) {
121+
if (error){
120122
const uri = request.url;
121123
const statusCode = error.status;
122124
let errorDescription = `${statusCode ? 'HTTP error ' + statusCode : 'Network error'} from ${uri}`;
123125
let shortErrorDescription;
124-
if (body && body.error_description) {
126+
if (body && body.error_description){
125127
errorDescription += ' - ' + body.error_description;
126128
shortErrorDescription = body.error_description;
127129
}
@@ -137,90 +139,93 @@ export default class Agent {
137139
});
138140
}
139141

140-
_buildRequest({ uri, method, data, auth, query, form, files, context, makerequest = request }) {
142+
_buildRequest({ uri, method, headers, data, auth, query, form, files, context, makerequest = request }){
141143
const req = makerequest(method, uri);
142-
if (this.prefix) {
144+
if (this.prefix){
143145
req.use(this.prefix);
144146
}
145147
this._authorizationHeader(req, auth);
146-
if (context) {
148+
if (context){
147149
this._applyContext(req, context);
148150
}
149-
if (query) {
151+
if (query){
150152
req.query(query);
151153
}
152-
if (files) {
153-
for (let [name, file] of Object.entries(files)) {
154+
if (headers){
155+
req.set(headers);
156+
}
157+
if (files){
158+
for (let [name, file] of Object.entries(files)){
154159
// API for Form Data is different in Node and in browser
155160
let options = {
156161
filepath: file.path
157162
};
158-
if (this.isForBrowser(makerequest)) {
163+
if (this.isForBrowser(makerequest)){
159164
options = file.path;
160165
}
161166
req.attach(name, file.data, options);
162167
}
163-
if (form) {
164-
for (let [name, value] of Object.entries(form)) {
168+
if (form){
169+
for (let [name, value] of Object.entries(form)){
165170
req.field(name, value);
166171
}
167172
}
168-
} else if (form) {
173+
} else if (form){
169174
req.type('form');
170175
req.send(form);
171-
} else if (data) {
176+
} else if (data){
172177
req.send(data);
173178
}
174179
return req;
175180
}
176181

177-
isForBrowser(makerequest = request) {
182+
isForBrowser(makerequest = request){
178183
// superagent only has the getXHR method in the browser version
179184
return !!makerequest.getXHR;
180185
}
181186

182-
_applyContext(req, context) {
183-
if (context.tool) {
187+
_applyContext(req, context){
188+
if (context.tool){
184189
this._addToolContext(req, context.tool);
185190
}
186-
if (context.project) {
191+
if (context.project){
187192
this._addProjectContext(req, context.project);
188193
}
189194
}
190195

191-
_addToolContext(req, tool) {
196+
_addToolContext(req, tool){
192197
let value = '';
193-
if (tool.name) {
198+
if (tool.name){
194199
value += this._toolIdent(tool);
195-
if (tool.components) {
196-
for (let component of tool.components) {
200+
if (tool.components){
201+
for (let component of tool.components){
197202
value += ', '+this._toolIdent(component);
198203
}
199204
}
200205
}
201-
if (value) {
206+
if (value){
202207
req.set('X-Particle-Tool', value);
203208
}
204209
}
205210

206-
_toolIdent(tool) {
211+
_toolIdent(tool){
207212
return this._nameAtVersion(tool.name, tool.version);
208213
}
209214

210-
_nameAtVersion(name, version) {
215+
_nameAtVersion(name, version){
211216
let value = '';
212-
if (name) {
217+
if (name){
213218
value += name;
214-
if (version) {
219+
if (version){
215220
value += '@'+version;
216221
}
217222
}
218223
return value;
219224
}
220225

221-
_addProjectContext(req, project) {
226+
_addProjectContext(req, project){
222227
let value = this._buildSemicolonSeparatedProperties(project, 'name');
223-
if (value) {
228+
if (value){
224229
req.set('X-Particle-Project', value);
225230
}
226231
}
@@ -233,12 +238,12 @@ export default class Agent {
233238
* @private
234239
* @return {string} The formatted string representing the object properties and the default property.
235240
*/
236-
_buildSemicolonSeparatedProperties(obj, primaryProperty) {
241+
_buildSemicolonSeparatedProperties(obj, primaryProperty){
237242
let value = '';
238-
if (obj[primaryProperty]) {
243+
if (obj[primaryProperty]){
239244
value += obj[primaryProperty];
240-
for (let prop in obj) {
241-
if (prop!==primaryProperty && obj.hasOwnProperty(prop)) {
245+
for (let prop in obj){
246+
if (prop!==primaryProperty && obj.hasOwnProperty(prop)){
242247
value += '; '+prop+'='+obj[prop];
243248
}
244249
}
@@ -253,9 +258,9 @@ export default class Agent {
253258
* or a username/password object.
254259
* @returns {Request} req The original request.
255260
*/
256-
_authorizationHeader(req, auth) {
257-
if (auth) {
258-
if (auth.username !== undefined) {
261+
_authorizationHeader(req, auth){
262+
if (auth){
263+
if (auth.username !== undefined){
259264
req.auth(auth.username, auth.password);
260265
} else {
261266
req.set({ Authorization: `Bearer ${auth}` });
@@ -269,9 +274,9 @@ export default class Agent {
269274
* @param {Array} files converts the file names to file, file1, file2.
270275
* @returns {object} the renamed files.
271276
*/
272-
_sanitizeFiles(files) {
277+
_sanitizeFiles(files){
273278
let requestFiles;
274-
if (files) {
279+
if (files){
275280
requestFiles = {};
276281
Object.keys(files).forEach((k, i) => {
277282
const name = i ? `file${i + 1}` : 'file';

0 commit comments

Comments
 (0)