Skip to content

Commit

Permalink
Merge pull request #162 from evert/hydrate-options
Browse files Browse the repository at this point in the history
Add an options hydrator
  • Loading branch information
evert authored Nov 6, 2019
2 parents bd1a167 + f834261 commit 6f60202
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 13 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
],
"types": "dist/index.d.ts",
"dependencies": {
"fetch-mw-oauth2": "^0.3.5",
"fetch-mw-oauth2": "^0.4.0",
"http-link-header": "^1.0.2",
"node-fetch": "^2.6.0",
"querystring-browser": "^1.0.4",
Expand Down
18 changes: 18 additions & 0 deletions src/ketting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ export default class Ketting {

}

/**
* Returns a list of all Ketting options.
*
* The primary purpose of this is for hydrating all options in for example LocalStorage.
*
* The options will not be an exact copy of what was passed, but instead will
* contain properties like refreshToken and accessToken, allowing authentication information
* to be cached.
*
* NOTE that this function is experimental and only handles top-level settings, and not for
* specific domains.
*/
getOptions(): Promise<KettingInit> {

return this.fetchHelper.getOptions();

}

/**
* This function does an arbitrary request using the fetch API.
*
Expand Down
62 changes: 53 additions & 9 deletions src/utils/fetch-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class FetchHelper {
private onBeforeRequest: beforeRequestCallback | null;
private onAfterRequest: afterRequestCallback | null;

constructor(options: Partial<KettingInit>, onBeforeRequest: beforeRequestCallback | null = null, onAfterRequest: afterRequestCallback | null = null) {
constructor(options: KettingInit, onBeforeRequest: beforeRequestCallback | null = null, onAfterRequest: afterRequestCallback | null = null) {
this.options = {
fetchInit: options.fetchInit || {},
auth: options.auth,
Expand Down Expand Up @@ -69,6 +69,40 @@ export default class FetchHelper {

}

/**
* Returns a list of all Ketting options.
*
* The primary purpose of this is for hydrating all options in for example LocalStorage.
*
* The options will not be an exact copy of what was passed, but instead will
* contain properties like refreshToken and accessToken, allowing authentication information
* to be cached.
*
* NOTE that this function is experimental and only handles top-level settings, and not for
* specific domains.
*/
async getOptions(): Promise<KettingInit> {

const options = this.getDomainOptions('*');
let auth;

if (options.auth && options.auth.type === 'oauth2') {
const oauth2 = this.getOAuth2Bucket(options);
auth = {
type: 'oauth2' as 'oauth2',
...await oauth2.getOptions(),
};
} else {
auth = options.auth;
}

return {
fetchInit: options.fetchInit,
auth,
};

}

getDomainOptions(uri: string): DomainOptions {

if (!this.options.match) {
Expand Down Expand Up @@ -117,7 +151,6 @@ export default class FetchHelper {

const options = this.getDomainOptions(request.url);
const authOptions = options.auth;
const authBucket = options.authBucket;

if (!authOptions) {
return this.doFetch(request);
Expand All @@ -131,21 +164,32 @@ export default class FetchHelper {
request.headers.set('Authorization', 'Bearer ' + authOptions.token);
return this.doFetch(request);
case 'oauth2' :
if (!this.oAuth2Buckets.has(authBucket)) {
this.oAuth2Buckets.set(
authBucket,
new OAuth2(authOptions)
);
}
if (this.onBeforeRequest) { this.onBeforeRequest(request); }
const response = await this.oAuth2Buckets.get(authBucket)!.fetch(request);
const response = await this.getOAuth2Bucket(options).fetch(request);
if (this.onAfterRequest) { this.onAfterRequest(request, response); }
return response;
}


}

private getOAuth2Bucket(options: DomainOptions): OAuth2 {

const authOptions = options.auth;
if (!authOptions || authOptions.type !== 'oauth2') {
throw new Error('getOAuth2Bucket can only be called for oauth2 credentials');
}

if (!this.oAuth2Buckets.has(options.authBucket)) {
this.oAuth2Buckets.set(
options.authBucket,
new OAuth2(authOptions)
);
}
return this.oAuth2Buckets.get(options.authBucket)!;

}

/**
* This function is the last mile before the actual fetch request is ran
*/
Expand Down

0 comments on commit 6f60202

Please sign in to comment.