@envive-ai/react-hooks 0.3.12 → 0.3.14
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/dist/application/commerce-api.cjs +4 -28
- package/dist/application/commerce-api.d.cts +1 -3
- package/dist/application/commerce-api.d.ts +1 -3
- package/dist/application/commerce-api.js +4 -28
- package/dist/application/models/featureGates.cjs +4 -1
- package/dist/application/models/featureGates.d.cts +4 -1
- package/dist/application/models/featureGates.d.ts +4 -1
- package/dist/application/models/featureGates.js +4 -1
- package/dist/application/utils/analyticsUtils.cjs +5 -5
- package/dist/application/utils/analyticsUtils.d.cts +2 -2
- package/dist/application/utils/analyticsUtils.d.ts +2 -2
- package/dist/application/utils/analyticsUtils.js +3 -3
- package/dist/atoms/app/index.d.ts +6 -6
- package/dist/atoms/app/variant.d.ts +6 -6
- package/dist/atoms/chat/chatState.cjs +5 -5
- package/dist/atoms/chat/chatState.d.cts +2 -2
- package/dist/atoms/chat/chatState.d.ts +2 -2
- package/dist/atoms/chat/chatState.js +3 -3
- package/dist/atoms/chat/form.d.cts +2 -2
- package/dist/atoms/chat/form.d.ts +3 -3
- package/dist/atoms/chat/index.d.ts +3 -3
- package/dist/atoms/chat/lastMessage.d.cts +2 -2
- package/dist/atoms/chat/lastMessage.d.ts +2 -2
- package/dist/atoms/chat/messageQueue.d.cts +6 -6
- package/dist/atoms/chat/messageQueue.d.ts +7 -7
- package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
- package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.ts +3 -3
- package/dist/atoms/chat/replies.cjs +4 -4
- package/dist/atoms/chat/replies.d.cts +2 -2
- package/dist/atoms/chat/replies.d.ts +3 -3
- package/dist/atoms/chat/replies.js +3 -3
- package/dist/atoms/chat/suggestions.d.cts +2 -2
- package/dist/atoms/chat/suggestions.d.ts +3 -3
- package/dist/atoms/envive/enviveConfig.d.cts +12 -12
- package/dist/atoms/envive/enviveConfig.d.ts +1 -1
- package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
- package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
- package/dist/atoms/org/customerService.d.cts +6 -6
- package/dist/atoms/org/graphqlConfig.d.cts +4 -4
- package/dist/atoms/org/graphqlConfig.d.ts +4 -4
- package/dist/atoms/org/index.cjs +1 -1
- package/dist/atoms/org/index.js +1 -1
- package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
- package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
- package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
- package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
- package/dist/atoms/search/chatSearch.d.cts +17 -17
- package/dist/atoms/search/chatSearch.d.ts +17 -17
- package/dist/atoms/search/searchAPI.d.cts +13 -13
- package/dist/atoms/search/searchAPI.d.ts +13 -13
- package/dist/atoms/search/utils.d.ts +1 -1
- package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
- package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
- package/dist/config/locators/components/search/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/amplitudeContext.cjs +5 -4
- package/dist/contexts/amplitudeContext/amplitudeContext.d.cts +3 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.d.ts +3 -2
- package/dist/contexts/amplitudeContext/amplitudeContext.js +5 -4
- package/dist/contexts/amplitudeContext/index.cjs +3 -3
- package/dist/contexts/amplitudeContext/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/index.d.ts +1 -1
- package/dist/contexts/amplitudeContext/index.js +1 -1
- package/dist/contexts/cdnContext/cdnContext.cjs +1 -1
- package/dist/contexts/cdnContext/cdnContext.js +1 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +1 -1
- package/dist/contexts/enviveConfigContext/enviveConfigContext.js +1 -1
- package/dist/contexts/enviveContext/types.d.cts +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.cjs +2 -2
- package/dist/contexts/graphqlContext/graphqlContext.js +2 -2
- package/dist/contexts/graphqlContext/mockV3Config.cjs +3 -2
- package/dist/contexts/graphqlContext/mockV3Config.js +3 -2
- package/dist/contexts/hardcopyContext/hardcopyContext.cjs +12 -9
- package/dist/contexts/hardcopyContext/hardcopyContext.js +10 -7
- package/dist/contexts/newOrgConfigContext/newOrgConfigContext.cjs +1 -1
- package/dist/contexts/newOrgConfigContext/newOrgConfigContext.js +1 -1
- package/dist/contexts/pageContext/pageContext.cjs +1 -1
- package/dist/contexts/pageContext/pageContext.js +1 -1
- package/dist/contexts/pageContext/types.d.cts +1 -1
- package/dist/contexts/salesAgentContext/chatAPI.cjs +11 -10
- package/dist/contexts/salesAgentContext/chatAPI.js +4 -3
- package/dist/contexts/salesAgentContext/salesAgentContext.cjs +1 -1
- package/dist/contexts/salesAgentContext/salesAgentContext.js +1 -1
- package/dist/contexts/salesAgentContext/salesAgentService.cjs +9 -8
- package/dist/contexts/salesAgentContext/salesAgentService.js +7 -6
- package/dist/contexts/searchContext/searchContext.cjs +2 -2
- package/dist/contexts/searchContext/searchContext.js +2 -2
- package/dist/contexts/systemSettingsContext/systemSettingsContext.cjs +1 -1
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
- package/dist/contexts/systemSettingsContext/systemSettingsContext.js +1 -1
- package/dist/contexts/types.d.cts +1 -1
- package/dist/contexts/types.d.ts +1 -1
- package/dist/contexts/typesV3.cjs +1 -1
- package/dist/contexts/typesV3.d.cts +10 -1
- package/dist/contexts/typesV3.d.ts +10 -1
- package/dist/contexts/typesV3.js +1 -1
- package/dist/contexts/userIdentityContext/userIdentityContext.cjs +2 -34
- package/dist/contexts/userIdentityContext/userIdentityContext.d.cts +1 -2
- package/dist/contexts/userIdentityContext/userIdentityContext.d.ts +1 -2
- package/dist/contexts/userIdentityContext/userIdentityContext.js +2 -33
- package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.cjs +1 -1
- package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.d.cts +2 -2
- package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.d.ts +2 -2
- package/dist/hooks/AmplitudeOperations/useAmplitudeOperations.js +1 -1
- package/dist/hooks/ChatToggle/useChatToggle.cjs +6 -5
- package/dist/hooks/ChatToggle/useChatToggle.js +4 -3
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
- package/dist/hooks/Search/useSearch.cjs +9 -8
- package/dist/hooks/Search/useSearch.js +4 -3
- package/dist/hooks/Search/useSearchInput.cjs +6 -6
- package/dist/hooks/Search/useSearchInput.js +3 -3
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.cjs +6 -5
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.d.cts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.d.ts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.js +3 -2
- package/dist/hooks/UpdateAnalyticsProps/useUpdateAnalyticsProps.cjs +4 -3
- package/dist/hooks/UpdateAnalyticsProps/useUpdateAnalyticsProps.js +3 -2
- package/dist/hooks/utils.d.cts +1 -1
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/services/amplitudeService/amplitudeService.cjs +17 -57
- package/dist/services/amplitudeService/amplitudeService.d.cts +4 -47
- package/dist/services/amplitudeService/amplitudeService.d.ts +4 -47
- package/dist/services/amplitudeService/amplitudeService.js +14 -52
- package/dist/services/amplitudeService/eventNames.cjs +59 -0
- package/dist/services/amplitudeService/eventNames.d.cts +54 -0
- package/dist/services/amplitudeService/eventNames.d.ts +54 -0
- package/dist/services/amplitudeService/eventNames.js +57 -0
- package/dist/services/amplitudeService/index.cjs +3 -2
- package/dist/services/amplitudeService/index.d.cts +2 -1
- package/dist/services/amplitudeService/index.d.ts +2 -1
- package/dist/services/amplitudeService/index.js +2 -1
- package/dist/services/ga4ProjectionService/ga4EventSchema.cjs +108 -0
- package/dist/services/ga4ProjectionService/ga4EventSchema.js +108 -0
- package/dist/services/ga4ProjectionService/ga4ProjectionService.cjs +71 -0
- package/dist/services/ga4ProjectionService/ga4ProjectionService.js +71 -0
- package/dist/types/customerService.cjs +4 -1
- package/dist/types/customerService.d.cts +4 -1
- package/dist/types/customerService.d.ts +4 -1
- package/dist/types/customerService.js +4 -1
- package/package.json +1 -6
- package/src/application/commerce-api.ts +0 -30
- package/src/application/models/featureGates.ts +3 -0
- package/src/application/utils/analyticsUtils.ts +1 -1
- package/src/atoms/chat/chatState.ts +1 -1
- package/src/atoms/chat/replies.ts +1 -1
- package/src/contexts/graphqlContext/mockV3Config.ts +3 -0
- package/src/contexts/hardcopyContext/hardcopyContext.tsx +2 -0
- package/src/contexts/salesAgentContext/salesAgentService.ts +5 -2
- package/src/contexts/typesV3.ts +10 -0
- package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +1 -66
- package/src/contexts/userIdentityContext/userIdentityContext.tsx +0 -47
- package/src/hooks/AmplitudeOperations/useAmplitudeOperations.ts +2 -4
- package/src/hooks/ChatToggle/useChatToggle.ts +2 -4
- package/src/hooks/Search/useSearch.tsx +2 -4
- package/src/hooks/Search/useSearchInput.ts +1 -1
- package/src/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.ts +2 -4
- package/src/hooks/UpdateAnalyticsProps/useUpdateAnalyticsProps.ts +2 -4
- package/src/services/amplitudeService/amplitudeService.ts +14 -50
- package/src/services/amplitudeService/eventNames.ts +52 -0
- package/src/services/ga4ProjectionService/__tests__/ga4ProjectionService.test.ts +334 -0
- package/src/services/ga4ProjectionService/ga4EventSchema.ts +143 -0
- package/src/services/ga4ProjectionService/ga4ProjectionService.ts +137 -0
- package/src/types/customerService.ts +3 -0
- package/dist/hooks/IdentifyUser/index.cjs +0 -3
- package/dist/hooks/IdentifyUser/index.d.cts +0 -2
- package/dist/hooks/IdentifyUser/index.d.ts +0 -2
- package/dist/hooks/IdentifyUser/index.js +0 -3
- package/dist/hooks/IdentifyUser/useIdentifyUser.cjs +0 -35
- package/dist/hooks/IdentifyUser/useIdentifyUser.d.cts +0 -10
- package/dist/hooks/IdentifyUser/useIdentifyUser.d.ts +0 -10
- package/dist/hooks/IdentifyUser/useIdentifyUser.js +0 -34
- package/src/hooks/IdentifyUser/index.ts +0 -1
- package/src/hooks/IdentifyUser/useIdentifyUser.ts +0 -29
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { EnviveMetricsEventName } from '../../amplitudeService/eventNames';
|
|
2
|
+
import { projectToGA4 } from '../ga4ProjectionService';
|
|
3
|
+
|
|
4
|
+
describe('projectToGA4', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
window.dataLayer = [];
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
delete (window as any).dataLayer;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('excluded events', () => {
|
|
14
|
+
it('should not push to dataLayer for WidgetTextRequest', () => {
|
|
15
|
+
projectToGA4(EnviveMetricsEventName.WidgetTextRequest, { widget_type: 'test' });
|
|
16
|
+
expect(window.dataLayer).toHaveLength(0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should not push to dataLayer for WidgetTextResponse', () => {
|
|
20
|
+
projectToGA4(EnviveMetricsEventName.WidgetTextResponse, { widget_type: 'test' });
|
|
21
|
+
expect(window.dataLayer).toHaveLength(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should not push to dataLayer for WidgetTextClicked', () => {
|
|
25
|
+
projectToGA4(EnviveMetricsEventName.WidgetTextClicked, { text: 'hello' });
|
|
26
|
+
expect(window.dataLayer).toHaveLength(0);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('Widget Rendered', () => {
|
|
31
|
+
it('should push filtered and flattened props', () => {
|
|
32
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
33
|
+
'context.page_type': 'pdp',
|
|
34
|
+
'context.page_id': 'product-123',
|
|
35
|
+
'trigger.widget': 'floating_button',
|
|
36
|
+
'trigger.interaction_id': 'abc-123',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(window.dataLayer).toHaveLength(1);
|
|
40
|
+
expect(window.dataLayer[0]).toEqual({
|
|
41
|
+
event: 'envive_widget_rendered',
|
|
42
|
+
context_page_type: 'pdp',
|
|
43
|
+
context_page_id: 'product-123',
|
|
44
|
+
trigger_widget: 'floating_button',
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should exclude fields not in allowedFields', () => {
|
|
49
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
50
|
+
'context.page_type': 'pdp',
|
|
51
|
+
'context.page_id': 'product-123',
|
|
52
|
+
'trigger.widget': 'floating_button',
|
|
53
|
+
'trigger.interaction_id': 'should-be-dropped',
|
|
54
|
+
'some.random_field': 'also-dropped',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const pushed = window.dataLayer[0];
|
|
58
|
+
expect(pushed).not.toHaveProperty('trigger_interaction_id');
|
|
59
|
+
expect(pushed).not.toHaveProperty('some_random_field');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('page_id sanitization', () => {
|
|
64
|
+
it('should keep page_id for pdp page type', () => {
|
|
65
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
66
|
+
'context.page_type': 'pdp',
|
|
67
|
+
'context.page_id': 'product-123',
|
|
68
|
+
'trigger.widget': 'floating_button',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(window.dataLayer[0]).toHaveProperty('context_page_id', 'product-123');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should keep page_id for plp page type', () => {
|
|
75
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
76
|
+
'context.page_type': 'plp',
|
|
77
|
+
'context.page_id': 'category-456',
|
|
78
|
+
'trigger.widget': 'floating_button',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(window.dataLayer[0]).toHaveProperty('context_page_id', 'category-456');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should omit page_id for search page type', () => {
|
|
85
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
86
|
+
'context.page_type': 'search',
|
|
87
|
+
'context.page_id': 'some search query',
|
|
88
|
+
'trigger.widget': 'floating_button',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(window.dataLayer[0]).not.toHaveProperty('context_page_id');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should omit page_id for homepage page type', () => {
|
|
95
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
96
|
+
'context.page_type': 'homepage',
|
|
97
|
+
'context.page_id': 'https://example.com',
|
|
98
|
+
'trigger.widget': 'floating_button',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(window.dataLayer[0]).not.toHaveProperty('context_page_id');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should omit page_id for other page type', () => {
|
|
105
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
106
|
+
'context.page_type': 'other',
|
|
107
|
+
'context.page_id': 'https://example.com/about',
|
|
108
|
+
'trigger.widget': 'floating_button',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(window.dataLayer[0]).not.toHaveProperty('context_page_id');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('Widget Interaction', () => {
|
|
116
|
+
it('should push base fields and flatten dot keys', () => {
|
|
117
|
+
projectToGA4(EnviveMetricsEventName.WidgetInteraction, {
|
|
118
|
+
'context.page_type': 'pdp',
|
|
119
|
+
'context.page_id': 'product-123',
|
|
120
|
+
'trigger.widget': 'chat_overlay',
|
|
121
|
+
'trigger.widget_interaction': 'link_clicked',
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
expect(window.dataLayer[0]).toEqual({
|
|
125
|
+
event: 'envive_widget_interaction',
|
|
126
|
+
context_page_type: 'pdp',
|
|
127
|
+
context_page_id: 'product-123',
|
|
128
|
+
trigger_widget: 'chat_overlay',
|
|
129
|
+
trigger_widget_interaction: 'link_clicked',
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should extract collapse_source from widget_interaction_data for widget_collapsed', () => {
|
|
134
|
+
projectToGA4(EnviveMetricsEventName.WidgetInteraction, {
|
|
135
|
+
'context.page_type': 'pdp',
|
|
136
|
+
'context.page_id': 'product-123',
|
|
137
|
+
'trigger.widget': 'chat_overlay',
|
|
138
|
+
'trigger.widget_interaction': 'widget_collapsed',
|
|
139
|
+
'trigger.widget_interaction_data': { collapse_source: 'close_button' },
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
expect(window.dataLayer[0]).toHaveProperty('trigger_collapse_source', 'close_button');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should extract product_id from widget_interaction_data for product_card_clicked', () => {
|
|
146
|
+
projectToGA4(EnviveMetricsEventName.WidgetInteraction, {
|
|
147
|
+
'context.page_type': 'pdp',
|
|
148
|
+
'context.page_id': 'product-123',
|
|
149
|
+
'trigger.widget': 'chat_overlay',
|
|
150
|
+
'trigger.widget_interaction': 'product_card_clicked',
|
|
151
|
+
'trigger.widget_interaction_data': { product_id: 'sku-789', url: 'https://example.com' },
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const pushed = window.dataLayer[0];
|
|
155
|
+
expect(pushed).toHaveProperty('trigger_product_id', 'sku-789');
|
|
156
|
+
expect(pushed).not.toHaveProperty('url');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should extract suggestion_id from widget_interaction_data for suggestion_scrolled', () => {
|
|
160
|
+
projectToGA4(EnviveMetricsEventName.WidgetInteraction, {
|
|
161
|
+
'context.page_type': 'pdp',
|
|
162
|
+
'context.page_id': 'product-123',
|
|
163
|
+
'trigger.widget': 'chat_overlay',
|
|
164
|
+
'trigger.widget_interaction': 'suggestion_scrolled',
|
|
165
|
+
'trigger.widget_interaction_data': { suggestion_id: 'sug-456' },
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
expect(window.dataLayer[0]).toHaveProperty('trigger_suggestion_id', 'sug-456');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should drop widget_interaction_data for unwhitelisted interactions', () => {
|
|
172
|
+
projectToGA4(EnviveMetricsEventName.WidgetInteraction, {
|
|
173
|
+
'context.page_type': 'pdp',
|
|
174
|
+
'context.page_id': 'product-123',
|
|
175
|
+
'trigger.widget': 'chat_overlay',
|
|
176
|
+
'trigger.widget_interaction': 'link_clicked',
|
|
177
|
+
'trigger.widget_interaction_data': { url: 'https://example.com' },
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const pushed = window.dataLayer[0];
|
|
181
|
+
expect(pushed).not.toHaveProperty('url');
|
|
182
|
+
expect(pushed).not.toHaveProperty('trigger_widget_interaction_data');
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe('Chat Request', () => {
|
|
187
|
+
it('should include only allowed fields', () => {
|
|
188
|
+
projectToGA4(EnviveMetricsEventName.ChatRequest, {
|
|
189
|
+
page_type: 'pdp',
|
|
190
|
+
page_id: 'product-123',
|
|
191
|
+
'trigger.widget': 'chat_overlay',
|
|
192
|
+
'chat.request_id': 'req-001',
|
|
193
|
+
'chat.request_type': 'suggestion',
|
|
194
|
+
'chat.request_text': 'Tell me about this product',
|
|
195
|
+
'chat.user_typed': false,
|
|
196
|
+
'chat.suggestion_id': 'sug-123',
|
|
197
|
+
'chat.suggestion_category': 'product_info',
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const pushed = window.dataLayer[0];
|
|
201
|
+
expect(pushed).toEqual({
|
|
202
|
+
event: 'envive_chat_request',
|
|
203
|
+
page_type: 'pdp',
|
|
204
|
+
page_id: 'product-123',
|
|
205
|
+
trigger_widget: 'chat_overlay',
|
|
206
|
+
chat_request_type: 'suggestion',
|
|
207
|
+
chat_user_typed: false,
|
|
208
|
+
chat_suggestion_id: 'sug-123',
|
|
209
|
+
chat_suggestion_category: 'product_info',
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe('Chat Response', () => {
|
|
215
|
+
it('should include only allowed fields', () => {
|
|
216
|
+
projectToGA4(EnviveMetricsEventName.ChatResponse, {
|
|
217
|
+
page_type: 'plp',
|
|
218
|
+
page_id: 'category-456',
|
|
219
|
+
'trigger.widget': 'chat_overlay',
|
|
220
|
+
'chat.response_time_ms': '1200',
|
|
221
|
+
'chat.request_type': 'text',
|
|
222
|
+
'chat.request_id': 'req-001',
|
|
223
|
+
'chat.request_text': 'Show me shoes',
|
|
224
|
+
'chat.user_typed': true,
|
|
225
|
+
'chat.product_cards_returned': 3,
|
|
226
|
+
'chat.review_cards_returned': 0,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const pushed = window.dataLayer[0];
|
|
230
|
+
expect(pushed).toEqual({
|
|
231
|
+
event: 'envive_chat_response',
|
|
232
|
+
page_type: 'plp',
|
|
233
|
+
page_id: 'category-456',
|
|
234
|
+
trigger_widget: 'chat_overlay',
|
|
235
|
+
chat_user_typed: true,
|
|
236
|
+
chat_response_time_ms: '1200',
|
|
237
|
+
chat_product_cards_returned: 3,
|
|
238
|
+
chat_review_cards_returned: 0,
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
describe('Envive Initialized', () => {
|
|
244
|
+
it('should include only allowed fields and drop environment details', () => {
|
|
245
|
+
projectToGA4(EnviveMetricsEventName.EnviveInitialized, {
|
|
246
|
+
'environment.execution_context': 'bundle',
|
|
247
|
+
'environment.page_url': 'https://example.com/products/shoe',
|
|
248
|
+
'environment.envive_user_id': 'user-abc',
|
|
249
|
+
'environment.execution_environment': 'prod',
|
|
250
|
+
'environment.context_source': 'app',
|
|
251
|
+
'environment.sales_agent_enabled': true,
|
|
252
|
+
'environment.search_enabled': false,
|
|
253
|
+
'environment.envive_on_query_param': false,
|
|
254
|
+
'environment.window_show': true,
|
|
255
|
+
'environment.client_session': true,
|
|
256
|
+
'environment.envive_enabled': true,
|
|
257
|
+
'performance.start_time_ms': 150,
|
|
258
|
+
'performance.initialize_time_ms': 320,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
expect(window.dataLayer[0]).toEqual({
|
|
262
|
+
event: 'envive_initialized',
|
|
263
|
+
environment_sales_agent_enabled: true,
|
|
264
|
+
environment_envive_enabled: true,
|
|
265
|
+
performance_start_time_ms: 150,
|
|
266
|
+
performance_initialize_time_ms: 320,
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
describe('Page Viewed', () => {
|
|
272
|
+
it('should use envive_page_context_evaluated as event name', () => {
|
|
273
|
+
projectToGA4(EnviveMetricsEventName.PageViewed, {
|
|
274
|
+
'context.page_type': 'pdp',
|
|
275
|
+
'context.page_id': 'product-123',
|
|
276
|
+
'context.supported': true,
|
|
277
|
+
'context.ready': true,
|
|
278
|
+
'context.page_variant_id': 'variant-A',
|
|
279
|
+
'environment.envive_enabled': true,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
expect(window.dataLayer[0]).toEqual({
|
|
283
|
+
event: 'envive_page_context_evaluated',
|
|
284
|
+
context_page_type: 'pdp',
|
|
285
|
+
context_page_id: 'product-123',
|
|
286
|
+
context_supported: true,
|
|
287
|
+
context_ready: true,
|
|
288
|
+
context_page_variant_id: 'variant-A',
|
|
289
|
+
environment_envive_enabled: true,
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should omit page_id for non-pdp/plp page types', () => {
|
|
294
|
+
projectToGA4(EnviveMetricsEventName.PageViewed, {
|
|
295
|
+
'context.page_type': 'search',
|
|
296
|
+
'context.page_id': 'shoes',
|
|
297
|
+
'context.supported': true,
|
|
298
|
+
'context.ready': true,
|
|
299
|
+
'environment.envive_enabled': true,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const pushed = window.dataLayer[0];
|
|
303
|
+
expect(pushed).not.toHaveProperty('context_page_id');
|
|
304
|
+
expect(pushed).toHaveProperty('context_page_type', 'search');
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe('edge cases', () => {
|
|
309
|
+
it('should handle undefined eventProps', () => {
|
|
310
|
+
projectToGA4(EnviveMetricsEventName.EnviveInitialized);
|
|
311
|
+
|
|
312
|
+
expect(window.dataLayer).toHaveLength(1);
|
|
313
|
+
expect(window.dataLayer[0]).toEqual({ event: 'envive_initialized' });
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('should handle empty eventProps', () => {
|
|
317
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {});
|
|
318
|
+
|
|
319
|
+
expect(window.dataLayer).toHaveLength(1);
|
|
320
|
+
expect(window.dataLayer[0]).toEqual({ event: 'envive_widget_rendered' });
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('should not throw when window.dataLayer is undefined', () => {
|
|
324
|
+
delete (window as any).dataLayer;
|
|
325
|
+
|
|
326
|
+
expect(() => {
|
|
327
|
+
projectToGA4(EnviveMetricsEventName.WidgetRendered, {
|
|
328
|
+
'context.page_type': 'pdp',
|
|
329
|
+
'trigger.widget': 'floating_button',
|
|
330
|
+
});
|
|
331
|
+
}).not.toThrow();
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GA4 Event Schema — single source of truth for Envive → GA4 projection.
|
|
3
|
+
*
|
|
4
|
+
* Every EnviveMetricsEventName MUST have an entry here. The Record type enforces
|
|
5
|
+
* this at compile time — adding a new enum member without a schema entry will
|
|
6
|
+
* cause a TypeScript error.
|
|
7
|
+
*
|
|
8
|
+
* ## How to update this file
|
|
9
|
+
*
|
|
10
|
+
* When adding or modifying event properties, decide whether they belong in `allowedFields` using these criteria:
|
|
11
|
+
* - **Low cardinality** — avoid unbounded values (free text, IDs, URLs, timestamps).
|
|
12
|
+
* - **Non-sensitive** — no PII, user input text, or internal implementation details.
|
|
13
|
+
* - **Flat scalar** — GA4 custom dimensions are flat strings/numbers/booleans.
|
|
14
|
+
* Nested objects should NOT be added; extract specific sub-fields instead.
|
|
15
|
+
* - **Snake_case key** — must already be dot-notation snake_case (e.g. `chat.user_typed`).
|
|
16
|
+
* - **Analytically useful** — the field should enable meaningful filtering/segmentation
|
|
17
|
+
* for merchants in their GA4 dashboards.
|
|
18
|
+
*
|
|
19
|
+
* If excluded from `allowedFields`, the projection layer will automatically drop it.
|
|
20
|
+
*
|
|
21
|
+
* IF IN DOUBT, DON'T HESITATE TO REACH OUT TO THE ANALYTICS TEAM!!!
|
|
22
|
+
*/
|
|
23
|
+
import { EnviveMetricsEventName } from '../amplitudeService/eventNames';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Defines which fields to extract from `trigger.widget_interaction_data`
|
|
27
|
+
* for a given `trigger.widget_interaction` value.
|
|
28
|
+
*
|
|
29
|
+
* Key: the value of `trigger.widget_interaction` (e.g. "widget_collapsed")
|
|
30
|
+
* Value: mapping of { ga4FlatKey: sourceFieldInWidgetInteractionData }
|
|
31
|
+
*/
|
|
32
|
+
export type WidgetInteractionDataProjection = Record<string, Record<string, string>>;
|
|
33
|
+
|
|
34
|
+
export interface GA4ProjectedEventConfig {
|
|
35
|
+
gaEventName: string;
|
|
36
|
+
allowedFields: readonly string[];
|
|
37
|
+
widgetInteractionDataProjections?: WidgetInteractionDataProjection;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface GA4ExcludedEventConfig {
|
|
41
|
+
gaEventName: null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type GA4EventSchemaEntry = GA4ProjectedEventConfig | GA4ExcludedEventConfig;
|
|
45
|
+
|
|
46
|
+
const WIDGET_INTERACTION_DATA_PROJECTIONS: WidgetInteractionDataProjection = {
|
|
47
|
+
widget_collapsed: { trigger_collapse_source: 'collapse_source' },
|
|
48
|
+
product_card_clicked: { trigger_product_id: 'product_id' },
|
|
49
|
+
suggestion_scrolled: { trigger_suggestion_id: 'suggestion_id' },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const GA4_EVENT_SCHEMA: Record<EnviveMetricsEventName, GA4EventSchemaEntry> = {
|
|
53
|
+
[EnviveMetricsEventName.WidgetRendered]: {
|
|
54
|
+
gaEventName: 'envive_widget_rendered',
|
|
55
|
+
allowedFields: [
|
|
56
|
+
'context.page_type',
|
|
57
|
+
'context.page_id',
|
|
58
|
+
'trigger.widget',
|
|
59
|
+
'trigger.widget_role',
|
|
60
|
+
'context.surface',
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// This event is not currently implemented
|
|
65
|
+
[EnviveMetricsEventName.WidgetInteraction]: {
|
|
66
|
+
gaEventName: 'envive_widget_interaction',
|
|
67
|
+
allowedFields: [
|
|
68
|
+
'context.page_type',
|
|
69
|
+
'context.page_id',
|
|
70
|
+
'trigger.widget',
|
|
71
|
+
'trigger.widget_interaction',
|
|
72
|
+
'trigger.entity_role',
|
|
73
|
+
'context.surface',
|
|
74
|
+
],
|
|
75
|
+
widgetInteractionDataProjections: WIDGET_INTERACTION_DATA_PROJECTIONS,
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
[EnviveMetricsEventName.ChatRequest]: {
|
|
79
|
+
gaEventName: 'envive_chat_request',
|
|
80
|
+
allowedFields: [
|
|
81
|
+
'page_type',
|
|
82
|
+
'page_id',
|
|
83
|
+
'trigger.widget',
|
|
84
|
+
'chat.request_type',
|
|
85
|
+
// 'chat.request_text', // This is high cardinality and potentially PII but we might want to include it later
|
|
86
|
+
'chat.user_typed',
|
|
87
|
+
'chat.suggestion_id', // not currently implemented
|
|
88
|
+
'chat.suggestion_category', // not currently implemented
|
|
89
|
+
'chat.suggestion_created_at', // not currently implemented
|
|
90
|
+
'chat.suggestion_is_answer', // not currently implemented
|
|
91
|
+
'chat.form_type', // not currently implemented
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
[EnviveMetricsEventName.ChatResponse]: {
|
|
96
|
+
gaEventName: 'envive_chat_response',
|
|
97
|
+
allowedFields: [
|
|
98
|
+
'page_type',
|
|
99
|
+
'page_id',
|
|
100
|
+
'trigger.widget', // not currently implemented (maybe it should'nt be???)
|
|
101
|
+
'chat.user_typed',
|
|
102
|
+
'chat.response_time_ms',
|
|
103
|
+
'chat.product_cards_returned',
|
|
104
|
+
'chat.review_cards_returned',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
[EnviveMetricsEventName.EnviveInitialized]: {
|
|
109
|
+
gaEventName: 'envive_initialized',
|
|
110
|
+
allowedFields: [
|
|
111
|
+
'environment.sales_agent_enabled',
|
|
112
|
+
'environment.envive_enabled',
|
|
113
|
+
// 'environment.search_enabled', // For now, search is not implemented. We will add it later.
|
|
114
|
+
'performance.start_time_ms',
|
|
115
|
+
'performance.initialize_time_ms',
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// This event is not currently implemented
|
|
120
|
+
[EnviveMetricsEventName.PageViewed]: {
|
|
121
|
+
gaEventName: 'envive_page_context_evaluated',
|
|
122
|
+
allowedFields: [
|
|
123
|
+
'context.page_type',
|
|
124
|
+
'context.page_id',
|
|
125
|
+
'context.supported',
|
|
126
|
+
'context.ready',
|
|
127
|
+
'context.page_variant_id',
|
|
128
|
+
'environment.envive_enabled',
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
[EnviveMetricsEventName.WidgetTextRequest]: {
|
|
133
|
+
gaEventName: null,
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
[EnviveMetricsEventName.WidgetTextResponse]: {
|
|
137
|
+
gaEventName: null,
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
[EnviveMetricsEventName.WidgetTextClicked]: {
|
|
141
|
+
gaEventName: null,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import Logger from 'src/application/logging/logger';
|
|
2
|
+
import { EnviveMetricsEventName } from '../amplitudeService/eventNames';
|
|
3
|
+
import { GA4ProjectedEventConfig, GA4_EVENT_SCHEMA } from './ga4EventSchema';
|
|
4
|
+
|
|
5
|
+
const filterToSchema = (
|
|
6
|
+
eventProps: Record<string, unknown>,
|
|
7
|
+
allowedFields: readonly string[],
|
|
8
|
+
): Record<string, unknown> => {
|
|
9
|
+
const result: Record<string, unknown> = {};
|
|
10
|
+
for (const field of allowedFields) {
|
|
11
|
+
if (field in eventProps) {
|
|
12
|
+
result[field] = eventProps[field];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// "context.page_type" → "context_page_type"
|
|
19
|
+
const flattenDotKeys = (obj: Record<string, unknown>): Record<string, unknown> => {
|
|
20
|
+
const result: Record<string, unknown> = {};
|
|
21
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
22
|
+
result[key.replace(/\./g, '_')] = value;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Omit context.page_id for non-pdp/plp page types. The current implementation for context.page_id is:
|
|
28
|
+
// PDP: product_id
|
|
29
|
+
// PLP: plp_id
|
|
30
|
+
// Search: search query
|
|
31
|
+
// Other: page url
|
|
32
|
+
// We want to omit all but pdp and plp page types to provide a clear, consistent interface for merchants.
|
|
33
|
+
const sanitizePageId = (filtered: Record<string, unknown>): Record<string, unknown> => {
|
|
34
|
+
const pageType = filtered['context.page_type'];
|
|
35
|
+
if (pageType === 'pdp' || pageType === 'plp') {
|
|
36
|
+
return filtered;
|
|
37
|
+
}
|
|
38
|
+
const rest = { ...filtered };
|
|
39
|
+
delete rest['context.page_id'];
|
|
40
|
+
return rest;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Extract whitelisted sub-fields from trigger.widget_interaction_data
|
|
44
|
+
const projectWidgetInteractionData = (
|
|
45
|
+
eventProps: Record<string, unknown>,
|
|
46
|
+
config: GA4ProjectedEventConfig,
|
|
47
|
+
): Record<string, unknown> => {
|
|
48
|
+
if (!config.widgetInteractionDataProjections) {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const interaction = eventProps['trigger.widget_interaction'];
|
|
53
|
+
if (typeof interaction !== 'string') {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const projectionMap = config.widgetInteractionDataProjections[interaction];
|
|
58
|
+
if (!projectionMap) {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const interactionData = eventProps['trigger.widget_interaction_data'];
|
|
63
|
+
if (
|
|
64
|
+
interactionData === null ||
|
|
65
|
+
interactionData === undefined ||
|
|
66
|
+
typeof interactionData !== 'object'
|
|
67
|
+
) {
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const data = interactionData as Record<string, unknown>;
|
|
72
|
+
const result: Record<string, unknown> = {};
|
|
73
|
+
for (const [gaKey, sourceField] of Object.entries(projectionMap)) {
|
|
74
|
+
if (sourceField in data) {
|
|
75
|
+
result[gaKey] = data[sourceField];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const truncateString = (value: unknown): unknown => {
|
|
82
|
+
if (typeof value === 'string' && value.length > 100) {
|
|
83
|
+
return `${value.substring(0, 97)}...`;
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const truncateValues = (obj: Record<string, unknown>): Record<string, unknown> => {
|
|
89
|
+
const result: Record<string, unknown> = {};
|
|
90
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
91
|
+
result[key] = truncateString(value);
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const pushToDataLayer = (gaEvent: Record<string, unknown>): void => {
|
|
97
|
+
if (typeof window !== 'undefined' && window.dataLayer) {
|
|
98
|
+
window.dataLayer.push(gaEvent);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const projectToGA4 = (
|
|
103
|
+
eventName: EnviveMetricsEventName,
|
|
104
|
+
eventProps?: Record<string, unknown>,
|
|
105
|
+
): void => {
|
|
106
|
+
try {
|
|
107
|
+
const schemaEntry = GA4_EVENT_SCHEMA[eventName];
|
|
108
|
+
|
|
109
|
+
if (schemaEntry.gaEventName === null) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const config = schemaEntry;
|
|
114
|
+
const props = eventProps ?? {};
|
|
115
|
+
|
|
116
|
+
let filtered = filterToSchema(props, config.allowedFields);
|
|
117
|
+
filtered = sanitizePageId(filtered);
|
|
118
|
+
|
|
119
|
+
const interactionFields = projectWidgetInteractionData(props, config);
|
|
120
|
+
|
|
121
|
+
const flatParams = {
|
|
122
|
+
...flattenDotKeys(filtered),
|
|
123
|
+
...interactionFields,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const truncatedParams = truncateValues(flatParams);
|
|
127
|
+
|
|
128
|
+
pushToDataLayer({
|
|
129
|
+
event: config.gaEventName,
|
|
130
|
+
...truncatedParams,
|
|
131
|
+
});
|
|
132
|
+
} catch (err) {
|
|
133
|
+
Logger.logError('[envive-ai] Error projecting event to GA4', err, {
|
|
134
|
+
eventName,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
@@ -11,6 +11,9 @@ export enum CustomerServiceType {
|
|
|
11
11
|
gladly = 'gladly',
|
|
12
12
|
richpanel = 'richpanel',
|
|
13
13
|
zendesk = 'zendesk',
|
|
14
|
+
helpscout = 'helpscout',
|
|
15
|
+
talkdesk = 'talkdesk',
|
|
16
|
+
eightByEight = '8x8',
|
|
14
17
|
unsupported = 'unsupported',
|
|
15
18
|
}
|
|
16
19
|
export enum CustomerServiceIntegrationMode {
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
-
const require_userIdentityContext = require('../../contexts/userIdentityContext/userIdentityContext.cjs');
|
|
3
|
-
let react = require("react");
|
|
4
|
-
|
|
5
|
-
//#region src/hooks/IdentifyUser/useIdentifyUser.ts
|
|
6
|
-
const useIdentifyUser = () => {
|
|
7
|
-
const { identifyUser, isReady } = require_userIdentityContext.useUserIdentity();
|
|
8
|
-
const [loading, setLoading] = (0, react.useState)(false);
|
|
9
|
-
const [error, setError] = (0, react.useState)(null);
|
|
10
|
-
return {
|
|
11
|
-
loading,
|
|
12
|
-
error,
|
|
13
|
-
executeIdentifyUser: (0, react.useCallback)(async () => {
|
|
14
|
-
if (!isReady) {
|
|
15
|
-
setError(/* @__PURE__ */ new Error("UserIdentityContext not ready."));
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
setLoading(true);
|
|
19
|
-
setError(null);
|
|
20
|
-
try {
|
|
21
|
-
await identifyUser();
|
|
22
|
-
} catch (err) {
|
|
23
|
-
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error during user identification."));
|
|
24
|
-
throw err;
|
|
25
|
-
} finally {
|
|
26
|
-
setLoading(false);
|
|
27
|
-
}
|
|
28
|
-
}, [identifyUser, isReady]),
|
|
29
|
-
isReady
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
//#endregion
|
|
34
|
-
exports.useIdentifyUser = useIdentifyUser;
|
|
35
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlSWRlbnRpZnlVc2VyLmNqcyIsIm5hbWVzIjpbInVzZVVzZXJJZGVudGl0eSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy9JZGVudGlmeVVzZXIvdXNlSWRlbnRpZnlVc2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZVVzZXJJZGVudGl0eSB9IGZyb20gJ3NyYy9jb250ZXh0cy91c2VySWRlbnRpdHlDb250ZXh0L3VzZXJJZGVudGl0eUNvbnRleHQnO1xuXG5leHBvcnQgY29uc3QgdXNlSWRlbnRpZnlVc2VyID0gKCkgPT4ge1xuICBjb25zdCB7IGlkZW50aWZ5VXNlciwgaXNSZWFkeSB9ID0gdXNlVXNlcklkZW50aXR5KCk7XG4gIGNvbnN0IFtsb2FkaW5nLCBzZXRMb2FkaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW2Vycm9yLCBzZXRFcnJvcl0gPSB1c2VTdGF0ZTxFcnJvciB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IGV4ZWN1dGVJZGVudGlmeVVzZXIgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKCFpc1JlYWR5KSB7XG4gICAgICBzZXRFcnJvcihuZXcgRXJyb3IoJ1VzZXJJZGVudGl0eUNvbnRleHQgbm90IHJlYWR5LicpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRMb2FkaW5nKHRydWUpO1xuICAgIHNldEVycm9yKG51bGwpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGlkZW50aWZ5VXNlcigpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgc2V0RXJyb3IoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIgOiBuZXcgRXJyb3IoJ1Vua25vd24gZXJyb3IgZHVyaW5nIHVzZXIgaWRlbnRpZmljYXRpb24uJykpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRMb2FkaW5nKGZhbHNlKTtcbiAgICB9XG4gIH0sIFtpZGVudGlmeVVzZXIsIGlzUmVhZHldKTtcblxuICByZXR1cm4geyBsb2FkaW5nLCBlcnJvciwgZXhlY3V0ZUlkZW50aWZ5VXNlciwgaXNSZWFkeSB9O1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFHQSxNQUFhLHdCQUF3QjtDQUNuQyxNQUFNLEVBQUUsY0FBYyxZQUFZQSw2Q0FBaUI7Q0FDbkQsTUFBTSxDQUFDLFNBQVMsa0NBQXVCLE1BQU07Q0FDN0MsTUFBTSxDQUFDLE9BQU8sZ0NBQW1DLEtBQUs7QUFxQnRELFFBQU87RUFBRTtFQUFTO0VBQU8sNENBbkJlLFlBQVk7QUFDbEQsT0FBSSxDQUFDLFNBQVM7QUFDWiw2QkFBUyxJQUFJLE1BQU0saUNBQWlDLENBQUM7QUFDckQ7O0FBR0YsY0FBVyxLQUFLO0FBQ2hCLFlBQVMsS0FBSztBQUVkLE9BQUk7QUFDRixVQUFNLGNBQWM7WUFDYixLQUFLO0FBQ1osYUFBUyxlQUFlLFFBQVEsc0JBQU0sSUFBSSxNQUFNLDRDQUE0QyxDQUFDO0FBQzdGLFVBQU07YUFDRTtBQUNSLGVBQVcsTUFBTTs7S0FFbEIsQ0FBQyxjQUFjLFFBQVEsQ0FBQztFQUVtQjtFQUFTIn0=
|