@commercetools-frontend/application-shell-connectors
Version:
Contains complementary tools for @commercetools-frontend/application-shell
955 lines (907 loc) • 53.9 kB
JavaScript
import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty';
import _pt from 'prop-types';
import { createContext, useContext, useMemo, useEffect } from 'react';
import moment from 'moment-timezone';
import { reportErrorToSentry } from '@commercetools-frontend/sentry';
import _URL from '@babel/runtime-corejs3/core-js-stable/url';
import _slicedToArray from '@babel/runtime-corejs3/helpers/esm/slicedToArray';
import _reduceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/reduce';
import _Object$entries from '@babel/runtime-corejs3/core-js-stable/object/entries';
import _valuesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/values';
import { jsx } from '@emotion/react/jsx-runtime';
import { useQuery, useLazyQuery, useMutation } from '@apollo/client/react';
import warning from 'tiny-warning';
import { GRAPHQL_TARGETS, SUPPORTED_HEADERS, STATUS_CODES, LOGOUT_REASONS, STORAGE_KEYS, LOGIN_STRATEGY_OIDC } from '@commercetools-frontend/constants';
import _findInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/find';
import { ApolloLink, ApolloClient, InMemoryCache, createHttpLink, from } from '@apollo/client';
import loggerLink from 'apollo-link-logger';
import { onError } from '@apollo/client/link/error';
import history from '@commercetools-frontend/browser-history';
import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
import _someInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/some';
import _Object$values from '@babel/runtime-corejs3/core-js-stable/object/values';
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
import createHttpUserAgent from '@commercetools/http-user-agent';
import omitEmpty from 'omit-empty-es';
import { v4 } from 'uuid';
import _Reflect$construct from '@babel/runtime-corejs3/core-js-stable/reflect/construct';
import _createClass from '@babel/runtime-corejs3/helpers/esm/createClass';
import _classCallCheck from '@babel/runtime-corejs3/helpers/esm/classCallCheck';
import _assertThisInitialized from '@babel/runtime-corejs3/helpers/esm/assertThisInitialized';
import _inherits from '@babel/runtime-corejs3/helpers/esm/inherits';
import _possibleConstructorReturn from '@babel/runtime-corejs3/helpers/esm/possibleConstructorReturn';
import _getPrototypeOf from '@babel/runtime-corejs3/helpers/esm/getPrototypeOf';
import _wrapNativeSuper from '@babel/runtime-corejs3/helpers/esm/wrapNativeSuper';
import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
import { RetryLink } from '@apollo/client/link/retry';
// NOTE: This string will be replaced on build time with the package version.
var version = "24.2.0";
// From https://github.com/acdlite/recompose/blob/master/src/packages/recompose/getDisplayName.js
const getDisplayName = Component => {
if (typeof Component === 'string') {
return Component;
}
if (!Component) {
return undefined;
}
return Component.displayName || Component.name || 'Component';
};
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 = origin => {
const url = new _URL(origin);
const originTld = getMcOriginTld(url.host);
return `${url.protocol}//mc-api.${originTld}`;
};
const parseAsBoolean = value => value === true || value === 'true';
function getMcApiUrl() {
let environment = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.app;
let origin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.origin;
const isServedByProxy = parseAsBoolean(environment.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(origin);
}
return environment.mcApiUrl;
}
function ownKeys$7(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context2 = ownKeys$7(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context3 = ownKeys$7(Object(t))).call(_context3, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
// Menu visibilities
// Permissions
// Action rights
// Data fences
/**
* NOTE:
*
* Permissions and menu visibilities are being fetched though the `allAppliedPermissions`
* and the `allAppliedMenuVisibilities` which both return an array of `{ name: string, value: boolean }`.
* This gives more flexibility to introduce new values to apps without having to release
* the merchant-center-app-kit by adding/exposing them from the mc-be (our proxy service).
*
* The application below however expects both permissions an menu visibilities to be of the shape
* `[name: string]: boolean` which is what the shape above is mapped into here. This object shape is easier
* to work with in application level code (while be a non breaking change to other packages) as you can just
* do `canViewProducts`.
*
* This function considering its concern belongs into the `permissions` package. However,
* for now it doesn't have to be shared and as a result can be co-located with
* the fetching logic. Given this mapping needs to be used elsewere feel free
* to move this over to `permissions` and export it there.
*/
const normalizeAllAppliedPermissions = allAppliedPermissions => {
if (!allAppliedPermissions || allAppliedPermissions.length === 0) {
return null;
}
return _reduceInstanceProperty(allAppliedPermissions).call(allAppliedPermissions, (transformedAllApplied, allApplied) => {
if (!allApplied) return transformedAllApplied;
return _objectSpread$7(_objectSpread$7({}, transformedAllApplied), {}, {
[allApplied.name]: allApplied.value
});
}, {});
};
const normalizeAllAppliedMenuVisibilities = allAppliedMenuVisibilities => {
if (!allAppliedMenuVisibilities || allAppliedMenuVisibilities.length === 0) {
return null;
}
return _reduceInstanceProperty(allAppliedMenuVisibilities).call(allAppliedMenuVisibilities, (transformedAllApplied, allApplied) => {
if (!allApplied) return transformedAllApplied;
return _objectSpread$7(_objectSpread$7({}, transformedAllApplied), {}, {
[allApplied.name]: allApplied.value
});
}, {});
};
const normalizeAllAppliedActionRights = allAppliedActionRights => {
if (!allAppliedActionRights || allAppliedActionRights.length === 0) {
return null;
}
return _reduceInstanceProperty(allAppliedActionRights).call(allAppliedActionRights, (transformedAllApplied, allApplied) => {
if (!allApplied) return transformedAllApplied;
const previousAllAppliedGroup = transformedAllApplied[allApplied.group];
return _objectSpread$7(_objectSpread$7({}, transformedAllApplied), {}, {
[allApplied.group]: _objectSpread$7(_objectSpread$7({}, previousAllAppliedGroup), {}, {
[allApplied.name]: allApplied.value
})
});
}, {});
};
const normalizeAppliedDataFencesForStoresByResourceType = dataFences => {
var _context;
const groupedByResourceType = _reduceInstanceProperty(dataFences).call(dataFences, (previousGroupsOfSameType, appliedDataFence) => {
if (!appliedDataFence) return previousGroupsOfSameType;
const previousGroup = previousGroupsOfSameType[appliedDataFence.group];
return _objectSpread$7(_objectSpread$7({}, previousGroupsOfSameType), {}, {
[appliedDataFence.group]: [...(previousGroup || []), appliedDataFence]
});
}, {});
return _reduceInstanceProperty(_context = _Object$entries(groupedByResourceType)).call(_context, (previousGroupedByResourceType, _ref) => {
let _ref2 = _slicedToArray(_ref, 2),
resourceType = _ref2[0],
dataFences = _ref2[1];
const groupByDataFenceName = _reduceInstanceProperty(dataFences).call(dataFences, (nextDataFenceValues, dataFence) => {
const dataFenceByName = nextDataFenceValues[dataFence.name] || {
values: []
};
return _objectSpread$7(_objectSpread$7({}, nextDataFenceValues), {}, {
[dataFence.name]: _objectSpread$7(_objectSpread$7({}, dataFenceByName), {}, {
values: [..._valuesInstanceProperty(dataFenceByName), dataFence.value]
})
});
}, {});
return _objectSpread$7(_objectSpread$7({}, previousGroupedByResourceType), {}, {
[resourceType]: groupByDataFenceName
});
}, {});
};
// input:
// [
// {
// type: 'store',
// name: 'canManageOrders',
// value: 'usa',
// group: 'orders',
// },
// {
// type: 'store',
// name: 'canManageOrders',
// value: 'germany',
// group: 'orders',
// },
// {
// type: 'store',
// name: 'canViewOrders',
// value: 'canada',
// group: 'orders',
// },
// ]
// output:
// {
// store: {
// orders: {
// canManageOrders: { values: ['usa', 'germany'] },
// canViewOrders: { values: ['canada'] },
// }
// }
// }
const normalizeAllAppliedDataFences = allAppliedDataFences => {
if (!allAppliedDataFences || allAppliedDataFences.length === 0) {
return null;
}
const groupedByType = _reduceInstanceProperty(allAppliedDataFences).call(allAppliedDataFences, (previousGroupsOfSameType, appliedDataFence) => {
if (!appliedDataFence) return previousGroupsOfSameType;
const previousGroup = previousGroupsOfSameType[appliedDataFence.type];
return _objectSpread$7(_objectSpread$7({}, previousGroupsOfSameType), {}, {
[appliedDataFence.type]: [...(previousGroup || []), appliedDataFence]
});
}, {});
const normalizedDataFences = _objectSpread$7({}, 'store' in groupedByType ? {
store: normalizeAppliedDataFencesForStoresByResourceType(groupedByType.store)
} : {});
if (_Object$keys(normalizedDataFences).length > 0) return normalizedDataFences;
return null;
};
function ownKeys$6(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$6(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys$6(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys$6(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
const Context$2 = /*#__PURE__*/createContext({});
const defaultTimeZone = moment.tz.guess() || 'Etc/UTC';
// Expose only certain fields as some of them are only meant to
// be used internally in the AppShell
const mapUserToApplicationContextUser = user => {
if (!user) return null;
let applicationContextUser = {
id: user.id,
email: user.email,
createdAt: user.createdAt,
firstName: user.firstName,
lastName: user.lastName,
businessRole: user.businessRole,
// NOTE: this is an alias for the original field `user.language` but it's actually
// a locale (language + country).
locale: user.language,
timeZone: user.timeZone || defaultTimeZone,
projects: user.projects
};
// This property will only be populated when user has logged in using SSO
if (user.idTokenUserInfo) {
let additionalClaims = {};
try {
additionalClaims = JSON.parse(user.idTokenUserInfo.additionalClaims || '{}');
} catch (error) {
reportErrorToSentry(new Error('@commercetools-frontend/application-shell-connectors: Could not parse received user sso token additional claims from server.'), {
extra: {
receivedAdditionalClaims: user.idTokenUserInfo.additionalClaims
}
});
}
applicationContextUser.idTokenUserInfo = _objectSpread$6(_objectSpread$6({}, user.idTokenUserInfo), {}, {
additionalClaims
});
}
return applicationContextUser;
};
// Adjust certain fields which depend e.g. on the origin
const mapEnvironmentToApplicationContextEnvironment = (environment, origin) => _objectSpread$6(_objectSpread$6({}, environment), {}, {
// NOTE: The `mcApiUrl` depends on `servedByProxy`
mcApiUrl: getMcApiUrl(environment, origin)
});
// Expose only certain fields as some of them are only meant to
// be used internally in the AppShell
const mapProjectToApplicationContextProject = project => {
if (!project) return null;
return {
key: project.key,
version: project.version,
name: project.name,
countries: project.countries,
currencies: project.currencies,
languages: project.languages,
ownerId: project.owner.id,
ownerName: project.owner.name,
sampleDataImportDataset: project.sampleDataImportDataset,
isUserAdminOfCurrentProject: project.isUserAdminOfCurrentProject,
isProductionProject: project.isProductionProject
};
};
const createApplicationContext = (environment, user, project, projectDataLocale) => ({
environment: mapEnvironmentToApplicationContextEnvironment(environment),
user: mapUserToApplicationContextUser(user),
project: mapProjectToApplicationContextProject(project),
permissions: normalizeAllAppliedPermissions(project?.allAppliedPermissions),
actionRights: normalizeAllAppliedActionRights(project?.allAppliedActionRights),
dataFences: normalizeAllAppliedDataFences(project?.allAppliedDataFences),
dataLocale: projectDataLocale || null
});
const ApplicationContextProvider = props => jsx(Context$2.Provider, {
value: createApplicationContext(props.environment, props.user, props.project, props.projectDataLocale),
children: props.children
});
ApplicationContextProvider.propTypes = process.env.NODE_ENV !== "production" ? {
projectDataLocale: _pt.string,
children: _pt.node.isRequired
} : {};
ApplicationContextProvider.displayName = 'ApplicationContextProvider';
const ApplicationContext = props => jsx(Context$2.Consumer, {
children: context => {
// Because of the way the ApplicationShell configures the Context.Provider,
// we ensure that, when we read from the context, we always get actual
// context object and not the initial value.
// Therefore, we can safely cast the value to be out `TApplicationContext` type.
const applicationContext = context;
return props.render(applicationContext);
}
});
ApplicationContext.propTypes = process.env.NODE_ENV !== "production" ? {
render: _pt.func.isRequired
} : {};
ApplicationContext.displayName = 'ApplicationContext';
function withApplicationContext(mapApplicationContextToProps) {
return Component => {
const WrappedComponent = props => jsx(ApplicationContext, {
render: applicationContext => {
const mappedProps = mapApplicationContextToProps ? mapApplicationContextToProps(applicationContext) : {
applicationContext
};
// @ts-ignore: relates to https://github.com/emotion-js/emotion/issues/3245
return jsx(Component, _objectSpread$6(_objectSpread$6({}, props), mappedProps));
}
});
WrappedComponent.displayName = `withApplicationContext(${getDisplayName(Component)})`;
return WrappedComponent;
};
}
// Use function overloading to declare two possible signatures with two
// distict return types, based on the selector function argument.
// Then implement the function. Typescript will pick the appropriate signature
// based on the function arguments.
function useApplicationContextHook(selector) {
const context = useContext(Context$2);
// Because of the way the ApplicationShell configures the Context.Provider,
// we ensure that, when we read from the context, we always get actual
// context object and not the initial value.
// Therefore, we can safely cast the value to be out `TApplicationContext` type.
const applicationContext = context;
return selector ? selector(applicationContext) : applicationContext;
}
// This is a workaround to trick babel/rollup to correctly export the function.
// Most likely the problem arises with the use of overloading.
// See related issue: https://github.com/babel/babel/issues/8361
const useApplicationContext = useApplicationContextHook;
function ownKeys$5(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys$5(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys$5(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
const Context$1 = /*#__PURE__*/createContext({});
const CustomViewContextProvider = props => {
const contextValue = useMemo(() => ({
hostUrl: props.hostUrl,
customViewConfig: props.customViewConfig
}), [props.hostUrl, props.customViewConfig]);
return jsx(Context$1.Provider, {
value: contextValue,
children: props.children
});
};
// Use function overloading to declare two possible signatures with two
// distict return types, based on the selector function argument.
CustomViewContextProvider.propTypes = process.env.NODE_ENV !== "production" ? {
hostUrl: _pt.string.isRequired,
customViewConfig: _pt.any.isRequired,
children: _pt.node.isRequired
} : {};
// Then implement the function. Typescript will pick the appropriate signature
// based on the function arguments.
function useCustomViewContextHook(selector) {
// Because of the way the CustomViewShell configures the Context.Provider,
// we ensure that, when we read from the context, we always get actual
// context object and not the initial value.
// Therefore, we can safely cast the value to be out `TCustomViewContext` type.
const customViewContext = useContext(Context$1);
const applicationContext = useApplicationContext();
const mergedContext = _objectSpread$5(_objectSpread$5({}, applicationContext), customViewContext);
return selector ? selector(mergedContext) : mergedContext;
}
// This is a workaround to trick babel/rollup to correctly export the function.
// Most likely the problem arises with the use of overloading.
// See related issue: https://github.com/babel/babel/issues/8361
const useCustomViewContext = useCustomViewContextHook;
function ownKeys$4(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys$4(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys$4(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
var FetchProjectExtensionImageRegex = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "FetchProjectExtensionImageRegex" }, variableDefinitions: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "projectExtension" }, arguments: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" }, arguments: [], directives: [] }, { kind: "Field", name: { kind: "Name", value: "imageRegex" }, arguments: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "thumb" }, arguments: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "FragmentSpread", name: { kind: "Name", value: "ImageRegex" }, directives: [] }] } }, { kind: "Field", name: { kind: "Name", value: "small" }, arguments: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "FragmentSpread", name: { kind: "Name", value: "ImageRegex" }, directives: [] }] } }] } }] } }] } }, { kind: "FragmentDefinition", name: { kind: "Name", value: "ImageRegex" }, typeCondition: { kind: "NamedType", name: { kind: "Name", value: "ImageRegexOptions" } }, directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "flag" }, arguments: [], directives: [] }, { kind: "Field", name: { kind: "Name", value: "search" }, arguments: [], directives: [] }, { kind: "Field", name: { kind: "Name", value: "replace" }, arguments: [], directives: [] }] } }], loc: { start: 0, end: 256, source: { body: "query FetchProjectExtensionImageRegex {\n projectExtension {\n id\n imageRegex {\n thumb {\n ...ImageRegex\n }\n small {\n ...ImageRegex\n }\n }\n }\n}\nfragment ImageRegex on ImageRegexOptions {\n flag\n search\n replace\n}\n", name: "GraphQL request", locationOffset: { line: 1, column: 1 } } } };
const useWarning = (condition, message) => {
useEffect(() => {
process.env.NODE_ENV !== "production" ? warning(condition, message) : void 0;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
};
const Context = /*#__PURE__*/createContext({
isLoading: false
});
const useProjectExtensionImageRegex = () => {
const _useContext = useContext(Context),
isLoading = _useContext.isLoading,
imageRegex = _useContext.imageRegex;
return {
isLoading,
imageRegex
};
};
const ProjectExtensionProviderForImageRegex = props => {
const _useQuery = useQuery(FetchProjectExtensionImageRegex, {
skip: props.skip,
context: {
target: GRAPHQL_TARGETS.SETTINGS_SERVICE
}
}),
loading = _useQuery.loading,
data = _useQuery.data;
return jsx(Context.Provider, {
value: {
isLoading: loading,
imageRegex: data && data.projectExtension && data.projectExtension.imageRegex
},
children: props.children
});
};
ProjectExtensionProviderForImageRegex.propTypes = process.env.NODE_ENV !== "production" ? {
skip: _pt.bool,
children: _pt.node.isRequired
} : {};
ProjectExtensionProviderForImageRegex.displayName = 'ProjectExtensionProviderForImageRegex';
const GetProjectExtensionImageRegex = props => {
useWarning(false, `@commercetools-frontend/application-shell-connectors: It is not recommended to use the 'GetProjectExtensionImageRegex' anymore. Please use the 'useProjectExtensionImageRegex' hook instead.`);
return jsx(Context.Consumer, {
children: imageRegexContext => props.render(imageRegexContext)
});
};
GetProjectExtensionImageRegex.propTypes = process.env.NODE_ENV !== "production" ? {
render: _pt.func.isRequired
} : {};
GetProjectExtensionImageRegex.displayName = 'GetProjectExtensionImageRegex';
function withProjectExtensionImageRegex() {
let propKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'imageRegexData';
return Component => {
const WrappedComponent = props => {
useWarning(false, `@commercetools-frontend/application-shell-connectors: It is not recommended to use the 'withProjectExtensionImageRegex' high order component anymore. Please use the 'useProjectExtensionImageRegex' hook instead.`);
const imageregexContext = useProjectExtensionImageRegex();
return jsx(GetProjectExtensionImageRegex, {
render: () =>
// @ts-ignore: relates to https://github.com/emotion-js/emotion/issues/3245
jsx(Component, _objectSpread$4(_objectSpread$4({}, props), {}, {
[propKey]: imageregexContext
}))
});
};
WrappedComponent.displayName = `withProjectExtensionImageRegex(${getDisplayName(Component)})`;
return WrappedComponent;
};
}
function ownKeys$3(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(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(_context2 = ownKeys$3(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context3 = ownKeys$3(Object(t))).call(_context3, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
const getSkipTokenRetry = context => {
const skipTokenRetry = Boolean(context.skipTokenRetry);
return skipTokenRetry;
};
const forwardTokenRetryHeader = headers => _objectSpread$3(_objectSpread$3({}, headers), {}, {
[SUPPORTED_HEADERS.X_TOKEN_RETRY]: 'true'
});
// This link retries requests to the CTP API that have been rejected
// because of an invalid/expired oauth token.
// To do so, we resend the request with the header "X-Force-Token: true"
// so that the MC BE can issue a new token.
// NOTE: the retry is not meant to work for the MC access token.
const getDoesGraphQLTargetSupportTokenRetry = context => {
var _context;
const graphQLTarget = context.headers?.[SUPPORTED_HEADERS.X_GRAPHQL_TARGET] || context.headers?.[SUPPORTED_HEADERS.X_GRAPHQL_TARGET.toLowerCase()];
return Boolean(graphQLTarget && _includesInstanceProperty(_context = [GRAPHQL_TARGETS.COMMERCETOOLS_PLATFORM, GRAPHQL_TARGETS.ADMINISTRATION_SERVICE, GRAPHQL_TARGETS.SETTINGS_SERVICE, GRAPHQL_TARGETS.MERCHANT_CENTER_BACKEND]).call(_context, graphQLTarget));
};
const isHttpError = error => error.statusCode !== undefined || error.statusCode !== undefined;
const isGraphQLError = error => _Array$isArray(error) && _someInstanceProperty(error).call(error, err => err.message !== undefined || err.extensions !== undefined);
// Checks response from GraphQL in order to scan 401 errors and redirect the
// user to the login page resetting the store and showing the proper message
const errorLink = onError(_ref => {
let graphQLErrors = _ref.graphQLErrors,
networkError = _ref.networkError,
operation = _ref.operation,
forward = _ref.forward;
if (networkError && isHttpError(networkError) && networkError.statusCode === STATUS_CODES.UNAUTHORIZED) {
history.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
return;
}
// In case of graphql errors, we want to retry unauthenticated requests by
// forcing our API to fetch a new token, using the `X-Force-Token` header.
// https://www.apollographql.com/docs/link/links/error/#retrying-failed-requests
// We need to do this as the `token-retry-link` only works for network errors.
// https://www.apollographql.com/docs/link/links/retry/
const context = operation.getContext();
if (graphQLErrors && isGraphQLError(graphQLErrors)) {
for (const err of graphQLErrors) {
const isNonAuthenticatedViaExtensionCode = err?.extensions?.code === 'UNAUTHENTICATED';
/**
* NOTE:
* Not not all GraphQL APIs expose an `extensions` field in
* each error. For those we have to use the `message`
* property until they introduced support for the `extensions`
* field.
*/
const isNonAuthenticatedViaCode = err?.message === 'invalid_token';
if ((isNonAuthenticatedViaExtensionCode || isNonAuthenticatedViaCode) && getDoesGraphQLTargetSupportTokenRetry(context) && !getSkipTokenRetry(context)) {
operation.setContext(_ref2 => {
let headers = _ref2.headers;
return {
headers: forwardTokenRetryHeader(headers)
};
});
// retry the request, returning the new observable
return forward(operation);
}
}
}
// Report unhandled errors to Sentry
if (context.enableSentryErrorReporting && networkError) {
reportErrorToSentry(networkError, {
extra: {
operationName: operation.operationName
}
});
}
if (context.enableSentryErrorReporting && graphQLErrors) {
for (const err of graphQLErrors) {
reportErrorToSentry(err, {
extra: {
operationName: operation.operationName
}
});
}
}
return;
});
// Attempt to load the `teamId` from sessionStorage
function selectTeamIdFromStorage() {
return window.sessionStorage.getItem(STORAGE_KEYS.ACTIVE_TEAM_ID) || window.app.__DEVELOPMENT__?.oidc?.teamId;
}
const staticUrlPathsInPositionOfProjectKey = ['login', 'logout', 'account'];
// Attempt to extract the `:projectKey` from the URL.
// If the value matches one of the values in the list above,
// return `undefined` as we're not within a project context.
function selectProjectKeyFromUrl() {
let locationPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.pathname;
let possibleProjectKey = '';
const pathParts = locationPath.split('/');
if (pathParts[1] === 'custom-views') {
// Custom Views paths: /custom-views/:customViewId/projects/:projectKey
possibleProjectKey = pathParts[4];
} else {
// Application paths: /:projectKey/:applicationId
possibleProjectKey = pathParts[1];
}
return _includesInstanceProperty(staticUrlPathsInPositionOfProjectKey).call(staticUrlPathsInPositionOfProjectKey, possibleProjectKey) ? undefined : possibleProjectKey;
}
// Keep an in-memory reference to the apollo client that would be initialized
// by the application. This is useful to retrieve on runtime the reference
// to the apollo client in other static modules.
let cachedApolloClient;
const setCachedApolloClient = apolloClient => {
cachedApolloClient = apolloClient;
};
const getCachedApolloClient = () => cachedApolloClient;
var FetchUserId = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "FetchUserId" }, variableDefinitions: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", alias: { kind: "Name", value: "user" }, name: { kind: "Name", value: "me" }, arguments: [], directives: [], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" }, arguments: [], directives: [] }] } }] } }], loc: { start: 0, end: 46, source: { body: "query FetchUserId {\n user: me {\n id\n }\n}\n", name: "GraphQL request", locationOffset: { line: 1, column: 1 } } } };
function selectUserId() {
const apolloClient = getCachedApolloClient();
if (!apolloClient) {
return null;
}
try {
const queryResult = apolloClient.readQuery({
query: FetchUserId
});
if (queryResult && queryResult.user) {
return queryResult.user.id;
}
} catch (e) {
return null;
}
return null;
}
const VALID_ID_PART_FORMAT = /^[\w-/]+$/;
const skipMalformedPart = part => part && VALID_ID_PART_FORMAT.test(part);
function getCorrelationId() {
var _context;
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
userId = _ref.userId;
return _filterInstanceProperty(_context = ['mc', selectProjectKeyFromUrl(), userId, v4()]).call(_context, skipMalformedPart).join('/');
}
const createApolloContextForProxyForwardTo = proxyForwardTocontext => ({
// Send the request to the forward-to endpoint.
uri: `${getMcApiUrl()}/proxy/forward-to`,
// Custom properties to be used by the "header-link".
forwardToConfig: proxyForwardTocontext,
skipGraphQlTargetCheck: true
});
/* 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(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);
}
};
const getSessionToken = () => window.sessionStorage.getItem(STORAGE_KEYS.SESSION_TOKEN);
const setActiveSession = sessionToken => {
if (!sessionToken) return;
window.sessionStorage.setItem(STORAGE_KEYS.SESSION_TOKEN, sessionToken ?? '');
window.localStorage.setItem(STORAGE_KEYS.LOGIN_STRATEGY, LOGIN_STRATEGY_OIDC);
// Remove flag for original workflow
window.localStorage.removeItem(STORAGE_KEYS.IS_AUTHENTICATED);
};
const clearSession = () => {
window.sessionStorage.removeItem(STORAGE_KEYS.SESSION_TOKEN);
window.sessionStorage.removeItem(STORAGE_KEYS.SESSION_SCOPE);
window.sessionStorage.removeItem(STORAGE_KEYS.IS_AUTHENTICATED);
};
const getActiveProjectKey = () => window.localStorage.getItem(STORAGE_KEYS.ACTIVE_PROJECT_KEY);
const removeActiveProjectKey = () => {
window.localStorage.removeItem(STORAGE_KEYS.ACTIVE_PROJECT_KEY);
};
const setActiveProjectKey = projectKey => {
window.localStorage.setItem(STORAGE_KEYS.ACTIVE_PROJECT_KEY, projectKey);
};
const getSessionScope = () => window.sessionStorage.getItem(STORAGE_KEYS.SESSION_SCOPE);
const setSessionScope = scope => {
window.sessionStorage.setItem(STORAGE_KEYS.SESSION_SCOPE, scope);
};
const getSessionState = stateId => {
const sessionStateKey = `${STORAGE_KEYS.NONCE}_${stateId}`;
const unparsedSessionState = window.sessionStorage.getItem(sessionStateKey);
if (unparsedSessionState) {
try {
const parsedSessionState = JSON.parse(unparsedSessionState);
return parsedSessionState;
} catch (error) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn(`Cannot parse session state for "${sessionStateKey}".\n${unparsedSessionState}`);
}
}
}
return null;
};
const setSessionState = (stateId, state) => {
const sessionStateKey = `${STORAGE_KEYS.NONCE}_${stateId}`;
window.sessionStorage.setItem(sessionStateKey, _JSON$stringify(state));
};
const removeSessionState = stateId => {
const sessionStateKey = `${STORAGE_KEYS.NONCE}_${stateId}`;
window.sessionStorage.removeItem(sessionStateKey);
};
var oidcStorage = /*#__PURE__*/Object.freeze({
__proto__: null,
getSessionToken: getSessionToken,
setActiveSession: setActiveSession,
clearSession: clearSession,
getSessionState: getSessionState,
setSessionState: setSessionState,
removeSessionState: removeSessionState,
getActiveProjectKey: getActiveProjectKey,
setActiveProjectKey: setActiveProjectKey,
removeActiveProjectKey: removeActiveProjectKey,
getSessionScope: getSessionScope,
setSessionScope: setSessionScope
});
function _createSuper(t) { var r = _isNativeReflectConstruct(); return function () { var e, o = _getPrototypeOf(t); if (r) { var s = _getPrototypeOf(this).constructor; e = _Reflect$construct(o, arguments, s); } else e = o.apply(this, arguments); return _possibleConstructorReturn(this, e); }; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); }
function ownKeys$2(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context2 = ownKeys$2(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context3 = ownKeys$2(Object(t))).call(_context3, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
let _userAgent$1;
const getUserAgent$1 = () => {
if (!_userAgent$1) {
_userAgent$1 = createHttpUserAgent({
name: 'unknown-http-client',
libraryName: typeof window !== 'undefined' ? window.app?.applicationName ?? 'unknown-application-name' : undefined
});
}
return _userAgent$1;
};
const defaultForwardToVersion = 'v2';
const defaultForwardToAudiencePolicy = 'forward-url-full-path';
function buildApiUrl(endpoint) {
const apiUrl = getMcApiUrl().replace(/\/$/, '');
return `${apiUrl}${endpoint}`;
}
const getAppliedForwardToHeaders = forwardToConfig => {
var _context;
if (!forwardToConfig) {
return {};
}
if (!forwardToConfig.uri) {
throw new Error(`Missing required "uri" option.`);
}
const exchangeTokenClaims = [];
if (forwardToConfig.includeUserPermissions) {
exchangeTokenClaims.push('permissions');
}
return _objectSpread$2(_objectSpread$2({}, _reduceInstanceProperty(_context = _Object$entries(forwardToConfig.headers ?? {})).call(_context, (customForwardHeaders, _ref) => {
let _ref2 = _slicedToArray(_ref, 2),
headerName = _ref2[0],
headerValue = _ref2[1];
return _objectSpread$2(_objectSpread$2({}, customForwardHeaders), {}, {
// Prefix headers so that the MC API can allow and forward them.
[`x-forward-header-${headerName}`]: headerValue
});
}, {})), {}, {
[SUPPORTED_HEADERS.ACCEPT_VERSION]: forwardToConfig.version ?? defaultForwardToVersion,
[SUPPORTED_HEADERS.X_FORWARD_TO]: forwardToConfig.uri,
[SUPPORTED_HEADERS.X_FORWARD_TO_AUDIENCE_POLICY]: forwardToConfig.audiencePolicy ?? defaultForwardToAudiencePolicy,
[SUPPORTED_HEADERS.X_FORWARD_TO_CLAIMS]: exchangeTokenClaims.join(' ')
});
};
function createHttpClientOptions() {
let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const sessionToken = getSessionToken();
const projectKey = config.projectKey ?? selectProjectKeyFromUrl();
const userId = selectUserId();
const userAgent = config?.userAgent || getUserAgent$1();
return {
credentials: 'include',
headers: omitEmpty(_objectSpread$2(_objectSpread$2({}, config.headers), {}, {
// Required headers
[SUPPORTED_HEADERS.ACCEPT]: 'application/json',
[SUPPORTED_HEADERS.AUTHORIZATION]: sessionToken ? `Bearer ${sessionToken}` : undefined,
[SUPPORTED_HEADERS.X_APPLICATION_ID]: window.app.applicationIdentifier,
[SUPPORTED_HEADERS.X_CUSTOM_VIEW_ID]: window.app.customViewId,
[SUPPORTED_HEADERS.X_CORRELATION_ID]: getCorrelationId({
userId
}),
[SUPPORTED_HEADERS.X_PROJECT_KEY]: projectKey,
[SUPPORTED_HEADERS.X_USER_AGENT]: userAgent
}, getAppliedForwardToHeaders(config.forwardToConfig)))
};
}
let RenewTokenError = /*#__PURE__*/function (_Error) {
_inherits(RenewTokenError, _Error);
var _super = _createSuper(RenewTokenError);
function RenewTokenError(message) {
var _this;
_classCallCheck(this, RenewTokenError);
_this = _super.call(this, message);
_Object$defineProperty(_assertThisInitialized(_this), 'name', {
value: 'RenewTokenError'
});
return _this;
}
return _createClass(RenewTokenError);
}(/*#__PURE__*/_wrapNativeSuper(Error));
async function executeHttpClientRequest(fetcher) {
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Wrapper function to be called again (once) on retry.
async function sendRequest() {
let _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
shouldRenewToken = _ref3.shouldRenewToken;
const requestOptions = createHttpClientOptions(config);
const response = await fetcher(_objectSpread$2(_objectSpread$2({}, requestOptions), {}, {
headers: omitEmpty(_objectSpread$2(_objectSpread$2({}, requestOptions.headers), {}, {
// Passing this header forces a token renewal.
[SUPPORTED_HEADERS.X_TOKEN_RETRY]: shouldRenewToken
}))
}));
if (response.statusCode === STATUS_CODES.UNAUTHORIZED) {
throw new RenewTokenError(`Unauthorized response, attempting retry.`);
}
// In case a new session token is returned from the server, save it.
const refreshedSessionToken = response.getHeader('x-refreshed-session-token');
if (refreshedSessionToken) {
setActiveSession(refreshedSessionToken);
}
return response.data;
}
// Attempt to send the request.
return sendRequest().catch(error => {
if (error instanceof RenewTokenError) {
// Retry the request and ask to renew the token.
return sendRequest({
shouldRenewToken: true
});
}
throw error;
});
}
function ownKeys$1(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _context4, _context5; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context4 = ownKeys$1(Object(t), !0)).call(_context4, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context5 = ownKeys$1(Object(t))).call(_context5, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
let _userAgent;
const getUserAgent = () => {
if (!_userAgent) {
var _context;
_userAgent = createHttpUserAgent({
name: 'apollo-client',
// version: apolloVersion,
libraryName: _filterInstanceProperty(_context = [typeof window !== 'undefined' ? window.app?.applicationName ?? 'unknown-application-name' : undefined, 'application-shell']).call(_context, Boolean).join('/'),
libraryVersion: version,
contactUrl: 'https://git.io/fjuyC',
// points to the appkit repo issues
contactEmail: 'support@commercetools.com'
});
}
return _userAgent;
};
const isKnownGraphQlTarget = target => {
var _context2;
return target ? _includesInstanceProperty(_context2 = _Object$values(GRAPHQL_TARGETS)).call(_context2, target) : false;
};
const extractSessionTokenFromResponse = context => {
const refreshedSessionToken = context.response?.headers?.get('x-refreshed-session-token');
if (refreshedSessionToken) {
return refreshedSessionToken ?? null;
}
const restResponseWithRefreshTokenHeader = context.restResponses?.find(response => response.headers?.has('x-refreshed-session-token'));
if (restResponseWithRefreshTokenHeader) {
return restResponseWithRefreshTokenHeader.headers.get('x-refreshed-session-token') ?? null;
}
return null;
};
/* eslint-disable import/prefer-default-export */
// Use a middleware to update the request headers with the correct params.
const headerLink = new ApolloLink((operation, forward) => {
var _context3;
const apolloContext = operation.getContext();
const variables = operation.variables;
const graphQlTarget = apolloContext.target || variables.target;
if (!apolloContext.skipGraphQlTargetCheck && !isKnownGraphQlTarget(graphQlTarget)) throw new Error(`GraphQL target "${graphQlTarget}" is missing (or is not supported) in operation "${operation.operationName}"`);
/**
* NOTE:
* The project key is read from the url in a project related application context.
* This holds for most applications like `application-categories`, `application-discounts` etc.
* However, the `application-account` does not run with the project key being part of the url.
* As a result we allow passing the project key as a variable on the operation allowing
* it to be the fallback.
*/
const projectKey = apolloContext.projectKey || variables.projectKey || selectProjectKeyFromUrl();
const teamId = apolloContext.teamId || variables.teamId || selectTeamIdFromStorage();
const featureFlag = apolloContext.featureFlag || variables.featureFlag;
operation.setContext(createHttpClientOptions({
userAgent: getUserAgent(),
headers: omitEmpty(_objectSpread$1(_objectSpread$1({}, apolloContext.headers), {}, {
// Required headers for GraphQL API.
[SUPPORTED_HEADERS.X_GRAPHQL_TARGET]: graphQlTarget,
// For logging/debugging purposes.
[SUPPORTED_HEADERS.X_GRAPHQL_OPERATION_NAME]: operation.operationName,
// Experimental features, use with caution.
[SUPPORTED_HEADERS.X_TEAM_ID]: teamId,
[SUPPORTED_HEADERS.X_FEATURE_FLAG]: featureFlag
})),
forwardToConfig: apolloContext.forwardToConfig,
projectKey
}));
return _mapInstanceProperty(_context3 = forward(operation)).call(_context3, response => {
const context = operation.getContext();
const refreshedSessionToken = extractSessionTokenFromResponse(context);
if (refreshedSessionToken) {
setActiveSession(refreshedSessionToken);
}
return response;
});
});
const tokenRetryLink = new RetryLink({
attempts: (count, operation, error) => {
const context = operation.getContext();
if (error?.statusCode === STATUS_CODES.UNAUTHORIZED && count === 1 && getDoesGraphQLTargetSupportTokenRetry(context) && !getSkipTokenRetry(context)) {
operation.setContext(_ref => {
let headers = _ref.headers;
return {
headers: forwardTokenRetryHeader(headers)
};
});
return true;
}
return false;
}
});
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
const createApolloLink = function () {
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const httpLink = createHttpLink({
uri: `${getMcApiUrl()}/graphql`,
fetch
});
// The order of links is IMPORTANT!
// In the request-phase they are executed top to bottom.
// In the response/phase they are executed bottom to top.
// The `httpLink` is terminating so it must be last, while `tokenRetryLink` and `errorLink`
// wrap the links the their right.
return from([headerLink,
// See https://www.apollographql.com/docs/react/api/link/apollo-link-rest/#link-order
/