@commercetools-frontend/sdk
Version:
Tools for declarative fetching
608 lines (579 loc) • 28 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
var omitEmpty = require('omit-empty-es');
var _Reflect$construct = require('@babel/runtime-corejs3/core-js-stable/reflect/construct');
var _classCallCheck = require('@babel/runtime-corejs3/helpers/classCallCheck');
var _createClass = require('@babel/runtime-corejs3/helpers/createClass');
var _inherits = require('@babel/runtime-corejs3/helpers/inherits');
var _possibleConstructorReturn = require('@babel/runtime-corejs3/helpers/possibleConstructorReturn');
var _getPrototypeOf = require('@babel/runtime-corejs3/helpers/getPrototypeOf');
var _pt = require('prop-types');
var react = require('react');
var fastEquals = require('fast-equals');
var reactRedux = require('react-redux');
var apiRequestBuilder = require('@commercetools/api-request-builder');
var constants = require('@commercetools-frontend/constants');
var _URL = require('@babel/runtime-corejs3/core-js-stable/url');
var qss = require('qss');
var _globalThis = require('@babel/runtime-corejs3/core-js/global-this');
var buffer = require('buffer');
var createHttpUserAgent = require('@commercetools/http-user-agent');
var sdkClient = require('@commercetools/sdk-client');
var sdkMiddlewareCorrelationId = require('@commercetools/sdk-middleware-correlation-id');
var sdkMiddlewareHttp = require('@commercetools/sdk-middleware-http');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
var omitEmpty__default = /*#__PURE__*/_interopDefault(omitEmpty);
var _Reflect$construct__default = /*#__PURE__*/_interopDefault(_Reflect$construct);
var _pt__default = /*#__PURE__*/_interopDefault(_pt);
var _URL__default = /*#__PURE__*/_interopDefault(_URL);
var _globalThis__default = /*#__PURE__*/_interopDefault(_globalThis);
var createHttpUserAgent__default = /*#__PURE__*/_interopDefault(createHttpUserAgent);
function ownKeys$3(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context2 = ownKeys$3(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context3 = ownKeys$3(Object(t))).call(_context3, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
function get(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'GET'
})
};
}
// contrary to the other methods this does not bear the exact name of the HTTP-verb
// because `delete` is a reserved keyword in ECMAScript
function del(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'DELETE'
})
};
}
function head(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'HEAD'
})
};
}
function post(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'POST'
})
};
}
const enhancePayloadForForwardToProxy = payload => {
var _context;
const headers = payload.headers ?? {};
const exchangeTokenClaims = [];
if (payload.includeUserPermissions) {
exchangeTokenClaims.push('permissions');
}
return {
uri: '/proxy/forward-to',
mcApiProxyTarget: undefined,
headers: omitEmpty__default["default"](_objectSpread$3(_objectSpread$3({}, _reduceInstanceProperty__default["default"](_context = _Object$entries__default["default"](headers)).call(_context, (customForwardHeaders, _ref) => {
let _ref2 = _slicedToArray(_ref, 2),
headerName = _ref2[0],
headerValue = _ref2[1];
return _objectSpread$3(_objectSpread$3({}, customForwardHeaders), {}, {
// Prefix headers so that the MC API can allow and forward them.
[`x-forward-header-${headerName}`]: headerValue
});
}, {})), {}, {
'Accept-version': 'v2',
'X-Forward-To': payload.uri,
'X-Forward-To-Audience-Policy': payload.audiencePolicy || 'forward-url-full-path',
'X-Forward-To-Claims': exchangeTokenClaims.join(' ')
}))
};
};
const forwardTo = {
get(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'GET'
}, enhancePayloadForForwardToProxy(payload))
};
},
del(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'DELETE'
}, enhancePayloadForForwardToProxy(payload))
};
},
head(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'HEAD'
}, enhancePayloadForForwardToProxy(payload))
};
},
post(payload) {
return {
type: 'SDK',
payload: _objectSpread$3(_objectSpread$3({}, payload), {}, {
method: 'POST'
}, enhancePayloadForForwardToProxy(payload))
};
}
};
var index = /*#__PURE__*/Object.freeze({
__proto__: null,
get: get,
del: del,
head: head,
post: post,
forwardTo: forwardTo
});
function _createSuper(t) { var r = _isNativeReflectConstruct(); return function () { var e, o = _getPrototypeOf(t); if (r) { var s = _getPrototypeOf(this).constructor; e = _Reflect$construct__default["default"](o, arguments, s); } else e = o.apply(this, arguments); return _possibleConstructorReturn(this, e); }; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct__default["default"](Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); }
const defaultProps = {
actionCreatorArgs: [],
shouldRefetch: (prevArgs, nextArgs) => !fastEquals.deepEqual(prevArgs, nextArgs)
};
let SdkGet = /*#__PURE__*/function (_Component) {
_inherits(SdkGet, _Component);
var _super = _createSuper(SdkGet);
function SdkGet() {
var _this;
_classCallCheck(this, SdkGet);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call(this, ...args);
_this.state = {
// We want the component to have a loading state by default, so we
// keep track of whether the first request has completed.
// We can't use requestsInFlight only as that would lead to a flash of
// the loading state until the first request starts in componentDidMount.
isWaitingForCompletionOfFirstRequest: true,
requestsInFlight: 0,
result: undefined,
error: undefined
};
_this.isComponentMounted = false;
_this.changeRequestsInFlight = delta => {
if (_this.isComponentMounted) _this.setState(prevState => ({
requestsInFlight: prevState.requestsInFlight + delta
}));
};
_this.fetch = _ref => {
let dispatch = _ref.dispatch,
actionCreator = _ref.actionCreator,
actionCreatorArgs = _ref.actionCreatorArgs,
onSuccess = _ref.onSuccess,
onError = _ref.onError;
_this.changeRequestsInFlight(1);
return dispatch(actionCreator(...(actionCreatorArgs ?? defaultProps.actionCreatorArgs))).then(result => {
_this.changeRequestsInFlight(-1);
if (_this.isComponentMounted) _this.setState({
error: undefined,
result
});
if (onSuccess) onSuccess(result);
return result;
}, error => {
_this.changeRequestsInFlight(-1);
if (_this.isComponentMounted) _this.setState({
error,
result: undefined
});
if (onError) onError(error);else SdkGet.errorHandler(error);
});
};
_this.refresh = () => _this.fetch({
dispatch: _this.props.dispatch,
actionCreator: _this.props.actionCreator,
actionCreatorArgs: _this.props.actionCreatorArgs,
onSuccess: _this.props.onSuccess,
onError: _this.props.onError
});
return _this;
}
_createClass(SdkGet, [{
key: "componentDidMount",
value: function componentDidMount() {
this.isComponentMounted = true;
this.fetch({
dispatch: this.props.dispatch,
actionCreator: this.props.actionCreator,
actionCreatorArgs: this.props.actionCreatorArgs,
onSuccess: this.props.onSuccess,
onError: this.props.onError
}).then(result => {
if (this.isComponentMounted) this.setState({
isWaitingForCompletionOfFirstRequest: false
});
return result;
}, error => {
if (this.isComponentMounted) this.setState({
isWaitingForCompletionOfFirstRequest: false
});
throw error;
});
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
const shouldRefetch = this.props.shouldRefetch ?? defaultProps.shouldRefetch;
if (shouldRefetch(prevProps.actionCreatorArgs ?? defaultProps.actionCreatorArgs, this.props.actionCreatorArgs ?? defaultProps.actionCreatorArgs)) {
this.fetch({
dispatch: this.props.dispatch,
actionCreator: this.props.actionCreator,
actionCreatorArgs: this.props.actionCreatorArgs,
onSuccess: this.props.onSuccess,
onError: this.props.onError
});
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.isComponentMounted = false;
}
}, {
key: "render",
value: function render() {
return this.props.render({
isLoading: this.state.requestsInFlight > 0 || this.state.isWaitingForCompletionOfFirstRequest,
refresh: this.refresh,
result: this.state.result,
error: this.state.error
});
}
}]);
return SdkGet;
}(react.Component);
SdkGet.displayName = 'SdkGet';
SdkGet.errorHandler = error => {
throw error;
};
SdkGet.propTypes = process.env.NODE_ENV !== "production" ? {
dispatch: _pt__default["default"].func.isRequired,
actionCreator: _pt__default["default"].func.isRequired,
actionCreatorArgs: _pt__default["default"].arrayOf(_pt__default["default"].any),
shouldRefetch: _pt__default["default"].func,
onSuccess: _pt__default["default"].func,
onError: _pt__default["default"].func,
render: _pt__default["default"].func.isRequired
} : {};
const mapDispatchToProps = dispatch => ({
dispatch
});
var SdkGet$1 = reactRedux.connect(null, mapDispatchToProps)(SdkGet);
// NOTE: This string will be replaced on build time with the package version.
var version = "24.2.1";
/* eslint-disable no-console */
const isLoggerEnabled = () => {
if (process.env.DEBUG === 'true') return true;
if (process.env.NODE_ENV === 'development') return true;
const queryParams = new _URL__default["default"](window.location.href);
if (process.env.NODE_ENV === 'production' && queryParams.searchParams.get('debug') === 'true') return true;
return false;
};
const logger = {
groupCollapsed: function () {
return isLoggerEnabled() && console.groupCollapsed(...arguments);
},
groupEnd: () => isLoggerEnabled() && console.groupEnd(),
info: function () {
return isLoggerEnabled() && console.info(...arguments);
},
log: function () {
return isLoggerEnabled() && console.log(...arguments);
},
error: function () {
return isLoggerEnabled() && console.error(...arguments);
},
warn: function () {
return isLoggerEnabled() && console.warn(...arguments);
}
};
function ownKeys$2(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context = ownKeys$2(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context2 = ownKeys$2(Object(t))).call(_context2, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
const parseUri = uri => {
const parser = document.createElement('a');
parser.href = uri;
return {
pathname: parser.pathname,
search: qss.decode(parser.search.substring(1))
};
};
const isPostAction = action => action.payload.method === 'POST';
const logRequest = _ref => {
let method = _ref.method,
request = _ref.request,
response = _ref.response,
error = _ref.error,
action = _ref.action;
const uriParts = parseUri(request.uri);
const groupName = `%c${method} %c${uriParts.pathname}`;
logger.groupCollapsed(groupName, `color: ${error ? 'red' : 'black'}; font-weight: bold;`, 'color: gray; font-weight: lighter;');
logger.log('%caction', 'color: cadetblue; font-weight: bold;', action);
logger.log('%crequest', `color: cornflowerblue; font-weight: bold;`, _objectSpread$2({
headers: request.headers,
uri: request.uri,
params: uriParts.search
}, isPostAction(action) ? {
body: action.payload.payload
} : {}));
if (response) logger.log('%cresponse', `color: green; font-weight: bold;`, response);
if (error) logger.log('%cerror', `color: red; font-weight: bold;`, error);
logger.groupEnd();
};
const mcHostnameRegex = /^mc(-(\d){4,})?\.(.*)$/;
const mcPreviewHostnameRegex = /^.*\.mc-preview\.(.*)$/;
const getMcOriginTld = host => {
if (host.match(mcPreviewHostnameRegex)) {
return host.replace(mcPreviewHostnameRegex, '$1');
}
return host.replace(mcHostnameRegex, '$3');
};
const getMcApiUrlFromOrigin = actualWindow => {
const url = new _URL__default["default"](actualWindow.origin);
const originTld = getMcOriginTld(url.host);
return `${url.protocol}//mc-api.${originTld}`;
};
const parseAsBoolean = value => value === true || value === 'true';
function getMcApiUrl() {
let actualWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
const isServedByProxy = parseAsBoolean(actualWindow.app.servedByProxy);
/**
* Prefer using the origin URL for the MC API based on the origin value
* of the browser's `window.location`.
* This ensures that the application always uses the correct URL associated
* with that environment, instead of relying on the config value.
*/
if (isServedByProxy) {
return getMcApiUrlFromOrigin(actualWindow);
}
return actualWindow.app.mcApiUrl;
}
function ownKeys$1(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context = ownKeys$1(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context2 = ownKeys$1(Object(t))).call(_context2, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
// This is currently required by @commercetools/sdk-middleware-http package
_globalThis__default["default"].Buffer = buffer.Buffer;
const userAgent = createHttpUserAgent__default["default"]({
name: '@commercetools/sdk-client',
libraryName: [typeof window !== 'undefined' ? window.app.applicationName : 'unknown-application-name', 'sdk'].join('/'),
libraryVersion: version,
contactUrl: 'https://git.io/fjuyC',
// points to the appkit repo issues
contactEmail: 'mc@commercetools.com'
});
const customUserAgentMiddleware = next => (request, response) => {
const requestWithCustomUserAgent = _objectSpread$1(_objectSpread$1({}, request), {}, {
headers: _objectSpread$1(_objectSpread$1({}, request.headers), {}, {
'X-User-Agent': userAgent
})
});
next(requestWithCustomUserAgent, response);
};
// NOTE we should not use these directly but rather have them passed in from
// the application
const httpMiddleware = sdkMiddlewareHttp.createHttpMiddleware({
host: getMcApiUrl(),
includeResponseHeaders: true,
credentialsMode: 'include',
fetch
});
const createCorrelationIdMiddleware = _ref => {
let getCorrelationId = _ref.getCorrelationId;
return sdkMiddlewareCorrelationId.createCorrelationIdMiddleware({
generate: getCorrelationId
});
};
const createClient = _ref2 => {
let getCorrelationId = _ref2.getCorrelationId;
return sdkClient.createClient({
middlewares: [createCorrelationIdMiddleware({
getCorrelationId
}), customUserAgentMiddleware, httpMiddleware]
});
};
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context2 = ownKeys(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context3 = ownKeys(Object(t))).call(_context3, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
const isSdkActionForUri = actionPayload => actionPayload.uri !== undefined;
// https://github.com/commercetools/nodejs/blob/master/packages/api-request-builder/src/default-services.js#L200:L200
const ORDER_EDIT_SERVICE = 'orderEdits';
const actionToUri = (action, projectKey) => {
if (isSdkActionForUri(action.payload)) return action.payload.uri;
// Validate that `projectKey` exists
if (!projectKey) {
throw new Error(`Expected projectKey to be defined for action service "${action.payload.service}" (method "${action.payload.method}")`);
}
const requestBuilder = apiRequestBuilder.createRequestBuilder({
projectKey
});
// NOTE it's weird that we have to access this from the request builder.
// Shouldn't it just be a part of the object we parse?
// NOTE shouldn't requestBuilder be called requestUriBuilder instead?
const service = requestBuilder[action.payload.service];
if (action.payload.options) service.parse(action.payload.options);
return service.build({
// given `service=orderEdits` and given `applyOrderEditTo`, we build an apply endpoint
// given `service=orderEdits` and no `applyOrderEditTo`, we build an update endpoint
// https://docs.commercetools.com/api/projects/order-edits
applyOrderEdit: action.payload.service === ORDER_EDIT_SERVICE && typeof action.payload.options?.applyOrderEditTo === 'string',
// at this stage, the `projectKey` should be available already.
withProjectKey: true
});
};
// Force TS cast of generic action to TNotificationAction
const isSdkAction = action => action.type === 'SDK';
const isSdkError = error => error.statusCode !== undefined;
function createSdkMiddleware(_ref) {
let getCorrelationId = _ref.getCorrelationId,
getProjectKey = _ref.getProjectKey,
getAdditionalHeaders = _ref.getAdditionalHeaders;
const client = createClient({
getCorrelationId
});
const middleware = _ref2 => {
let dispatch = _ref2.dispatch;
return next => action => {
var _context;
if (!isSdkAction(action)) {
return next(action);
}
const projectKey = getProjectKey();
const uri = _filterInstanceProperty__default["default"](_context = [action.payload.mcApiProxyTarget && `/proxy/${action.payload.mcApiProxyTarget}`, actionToUri(action, projectKey)]).call(_context, Boolean).join('');
// This `requestName` is never really used.
//
// We keep track of requests which are in progress in the `loading` state of
// the application. The `loading` state is an array of strings
// (which are correlation Ids, action types or request names).
// This is just done so that debugging is easier.
//
// It's easier to debug
// loading: ['PRODUCTS_FETCHED', 'sdk.fetch(/product-projection-search)']
// than to debug
// loading: 2
const requestName = `sdk.${action.payload.method.toLowerCase()}(${uri})`;
// NOTE here the middleware is aware of the application
// Instead we should probably convert to a middleware factory
// and provide hooks for `onFetch`, `onResult` and `onError
dispatch({
type: constants.SHOW_LOADING,
payload: requestName
});
// NOTE the promise returned by the client resolves to a custom format
// it will contain { statusCode, headers, body }
// NOTE This retry logic could be moved to an sdk client middleware,
// but the client's middleware system is not capable of that right now
// https://github.com/commercetools/merchant-center-frontend/pull/3304
// https://github.com/commercetools/nodejs/issues/390
const sendRequest = function () {
let _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
shouldRenewToken = _ref3.shouldRenewToken;
const additionalHeaders = getAdditionalHeaders();
const headers = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
Accept: 'application/json'
}, action.payload.headers || {}), shouldRenewToken ? {
'X-Force-Token': 'true'
} : {}), projectKey && {
'X-Project-Key': projectKey
}), additionalHeaders ?? {});
const body = action.payload.method === 'POST' ? action.payload.payload : undefined;
return client.execute({
uri,
method: action.payload.method,
headers,
body
}).then(result => {
if (process.env.NODE_ENV === 'development') logRequest({
method: action.payload.method,
request: {
headers,
uri
},
response: result.body,
action
});
return result;
}, error => {
if (process.env.NODE_ENV === 'development') logRequest({
method: action.payload.method,
request: {
headers,
uri
},
error,
action
});
throw error;
});
};
return sendRequest().catch(error => {
// in case of 401 error, try again with a new token
// https://github.com/commercetools/merchant-center-backend/blob/master/docs/AUTHENTICATION.md#problems-due-to-oauth-token-caching
if (isSdkError(error) && error.statusCode === constants.STATUS_CODES.UNAUTHORIZED) {
return sendRequest({
shouldRenewToken: true
});
}
throw error;
}).then(result => {
dispatch({
type: constants.HIDE_LOADING,
payload: requestName
});
// The promise returned by "fetch" will reject when the request fails,
// but only in certain cases. See "Checking that the fetch was successful"
// in https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
// The SDK already handles this case for us.
return result.body;
}, error => {
dispatch({
type: constants.HIDE_LOADING,
payload: requestName
});
throw error;
});
};
};
return middleware;
}
// Wraps `dispatch` and cast the return type to a Promise, as the middleware
// returns a Promise.
function useAsyncDispatch() {
const dispatch = reactRedux.useDispatch();
return dispatch;
}
const Sdk = {
Get: SdkGet$1
};
exports.Sdk = Sdk;
exports.actions = index;
exports.createMiddleware = createSdkMiddleware;
exports.useAsyncDispatch = useAsyncDispatch;
exports.version = version;