@shopgate/pwa-common 7.30.0-alpha.6 → 7.30.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/App.js +48 -6
- package/action-creators/app/index.js +75 -12
- package/action-creators/app/spec.js +96 -1
- package/action-creators/client/index.js +27 -5
- package/action-creators/client/spec.js +44 -1
- package/action-creators/error/index.js +15 -3
- package/action-creators/index.js +9 -1
- package/action-creators/menu/index.js +23 -4
- package/action-creators/menu/spec.js +37 -1
- package/action-creators/modal/index.js +15 -3
- package/action-creators/modal/spec.js +26 -1
- package/action-creators/page/index.js +24 -4
- package/action-creators/page/spec.js +38 -1
- package/action-creators/router/index.js +48 -7
- package/action-creators/url/index.js +24 -4
- package/action-creators/url/spec.js +45 -1
- package/action-creators/user/index.js +90 -13
- package/action-creators/user/spec.js +186 -2
- package/actions/app/handleDeepLink.js +11 -2
- package/actions/app/handleLink.js +62 -6
- package/actions/app/handlePushNotification.js +32 -4
- package/actions/app/handleUniversalLink.js +11 -2
- package/actions/app/registerLinkEvents.js +24 -3
- package/actions/client/fetchClientInformation.js +26 -2
- package/actions/menu/fetchMenu.js +23 -2
- package/actions/modal/closeModal.js +18 -2
- package/actions/modal/promiseMap.js +3 -1
- package/actions/modal/showModal.js +54 -8
- package/actions/page/fetchPageConfig.js +69 -2
- package/actions/page/getPageConfig.js +6 -2
- package/actions/page/index.js +1 -1
- package/actions/router/historyPop.js +12 -2
- package/actions/router/historyPopToRoute.js +27 -2
- package/actions/router/historyPush.js +12 -2
- package/actions/router/historyRedirect.js +21 -2
- package/actions/router/historyReplace.js +20 -3
- package/actions/router/historyReset.js +11 -2
- package/actions/router/historyResetTo.js +12 -2
- package/actions/router/index.js +17 -1
- package/actions/router/routeDidPop.js +11 -2
- package/actions/router/routeDidPush.js +13 -2
- package/actions/router/routeDidReplace.js +11 -2
- package/actions/router/routeDidReset.js +11 -2
- package/actions/router/routeDidUpdate.js +10 -2
- package/actions/router/routeWillPop.js +11 -2
- package/actions/router/routeWillPush.js +13 -2
- package/actions/router/routeWillReplace.js +11 -2
- package/actions/router/routeWillReset.js +11 -2
- package/actions/router/windowOpenOverride.js +10 -2
- package/actions/user/fetchRegisterUrl.js +36 -2
- package/actions/user/fetchUser.js +29 -3
- package/actions/user/getUser.js +6 -2
- package/actions/user/index.js +1 -1
- package/actions/user/login.js +76 -9
- package/actions/user/logout.js +30 -2
- package/collections/AuthRoutes.js +73 -14
- package/collections/Configuration.js +54 -7
- package/collections/EmbeddedMedia.js +84 -11
- package/collections/PersistedReducers.js +41 -6
- package/collections/Redirects.js +103 -17
- package/collections/index.js +5 -1
- package/collections/media-providers/MediaProvider.js +151 -26
- package/collections/media-providers/Vimeo.js +113 -19
- package/collections/media-providers/YouTube.js +74 -14
- package/collections/media-providers/index.js +3 -1
- package/collections/media-providers/style.js +52 -2
- package/components/Backdrop/index.js +95 -6
- package/components/Backdrop/spec.js +23 -1
- package/components/Backdrop/style.js +11 -2
- package/components/Button/index.js +47 -5
- package/components/Button/spec.js +36 -1
- package/components/Button/style.js +6 -1
- package/components/Checkbox/index.js +126 -32
- package/components/Checkbox/spec.js +94 -3
- package/components/Consume/helpers/buildParams.js +13 -2
- package/components/Consume/index.js +14 -2
- package/components/CountdownTimer/index.js +115 -17
- package/components/CountdownTimer/spec.js +126 -12
- package/components/Drawer/index.js +131 -16
- package/components/Drawer/spec.js +76 -1
- package/components/Drawer/style.js +37 -1
- package/components/Dropdown/index.js +65 -6
- package/components/Dropdown/style.js +4 -1
- package/components/Dropdown/transitions.js +34 -1
- package/components/Ellipsis/index.js +16 -2
- package/components/Ellipsis/spec.js +13 -1
- package/components/EmbeddedMedia/index.js +56 -6
- package/components/EmbeddedMedia/spec.js +52 -3
- package/components/ErrorBoundary/connector.js +9 -2
- package/components/ErrorBoundary/index.js +43 -7
- package/components/Grid/components/Item/index.js +40 -4
- package/components/Grid/components/Item/spec.js +23 -1
- package/components/Grid/components/Item/style.js +17 -3
- package/components/Grid/index.js +36 -4
- package/components/Grid/spec.js +23 -1
- package/components/Grid/style.js +11 -2
- package/components/HtmlSanitizer/connector.js +24 -3
- package/components/HtmlSanitizer/index.js +104 -12
- package/components/HtmlSanitizer/spec.js +207 -6
- package/components/I18n/components/FormatDate/index.js +26 -2
- package/components/I18n/components/FormatDate/spec.js +46 -1
- package/components/I18n/components/FormatNumber/index.js +34 -2
- package/components/I18n/components/FormatNumber/spec.js +41 -2
- package/components/I18n/components/FormatPrice/index.js +32 -2
- package/components/I18n/components/FormatPrice/spec.js +46 -1
- package/components/I18n/components/FormatTime/index.js +26 -2
- package/components/I18n/components/FormatTime/spec.js +43 -2
- package/components/I18n/components/I18nProvider/index.js +52 -9
- package/components/I18n/components/I18nProvider/spec.js +39 -1
- package/components/I18n/components/Placeholder/index.js +8 -2
- package/components/I18n/components/Placeholder/spec.js +30 -1
- package/components/I18n/components/Translate/index.js +68 -7
- package/components/I18n/components/Translate/spec.js +30 -1
- package/components/I18n/index.js +16 -1
- package/components/Icon/index.js +25 -2
- package/components/Icon/style.js +6 -1
- package/components/Image/Image.js +176 -19
- package/components/Image/ImageInner.js +48 -2
- package/components/Image/index.js +1 -1
- package/components/Image/style.js +29 -2
- package/components/InfiniteContainer/index.js +381 -49
- package/components/InfiniteContainer/spec.js +199 -10
- package/components/Input/components/DateInput.js +262 -6
- package/components/Input/components/MultiLineInput.js +98 -12
- package/components/Input/components/SimpleInput.js +207 -31
- package/components/Input/index.js +32 -3
- package/components/Input/spec.js +122 -1
- package/components/KeyboardConsumer/index.js +48 -7
- package/components/Link/connector.js +7 -1
- package/components/Link/index.js +96 -11
- package/components/Link/spec.js +56 -1
- package/components/Link/style.js +10 -1
- package/components/List/components/Item/index.js +35 -3
- package/components/List/components/Item/style.js +16 -1
- package/components/List/index.js +20 -2
- package/components/List/spec.js +31 -1
- package/components/Loading/index.js +6 -2
- package/components/Modal/index.js +38 -3
- package/components/Modal/style.js +36 -1
- package/components/ModalContainer/connector.js +17 -3
- package/components/ModalContainer/index.js +36 -3
- package/components/ModalContainer/spec.js +105 -5
- package/components/Picker/components/Button/index.js +34 -2
- package/components/Picker/components/Button/style.js +19 -1
- package/components/Picker/components/List/index.js +33 -2
- package/components/Picker/components/List/style.js +17 -1
- package/components/Picker/components/Modal/index.js +60 -7
- package/components/Picker/components/Modal/style.js +78 -1
- package/components/Picker/index.js +167 -21
- package/components/Picker/spec.js +83 -2
- package/components/Portal/index.js +130 -19
- package/components/ProductCharacteristics/connector.js +33 -4
- package/components/ProductCharacteristics/context.js +2 -1
- package/components/ProductCharacteristics/helpers/index.js +135 -21
- package/components/ProductCharacteristics/index.js +266 -31
- package/components/RangeSlider/components/Handle/index.js +25 -2
- package/components/RangeSlider/components/Handle/style.js +14 -1
- package/components/RangeSlider/helper.js +43 -8
- package/components/RangeSlider/index.js +228 -38
- package/components/RangeSlider/style.js +14 -1
- package/components/Route/RouteNotFound.js +46 -3
- package/components/Route/index.js +78 -10
- package/components/Router/connector.js +9 -2
- package/components/Router/index.js +237 -31
- package/components/ScannerContainer/connector.js +9 -2
- package/components/ScannerContainer/index.js +42 -6
- package/components/Select/components/Item/index.js +20 -4
- package/components/Select/components/Item/style.js +4 -1
- package/components/Select/index.js +149 -28
- package/components/Select/spec.js +86 -2
- package/components/Select/style.js +17 -1
- package/components/SelectBox/components/Item/index.js +47 -5
- package/components/SelectBox/components/Item/style.js +7 -1
- package/components/SelectBox/index.js +173 -17
- package/components/SelectBox/spec.js +59 -3
- package/components/SelectBox/style.js +18 -1
- package/components/Slider/index.js +6 -2
- package/components/SurroundPortals/index.js +26 -2
- package/components/Swiper/components/SwiperItem/index.js +28 -4
- package/components/Swiper/components/SwiperItem/spec.js +17 -1
- package/components/Swiper/components/SwiperItem/styles.js +5 -1
- package/components/Swiper/index.js +210 -18
- package/components/Swiper/styles.js +75 -7
- package/components/Toaster/index.js +10 -2
- package/components/Transition/index.js +89 -13
- package/components/Widgets/components/Widget/index.js +52 -4
- package/components/Widgets/components/Widget/spec.js +68 -3
- package/components/Widgets/components/Widget/style.js +21 -3
- package/components/Widgets/components/WidgetGrid/index.js +52 -7
- package/components/Widgets/components/WidgetGrid/spec.js +46 -2
- package/components/Widgets/components/WidgetGrid/style.js +8 -1
- package/components/Widgets/helpers/shouldShowWidget.js +44 -7
- package/components/Widgets/index.js +127 -15
- package/components/Widgets/spec.js +213 -6
- package/components/index.js +9 -1
- package/constants/ActionTypes.js +97 -19
- package/constants/Configuration.js +12 -2
- package/constants/Device.js +29 -2
- package/constants/DisplayOptions.js +8 -1
- package/constants/MenuIDs.js +2 -1
- package/constants/ModalTypes.js +1 -1
- package/constants/PageIDs.js +1 -1
- package/constants/Pipelines.js +7 -1
- package/constants/Portals.js +136 -3
- package/constants/Registration.js +3 -1
- package/constants/RoutePaths.js +13 -2
- package/constants/Tracking.js +3 -1
- package/constants/client.js +6 -1
- package/constants/ui.js +2 -1
- package/constants/user.js +6 -2
- package/context/index.js +33 -3
- package/helpers/config/index.js +139 -21
- package/helpers/config/mock.js +200 -8
- package/helpers/config/theme.js +50 -4
- package/helpers/data/index.js +204 -29
- package/helpers/data/spec.js +187 -7
- package/helpers/date/index.js +58 -6
- package/helpers/date/spec.js +92 -1
- package/helpers/dom/index.js +48 -11
- package/helpers/environment/index.js +14 -2
- package/helpers/html/decodeHTML.js +7 -1
- package/helpers/html/handleDOM.js +172 -21
- package/helpers/html/parseHTML.js +67 -12
- package/helpers/i18n/getDateFormatter.js +23 -4
- package/helpers/i18n/getNumberFormatter.js +32 -4
- package/helpers/i18n/getPriceFormatter.js +38 -4
- package/helpers/i18n/getTimeFormatter.js +23 -4
- package/helpers/i18n/getTranslator.js +62 -8
- package/helpers/i18n/index.js +5 -1
- package/helpers/i18n/mergeTranslations.js +36 -9
- package/helpers/i18n/messageCache.js +3 -1
- package/helpers/legacy/index.js +47 -9
- package/helpers/modal/withShowModal.js +13 -2
- package/helpers/portals/portalCollection.js +28 -6
- package/helpers/portals/routePortals.js +12 -1
- package/helpers/redux/compareObjects.js +7 -2
- package/helpers/redux/generateResultHash.js +36 -3
- package/helpers/redux/generateSortedHash.js +7 -2
- package/helpers/redux/hasExpired.js +10 -2
- package/helpers/redux/index.js +7 -1
- package/helpers/redux/mutable.js +143 -24
- package/helpers/redux/shouldFetchData.js +46 -10
- package/helpers/redux/shouldFetchFilters.js +17 -4
- package/helpers/router/index.js +49 -5
- package/helpers/style/index.js +43 -4
- package/helpers/style/spec.js +108 -2
- package/helpers/tracking/index.js +52 -9
- package/helpers/validation/index.js +39 -12
- package/helpers/validation/spec.js +10 -1
- package/package.json +3 -3
- package/providers/index.js +4 -1
- package/providers/loading/context.js +2 -1
- package/providers/loading/index.js +137 -22
- package/providers/toast/context.js +2 -1
- package/providers/toast/index.js +105 -11
- package/reducers/client/connectivity.js +22 -2
- package/reducers/client/index.js +7 -1
- package/reducers/client/info.js +27 -2
- package/reducers/index.js +23 -4
- package/reducers/menu/index.js +5 -1
- package/reducers/menu/menusById.js +41 -2
- package/reducers/modal/index.js +14 -2
- package/reducers/page/index.js +68 -5
- package/reducers/router/index.js +48 -2
- package/reducers/url/index.js +42 -3
- package/reducers/user/data.js +27 -2
- package/reducers/user/index.js +7 -1
- package/reducers/user/login.js +65 -2
- package/selectors/client.js +138 -21
- package/selectors/history.js +49 -11
- package/selectors/menu.js +34 -6
- package/selectors/modal.js +15 -4
- package/selectors/page.js +25 -4
- package/selectors/router.js +154 -30
- package/selectors/url.js +25 -4
- package/selectors/user.js +90 -13
- package/store/index.js +60 -6
- package/store/middelwares/logger.js +7 -1
- package/store/middelwares/streams.js +19 -2
- package/streams/app.js +60 -8
- package/streams/client.js +8 -2
- package/streams/error.js +14 -3
- package/streams/index.js +6 -1
- package/streams/interval.js +6 -2
- package/streams/main.js +27 -2
- package/streams/router.js +45 -8
- package/streams/user.js +89 -15
- package/streams/view.js +97 -25
- package/styles/reset/form.js +57 -5
- package/styles/reset/index.js +6 -1
- package/styles/reset/media.js +22 -1
- package/styles/reset/root.js +33 -1
- package/styles/reset/table.js +10 -1
- package/styles/reset/typography.js +26 -1
- package/subscriptions/app.js +148 -17
- package/subscriptions/error.js +292 -13
- package/subscriptions/helpers/buildRegisterUrl.js +25 -6
- package/subscriptions/helpers/clearUpInAppBrowser.js +14 -3
- package/subscriptions/helpers/handleLinks.js +267 -25
- package/subscriptions/helpers/pipeline.js +12 -1
- package/subscriptions/history.js +34 -6
- package/subscriptions/index.js +25 -4
- package/subscriptions/menu.js +22 -5
- package/subscriptions/mock.js +39 -7
- package/subscriptions/router.js +336 -23
- package/subscriptions/user.js +93 -3
package/helpers/data/index.js
CHANGED
|
@@ -1,25 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import "core-js/modules/es.string.replace.js";
|
|
3
|
+
import { logger } from '@shopgate/pwa-core/helpers';
|
|
4
|
+
import { isAndroidOs } from '@shopgate/pwa-core';
|
|
5
|
+
import { isObject, isArray } from "../validation";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* Tests if the prop is an object or an array.
|
|
3
9
|
* @param {*} prop The property to test.
|
|
4
10
|
* @return {boolean}
|
|
5
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
const isObjectOrArray = prop => isObject(prop) || isArray(prop);
|
|
13
|
+
|
|
14
|
+
/**
|
|
6
15
|
* Remove the first element of the array.
|
|
7
16
|
* @param {Array} array The array to remove the first element from.
|
|
8
17
|
* @returns {Array} The reduced array.
|
|
9
|
-
*/
|
|
18
|
+
*/
|
|
19
|
+
export const shift = ([, ...newArray]) => newArray;
|
|
20
|
+
|
|
21
|
+
/**
|
|
10
22
|
* Returns a new object without certain keys.
|
|
11
23
|
* @param {Object} obj The original object.
|
|
12
24
|
* @param {Array} [keys=[]] An array of unwanted keys.
|
|
13
25
|
* @return {Object} The reduced object.
|
|
14
|
-
*/
|
|
26
|
+
*/
|
|
27
|
+
export const objectWithoutProps = (obj, keys = []) => {
|
|
28
|
+
const target = {};
|
|
29
|
+
Object.keys(obj).forEach(key => {
|
|
30
|
+
if (!keys.includes(key)) {
|
|
31
|
+
target[key] = obj[key];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
15
38
|
* Checks if a URL is an external URL.
|
|
16
39
|
* @param {string} url The URL to check.
|
|
17
40
|
* @return {boolean}
|
|
18
|
-
*/
|
|
41
|
+
*/
|
|
42
|
+
export const isExternal = url => url.includes('http://') || url.includes('https://') || url.includes('//');
|
|
43
|
+
|
|
44
|
+
/**
|
|
19
45
|
* Checks whether the url is an HTTPS url.
|
|
20
46
|
* @param {string} url The url to open.
|
|
21
47
|
* @return {boolean}
|
|
22
|
-
*/
|
|
48
|
+
*/
|
|
49
|
+
export const isHTTPS = (url = '') => url.startsWith('https://');
|
|
50
|
+
|
|
51
|
+
/**
|
|
23
52
|
* Returns the actual url to the image, by adding url parameters with the dimensions for img-cdn
|
|
24
53
|
* @param {string} src Source to the image.
|
|
25
54
|
* @param {Object} dimension Dimension of the requested image.
|
|
@@ -27,43 +56,148 @@ function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="s
|
|
|
27
56
|
* @param {number} dimension.height Height in pixels.
|
|
28
57
|
* @deprecated use getFullImageSource from @shopgate/engage/core/helpers instead
|
|
29
58
|
* @returns {string}
|
|
30
|
-
*/
|
|
59
|
+
*/
|
|
60
|
+
export const getActualImageSource = (src, {
|
|
61
|
+
width,
|
|
62
|
+
height
|
|
63
|
+
}) => {
|
|
64
|
+
if (src && src.includes('images.shopgate.services')) {
|
|
65
|
+
const fillColor = 'FFFFFF,1';
|
|
66
|
+
const format = isAndroidOs ? 'webp' : 'jpeg';
|
|
67
|
+
return `${src}&format=${format}&width=${width}&height=${height}&quality=75&fill=${fillColor.replace('#', '')}`;
|
|
68
|
+
}
|
|
69
|
+
if (src && src.startsWith('https://img-cdn.shopgate.com') && !src.includes('?')) {
|
|
70
|
+
return `${src}?w=${width}&h=${height}&q=70&zc=resize&fillc=FFFFFF`;
|
|
71
|
+
}
|
|
72
|
+
return src;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
31
76
|
* Finds the index of a property inside an array.
|
|
32
77
|
* @param {Array} arr The array to check.
|
|
33
78
|
* @param {Function} fn The callback function to filter inside the array.
|
|
34
79
|
* @return {number} The index of the property.
|
|
35
|
-
*/
|
|
80
|
+
*/
|
|
81
|
+
export const findIndex = (arr, fn) => {
|
|
82
|
+
if (Array.isArray(arr)) {
|
|
83
|
+
for (let i = 0; i < arr.length; i += 1) {
|
|
84
|
+
if (fn(arr[i])) {
|
|
85
|
+
return i;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return -1;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
36
93
|
* Convert binary data into hexadecimal representation
|
|
37
94
|
* @param {string|number} str The string that shall be encoded
|
|
38
95
|
* @see http://locutus.io/php/strings/bin2hex/
|
|
39
96
|
* @return {string} The hexadecimal representation of the given string
|
|
40
|
-
*/
|
|
97
|
+
*/
|
|
98
|
+
export const bin2hex = str => {
|
|
99
|
+
const s = `${str}`;
|
|
100
|
+
let i;
|
|
101
|
+
let l;
|
|
102
|
+
let o = '';
|
|
103
|
+
let n;
|
|
104
|
+
for (i = 0, l = s.length; i < l; i += 1) {
|
|
105
|
+
n = s.charCodeAt(i).toString(16);
|
|
106
|
+
o += n.length < 2 ? `0${n}` : n;
|
|
107
|
+
}
|
|
108
|
+
return o;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
41
112
|
* Decodes a hexadecimal encoded binary string
|
|
42
113
|
* @param {string} str The string that shall be decoded
|
|
43
114
|
* @see http://locutus.io/php/strings/hex2bin/
|
|
44
115
|
* @returns {string|boolean} Hexadecimal representation of data. FALSE if decoding failed.
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
|
|
116
|
+
*/
|
|
117
|
+
export const hex2bin = str => {
|
|
118
|
+
const s = `${str}`;
|
|
119
|
+
const ret = [];
|
|
120
|
+
let i = 0;
|
|
121
|
+
let l;
|
|
122
|
+
for (l = s.length; i < l; i += 2) {
|
|
123
|
+
const c = parseInt(s.substr(i, 1), 16);
|
|
124
|
+
const k = parseInt(s.substr(i + 1, 1), 16);
|
|
125
|
+
if (Number.isNaN(c) || Number.isNaN(k)) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// eslint-disable-next-line no-bitwise
|
|
130
|
+
ret.push(c << 4 | k);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line prefer-spread
|
|
134
|
+
return String.fromCharCode.apply(String, ret);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
48
138
|
* Compares two strings of object keys for object sorting.
|
|
49
139
|
* @param {string} a The first key.
|
|
50
140
|
* @param {string} b The second key.
|
|
51
141
|
* @return {number} The sort order.
|
|
52
|
-
*/
|
|
142
|
+
*/
|
|
143
|
+
const defaultKeySortFn = (a, b) => a.localeCompare(b);
|
|
144
|
+
|
|
145
|
+
/**
|
|
53
146
|
* Deep sorts an object by its keys.
|
|
54
147
|
* @param {Object} src The object to sort.
|
|
55
148
|
* @param {Function} [comparator=defaultKeySortFn] The sorting operator callback.
|
|
56
149
|
* @return {Object} The sorted object.
|
|
57
|
-
*/
|
|
150
|
+
*/
|
|
151
|
+
export const sortObject = (src, comparator = defaultKeySortFn) => {
|
|
152
|
+
if (Array.isArray(src)) {
|
|
153
|
+
return src.map(item => sortObject(item, comparator));
|
|
154
|
+
}
|
|
155
|
+
if (isObject(src)) {
|
|
156
|
+
return Object.keys(src).sort(comparator).reduce((obj, key) => ({
|
|
157
|
+
...obj,
|
|
158
|
+
[key]: sortObject(src[key], comparator)
|
|
159
|
+
}), {});
|
|
160
|
+
}
|
|
161
|
+
return src;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
58
165
|
* Transforms widget display options to match pipeline specifications.
|
|
59
166
|
* @param {string} displayOptions The display options as specified by the widget settings.
|
|
60
167
|
* @returns {string} The transformed string compatible with the pipeline requests.
|
|
61
|
-
*/
|
|
168
|
+
*/
|
|
169
|
+
export const transformDisplayOptions = displayOptions => {
|
|
170
|
+
switch (displayOptions) {
|
|
171
|
+
case 'relevance_asc':
|
|
172
|
+
case 'relevance_desc':
|
|
173
|
+
return 'relevance';
|
|
174
|
+
case 'price_asc':
|
|
175
|
+
return 'priceAsc';
|
|
176
|
+
case 'price_desc':
|
|
177
|
+
return 'priceDesc';
|
|
178
|
+
case 'name_asc':
|
|
179
|
+
return 'nameAsc';
|
|
180
|
+
case 'name_desc':
|
|
181
|
+
return 'nameDesc';
|
|
182
|
+
default:
|
|
183
|
+
return displayOptions;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
62
188
|
* Validates all parameters. The selector will return null if one parameter is invalid.
|
|
63
189
|
* @param {Function} selector The original selector.
|
|
64
190
|
* @param {Object} [defaultResult] The result when the selector fails.
|
|
65
191
|
* @return {Function}
|
|
66
|
-
*/
|
|
192
|
+
*/
|
|
193
|
+
export const validateSelectorParams = (selector, defaultResult = null) => (...params) => {
|
|
194
|
+
if (params.some(param => param === null || typeof param === 'undefined')) {
|
|
195
|
+
return defaultResult;
|
|
196
|
+
}
|
|
197
|
+
return selector(...params);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
67
201
|
* @callback ArrayItemComparator
|
|
68
202
|
* @param {string} path
|
|
69
203
|
* @param {*} prev
|
|
@@ -71,7 +205,8 @@ return String.fromCharCode.apply(String,ret);};/**
|
|
|
71
205
|
* @param {number} prevIndex
|
|
72
206
|
* @param {number} nextIndex
|
|
73
207
|
* @returns {boolean}
|
|
74
|
-
*/
|
|
208
|
+
*/
|
|
209
|
+
/**
|
|
75
210
|
* Takes a destination object and a source and merges the source object into the destination.
|
|
76
211
|
* Differing properties will replaced. References are kept where possible.
|
|
77
212
|
* @param {Object} destination Object to mutate
|
|
@@ -79,15 +214,55 @@ return String.fromCharCode.apply(String,ret);};/**
|
|
|
79
214
|
* @param {boolean} [warn] Enables log output on mismatching types. Defaults to 'true'.
|
|
80
215
|
* @param {ArrayItemComparator|null} [arrayComparator] Defines how to compare array items.
|
|
81
216
|
* @param {string} [path] Path that specifies the position of a given merge within the object tree.
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
217
|
+
*/
|
|
218
|
+
export function assignObjectDeep(destination, source, warn = true, arrayComparator = null, path = '') {
|
|
219
|
+
// Avoids eslint warning on param mutation, which is necessary
|
|
220
|
+
const dest = destination;
|
|
221
|
+
const src = source;
|
|
222
|
+
|
|
223
|
+
// Don't do anything when types are scalar (can occur in recursion)
|
|
224
|
+
if (typeof dest !== 'object' || typeof src !== 'object') {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
Object.keys(src).forEach(key => {
|
|
228
|
+
const keyPath = `${path}.${key}`.replace(/^\./, '');
|
|
229
|
+
const prop = src[key];
|
|
230
|
+
if (!isObjectOrArray(dest[key]) || !isObjectOrArray(prop)) {
|
|
231
|
+
// output a warning if only one of both is an object (undefined dest is fine -> no warning)
|
|
232
|
+
if (warn && dest[key] !== undefined && (!isObjectOrArray(dest[key]) ? isObjectOrArray(prop) : !isObjectOrArray(prop))) {
|
|
233
|
+
logger.warn('Trying to merge object properties with mixed object types: ', prop, dest[key]);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Overwrite always if one of the props is not an object or array
|
|
237
|
+
dest[key] = prop;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Both structures are objects but one or both can be an array
|
|
242
|
+
if (isArray(prop) && isArray(dest[key])) {
|
|
243
|
+
// Try to keep reference of as many array items as possible
|
|
244
|
+
prop.forEach((element, destIndex) => {
|
|
245
|
+
const itemPath = `${keyPath}.${destIndex}`;
|
|
246
|
+
// Check if a maching array item exists for merging
|
|
247
|
+
const existing = dest[key].find((prev, prevIndex) => arrayComparator(itemPath, prev, element, prevIndex, destIndex));
|
|
248
|
+
|
|
249
|
+
// Merge into existing if found or add to array otherwise
|
|
250
|
+
if (existing !== undefined) {
|
|
251
|
+
// Scalar types can't be merged and will be ignored when an equal exists
|
|
252
|
+
assignObjectDeep(existing, element, warn, arrayComparator, itemPath);
|
|
253
|
+
} else {
|
|
254
|
+
dest[key].push(element);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
} else if (!isArray(prop) && !isArray(dest[key])) {
|
|
258
|
+
// Merge objects
|
|
259
|
+
assignObjectDeep(dest[key], prop, warn, arrayComparator, keyPath);
|
|
260
|
+
} else {
|
|
261
|
+
// Object types differ, print a warning
|
|
262
|
+
if (warn) {
|
|
263
|
+
logger.warn('Merging object properties with mixed object types: ', prop, dest[key]);
|
|
264
|
+
}
|
|
265
|
+
dest[key] = prop;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
package/helpers/data/spec.js
CHANGED
|
@@ -1,6 +1,100 @@
|
|
|
1
|
-
import{assignObjectDeep}from'.';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { assignObjectDeep } from '.';
|
|
2
|
+
import { isObject } from "../validation";
|
|
3
|
+
describe('helpers/data', () => {
|
|
4
|
+
describe('assignObjectDeep', () => {
|
|
5
|
+
it('should merge simple objects correctly', () => {
|
|
6
|
+
const modifier = {
|
|
7
|
+
b: 0,
|
|
8
|
+
c: null,
|
|
9
|
+
d: undefined,
|
|
10
|
+
g: 1.7,
|
|
11
|
+
h: 'g',
|
|
12
|
+
i: {
|
|
13
|
+
x: 'x'
|
|
14
|
+
},
|
|
15
|
+
j: ['a', 'b']
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Object to be mutated
|
|
19
|
+
const actual = {
|
|
20
|
+
a: 0,
|
|
21
|
+
b: 1,
|
|
22
|
+
c: 'abc',
|
|
23
|
+
d: 'def',
|
|
24
|
+
e: 'ghi',
|
|
25
|
+
f: null,
|
|
26
|
+
g: 1.6
|
|
27
|
+
};
|
|
28
|
+
assignObjectDeep(actual, modifier, false);
|
|
29
|
+
expect(actual).toEqual({
|
|
30
|
+
a: 0,
|
|
31
|
+
b: 0,
|
|
32
|
+
c: null,
|
|
33
|
+
d: undefined,
|
|
34
|
+
e: 'ghi',
|
|
35
|
+
f: null,
|
|
36
|
+
g: 1.7,
|
|
37
|
+
h: 'g',
|
|
38
|
+
i: {
|
|
39
|
+
x: 'x'
|
|
40
|
+
},
|
|
41
|
+
j: ['a', 'b']
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('should merge objects containing sub-objects correctly', () => {
|
|
45
|
+
const modifier = {
|
|
46
|
+
a: {
|
|
47
|
+
x: 2,
|
|
48
|
+
y: {
|
|
49
|
+
i: 'first mod',
|
|
50
|
+
k: 'new entry'
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
b: 'c',
|
|
54
|
+
c: undefined,
|
|
55
|
+
d: {
|
|
56
|
+
x: 'x'
|
|
57
|
+
},
|
|
58
|
+
e: ['a', 'b']
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Object to be mutated
|
|
62
|
+
const actual = {
|
|
63
|
+
a: {
|
|
64
|
+
x: 1,
|
|
65
|
+
y: {
|
|
66
|
+
i: 'first',
|
|
67
|
+
j: 'second'
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
b: {
|
|
71
|
+
x: 2,
|
|
72
|
+
y: {
|
|
73
|
+
i: 'first',
|
|
74
|
+
j: 'second'
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
assignObjectDeep(actual, modifier, false);
|
|
79
|
+
expect(actual).toEqual({
|
|
80
|
+
a: {
|
|
81
|
+
x: 2,
|
|
82
|
+
y: {
|
|
83
|
+
i: 'first mod',
|
|
84
|
+
j: 'second',
|
|
85
|
+
k: 'new entry'
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
b: 'c',
|
|
89
|
+
c: undefined,
|
|
90
|
+
d: {
|
|
91
|
+
x: 'x'
|
|
92
|
+
},
|
|
93
|
+
e: ['a', 'b']
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
it('should merge objects containing arrays correctly', () => {
|
|
97
|
+
/**
|
|
4
98
|
* This comparator detects unique scalar types and objects containing an id
|
|
5
99
|
* within the 'a' prop
|
|
6
100
|
*
|
|
@@ -8,7 +102,93 @@ var actual={a:{x:1,y:{i:'first',j:'second'}},b:{x:2,y:{i:'first',j:'second'}}};a
|
|
|
8
102
|
* @param {*} prev prev
|
|
9
103
|
* @param {*} next next
|
|
10
104
|
* @returns {boolean}
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
105
|
+
*/
|
|
106
|
+
const comparator = (path, prev, next) => {
|
|
107
|
+
// Scalar types
|
|
108
|
+
if (!isObject(prev) || !isObject(next)) {
|
|
109
|
+
return prev === next;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Object merge only occurring on array object-items within the 'a' prop
|
|
113
|
+
if (path.startsWith('$.a.')) {
|
|
114
|
+
return prev.id === next.id;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
118
|
+
const modifier = {
|
|
119
|
+
b: [1, 2, 3],
|
|
120
|
+
a: [['non-unique1', 'non-unique1'], 'unique element', 2, {
|
|
121
|
+
id: 'custom-id-2',
|
|
122
|
+
data: {
|
|
123
|
+
x: null,
|
|
124
|
+
y: {
|
|
125
|
+
i: 'first',
|
|
126
|
+
j: 'second mod',
|
|
127
|
+
k: 'third'
|
|
128
|
+
},
|
|
129
|
+
z: 'new data entry'
|
|
130
|
+
}
|
|
131
|
+
}, {
|
|
132
|
+
id: 'custom-id-3',
|
|
133
|
+
data: {
|
|
134
|
+
x: 'a'
|
|
135
|
+
}
|
|
136
|
+
}]
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Object to be mutated
|
|
140
|
+
const actual = {
|
|
141
|
+
a: [1, 'unique element', {
|
|
142
|
+
id: 'custom-id-1',
|
|
143
|
+
data: {
|
|
144
|
+
x: 1,
|
|
145
|
+
y: {
|
|
146
|
+
i: 'first',
|
|
147
|
+
j: 'second'
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}, {
|
|
151
|
+
id: 'custom-id-2',
|
|
152
|
+
data: {
|
|
153
|
+
x: 1,
|
|
154
|
+
y: {
|
|
155
|
+
i: 'first',
|
|
156
|
+
j: 'second'
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}, ['non-unique1', 'non-unique1']],
|
|
160
|
+
b: [0]
|
|
161
|
+
};
|
|
162
|
+
assignObjectDeep(actual, modifier, false, comparator, '$');
|
|
163
|
+
expect(actual).toEqual({
|
|
164
|
+
a: [1, 'unique element', {
|
|
165
|
+
id: 'custom-id-1',
|
|
166
|
+
data: {
|
|
167
|
+
x: 1,
|
|
168
|
+
y: {
|
|
169
|
+
i: 'first',
|
|
170
|
+
j: 'second'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}, {
|
|
174
|
+
id: 'custom-id-2',
|
|
175
|
+
data: {
|
|
176
|
+
x: null,
|
|
177
|
+
y: {
|
|
178
|
+
i: 'first',
|
|
179
|
+
j: 'second mod',
|
|
180
|
+
k: 'third'
|
|
181
|
+
},
|
|
182
|
+
z: 'new data entry'
|
|
183
|
+
}
|
|
184
|
+
}, ['non-unique1', 'non-unique1'], ['non-unique1', 'non-unique1'], 2, {
|
|
185
|
+
id: 'custom-id-3',
|
|
186
|
+
data: {
|
|
187
|
+
x: 'a'
|
|
188
|
+
}
|
|
189
|
+
}],
|
|
190
|
+
b: [0, 1, 2, 3]
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
package/helpers/date/index.js
CHANGED
|
@@ -1,28 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @refactor install moment.js
|
|
3
|
-
*/
|
|
3
|
+
*/
|
|
4
|
+
const durationRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
|
|
5
|
+
const durationModifiers = {
|
|
6
|
+
Year: (date, unit) => date.setFullYear(date.getFullYear() + unit),
|
|
7
|
+
Month: (date, unit) => date.setMonth(date.getMonth() + unit),
|
|
8
|
+
Week: (date, unit) => date.setDate(date.getDate() + unit * 7),
|
|
9
|
+
Day: (date, unit) => date.setDate(date.getDate() + unit),
|
|
10
|
+
Hour: (date, unit) => date.setHours(date.getHours() + unit),
|
|
11
|
+
Minute: (date, unit) => date.setMinutes(date.getMinutes() + unit),
|
|
12
|
+
Second: (date, unit) => date.setSeconds(date.getSeconds() + unit)
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
4
16
|
* Returns true if date exclusively before (<=).
|
|
5
17
|
* @param {Date} date date object.
|
|
6
18
|
* @param {Date} beforeDate comparison date.
|
|
7
19
|
* @return {boolean}.
|
|
8
|
-
*/
|
|
20
|
+
*/
|
|
21
|
+
export const isBefore = (date, beforeDate) => !!(beforeDate && date < beforeDate);
|
|
22
|
+
|
|
23
|
+
/**
|
|
9
24
|
* Returns true if date exclusively after (>=).
|
|
10
25
|
* @param {Date} date date object.
|
|
11
26
|
* @param {Date} afterDate comparison date.
|
|
12
27
|
* @return {boolean}.
|
|
13
|
-
*/
|
|
28
|
+
*/
|
|
29
|
+
export const isAfter = (date, afterDate) => !!(afterDate && date > afterDate);
|
|
30
|
+
|
|
31
|
+
/**
|
|
14
32
|
* Returns true if date inclusively between (>= & <=).
|
|
15
33
|
* @param {Date} date date object.
|
|
16
34
|
* @param {Date} leftDate left bound.
|
|
17
35
|
* @param {Date} rightDate right bound.
|
|
18
36
|
* @return {boolean}.
|
|
19
|
-
*/
|
|
37
|
+
*/
|
|
38
|
+
export const isBetween = (date, leftDate, rightDate) => {
|
|
39
|
+
if (!rightDate) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
if (!leftDate && rightDate) {
|
|
43
|
+
return isBefore(date, rightDate);
|
|
44
|
+
}
|
|
45
|
+
return date >= leftDate && date <= rightDate;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
20
49
|
* Parse duration
|
|
21
50
|
* @param {string} duration ISO 8601 duration.
|
|
22
51
|
* @return {Object}
|
|
23
|
-
*/
|
|
52
|
+
*/
|
|
53
|
+
export const parseDuration = duration => {
|
|
54
|
+
const d = durationRegex.exec(duration) || [];
|
|
55
|
+
const fr = d[1] === '-' ? -1 : 1;
|
|
56
|
+
return {
|
|
57
|
+
Year: d[2] && (d[2] > 0 ? d[2] * fr : d[2]),
|
|
58
|
+
Month: d[3] && (d[3] > 0 ? d[3] * fr : d[3]),
|
|
59
|
+
Week: d[4] && (d[4] > 0 ? d[4] * fr : d[4]),
|
|
60
|
+
Day: d[5] && (d[5] > 0 ? d[5] * fr : d[5]),
|
|
61
|
+
Hour: d[6] && (d[6] > 0 ? d[6] * fr : d[6]),
|
|
62
|
+
Minute: d[7] && (d[7] > 0 ? d[7] * fr : d[7]),
|
|
63
|
+
Second: d[8] && (d[8] > 0 ? d[8] * fr : d[8])
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
24
68
|
* Add duration to given date
|
|
25
69
|
* @param {Date} date date object.
|
|
26
70
|
* @param {string} duration ISO 8601 duration.
|
|
27
71
|
* @return {void}
|
|
28
|
-
*/
|
|
72
|
+
*/
|
|
73
|
+
export const addDuration = (date, duration) => {
|
|
74
|
+
const parsed = parseDuration(duration);
|
|
75
|
+
Object.keys(parsed).forEach(k => {
|
|
76
|
+
if (parsed[k]) {
|
|
77
|
+
durationModifiers[k](date, parsed[k]);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|