Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
"extends": "airbnb-base",
"env": {
"mocha": true
}
};
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: node_js
node_js:
- "5"
- "8"
57 changes: 19 additions & 38 deletions lib/RequestMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
var digest = require('./digest')
var jsonDB = require('./jsonDb')
/* eslint-disable no-param-reassign */
const digest = require('./digest');
const jsonDB = require('./jsonDb');

function loadFixture(cassettePath, axiosConfig) {
var requestKey = digest(axiosConfig)
return jsonDB.loadAt(cassettePath, requestKey)
}
const loadFixture = (cassettePath, axiosConfig) => {
const requestKey = digest(axiosConfig);
return jsonDB.loadAt(cassettePath, requestKey);
};

function injectVCRHeader(axiosConfig) {
// This is done like this because Axios injects a custom User-Agent in
// the request config if it hasn't been defined by the client.
//
// We need to do the same thing and inject our own so Axios doesn't modify
// the request config object at a later point (which breaks our logic because
// digests will be different at request and response times)
exports.success = cassettePath =>
axiosConfig =>
loadFixture(cassettePath, axiosConfig)
.then((cassette) => {
axiosConfig.adapter = () =>
new Promise((resolve) => {
cassette.originalResponseData.fixture = true;
return resolve(cassette.originalResponseData);
});
return axiosConfig;
}).catch(() => axiosConfig);

var headers = axiosConfig.headers
if (!headers['User-Agent'] && !headers['user-agent']) {
headers['User-Agent'] = 'axios-vcr'
}
}

exports.success = function (cassettePath) {
return function(axiosConfig) {
injectVCRHeader(axiosConfig)

return loadFixture(cassettePath, axiosConfig).then(function(cassette) {
axiosConfig.adapter = function(resolve, _reject, _cfg) {
cassette.originalResponseData.fixture = true
return resolve(cassette.originalResponseData)
}
return axiosConfig
}).catch(function(err) {
return axiosConfig
})
}
}

exports.failure = function(error) {
return Promise.reject(error)
}
exports.failure = error => Promise.reject(error);
52 changes: 24 additions & 28 deletions lib/ResponseMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
var jsonDB = require('./jsonDb')
var digest = require('./digest')
const jsonDB = require('./jsonDb');
const digest = require('./digest');

function serialize(response) {
var meta = {
const serialize = (response) => {
const meta = {
url: response.config.url,
method: response.config.method,
data: response.config.data,
headers: response.config.headers
}
headers: response.config.headers,
};

return {
meta: meta,
meta,
fixture: true,

originalResponseData: {
status: response.status,
statusText: response.statusText,
headers: response.headers,
data: response.data,
config: meta
}
}
}
config: meta,
},
};
};

function storeFixture(cassettePath, response) {
var requestKey = digest(response.config)
var fixture = serialize(response)
return jsonDB.writeAt(cassettePath, requestKey, fixture)
}
const storeFixture = (cassettePath, response) => {
const requestKey = digest(response.config);
const fixture = serialize(response);
return jsonDB.writeAt(cassettePath, requestKey, fixture);
};

exports.success = function (cassettePath) {
return function(res) {
if (res.fixture)
return res
exports.success = cassettePath =>
(res) => {
if (res.fixture) {
return res;
}

return storeFixture(cassettePath, res).then(function() {
return res
})
}
}
return storeFixture(cassettePath, res).then(() => res);
};

exports.failure = function(error) {
return Promise.reject(error)
}
exports.failure = error => Promise.reject(error);
55 changes: 39 additions & 16 deletions lib/digest.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,44 @@
var md5 = require('md5')
var _ = require('lodash')
const md5 = require('md5');
const _ = require('lodash');

