Skip to content

Commit

Permalink
Merge pull request #68 from lifeomic/convertToTypescript
Browse files Browse the repository at this point in the history
Update to typescript, and publish the types
  • Loading branch information
David Tanner authored Apr 16, 2021
2 parents 650b6e2 + 1771fa7 commit 9ebf8b9
Show file tree
Hide file tree
Showing 8 changed files with 486 additions and 189 deletions.
18 changes: 18 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": [
"plugin:@lifeomic/node/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-var-requires": "off",
"lodash/import-scope": "off"
}
}
31 changes: 22 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{
"name": "@lifeomic/axios-fetch",
"version": "1.5.2",
"version": "2.0.0",
"description": "A WebAPI Fetch implementation backed by an Axios client",
"main": "src/index.js",
"types": "src/index.ts",
"scripts": {
"test": "nyc ava",
"lint": "eslint .",
"lint": "eslint . --ext .js,.ts -f codeframe && tsc --noEmit",
"pretest": "yarn lint",
"coverage": "nyc report --reporter=text-lcov > ./.nyc_output/lcov.info"
"coverage": "nyc report --reporter=text-lcov > ./.nyc_output/lcov.info",
"prepublishOnly": "yarn tsc"
},
"engines": {
"node": ">=12"
Expand All @@ -16,24 +18,35 @@
"fetch",
"axios"
],
"ava": {
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
},
"author": "LifeOmic <development@lifeomic.com>",
"license": "MIT",
"devDependencies": {
"@lifeomic/eslint-plugin-node": "^2.0.1",
"@types/sinon": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"ava": "^3.15.0",
"axios": "0.21.1",
"coveralls": "^3.1.0",
"eslint": "^6.0.0",
"lodash.mapvalues": "^4.6.0",
"nock": "^11.3.3",
"nyc": "^15.0.0",
"sinon": "^7.2.4"
"sinon": "^10.0.1",
"ts-node": "^9.1.1",
"typescript": "^4.2.4"
},
"dependencies": {
"form-data": "^2.3.3",
"lodash.identity": "^3.0.0",
"lodash.mapkeys": "^4.6.0",
"node-fetch": "^2.0.0"
"@types/node-fetch": "^2.5.10",
"form-data": "^2.5.0",
"node-fetch": "^2.6.1"
},
"eslintConfig": {
"extends": "plugin:@lifeomic/node/recommended"
Expand Down
55 changes: 0 additions & 55 deletions src/index.js

This file was deleted.

72 changes: 72 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Response, Headers as FetchHeaders } from 'node-fetch';
import FormData from 'form-data';
import { AxiosInstance, AxiosRequestConfig } from './types';

export interface FetchInit extends Record<string, any> {
headers?: Record<string, string>;
method?: AxiosRequestConfig['method'];
body?: FormData | any;
extra?: any;
}

export type AxiosTransformer = (config: AxiosRequestConfig, input: string | undefined, init: FetchInit) => AxiosRequestConfig;

export type AxiosFetch = (input?: string, init?: FetchInit) => Response;

/**
* A Fetch WebAPI implementation based on the Axios client
*/
async function axiosFetch (
axios: AxiosInstance,
// Convert the `fetch` style arguments into a Axios style config
transformer: AxiosTransformer,
input?: string,
init: FetchInit = {}
) {
const rawHeaders: Record<string, string> = init.headers || {};
const lowerCasedHeaders = Object.keys(rawHeaders)
.reduce<Record<string, string>>(
(acc, key) => {
acc[key.toLowerCase()] = rawHeaders[key];
return acc;
},
{}
);

if (!('content-type' in lowerCasedHeaders)) {
lowerCasedHeaders['content-type'] = 'text/plain;charset=UTF-8';
}

const rawConfig: AxiosRequestConfig = {
url: input,
method: init.method || 'GET',
data: typeof init.body === 'undefined' || init.body instanceof FormData ? init.body : String(init.body),
headers: lowerCasedHeaders,
// Force the response to an arraybuffer type. Without this, the Response
// object will try to guess the content type and add headers that weren't in
// the response.
// NOTE: Don't use 'stream' because it's not supported in the browser
responseType: 'arraybuffer'
};

const config = transformer ? transformer(rawConfig, input, init) : rawConfig;

let result;
try {
result = await axios.request(config);
} catch (err) {
result = err.response;
}

const fetchHeaders = new FetchHeaders(result.headers);

return new Response(result.data, {
status: result.status,
statusText: result.statusText,
headers: fetchHeaders
});
}

export function buildAxiosFetch (axios: AxiosInstance, transformer?: AxiosTransformer): AxiosFetch {
return axiosFetch.bind(undefined, axios, transformer);
}
45 changes: 45 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copied and edited from axios@0.21.1 because types aren't available in version 0.17

export type Method =
| 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
| 'options' | 'OPTIONS'
| 'post' | 'POST'
| 'put' | 'PUT'
| 'patch' | 'PATCH'
| 'purge' | 'PURGE'
| 'link' | 'LINK'
| 'unlink' | 'UNLINK';

export type ResponseType =
| 'arraybuffer'
| 'blob'
| 'document'
| 'json'
| 'text'
| 'stream';

export interface AxiosRequestConfig {
url?: string;
method?: Method;
headers?: any;
data?: any;
responseType?: ResponseType;
[key: string]: any;
}

export interface AxiosResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
config: AxiosRequestConfig;
request?: any;
}

export type AxiosPromise<T = any> = Promise<AxiosResponse<T>> & any

export interface AxiosInstance {
request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
}
Loading

0 comments on commit 9ebf8b9

Please sign in to comment.