Skip to content

Commit

Permalink
feat: add an adapter option for request overrides (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored Feb 5, 2019
1 parent 1c1a1e8 commit 88a47e0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ gaxios.request({url: '/data'}).then(...);
// The timeout for the HTTP request. Defaults to 0.
timeout: 1000,

// Optional method to override making the actual HTTP request. Useful
// for writing tests.
adapter?: (options) => {
return {
data: 'your data'
}
};

// The expected return type of the request. Options are:
// json | stream | blob | arraybuffer | text
// Defaults to `json`.
Expand Down
5 changes: 5 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export interface GaxiosResponse<T = any> {
* Request options that are used to form the request.
*/
export interface GaxiosOptions {
/**
* Optional method to override making the actual HTTP request. Useful
* for writing tests.
*/
adapter?: <T = any>(options: GaxiosOptions) => GaxiosPromise<T>;
url?: string;
baseUrl?: string; // deprecated
baseURL?: string;
Expand Down
19 changes: 12 additions & 7 deletions src/gaxios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,20 @@ export class Gaxios {
async request<T = any>(opts: GaxiosOptions = {}): GaxiosPromise<T> {
opts = this.validateOpts(opts);
try {
const res = await fetch(opts.url!, opts);
const data = await this.getResponseData(opts, res);
const translatedResponse = this.translateResponse(opts, res, data);
if (!opts.validateStatus!(res.status)) {
let translatedResponse: GaxiosResponse<T>;
if (opts.adapter) {
translatedResponse = await opts.adapter<T>(opts);
} else {
const res = await fetch(opts.url!, opts);
const data = await this.getResponseData(opts, res);
translatedResponse = this.translateResponse<T>(opts, res, data);
}
if (!opts.validateStatus!(translatedResponse.status)) {
throw new GaxiosError<T>(
`Request failed with status code ${res.status}`, opts,
translatedResponse);
`Request failed with status code ${translatedResponse.status}`,
opts, translatedResponse);
}
return this.translateResponse<T>(opts, res, data);
return translatedResponse;
} catch (e) {
const err = e as GaxiosError;
err.config = opts;
Expand Down
17 changes: 16 additions & 1 deletion test/test.getch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as stream from 'stream';
const assertRejects = require('assert-rejects');
// tslint:disable-next-line variable-name
const HttpsProxyAgent = require('https-proxy-agent');
import {Gaxios, GaxiosError, request, GaxiosOptions} from '../src';
import {Gaxios, GaxiosError, request, GaxiosOptions, GaxiosResponse} from '../src';
import * as qs from 'querystring';
import * as fs from 'fs';
import {Blob} from 'node-fetch';
Expand Down Expand Up @@ -90,6 +90,21 @@ describe('🥁 configuration options', () => {
scope.done();
});

it('should allow overriding the adapter', async () => {
const response: GaxiosResponse = {
data: {hello: '🌎'},
config: {},
status: 200,
statusText: 'OK',
headers: {}
};
const adapter = (options: GaxiosOptions) => {
return Promise.resolve(response);
};
const res = await request({url, adapter});
assert.strictEqual(response, res);
});

it('should encode query string parameters', async () => {
const opts = {url, params: {james: 'kirk', montgomery: 'scott'}};
const path = '/?james=kirk&montgomery=scott';
Expand Down

0 comments on commit 88a47e0

Please sign in to comment.