function key(axiosConfig) {
//Content-Length is calculated automatically by Axios before sending a request
//We don't want to include it here because it could be changed by axios
const key = (args) => {
const {
baseURL, method, data, transformRequest,
} = args;
let { url, headers = {} } = args;
// Flatten headers
// Same happening in dispatchResponse.js


var baseConfig = {
url: axiosConfig.url,
method: axiosConfig.method,
data: axiosConfig.data,
headers: _.omit(axiosConfig.headers, [
'Content-Length', 'content-length'
])
// Support baseURL config
if (baseURL && !/^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)) {
url = url
? `${baseURL.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}`
: baseURL;
}

return md5(JSON.stringify(baseConfig))
}
headers = _.merge(
headers.common || {},
headers[method] || {},
headers || {},
);

headers = _.omit(
headers,
['delete', 'get', 'head', 'post', 'put', 'patch', 'common',
// Content-Length is calculated automatically by Axios before sending a request
// We don't want to include it here because it could be changed by axios
'Content-Length', 'content-length',
],
);

const baseConfig = {
url,
method,
data: _.values(transformRequest).reduce((nextData, fn) => fn(nextData, headers), data),
headers,
};

return md5(JSON.stringify(baseConfig));
};

module.exports = key
module.exports = key;
69 changes: 36 additions & 33 deletions lib/jsonDb.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
var fs = require('fs-promise')
var _ = require('lodash')
var mkdirp = require('mkdirp')
var getDirName = require('path').dirname

function loadAt(filePath, jsonPath) {
return fs.readJson(filePath).then(function(json) {
if (_.isUndefined(jsonPath))
return json

var value = _.get(json, jsonPath)
if (!_.isUndefined(value))
return value
else
throw "Invalid JSON Path"
})
}

function writeAt(filePath, jsonPath, value) {
mkdirp.sync(getDirName(filePath))

return fs.readJson(filePath).then(function(json) {
_.set(json, jsonPath, value)
return fs.writeJson(filePath, json)
}).catch(function(error) {
var json = {}
_.set(json, jsonPath, value)
return fs.writeJson(filePath, json)
})
}

const _ = require('lodash');
const mkdirp = require('mkdirp');
const getDirName = require('path').dirname;

const { readJson, writeJson } = require('./readWriteJson');

const loadAt = (filePath, jsonPath) =>
readJson(filePath).then((json) => {
if (_.isUndefined(jsonPath)) {
return json;
}

const value = _.get(json, jsonPath);
if (!_.isUndefined(value)) {
return value;
}

throw new Error('Invalid JSON Path');
});

const writeAt = (filePath, jsonPath, value) => {
mkdirp.sync(getDirName(filePath));

return readJson(filePath).then((json) => {
_.set(json, jsonPath, value);
return writeJson(filePath, json);
}).catch(() => {
const json = {};
_.set(json, jsonPath, value);
return writeJson(filePath, json);
});
};

module.exports = {
loadAt: loadAt,
writeAt: writeAt
}
loadAt,
writeAt,
};
9 changes: 9 additions & 0 deletions lib/readWriteJson.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const util = require('util');
const fs = require('fs');

const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const readJson = filePath => readFile(filePath, 'utf8').then(data => JSON.parse(data));
const writeJson = (filePath, json) => writeFile(filePath, JSON.stringify(json));

module.exports = { readJson, writeJson };
1 change: 1 addition & 0 deletions mocha.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require test/setup.js
18 changes: 12 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "index.js",
"homepage": "http://github.com/nettofarah/axios-vcr",
"scripts": {
"test": "mocha test/"
"test": "npm run lint && mocha test/",
"lint": "eslint test/ lib/"
},
"bugs": {
"url": "https://github.com/nettofarah/axios-vcr/issues"
Expand All @@ -15,9 +16,9 @@
"url": "https://github.com/nettofarah/axios-vcr.git"
},
"files": [
"index.js",
"lib"
],
"index.js",
"lib"
],
"keywords": [
"axios",
"vcr",
Expand All @@ -28,12 +29,17 @@
"author": "Netto Farah",
"license": "MIT",
"devDependencies": {
"axios": "^0.11.1",
"axios": "^0.17.0",
"eslint": "^4.10.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.8.0",
"mocha": "^2.5.3",
"rimraf": "^2.5.2"
},
"peerDependencies": {
"axios": "^0.17.0"
},
"dependencies": {
"fs-promise": "^0.5.0",
"lodash": "^4.13.1",
"md5": "^2.1.0",
"mkdirp": "^0.5.1"
Expand Down
Loading