Skip to content

Commit

Permalink
feat(request): CHECKOUT-2738 Add RequestSender
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchin committed Dec 22, 2017
1 parent f4fb86e commit 8c953bd
Show file tree
Hide file tree
Showing 22 changed files with 4,671 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.log
/coverage
/node_modules
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
language: node_js

node_js: 6

cache: yarn

dist: trusty

sudo: false

before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 0.27.5
- export PATH=$HOME/.yarn/bin:$PATH

script: yarn travis
6 changes: 6 additions & 0 deletions commit-validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"scopes": [
"common",
"request"
]
}
33 changes: 33 additions & 0 deletions eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"parser": "typescript-eslint-parser",
"env": {
"browser": true,
"es6": true,
"jest": true
},
"extends": "airbnb/base",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
},
"rules": {
"consistent-return": "off",
"indent": [2, 4],
"max-len": [0],
"no-console": "off",
"no-param-reassign": [2, { "props": false }],
"no-throw-literal": [0],
"no-shadow": "off",
"no-unused-expressions": "off",
"no-use-before-define": [2, "nofunc"],
"quote-props": [2, "consistent-as-needed"],
"valid-jsdoc": [
2,
{
"requireParamDescription": false,
"requireReturnDescription": false
}
]
}
}
30 changes: 30 additions & 0 deletions jest-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
browser: true,
transform: {
'\\.(ts|js)$': '<rootDir>/node_modules/ts-jest/preprocessor.js',
},
moduleFileExtensions: [
'ts',
'tsx',
'js',
'jsx',
'json',
],
testRegex: '.*\\.spec.(js|ts)$',
setupTestFrameworkScriptFile: '<rootDir>/jest-setup.js',
collectCoverageFrom: [
'src/**/*.{js,ts}',
],
coveragePathIgnorePatterns: [
'\\.mock\\.(js|ts)$',
'\\.typedef\\.(js|ts)$',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};
3 changes: 3 additions & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
beforeAll(() => {
expect.hasAssertions();
});
56 changes: 56 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@bigcommerce/request-sender",
"version": "0.0.0",
"main": "lib/index.js",
"files": [
"lib/"
],
"engines": {
"node": "^6.10.0",
"yarn": "^0.27.5"
},
"repository": {
"type": "git",
"url": "git://github.com/bigcommerce/request-sender-js.git"
},
"author": "BigCommerce",
"bugs": {
"url": "https://github.com/bigcommerce/request-sender-js/issues"
},
"homepage": "https://github.com/bigcommerce/request-sender-js",
"scripts": {
"prebuild": "yarn lint && yarn test",
"build": "yarn compile",
"precompile": "rm -rf lib",
"compile": "tsc --outDir lib",
"compile:watch": "yarn compile -- --watch",
"lint": "eslint src --config eslintrc.json",
"prerelease": "git fetch --tags && yarn validate-dependencies && yarn validate-commits && yarn build",
"release": "git add dist lib && standard-version -a",
"test": "jest --config jest-config.js",
"test:coverage": "yarn test -- --coverage",
"test:series": "yarn test -- --runInBand",
"test:watch": "yarn test -- --watch",
"travis": "yarn lint && yarn test:series -- --coverage",
"validate-commits": "validate-commits",
"validate-dependencies": "yarn install --check-files --frozen-lockfile"
},
"dependencies": {
"is-promise": "^2.1.0",
"js-cookie": "^2.1.4",
"query-string": "^5.0.0",
"tslib": "^1.8.0"
},
"devDependencies": {
"eslint": "2.8.0",
"eslint-config-airbnb": "6.0.2",
"eslint-plugin-react": "4.1.0",
"jest": "^21.2.1",
"standard-version": "^4.2.0",
"ts-jest": "^21.2.3",
"ts-loader": "^3.2.0",
"typescript": "^2.6.2",
"typescript-eslint-parser": "^9.0.1",
"validate-commits": "git+ssh://[email protected]/bigcommerce-labs/validate-commits.git#1.1.0"
}
}
24 changes: 24 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as cookie from 'js-cookie';
import RequestFactory from './request-factory';
import RequestSender from './request-sender';
import PayloadTransformer from './payload-transformer';
import Timeout from './timeout';

/**
* @return {RequestSender}
*/
export function createRequestSender() {
return new RequestSender(
new RequestFactory(),
new PayloadTransformer(),
cookie
);
}

/**
* @param {number} [delay]
* @return {Timeout}
*/
export function createTimeout(delay) {
return new Timeout(delay);
}
86 changes: 86 additions & 0 deletions src/payload-transformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const JSON_CONTENT_TYPE_REGEXP = /application\/(\w+\+)?json/;

export default class PayloadTransformer {
/**
* @param {RequestOptions} options
* @returns {any}
*/
toRequestBody(options) {
const contentType = this._getHeader(options.headers, 'Content-Type');

if (options.body && JSON_CONTENT_TYPE_REGEXP.test(contentType)) {
return JSON.stringify(options.body);
}

return options.body;
}

/**
* @param {XMLHttpRequest} xhr
* @returns {Response}
*/
toResponse(xhr) {
const headers = this._parseResponseHeaders(xhr.getAllResponseHeaders());
const body = this._parseResponseBody('response' in xhr ? xhr.response : xhr.responseText, headers);

return {
body,
headers,
status: xhr.status,
statusText: xhr.statusText,
};
}

/**
* @private
* @param {string} body
* @param {Object} headers
* @return {any}
*/
_parseResponseBody(body, headers) {
const contentType = this._getHeader(headers, 'Content-Type');

if (body && JSON_CONTENT_TYPE_REGEXP.test(contentType)) {
return JSON.parse(body);
}

return body;
}

/**
* @private
* @param {string} rawHeaders
* @return {Object}
*/
_parseResponseHeaders(rawHeaders) {
const lines = rawHeaders ? rawHeaders.replace(/\r?\n[\t ]+/g, ' ').split(/\r?\n/) : [];

return lines.reduce((headers, line) => {
const parts = line.split(':');
const key = parts.shift().trim();

if (!key) {
return headers;
}

return {
...headers,
[key.toLowerCase()]: parts.join(':').trim(),
};
}, {});
}

/**
* @private
* @param {Object} headers
* @param {string} key
* @return {string}
*/
_getHeader(headers, key) {
if (!headers || !key) {
return '';
}

return headers[key] || headers[key.toLowerCase()] || '';
}
}
Loading

0 comments on commit 8c953bd

Please sign in to comment.