Skip to content

Commit bba3584

Browse files
committed
Move fetch options generation into model
Previously this responsibility was shared between the Request class and the getFetchOptions() method on the model. Move this all to one public API so that consumers have more control.
1 parent 7d46cff commit bba3584

File tree

4 files changed

+45
-58
lines changed

4 files changed

+45
-58
lines changed

src/model.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import IncludeDirective from './util/include-directive';
1212
import DirtyChecker from './util/dirty-check';
1313
import ValidationErrors from './util/validation-errors';
1414
import relationshipIdentifiersFor from './util/relationship-identifiers';
15-
import Request, { FetchOptions } from './request';
15+
import Request from './request';
1616
import * as _cloneDeep from './util/clonedeep';
1717
let cloneDeep: any = (<any>_cloneDeep).default || _cloneDeep;
1818
if (cloneDeep.default) {
@@ -70,10 +70,19 @@ export default class Model {
7070
}
7171
}
7272

73-
static getFetchOptions() : FetchOptions {
74-
return {
75-
jwt: this.getJWT()
73+
static fetchOptions() : RequestInit {
74+
let options = {
75+
headers: {
76+
Accept: 'application/json',
77+
['Content-Type']: 'application/json'
78+
} as any
7679
}
80+
81+
if (this.getJWT()) {
82+
options.headers.Authorization = `Token token="${this.getJWT()}"`;
83+
}
84+
85+
return options
7786
}
7887

7988
static getJWTOwner() : typeof Model {

src/request.ts

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,28 @@
11
import Config from './configuration';
22
import colorize from './util/colorize';
3-
import cloneDeep from './util/clonedeep';
4-
5-
// RequestInit is the type expected by `fetch()` API.
6-
export interface FetchOptions extends RequestInit {
7-
jwt? : string | undefined
8-
}
93

104
export default class Request {
11-
get(url : string, options: FetchOptions) : Promise<any> {
12-
options['method'] = 'GET';
5+
get(url : string, options: RequestInit) : Promise<any> {
6+
options.method = 'GET';
137
return this._fetchWithLogging(url, options);
148
}
159

16-
post(url: string, payload: Object, options: FetchOptions) : Promise<any> {
17-
options['method'] = 'POST';
18-
options['body'] = JSON.stringify(payload);
10+
post(url: string, payload: Object, options: RequestInit) : Promise<any> {
11+
options.method = 'POST';
12+
options.body = JSON.stringify(payload);
1913

2014
return this._fetchWithLogging(url, options);
2115
}
2216

23-
put(url: string, payload: Object, options: FetchOptions) : Promise<any> {
24-
options['method'] = 'PUT';
25-
options['body'] = JSON.stringify(payload);
17+
put(url: string, payload: Object, options: RequestInit) : Promise<any> {
18+
options.method = 'PUT';
19+
options.body = JSON.stringify(payload);
2620

2721
return this._fetchWithLogging(url, options);
2822
}
2923

30-
delete(url: string, options: FetchOptions) : Promise<any> {
31-
options['method'] = 'DELETE';
24+
delete(url: string, options: RequestInit) : Promise<any> {
25+
options.method = 'DELETE';
3226
return this._fetchWithLogging(url, options);
3327
}
3428

@@ -42,23 +36,17 @@ export default class Request {
4236
Config.logger.debug(colorize('bold', JSON.stringify(responseJSON, null, 4)));
4337
}
4438

45-
private _fetchWithLogging(url: string, options: FetchOptions) : Promise<any> {
46-
this._logRequest(options['method'], url);
39+
private _fetchWithLogging(url: string, options: RequestInit) : Promise<any> {
40+
this._logRequest(options.method, url);
4741
let promise = this._fetch(url, options);
4842
promise.then((response : any) => {
4943
this._logResponse(response['jsonPayload']);
5044
});
5145
return promise;
5246
}
5347

54-
private _fetch(url: string, opts: FetchOptions) : Promise<any> {
48+
private _fetch(url: string, options: RequestInit) : Promise<any> {
5549
return new Promise((resolve, reject) => {
56-
// Clone options since we are changing the object
57-
let options : RequestInit = cloneDeep(opts as RequestInit)
58-
59-
let headers = this.buildHeaders(options);
60-
options.headers = headers;
61-
6250
let fetchPromise = fetch(url, options);
6351
fetchPromise.then((response) => {
6452
response.json().then((json) => {
@@ -70,22 +58,4 @@ export default class Request {
7058
fetchPromise.catch(reject);
7159
});
7260
}
73-
74-
private buildHeaders(options: FetchOptions) : any {
75-
let headers = {};
76-
77-
if (typeof options.headers == 'object') {
78-
headers = options.headers
79-
}
80-
81-
headers['Accept'] = 'application/json';
82-
headers['Content-Type'] = 'application/json';
83-
84-
if (options.jwt) {
85-
headers['Authorization'] = `Token token="${options.jwt}"`;
86-
delete options.jwt
87-
}
88-
89-
return headers;
90-
}
9161
}

src/scope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ export default class Scope {
219219
url = `${url}?${qp}`;
220220
}
221221
let request = new Request();
222-
let fetchOpts = this.model.getFetchOptions()
222+
let fetchOpts = this.model.fetchOptions()
223223

224224
return request.get(url, fetchOpts).then((response) => {
225225
let jwtHeader = response.headers.get('X-JWT');

test/unit/model-test.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,26 @@ describe('Model', function() {
134134
});
135135
});
136136

137-
describe('#getFetchOptions', function() {
138-
beforeEach(function() {
139-
ApplicationRecord.jwt = 'g3tm3';
140-
});
137+
describe('#fetchOptions', function() {
138+
context('jwt is set', function() {
139+
beforeEach(function() {
140+
ApplicationRecord.jwt = 'g3tm3';
141+
});
141142

142-
afterEach(function() {
143-
ApplicationRecord.jwt = null;
144-
});
143+
afterEach(function() {
144+
ApplicationRecord.jwt = null;
145+
});
145146

146-
it('includes the jwt', function() {
147-
expect(Author.getFetchOptions().jwt).to.eq('g3tm3');
148-
});
147+
it('sets the auth header', function() {
148+
expect(Author.fetchOptions().headers.Authorization).to.eq('Token token="g3tm3"');
149+
});
150+
})
151+
152+
it('includes the content headers', function() {
153+
let headers = Author.fetchOptions().headers
154+
expect(headers.Accept).to.eq('application/json')
155+
expect(headers['Content-Type']).to.eq('application/json')
156+
})
149157
})
150158

151159
describe('#isType', function() {

0 commit comments

Comments
 (0)