@applicaster/zapp-react-native-utils 15.0.0-rc.99 → 15.1.0-alpha.4285753931
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/actionsExecutor/ActionExecutorContext.tsx +51 -5
- package/actionsExecutor/feedDecorator.ts +6 -6
- package/adsUtils/index.ts +2 -2
- package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -2
- package/analyticsUtils/PlayerAnalyticsManager.ts +11 -1
- package/analyticsUtils/README.md +1 -1
- package/analyticsUtils/__tests__/analyticsMapper.test.ts +35 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testACP_events.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testBlockUnlistedParams_rules.json +1 -1
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEmptyRenameKeepsName_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testEventRegex_events.json +3 -9
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_events.json +18 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testIgnoreOrdering_rules.json +16 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexEventNoFallback_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexMultiGroupRename_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_events.json +4 -0
- package/analyticsUtils/__tests__/fixtures/analytics_mapper_testRegexNonNamedFullMatch_rules.json +6 -0
- package/analyticsUtils/__tests__/fixtures/index.js +20 -0
- package/analyticsUtils/analyticsMapper.ts +4 -1
- package/analyticsUtils/playerAnalyticsTracker.ts +26 -3
- package/appUtils/HooksManager/__tests__/__snapshots__/hooksManager.test.js.snap +188 -0
- package/appUtils/HooksManager/__tests__/hooksManager.test.js +2 -16
- package/appUtils/HooksManager/index.ts +47 -17
- package/appUtils/RiverFocusManager/{index.ts → index.js} +18 -25
- package/appUtils/accessibilityManager/const.ts +0 -4
- package/appUtils/accessibilityManager/utils.ts +1 -0
- package/appUtils/contextKeysManager/__tests__/getKeys/failure.test.ts +2 -7
- package/appUtils/contextKeysManager/__tests__/getKeys/success.test.ts +0 -48
- package/appUtils/contextKeysManager/contextResolver.ts +22 -51
- package/appUtils/contextKeysManager/index.ts +10 -65
- package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +0 -3
- package/appUtils/focusManager/index.ios.ts +4 -43
- package/appUtils/focusManagerAux/utils/index.ts +3 -5
- package/appUtils/focusManagerAux/utils/utils.ios.ts +3 -199
- package/appUtils/keyCodes/keys/keys.web.ts +4 -1
- package/appUtils/localizationsHelper.ts +4 -0
- package/appUtils/orientationHelper.ts +4 -2
- package/appUtils/platform/platformUtils.ts +1 -1
- package/appUtils/playerManager/__tests__/playerFactory.test.ts +150 -0
- package/appUtils/playerManager/index.ts +9 -0
- package/appUtils/playerManager/player.ts +1 -5
- package/appUtils/playerManager/playerFactory.ts +17 -34
- package/appUtils/playerManager/playerNative.ts +22 -30
- package/appUtils/playerManager/usePlayer.tsx +5 -3
- package/appUtils/playerManager/usePlayerState.tsx +2 -14
- package/cellUtils/__tests__/cellUtils.test.ts +39 -0
- package/cellUtils/index.ts +11 -1
- package/cloudEventsUtils/index.ts +1 -65
- package/configurationUtils/__tests__/manifestKeyParser.test.ts +26 -26
- package/dateUtils/__tests__/dayjs.test.ts +0 -3
- package/dateUtils/index.ts +2 -0
- package/focusManager/aux/index.ts +1 -1
- package/headersUtils/__tests__/headersUtils.test.js +1 -11
- package/headersUtils/index.ts +1 -2
- package/manifestUtils/defaultManifestConfigurations/player.js +7 -75
- package/manifestUtils/tvAction/container/index.js +1 -1
- package/numberUtils/__tests__/toNumber.test.ts +0 -12
- package/numberUtils/index.ts +1 -19
- package/package.json +4 -4
- package/pipesUtils/__tests__/buildUrlWithQuery.test.ts +33 -0
- package/pipesUtils/__tests__/withPipesEndpoint.test.tsx +56 -0
- package/pipesUtils/index.ts +1 -0
- package/pipesUtils/withPipesEndpoint.tsx +54 -0
- package/playerUtils/index.ts +24 -2
- package/pluginUtils/index.ts +4 -9
- package/reactHooks/advertising/index.ts +2 -2
- package/reactHooks/app/__tests__/useAppState.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackCurrentAutoScrollingElement.test.ts +1 -1
- package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +2 -1
- package/reactHooks/casting/index.ts +1 -0
- package/reactHooks/casting/useIsCasting.tsx +57 -0
- package/reactHooks/cell-click/__tests__/index.test.js +3 -1
- package/reactHooks/componentsMap/index.ts +55 -0
- package/reactHooks/configuration/__tests__/index.test.tsx +1 -1
- package/reactHooks/connection/__tests__/index.test.js +1 -1
- package/reactHooks/debugging/__tests__/index.test.js +4 -4
- package/reactHooks/device/useIsTablet.tsx +19 -14
- package/reactHooks/device/useMemoizedIsTablet.ts +3 -3
- package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +23 -32
- package/reactHooks/feed/__tests__/useBuildPipesUrl.test.tsx +19 -19
- package/reactHooks/feed/__tests__/useEntryScreenId.test.tsx +1 -4
- package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +30 -42
- package/reactHooks/feed/__tests__/useFeedRefresh.test.tsx +1 -1
- package/reactHooks/feed/__tests__/useInflatedUrl.test.tsx +1 -1
- package/reactHooks/feed/useBatchLoading.ts +1 -7
- package/reactHooks/feed/useEntryScreenId.ts +2 -2
- package/reactHooks/feed/useInflatedUrl.ts +1 -1
- package/reactHooks/feed/usePipesCacheReset.ts +1 -3
- package/reactHooks/flatList/useLoadNextPageIfNeeded.ts +16 -13
- package/reactHooks/layout/__tests__/index.test.tsx +1 -1
- package/reactHooks/layout/__tests__/useLayoutVersion.test.tsx +1 -1
- package/reactHooks/layout/useDimensions/__tests__/{useDimensions.test.tsx → useDimensions.test.ts} +25 -105
- package/reactHooks/layout/useDimensions/useDimensions.ts +2 -2
- package/reactHooks/navigation/__tests__/index.test.tsx +4 -2
- package/reactHooks/navigation/index.ts +6 -7
- package/reactHooks/navigation/useRoute.ts +6 -8
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +10 -27
- package/reactHooks/player/__tests__/useAutoSeek._test.tsx +1 -1
- package/reactHooks/player/__tests__/useTapSeek._test.ts +1 -1
- package/reactHooks/resolvers/__tests__/useCellResolver.test.tsx +1 -1
- package/reactHooks/resolvers/__tests__/useComponentResolver.test.tsx +1 -1
- package/reactHooks/resolvers/useCellResolver.ts +2 -6
- package/reactHooks/resolvers/useComponentResolver.ts +13 -9
- package/reactHooks/screen/__tests__/useCurrentScreenData.test.tsx +2 -2
- package/reactHooks/screen/__tests__/useCurrentScreenIsHook.test.ts +103 -0
- package/reactHooks/screen/__tests__/useCurrentScreenIsStartupHook.test.ts +94 -0
- package/reactHooks/screen/__tests__/useScreenBackgroundColor.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useScreenData.test.tsx +1 -1
- package/reactHooks/screen/__tests__/useTargetScreenData.test.tsx +4 -12
- package/reactHooks/screen/index.ts +6 -0
- package/reactHooks/screen/useCurrentScreenIsHook.ts +9 -0
- package/reactHooks/screen/useCurrentScreenIsStartupHook.ts +8 -0
- package/reactHooks/screen/useIsStandaloneFullscreen.ts +12 -0
- package/reactHooks/screen/useTargetScreenData.ts +2 -4
- package/reactHooks/state/__tests__/useComponentScreenState.test.ts +246 -0
- package/reactHooks/state/index.ts +2 -0
- package/reactHooks/state/useComponentScreenState.ts +45 -0
- package/reactHooks/state/useRivers.ts +1 -1
- package/reactHooks/usePluginConfiguration.ts +2 -2
- package/reactHooks/utils/__tests__/index.test.js +1 -1
- package/reactHooks/videoModal/hooks/useVideoModalScreenData.tsx +22 -4
- package/rectUtils/index.ts +2 -2
- package/riverComponetsMeasurementProvider/index.tsx +13 -13
- package/screenPickerUtils/index.ts +5 -0
- package/screenState/__tests__/index.test.ts +1 -1
- package/stringUtils/index.ts +1 -1
- package/testUtils/index.tsx +21 -30
- package/typeGuards/index.ts +0 -4
- package/utils/__tests__/clone.test.ts +158 -0
- package/utils/clone.ts +7 -0
- package/utils/index.ts +1 -13
- package/utils/path.ts +3 -6
- package/utils/pathOr.ts +1 -5
- package/zappFrameworkUtils/HookCallback/callbackNavigationAction.ts +2 -2
- package/zappFrameworkUtils/HookCallback/hookCallbackManifestExtensions.config.js +1 -1
- package/zappFrameworkUtils/loginPluginUtils.ts +1 -1
- package/adsUtils/__tests__/createVMAP.test.ts +0 -419
- package/appDataUtils/__tests__/urlScheme.test.ts +0 -678
- package/appUtils/focusManagerAux/utils/index.ios.ts +0 -122
- package/cloudEventsUtils/__tests__/index.test.ts +0 -529
- package/enumUtils/__tests__/getEnumKeyByEnumValue.test.ts +0 -207
- package/errorUtils/__tests__/GeneralError.test.ts +0 -97
- package/errorUtils/__tests__/HttpStatusCode.test.ts +0 -344
- package/errorUtils/__tests__/MissingPluginError.test.ts +0 -113
- package/errorUtils/__tests__/NetworkError.test.ts +0 -202
- package/errorUtils/__tests__/getParsedResponse.test.ts +0 -188
- package/errorUtils/__tests__/invariant.test.ts +0 -112
- package/numberUtils/__tests__/toPositiveNumber.test.ts +0 -165
- package/reactHooks/analytics/__tests__/useSendAnalyticsOnPress.test.ts +0 -537
- package/reactHooks/dev/__tests__/useReRenderLog.test.ts +0 -188
- package/reactHooks/ui/__tests__/useFadeOutWhenBlurred.test.ts +0 -580
- package/rectUtils/__tests__/index.test.ts +0 -549
- package/screenPickerUtils/__tests__/index.test.ts +0 -333
- package/searchUtils/const.ts +0 -7
- package/searchUtils/index.ts +0 -3
- package/time/__tests__/BackgroundTimer.test.ts +0 -156
- package/time/__tests__/Timer.test.ts +0 -236
- package/typeGuards/__tests__/isString.test.ts +0 -21
- package/utils/__tests__/mergeRight.test.ts +0 -48
- package/utils/__tests__/selectors.test.ts +0 -124
- package/utils/mergeRight.ts +0 -5
- package/utils/selectors.ts +0 -46
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useScreenContextV2 } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext";
|
|
3
|
+
import { useStore } from "zustand";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A custom hook that provides persistent state storage across component re-mounts
|
|
7
|
+
* using the screen's component state store.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link DOCS/adr/0010-useComponentScreenState.md} - ADR explaining why useComponentScreenState is used for List/Hero/Grid/Gallery components
|
|
10
|
+
*
|
|
11
|
+
* The state is shared across all components using the same componentId within the same screen context.
|
|
12
|
+
* If no value exists for the componentId, the initial value is returned as a fallback but is not persisted in the store.
|
|
13
|
+
* The initial value must be explicitly set using the returned setter function to persist it.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The type of value being stored
|
|
16
|
+
* @param componentId - Unique identifier for this state in the component state store
|
|
17
|
+
* @param initialValue - The default value if no value exists for the componentId
|
|
18
|
+
* @returns A tuple containing the current value and a memoized setter function
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* const [count, setCount] = useComponentScreenState<number>('counter', 0);
|
|
23
|
+
* const [name, setName] = useComponentScreenState<string>('username', 'Anonymous');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const useComponentScreenState = <T = unknown>(
|
|
27
|
+
componentId: string,
|
|
28
|
+
initialValue: T
|
|
29
|
+
): [T, (value: T) => void] => {
|
|
30
|
+
const store = useScreenContextV2()._componentStateStore;
|
|
31
|
+
|
|
32
|
+
const value = useStore(
|
|
33
|
+
store,
|
|
34
|
+
(state) => (state[componentId] as T | undefined) ?? initialValue
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const setValue = React.useCallback(
|
|
38
|
+
(nextValue: T) => {
|
|
39
|
+
store.setState({ [componentId]: nextValue });
|
|
40
|
+
},
|
|
41
|
+
[componentId, store]
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return [value, setValue] as const;
|
|
45
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
5
5
|
|
|
6
6
|
// importing this way prevents typescript packages importing from this
|
|
7
7
|
// file to go crazy reporting errors on JS
|
|
@@ -25,7 +25,7 @@ export function parsePluginConfiguration(plugin, manifest) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function usePluginConfiguration<T, S>(identifier, manifest) {
|
|
28
|
-
const plugins =
|
|
28
|
+
const { plugins } = usePickFromState(["plugins"]);
|
|
29
29
|
|
|
30
30
|
const plugin = useMemo(
|
|
31
31
|
() => R.find(R.propEq("identifier", identifier), plugins),
|
|
@@ -2,6 +2,12 @@ import React from "react";
|
|
|
2
2
|
import { useContentTypes } from "@applicaster/zapp-react-native-redux/hooks";
|
|
3
3
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
4
4
|
import { useRivers } from "../../state";
|
|
5
|
+
import { createLogger } from "../../../logger";
|
|
6
|
+
|
|
7
|
+
const { log_warning } = createLogger({
|
|
8
|
+
subsystem: "zapp-react-native-utils/reactHooks/videoModal",
|
|
9
|
+
category: "useVideoModalScreenData",
|
|
10
|
+
});
|
|
5
11
|
|
|
6
12
|
export const useVideoModalScreenData = ():
|
|
7
13
|
| (ZappEntry & { targetScreen: any }) // TODO: fix ZappEntry type ( was ZappRiver but conflict )
|
|
@@ -14,10 +20,22 @@ export const useVideoModalScreenData = ():
|
|
|
14
20
|
const rivers = useRivers();
|
|
15
21
|
|
|
16
22
|
return React.useMemo(() => {
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
const itemType = item?.type?.value;
|
|
24
|
+
|
|
25
|
+
if (!itemType) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
const screenId = contentTypes[itemType]?.screen_id;
|
|
30
|
+
|
|
31
|
+
if (!screenId) {
|
|
32
|
+
log_warning(
|
|
33
|
+
`Type mapping is missing for item type: ${itemType}, title: ${item.title}`
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return;
|
|
21
37
|
}
|
|
22
|
-
|
|
38
|
+
|
|
39
|
+
return { ...item, targetScreen: rivers?.[screenId] };
|
|
40
|
+
}, [contentTypes, item, rivers]);
|
|
23
41
|
};
|
package/rectUtils/index.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export function measureDimensionalIntersection(direction, current, target) {
|
|
11
11
|
if (direction.isHorizontal) {
|
|
12
|
-
return
|
|
12
|
+
return measureVerticalIntersectiont(current, target);
|
|
13
13
|
} else {
|
|
14
14
|
return measureHorizontalIntersection(current, target);
|
|
15
15
|
}
|
|
@@ -25,7 +25,7 @@ export function measureDimensionalIntersection(direction, current, target) {
|
|
|
25
25
|
* @param {Object} target rect object {right, left, top, bottom, x, y, width. height}
|
|
26
26
|
* @returns {Int} Returns vertical intersection of current and target object
|
|
27
27
|
*/
|
|
28
|
-
export function
|
|
28
|
+
export function measureVerticalIntersectiont(current, target) {
|
|
29
29
|
if (target.top >= current.bottom || target.bottom <= current.top) {
|
|
30
30
|
return 0;
|
|
31
31
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { NativeModules,
|
|
2
|
+
import { NativeModules, View, StyleSheet } from "react-native";
|
|
3
3
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
4
4
|
|
|
5
|
-
import { isApplePlatform, isWeb } from "../reactUtils";
|
|
5
|
+
import { isApplePlatform, isWeb, isTV } from "../reactUtils";
|
|
6
6
|
import { useRivers } from "../reactHooks";
|
|
7
7
|
|
|
8
|
+
const isTVPlatform = isTV();
|
|
9
|
+
|
|
10
|
+
const styles = StyleSheet.create({
|
|
11
|
+
container: isTVPlatform
|
|
12
|
+
? {
|
|
13
|
+
flex: 1,
|
|
14
|
+
}
|
|
15
|
+
: undefined,
|
|
16
|
+
});
|
|
17
|
+
|
|
8
18
|
const layoutReducer = (state, { payload }) => {
|
|
9
19
|
return state.map((item, index, _state) => ({
|
|
10
20
|
height: index === payload.index ? payload.height : item.height,
|
|
@@ -30,12 +40,6 @@ type MeasurementContext = {
|
|
|
30
40
|
onLayout: (index: number) => (event) => void;
|
|
31
41
|
};
|
|
32
42
|
|
|
33
|
-
const styles = StyleSheet.create({
|
|
34
|
-
container: {
|
|
35
|
-
flex: 1,
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
|
|
39
43
|
const { Logger } = getXray();
|
|
40
44
|
|
|
41
45
|
const logger = new Logger("general", "ui");
|
|
@@ -152,9 +156,5 @@ export const ScreenLoadingMeasurementsListItemWrapper = ({
|
|
|
152
156
|
}: ItemProps) => {
|
|
153
157
|
const { onLayout } = React.useContext(MeasurementsSettersContext);
|
|
154
158
|
|
|
155
|
-
return (
|
|
156
|
-
<View style={styles.container} onLayout={onLayout?.(index)}>
|
|
157
|
-
{children}
|
|
158
|
-
</View>
|
|
159
|
-
);
|
|
159
|
+
return <View onLayout={onLayout?.(index)}>{children}</View>;
|
|
160
160
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { endsWith } from "@applicaster/zapp-react-native-utils/utils";
|
|
2
|
+
|
|
1
3
|
export const getFocusableId = (id) => `PickerItem.${id}`;
|
|
2
4
|
|
|
3
5
|
export const getPickerSelectorId = (id) => `PickerSelector.${id}`;
|
|
@@ -11,3 +13,6 @@ export const getScreenPickerSelectorContainerId = (id) =>
|
|
|
11
13
|
|
|
12
14
|
export const getScreenPickerContentContainerId = (id) =>
|
|
13
15
|
`${getScreenPickerId(id)}-screen-container`;
|
|
16
|
+
|
|
17
|
+
export const isTabsScreenContentContainerId = (id) =>
|
|
18
|
+
endsWith("-screen-container", id);
|
package/stringUtils/index.ts
CHANGED
package/testUtils/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import React, { PropsWithChildren } from "react";
|
|
|
4
4
|
import configureStore from "redux-mock-store";
|
|
5
5
|
import { Provider } from "react-redux";
|
|
6
6
|
import { View } from "react-native";
|
|
7
|
-
import
|
|
7
|
+
import thunk from "redux-thunk";
|
|
8
8
|
import * as R from "ramda";
|
|
9
9
|
|
|
10
10
|
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
@@ -56,29 +56,9 @@ const initialState = {
|
|
|
56
56
|
contentTypes: null,
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const themeObjDefault = {
|
|
60
|
-
component_margin_top: 0,
|
|
61
|
-
component_margin_bottom: 0,
|
|
62
|
-
component_margin_left: 0,
|
|
63
|
-
component_margin_right: 0,
|
|
64
|
-
component_padding_top: 0,
|
|
65
|
-
component_padding_bottom: 0,
|
|
66
|
-
component_padding_left: 0,
|
|
67
|
-
component_padding_right: 0,
|
|
68
|
-
component_gutter_vertical: 0,
|
|
69
|
-
component_gutter_horizontal: 0,
|
|
70
|
-
component_corner_radius: 0,
|
|
71
|
-
app_background_color: "rgba(0,0,0,0)",
|
|
72
|
-
screen_margin_top: 0,
|
|
73
|
-
screen_margin_bottom: 0,
|
|
74
|
-
component_anchor_point_y: 0,
|
|
75
|
-
assets: "",
|
|
76
|
-
};
|
|
77
|
-
|
|
78
59
|
export const WrappedWithProviders = ({
|
|
79
60
|
children,
|
|
80
61
|
store: storeObj = {},
|
|
81
|
-
theme: themeObj = themeObjDefault,
|
|
82
62
|
}: any) => {
|
|
83
63
|
const _store = configureStore([thunk])(
|
|
84
64
|
R.mergeDeepRight(initialState, { ...storeObj })
|
|
@@ -90,7 +70,24 @@ export const WrappedWithProviders = ({
|
|
|
90
70
|
<ThemeContext.Provider
|
|
91
71
|
value={{
|
|
92
72
|
themes: {
|
|
93
|
-
light:
|
|
73
|
+
light: {
|
|
74
|
+
component_margin_top: 0,
|
|
75
|
+
component_margin_bottom: 0,
|
|
76
|
+
component_margin_left: 0,
|
|
77
|
+
component_margin_right: 0,
|
|
78
|
+
component_padding_top: 0,
|
|
79
|
+
component_padding_bottom: 0,
|
|
80
|
+
component_padding_left: 0,
|
|
81
|
+
component_padding_right: 0,
|
|
82
|
+
component_gutter_vertical: 0,
|
|
83
|
+
component_gutter_horizontal: 0,
|
|
84
|
+
component_corner_radius: 0,
|
|
85
|
+
app_background_color: "rgba(0,0,0,0)",
|
|
86
|
+
screen_margin_top: 0,
|
|
87
|
+
screen_margin_bottom: 0,
|
|
88
|
+
component_anchor_point_y: 0,
|
|
89
|
+
assets: "",
|
|
90
|
+
},
|
|
94
91
|
},
|
|
95
92
|
selectedThemeId: "light",
|
|
96
93
|
setSelectedThemeId: () => {},
|
|
@@ -116,17 +113,11 @@ export const WrappedWithProviders = ({
|
|
|
116
113
|
* @param store optional store to pass to the provider
|
|
117
114
|
* @returns
|
|
118
115
|
*/
|
|
119
|
-
export const renderWithProviders = (
|
|
120
|
-
component,
|
|
121
|
-
storeObj?: unknown,
|
|
122
|
-
themeObj?: unknown
|
|
123
|
-
) => {
|
|
116
|
+
export const renderWithProviders = (component, storeObj?: unknown) => {
|
|
124
117
|
return render(component, {
|
|
125
118
|
wrapper: function TestWrapper({ children }: PropsWithChildren<any>) {
|
|
126
119
|
return (
|
|
127
|
-
<WrappedWithProviders store={storeObj}
|
|
128
|
-
{children}
|
|
129
|
-
</WrappedWithProviders>
|
|
120
|
+
<WrappedWithProviders store={storeObj}>{children}</WrappedWithProviders>
|
|
130
121
|
);
|
|
131
122
|
},
|
|
132
123
|
});
|
package/typeGuards/index.ts
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { clone } from "../clone";
|
|
2
|
+
|
|
3
|
+
describe("clone", () => {
|
|
4
|
+
const originalStructuredClone = global.structuredClone;
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
// Restore the original structuredClone after each test
|
|
8
|
+
global.structuredClone = originalStructuredClone;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe("when structuredClone is available", () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
// Mock structuredClone if it's not available
|
|
14
|
+
if (typeof global.structuredClone === "undefined") {
|
|
15
|
+
global.structuredClone = jest.fn((value) =>
|
|
16
|
+
JSON.parse(JSON.stringify(value))
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("clones primitive values", () => {
|
|
22
|
+
expect(clone(42)).toBe(42);
|
|
23
|
+
expect(clone("test")).toBe("test");
|
|
24
|
+
expect(clone(true)).toBe(true);
|
|
25
|
+
expect(clone(null)).toBe(null);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("clones simple objects", () => {
|
|
29
|
+
const original = { a: 1, b: 2 };
|
|
30
|
+
const cloned = clone(original);
|
|
31
|
+
|
|
32
|
+
expect(cloned).toEqual(original);
|
|
33
|
+
expect(cloned).not.toBe(original);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("clones nested objects", () => {
|
|
37
|
+
const original = { a: { b: { c: 1 } } };
|
|
38
|
+
const cloned = clone(original);
|
|
39
|
+
|
|
40
|
+
expect(cloned).toEqual(original);
|
|
41
|
+
expect(cloned).not.toBe(original);
|
|
42
|
+
expect(cloned.a).not.toBe(original.a);
|
|
43
|
+
expect(cloned.a.b).not.toBe(original.a.b);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("clones arrays", () => {
|
|
47
|
+
const original = [1, 2, 3];
|
|
48
|
+
const cloned = clone(original);
|
|
49
|
+
|
|
50
|
+
expect(cloned).toEqual(original);
|
|
51
|
+
expect(cloned).not.toBe(original);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("clones arrays with nested objects", () => {
|
|
55
|
+
const original = [{ a: 1 }, { b: 2 }];
|
|
56
|
+
const cloned = clone(original);
|
|
57
|
+
|
|
58
|
+
expect(cloned).toEqual(original);
|
|
59
|
+
expect(cloned).not.toBe(original);
|
|
60
|
+
expect(cloned[0]).not.toBe(original[0]);
|
|
61
|
+
expect(cloned[1]).not.toBe(original[1]);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("does not mutate the original value", () => {
|
|
65
|
+
const original = { a: 1, b: { c: 2 } };
|
|
66
|
+
const cloned = clone(original);
|
|
67
|
+
|
|
68
|
+
cloned.a = 99;
|
|
69
|
+
cloned.b.c = 99;
|
|
70
|
+
|
|
71
|
+
expect(original.a).toBe(1);
|
|
72
|
+
expect(original.b.c).toBe(2);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("when structuredClone is not available (fallback to cloneDeep)", () => {
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
// Delete structuredClone to force fallback to cloneDeep
|
|
79
|
+
delete (global as any).structuredClone;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("clones primitive values using cloneDeep", () => {
|
|
83
|
+
expect(clone(42)).toBe(42);
|
|
84
|
+
expect(clone("test")).toBe("test");
|
|
85
|
+
expect(clone(true)).toBe(true);
|
|
86
|
+
expect(clone(null)).toBe(null);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("clones simple objects using cloneDeep", () => {
|
|
90
|
+
const original = { a: 1, b: 2 };
|
|
91
|
+
const cloned = clone(original);
|
|
92
|
+
|
|
93
|
+
expect(cloned).toEqual(original);
|
|
94
|
+
expect(cloned).not.toBe(original);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("clones nested objects using cloneDeep", () => {
|
|
98
|
+
const original = { a: { b: { c: 1 } } };
|
|
99
|
+
const cloned = clone(original);
|
|
100
|
+
|
|
101
|
+
expect(cloned).toEqual(original);
|
|
102
|
+
expect(cloned).not.toBe(original);
|
|
103
|
+
expect(cloned.a).not.toBe(original.a);
|
|
104
|
+
expect(cloned.a.b).not.toBe(original.a.b);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("clones arrays using cloneDeep", () => {
|
|
108
|
+
const original = [1, 2, 3];
|
|
109
|
+
const cloned = clone(original);
|
|
110
|
+
|
|
111
|
+
expect(cloned).toEqual(original);
|
|
112
|
+
expect(cloned).not.toBe(original);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("clones arrays with nested objects using cloneDeep", () => {
|
|
116
|
+
const original = [{ a: 1 }, { b: 2 }];
|
|
117
|
+
const cloned = clone(original);
|
|
118
|
+
|
|
119
|
+
expect(cloned).toEqual(original);
|
|
120
|
+
expect(cloned).not.toBe(original);
|
|
121
|
+
expect(cloned[0]).not.toBe(original[0]);
|
|
122
|
+
expect(cloned[1]).not.toBe(original[1]);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("does not mutate the original value when using cloneDeep", () => {
|
|
126
|
+
const original = { a: 1, b: { c: 2 } };
|
|
127
|
+
const cloned = clone(original);
|
|
128
|
+
|
|
129
|
+
cloned.a = 99;
|
|
130
|
+
cloned.b.c = 99;
|
|
131
|
+
|
|
132
|
+
expect(original.a).toBe(1);
|
|
133
|
+
expect(original.b.c).toBe(2);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("handles complex objects with multiple levels", () => {
|
|
137
|
+
const original = {
|
|
138
|
+
name: "test",
|
|
139
|
+
data: {
|
|
140
|
+
items: [
|
|
141
|
+
{ id: 1, value: "a" },
|
|
142
|
+
{ id: 2, value: "b" },
|
|
143
|
+
],
|
|
144
|
+
meta: { count: 2 },
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const cloned = clone(original);
|
|
149
|
+
|
|
150
|
+
expect(cloned).toEqual(original);
|
|
151
|
+
expect(cloned).not.toBe(original);
|
|
152
|
+
expect(cloned.data).not.toBe(original.data);
|
|
153
|
+
expect(cloned.data.items).not.toBe(original.data.items);
|
|
154
|
+
expect(cloned.data.items[0]).not.toBe(original.data.items[0]);
|
|
155
|
+
expect(cloned.data.meta).not.toBe(original.data.meta);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
package/utils/clone.ts
ADDED
package/utils/index.ts
CHANGED
|
@@ -18,10 +18,9 @@ export { take } from "./take";
|
|
|
18
18
|
|
|
19
19
|
export { mapAccum } from "./mapAccum";
|
|
20
20
|
|
|
21
|
-
export {
|
|
21
|
+
export { clone } from "./clone";
|
|
22
22
|
|
|
23
23
|
export {
|
|
24
|
-
cloneDeep as clone,
|
|
25
24
|
flatten,
|
|
26
25
|
drop,
|
|
27
26
|
size,
|
|
@@ -38,20 +37,9 @@ export {
|
|
|
38
37
|
last,
|
|
39
38
|
toLower,
|
|
40
39
|
isEqual as equals,
|
|
41
|
-
uniq,
|
|
42
40
|
uniqWith,
|
|
43
41
|
flowRight as compose,
|
|
44
42
|
partial,
|
|
45
|
-
clamp,
|
|
46
43
|
reverse,
|
|
47
|
-
takeRight,
|
|
48
|
-
fromPairs,
|
|
49
|
-
sortBy,
|
|
50
|
-
merge,
|
|
51
|
-
values,
|
|
52
|
-
head,
|
|
53
|
-
findIndex,
|
|
54
|
-
set,
|
|
55
44
|
compact,
|
|
56
|
-
identity,
|
|
57
45
|
} from "lodash";
|
package/utils/path.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { get } from "lodash";
|
|
2
2
|
|
|
3
|
-
export const path =
|
|
4
|
-
|
|
5
|
-
record: any
|
|
6
|
-
) => {
|
|
7
|
-
return pathOr<T>(undefined, route, record);
|
|
3
|
+
export const path = (route, record) => {
|
|
4
|
+
return get(record, route, undefined);
|
|
8
5
|
};
|
package/utils/pathOr.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { get } from "lodash";
|
|
2
2
|
|
|
3
|
-
export const pathOr =
|
|
4
|
-
defaultValue: T,
|
|
5
|
-
path: (number | string) | (number | string)[],
|
|
6
|
-
record: any
|
|
7
|
-
): T => {
|
|
3
|
+
export const pathOr = (defaultValue, path, record) => {
|
|
8
4
|
return get(record, path, defaultValue);
|
|
9
5
|
};
|
|
@@ -85,7 +85,7 @@ export const getNavigationKeys = (
|
|
|
85
85
|
const general = (item?.general ?? {}) as General;
|
|
86
86
|
|
|
87
87
|
const pluginIdentifier =
|
|
88
|
-
(item as any)
|
|
88
|
+
(item as any)?.identifier ?? item?.type ?? item?.component_type ?? "";
|
|
89
89
|
|
|
90
90
|
const legacy =
|
|
91
91
|
legacyMappingKeys[`${pluginIdentifier}.${resultType}`] ??
|
|
@@ -197,7 +197,7 @@ export const useCallbackNavigationAction = (
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
hookCallback?.({ ...args, success: false,
|
|
200
|
+
hookCallback?.({ ...args, success: false, abort: true });
|
|
201
201
|
const currentNavigation = navigationRef.current;
|
|
202
202
|
|
|
203
203
|
switch (data.action) {
|
|
@@ -20,7 +20,7 @@ const callbackKeyPrefix = (key, prefix, keySeparator = "_") =>
|
|
|
20
20
|
|
|
21
21
|
const extendManifestWithHookCallback = (prefix = null) => ({
|
|
22
22
|
group: true,
|
|
23
|
-
label: `
|
|
23
|
+
label: prefix ? `Callback Navigation: ${prefix}` : "Callback Navigation",
|
|
24
24
|
folded: true,
|
|
25
25
|
fields: [
|
|
26
26
|
{
|
|
@@ -20,7 +20,7 @@ const isAuthenticationRequired = ({ payload, logs }) => {
|
|
|
20
20
|
|
|
21
21
|
if (!payload) {
|
|
22
22
|
log_info(
|
|
23
|
-
"isAuthenticationRequired: No payload
|
|
23
|
+
"isAuthenticationRequired: No payload exists, authentication required"
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
return true;
|