react-redux-quest
Version:
API and generic utilities for react and redux eco-system
125 lines (99 loc) • 3.98 kB
JavaScript
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
import fetch from 'isomorphic-fetch';
import isPlainObject from 'lodash.isplainobject';
import { getTypes } from '../utils';
import { default as validate } from '../validation';
export var API = Symbol('@@API');
var isValidApiAction = function isValidApiAction(action) {
return isPlainObject(action) && action.hasOwnProperty(API);
};
// const isPromise = p => p && typeof p.then === "function";
function extractIfErrorHasBody(response) {
var error = new Error(response.statusText);
error.response = response;
var contentType = response.headers.get('content-type');
if (contentType && contentType.indexOf('application/json') === -1) {
return Promise.reject(error);
}
return response.json().then(function (json) {
error.responseJSON = json;
return Promise.reject(error);
});
}
function processResponse(response) {
return response.ok ? response.json().then(function (json) {
return Promise.resolve(json);
}) : extractIfErrorHasBody(response);
}
export function apiRequest(endpoint, options) {
return fetch(endpoint, options).then(processResponse);
}
// Options and its default values yet to be decided.
// It will be decided based on usage and need arise
// Currently `urlPrefix or apiRoot` seems to be good
function createQuestMiddleware(options) {
return function apiMiddleware(store) {
return function (next) {
return function (action) {
if (!isValidApiAction(action)) {
return next(action);
}
var settings = action[API];
var _validate = validate(settings),
isValidApiSettings = _validate.isValidApiSettings;
var types = getTypes(settings.types, settings.typePrefix);
if (!isValidApiSettings) {
return next(action);
}
var endpoint = settings.url,
meta = settings.meta,
init = _objectWithoutProperties(settings, ['url', 'meta']);
var requestType = types[0],
successType = types[1],
failureType = types[2];
var requestMeta = _extends({}, meta, {
operation: init.method
});
var requestAction = function requestAction() {
return { type: requestType, meta: requestMeta, isRequest: true };
},
successAction = function successAction(payload) {
return {
type: successType,
meta: requestMeta,
isRequest: false,
payload: payload
};
},
failureAction = function failureAction(payload) {
return {
type: failureType,
payload: payload,
meta: requestMeta,
isRequest: false,
error: true
};
};
next(requestAction());
// Not yet decideded if it is good to let configure
// This option enables user to use their choice of request library
// With `promise` support
/* if (isPromise(promise)) {
promise.then(
res => next(successAction(res)),
err => next(failureAction(err))
);
} */
fetch(endpoint, init).then(processResponse).then(function (response) {
return next(successAction(response));
}, function (error) {
return next(failureAction(error));
});
};
};
};
}
var questMiddleware = createQuestMiddleware();
questMiddleware.withOptions = createQuestMiddleware;
export default questMiddleware;