@envive-ai/react-hooks 0.3.18 → 0.3.19
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 +14 -13
- package/dist/application/commerce-api.js +14 -13
- package/dist/application/logging/logger.cjs +16 -10
- package/dist/application/logging/logger.js +16 -10
- package/dist/application/models/guards/api/isApiFormResponse.cjs +9 -8
- package/dist/application/models/guards/api/isApiFormResponse.js +9 -8
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +6 -5
- package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +6 -5
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +19 -18
- package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +19 -18
- package/dist/application/models/guards/api/isApiOrgConfigResults.cjs +27 -26
- package/dist/application/models/guards/api/isApiOrgConfigResults.js +27 -26
- package/dist/application/models/guards/api/isApiOrganizationConfig.cjs +23 -22
- package/dist/application/models/guards/api/isApiOrganizationConfig.js +23 -22
- package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +12 -11
- package/dist/application/models/guards/api/isApiProductResponseAttributes.js +12 -11
- package/dist/application/models/guards/api/isApiResponse.cjs +7 -6
- package/dist/application/models/guards/api/isApiResponse.js +7 -6
- package/dist/application/models/guards/graphQL/isGraphQLColorsConfig.cjs +5 -4
- package/dist/application/models/guards/graphQL/isGraphQLColorsConfig.js +5 -4
- package/dist/application/models/validators/validateGraphQLFrontendConfig.cjs +15 -14
- package/dist/application/models/validators/validateGraphQLFrontendConfig.js +15 -14
- package/dist/application/utils/analyticsUtils.cjs +4 -3
- package/dist/application/utils/analyticsUtils.js +4 -3
- package/dist/application/utils/nextMessageRequestToApiRequest.cjs +3 -1
- package/dist/application/utils/nextMessageRequestToApiRequest.js +3 -1
- package/dist/atoms/app/index.d.cts +7 -7
- package/dist/atoms/app/index.d.ts +7 -7
- package/dist/atoms/app/variant.cjs +3 -2
- package/dist/atoms/app/variant.js +3 -2
- package/dist/atoms/chat/chatState.d.cts +17 -17
- package/dist/atoms/chat/chatState.d.ts +17 -17
- package/dist/atoms/chat/form.d.cts +2 -2
- package/dist/atoms/chat/form.d.ts +2 -2
- package/dist/atoms/chat/index.d.cts +2 -2
- package/dist/atoms/chat/index.d.ts +2 -2
- 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 +6 -6
- package/dist/atoms/chat/performanceMetrics.cjs +3 -2
- package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
- package/dist/atoms/chat/performanceMetrics.js +3 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
- package/dist/atoms/chat/replies.d.cts +2 -2
- package/dist/atoms/chat/replies.d.ts +3 -3
- package/dist/atoms/chat/suggestions.d.cts +2 -2
- package/dist/atoms/chat/suggestions.d.ts +2 -2
- package/dist/atoms/envive/enviveConfig.cjs +5 -4
- package/dist/atoms/envive/enviveConfig.d.cts +13 -13
- package/dist/atoms/envive/enviveConfig.d.ts +13 -13
- package/dist/atoms/envive/enviveConfig.js +5 -4
- 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/customerService.d.ts +6 -6
- package/dist/atoms/org/graphqlConfig.d.cts +4 -4
- package/dist/atoms/org/graphqlConfig.d.ts +4 -4
- 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/types.d.cts +1 -1
- package/dist/atoms/search/types.d.ts +1 -1
- 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/contexts/amplitudeContext/amplitudeContext.cjs +4 -3
- package/dist/contexts/amplitudeContext/amplitudeContext.js +3 -2
- package/dist/contexts/enviveConfigContext/enviveConfigContext.cjs +26 -15
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.cts +2 -4
- package/dist/contexts/enviveConfigContext/enviveConfigContext.d.ts +2 -4
- package/dist/contexts/enviveConfigContext/enviveConfigContext.js +29 -16
- package/dist/contexts/enviveConfigContext/index.cjs +2 -1
- package/dist/contexts/enviveConfigContext/index.d.cts +2 -1
- package/dist/contexts/enviveConfigContext/index.d.ts +2 -1
- package/dist/contexts/enviveConfigContext/index.js +2 -1
- package/dist/contexts/enviveConfigContext/useEnviveConfig.cjs +12 -0
- package/dist/contexts/enviveConfigContext/useEnviveConfig.d.cts +7 -0
- package/dist/contexts/enviveConfigContext/useEnviveConfig.d.ts +7 -0
- package/dist/contexts/enviveConfigContext/useEnviveConfig.js +11 -0
- package/dist/contexts/enviveContext/WindowChatToggleBinder.cjs +7 -5
- package/dist/contexts/enviveContext/WindowChatToggleBinder.js +6 -4
- package/dist/contexts/enviveContext/enviveContext.cjs +34 -39
- package/dist/contexts/enviveContext/enviveContext.js +35 -40
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +7 -6
- package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +7 -6
- package/dist/contexts/graphqlContext/graphqlContext.cjs +8 -7
- package/dist/contexts/graphqlContext/graphqlContext.js +8 -7
- package/dist/contexts/hardcopyContext/hardcopyContext.cjs +9 -8
- package/dist/contexts/hardcopyContext/hardcopyContext.js +9 -8
- package/dist/contexts/localStorageContext/localStorageContext.cjs +4 -3
- package/dist/contexts/localStorageContext/localStorageContext.js +4 -3
- package/dist/contexts/pageContext/pageContext.cjs +3 -2
- package/dist/contexts/pageContext/pageContext.js +3 -2
- package/dist/contexts/salesAgentContext/chatAPI.cjs +3 -2
- package/dist/contexts/salesAgentContext/chatAPI.js +3 -2
- package/dist/contexts/salesAgentContext/salesAgentContext.cjs +4 -3
- package/dist/contexts/salesAgentContext/salesAgentContext.js +4 -3
- package/dist/contexts/salesAgentContext/salesAgentService.cjs +3 -2
- package/dist/contexts/salesAgentContext/salesAgentService.js +3 -2
- package/dist/contexts/searchContext/searchContext.cjs +8 -6
- package/dist/contexts/searchContext/searchContext.js +7 -5
- package/dist/contexts/sessionStorageContext/sessionStorageContext.cjs +3 -2
- package/dist/contexts/sessionStorageContext/sessionStorageContext.js +3 -2
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
- package/dist/contexts/types.d.cts +1 -1
- package/dist/contexts/types.d.ts +1 -1
- package/dist/contexts/typesV3.d.cts +1 -1
- package/dist/contexts/typesV3.d.ts +1 -1
- package/dist/contexts/uiConfigContext/index.cjs +0 -1
- package/dist/contexts/uiConfigContext/index.d.cts +2 -2
- package/dist/contexts/uiConfigContext/index.d.ts +2 -2
- package/dist/contexts/uiConfigContext/index.js +2 -2
- package/dist/contexts/uiConfigContext/uiConfigContext.cjs +13 -30
- package/dist/contexts/uiConfigContext/uiConfigContext.d.cts +5 -9
- package/dist/contexts/uiConfigContext/uiConfigContext.d.ts +5 -9
- package/dist/contexts/uiConfigContext/uiConfigContext.js +14 -29
- package/dist/contexts/userIdentityContext/userIdentityContext.cjs +7 -7
- package/dist/contexts/userIdentityContext/userIdentityContext.js +7 -7
- package/dist/contexts/widgetConfigContext/widgetConfigContext.cjs +4 -3
- package/dist/contexts/widgetConfigContext/widgetConfigContext.js +4 -3
- package/dist/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.cjs +4 -3
- package/dist/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.js +4 -3
- package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
- package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.cts +2 -2
- package/dist/hooks/WidgetInteraction/useWidgetInteraction.cjs +2 -2
- package/dist/hooks/WidgetInteraction/useWidgetInteraction.js +2 -2
- package/dist/hooks/WidgetInteraction/utils.cjs +2 -1
- package/dist/hooks/WidgetInteraction/utils.js +2 -1
- package/dist/hooks/utils.d.cts +1 -1
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/services/amplitudeService/amplitudeService.cjs +8 -7
- package/dist/services/amplitudeService/amplitudeService.js +8 -7
- package/dist/services/ga4ProjectionService/ga4ProjectionService.cjs +3 -2
- package/dist/services/ga4ProjectionService/ga4ProjectionService.js +3 -2
- package/dist/services/userIdentityService/userIdentityService.cjs +8 -7
- package/dist/services/userIdentityService/userIdentityService.js +8 -7
- package/package.json +1 -1
- package/src/application/commerce-api.ts +14 -12
- package/src/application/logging/logger.ts +33 -8
- package/src/application/models/guards/api/isApiFormResponse.ts +9 -7
- package/src/application/models/guards/api/isApiFormSubmittedResponseAttributes.ts +6 -4
- package/src/application/models/guards/api/isApiOrderResponseAttributes.ts +19 -17
- package/src/application/models/guards/api/isApiOrgConfigResults.ts +40 -48
- package/src/application/models/guards/api/isApiOrganizationConfig.ts +25 -38
- package/src/application/models/guards/api/isApiProductResponseAttributes.ts +12 -10
- package/src/application/models/guards/api/isApiResponse.ts +7 -5
- package/src/application/models/guards/graphQL/isGraphQLColorsConfig.ts +5 -3
- package/src/application/models/validators/validateGraphQLFrontendConfig.ts +15 -13
- package/src/application/utils/analyticsUtils.ts +4 -4
- package/src/application/utils/nextMessageRequestToApiRequest.ts +2 -0
- package/src/atoms/app/variant.ts +3 -1
- package/src/atoms/chat/performanceMetrics.ts +3 -1
- package/src/atoms/envive/enviveConfig.ts +5 -3
- package/src/contexts/amplitudeContext/amplitudeContext.tsx +1 -1
- package/src/contexts/enviveConfigContext/__tests__/enviveConfigContext.test.tsx +4 -3
- package/src/contexts/enviveConfigContext/enviveConfigContext.tsx +50 -35
- package/src/contexts/enviveConfigContext/index.ts +1 -0
- package/src/contexts/enviveConfigContext/useEnviveConfig.ts +9 -0
- package/src/contexts/enviveContext/WindowChatToggleBinder.tsx +6 -4
- package/src/contexts/enviveContext/enviveContext.tsx +40 -45
- package/src/contexts/featureFlagServiceContext/featureFlagServiceContext.tsx +11 -12
- package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +4 -4
- package/src/contexts/graphqlContext/graphqlContext.tsx +8 -6
- package/src/contexts/hardcopyContext/hardcopyContext.tsx +9 -7
- package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +6 -6
- package/src/contexts/localStorageContext/localStorageContext.tsx +4 -2
- package/src/contexts/pageContext/__tests__/pageContext.test.tsx +5 -5
- package/src/contexts/pageContext/pageContext.tsx +3 -1
- package/src/contexts/salesAgentContext/chatAPI.ts +5 -5
- package/src/contexts/salesAgentContext/salesAgentContext.tsx +4 -2
- package/src/contexts/salesAgentContext/salesAgentService.ts +4 -2
- package/src/contexts/searchContext/__tests__/searchContext.test.tsx +15 -12
- package/src/contexts/searchContext/searchContext.tsx +6 -4
- package/src/contexts/sessionStorageContext/sessionStorageContext.tsx +3 -1
- package/src/contexts/uiConfigContext/__tests__/uiConfigContext.test.tsx +7 -32
- package/src/contexts/uiConfigContext/uiConfigContext.tsx +17 -29
- package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +5 -5
- package/src/contexts/userIdentityContext/userIdentityContext.tsx +7 -6
- package/src/contexts/widgetConfigContext/__tests__/widgetConfigContext.test.tsx +7 -7
- package/src/contexts/widgetConfigContext/widgetConfigContext.tsx +4 -2
- package/src/hooks/CustomerSupportHandoff/useCustomerSupportHandoff.ts +4 -2
- package/src/hooks/Search/__tests__/useSearch.test.tsx +14 -8
- package/src/hooks/WidgetInteraction/useWidgetInteraction.ts +3 -2
- package/src/hooks/WidgetInteraction/utils.ts +3 -1
- package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +3 -3
- package/src/services/amplitudeService/amplitudeService.ts +8 -6
- package/src/services/ga4ProjectionService/ga4ProjectionService.ts +3 -1
- package/src/services/userIdentityService/userIdentityService.ts +8 -8
|
@@ -2,11 +2,13 @@ import Logger from 'src/application/logging/logger';
|
|
|
2
2
|
import { ResponseProductAttributes } from '@spiffy-ai/commerce-api-client';
|
|
3
3
|
import { hasPropertyOfType } from '../utils';
|
|
4
4
|
|
|
5
|
+
const logger = new Logger('isApiProductResponseAttributes');
|
|
6
|
+
|
|
5
7
|
export const isApiProductResponseAttributes = (
|
|
6
8
|
attributes: unknown,
|
|
7
9
|
): attributes is ResponseProductAttributes => {
|
|
8
10
|
if (attributes == null || typeof attributes !== 'object') {
|
|
9
|
-
|
|
11
|
+
logger.logError(
|
|
10
12
|
'isApiProductResponseAttributes: attributes is null or not an object',
|
|
11
13
|
undefined,
|
|
12
14
|
{
|
|
@@ -17,63 +19,63 @@ export const isApiProductResponseAttributes = (
|
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
if (!hasPropertyOfType(attributes, 'description', 'string', true)) {
|
|
20
|
-
|
|
22
|
+
logger.logError('isApiProductResponseAttributes: description is not a string', undefined, {
|
|
21
23
|
attributes,
|
|
22
24
|
});
|
|
23
25
|
return false;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
if (!hasPropertyOfType(attributes, 'image_url', 'string', true)) {
|
|
27
|
-
|
|
29
|
+
logger.logError('isApiProductResponseAttributes: image_url is not a string', undefined, {
|
|
28
30
|
attributes,
|
|
29
31
|
});
|
|
30
32
|
return false;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
if (!hasPropertyOfType(attributes, 'title', 'string')) {
|
|
34
|
-
|
|
36
|
+
logger.logError('isApiProductResponseAttributes: title is not a string', undefined, {
|
|
35
37
|
attributes,
|
|
36
38
|
});
|
|
37
39
|
return false;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
if (!hasPropertyOfType(attributes, 'url', 'string')) {
|
|
41
|
-
|
|
43
|
+
logger.logError('isApiProductResponseAttributes: url is not a string', undefined, {
|
|
42
44
|
attributes,
|
|
43
45
|
});
|
|
44
46
|
return false;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
if (!hasPropertyOfType(attributes, 'original_price', 'number', true)) {
|
|
48
|
-
|
|
50
|
+
logger.logError('isApiProductResponseAttributes: original_price is not a number', undefined, {
|
|
49
51
|
attributes,
|
|
50
52
|
});
|
|
51
53
|
return false;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
if (!hasPropertyOfType(attributes, 'sale_price', 'number', true)) {
|
|
55
|
-
|
|
57
|
+
logger.logError('isApiProductResponseAttributes: sale_price is not a number', undefined, {
|
|
56
58
|
attributes,
|
|
57
59
|
});
|
|
58
60
|
return false;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
if (!hasPropertyOfType(attributes, 'average_rating', 'number', true)) {
|
|
62
|
-
|
|
64
|
+
logger.logError('isApiProductResponseAttributes: average_rating is not a number', undefined, {
|
|
63
65
|
attributes,
|
|
64
66
|
});
|
|
65
67
|
return false;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
if (!hasPropertyOfType(attributes, 'number_reviews', 'number', true)) {
|
|
69
|
-
|
|
71
|
+
logger.logError('isApiProductResponseAttributes: number_reviews is not a number', undefined, {
|
|
70
72
|
attributes,
|
|
71
73
|
});
|
|
72
74
|
return false;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
if (!hasPropertyOfType(attributes, 'metadata', 'array', true)) {
|
|
76
|
-
|
|
78
|
+
logger.logError('isApiProductResponseAttributes: metadata is not an array', undefined, {
|
|
77
79
|
attributes,
|
|
78
80
|
});
|
|
79
81
|
return false;
|
|
@@ -2,14 +2,16 @@ import Logger from 'src/application/logging/logger';
|
|
|
2
2
|
import { Response, ResponseCategory } from '@spiffy-ai/commerce-api-client';
|
|
3
3
|
import { hasPropertyOfType } from 'src/application/models/guards/utils';
|
|
4
4
|
|
|
5
|
+
const logger = new Logger('isApiResponse');
|
|
6
|
+
|
|
5
7
|
export const isApiResponse = (data: unknown): data is Response => {
|
|
6
8
|
if (data == null || typeof data !== 'object') {
|
|
7
|
-
|
|
9
|
+
logger.logError('isApiResponse: data is null or not an object', undefined, { data });
|
|
8
10
|
return false;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
if (!hasPropertyOfType(data, 'id', 'string')) {
|
|
12
|
-
|
|
14
|
+
logger.logError('isApiResponse: id is not a string', undefined, { data });
|
|
13
15
|
return false;
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -17,7 +19,7 @@ export const isApiResponse = (data: unknown): data is Response => {
|
|
|
17
19
|
!hasPropertyOfType(data, 'category', 'string') ||
|
|
18
20
|
!Object.values(ResponseCategory).includes(data.category as ResponseCategory)
|
|
19
21
|
) {
|
|
20
|
-
|
|
22
|
+
logger.logError(
|
|
21
23
|
'isApiResponse: category is not a string or not a valid response category',
|
|
22
24
|
undefined,
|
|
23
25
|
{ data },
|
|
@@ -26,12 +28,12 @@ export const isApiResponse = (data: unknown): data is Response => {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
if (!hasPropertyOfType(data, 'created_at', 'string')) {
|
|
29
|
-
|
|
31
|
+
logger.logError('isApiResponse: created_at is not a string', undefined, { data });
|
|
30
32
|
return false;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
if (!hasPropertyOfType(data, 'attributes', 'object', true)) {
|
|
34
|
-
|
|
36
|
+
logger.logError('isApiResponse: attributes is not an object', undefined, { data });
|
|
35
37
|
return false;
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -22,9 +22,11 @@ const REQUIRED_COLOR_FIELDS = [
|
|
|
22
22
|
'text_secondary',
|
|
23
23
|
] as const;
|
|
24
24
|
|
|
25
|
+
const logger = new Logger('isGraphQLColorsConfig');
|
|
26
|
+
|
|
25
27
|
export const isGraphQLColorsConfig = (data: unknown): data is GetMerchantColorsQueryData => {
|
|
26
28
|
if (typeof data !== 'object' || data === null) {
|
|
27
|
-
|
|
29
|
+
logger.logError('Invalid graphql response for colors config', undefined, { data });
|
|
28
30
|
return false;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -34,12 +36,12 @@ export const isGraphQLColorsConfig = (data: unknown): data is GetMerchantColorsQ
|
|
|
34
36
|
);
|
|
35
37
|
|
|
36
38
|
if (missingFields.length === REQUIRED_COLOR_FIELDS.length) {
|
|
37
|
-
|
|
39
|
+
logger.logError('All color fields are missing or null', undefined);
|
|
38
40
|
return false;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
if (missingFields.length > 0) {
|
|
42
|
-
|
|
44
|
+
logger.logError('Missing or invalid color fields', undefined, {
|
|
43
45
|
data,
|
|
44
46
|
missingFields,
|
|
45
47
|
});
|
|
@@ -10,6 +10,8 @@ import { DOMInsertionType } from 'src/merchants/domInsertion';
|
|
|
10
10
|
import { GridInsertionType } from 'src/merchants/gridInsertion';
|
|
11
11
|
import Logger from 'src/application/logging/logger';
|
|
12
12
|
|
|
13
|
+
const logger = new Logger('validateGraphQLFrontendConfig');
|
|
14
|
+
|
|
13
15
|
// Helper function to validate and transform PageVariantQueryData to PageVariantConfig
|
|
14
16
|
export const validateAndTransformPageVariants = (
|
|
15
17
|
config: Record<string, unknown>,
|
|
@@ -407,7 +409,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
if (typeof data !== 'object' || Array.isArray(data)) {
|
|
410
|
-
|
|
412
|
+
logger.logWarn('Invalid GraphQL frontend config data: not an object', undefined, { data });
|
|
411
413
|
return undefined;
|
|
412
414
|
}
|
|
413
415
|
|
|
@@ -419,7 +421,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
419
421
|
typeof obj.merchant_override_css !== 'string' &&
|
|
420
422
|
obj.merchant_override_css !== null
|
|
421
423
|
) {
|
|
422
|
-
|
|
424
|
+
logger.logWarn(
|
|
423
425
|
'Invalid GraphQL frontend config data: merchant_override_css must be a string or null',
|
|
424
426
|
undefined,
|
|
425
427
|
{ data },
|
|
@@ -434,7 +436,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
434
436
|
obj.page_variants !== null &&
|
|
435
437
|
!Array.isArray(obj.page_variants)
|
|
436
438
|
) {
|
|
437
|
-
|
|
439
|
+
logger.logWarn(
|
|
438
440
|
'Invalid GraphQL frontend config data: page_variants must be an array or null/undefined',
|
|
439
441
|
undefined,
|
|
440
442
|
{ data },
|
|
@@ -450,7 +452,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
450
452
|
obj.mounting_configs !== null &&
|
|
451
453
|
!Array.isArray(obj.mounting_configs)
|
|
452
454
|
) {
|
|
453
|
-
|
|
455
|
+
logger.logWarn(
|
|
454
456
|
'Invalid GraphQL frontend config data: mounting_configs must be an array or null/undefined',
|
|
455
457
|
undefined,
|
|
456
458
|
{ data },
|
|
@@ -466,7 +468,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
466
468
|
obj.widget_configs !== null &&
|
|
467
469
|
!Array.isArray(obj.widget_configs)
|
|
468
470
|
) {
|
|
469
|
-
|
|
471
|
+
logger.logWarn(
|
|
470
472
|
'Invalid GraphQL frontend config data: widget_configs must be an array or null/undefined',
|
|
471
473
|
undefined,
|
|
472
474
|
{ data },
|
|
@@ -477,7 +479,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
477
479
|
|
|
478
480
|
// Validate ui_configs if present
|
|
479
481
|
if ('ui_configs' in obj && typeof obj.ui_configs !== 'object' && obj.ui_configs !== null) {
|
|
480
|
-
|
|
482
|
+
logger.logWarn(
|
|
481
483
|
'Invalid GraphQL frontend config data: ui_configs must be an object or null/undefined',
|
|
482
484
|
undefined,
|
|
483
485
|
{ data },
|
|
@@ -500,14 +502,14 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
500
502
|
const validatedVariant = validateAndTransformPageVariants(variant);
|
|
501
503
|
validatedPageVariants.push(validatedVariant);
|
|
502
504
|
} catch (error) {
|
|
503
|
-
|
|
505
|
+
logger.logWarn('Invalid page variant, skipping', error, {
|
|
504
506
|
variantId: variant.variantId,
|
|
505
507
|
variant,
|
|
506
508
|
});
|
|
507
509
|
// Continue processing other variants
|
|
508
510
|
}
|
|
509
511
|
} else {
|
|
510
|
-
|
|
512
|
+
logger.logWarn('Invalid page variant structure, skipping', undefined, { variant });
|
|
511
513
|
}
|
|
512
514
|
}
|
|
513
515
|
|
|
@@ -535,14 +537,14 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
535
537
|
const validatedConfig = validateAndTransformMountingConfig(config, item.key);
|
|
536
538
|
mountingConfigsRecord[item.key] = validatedConfig;
|
|
537
539
|
} catch (error) {
|
|
538
|
-
|
|
540
|
+
logger.logWarn('Invalid mounting config, skipping', error, {
|
|
539
541
|
configKey: item.key,
|
|
540
542
|
config: item.config,
|
|
541
543
|
});
|
|
542
544
|
// Continue processing other configs
|
|
543
545
|
}
|
|
544
546
|
} else {
|
|
545
|
-
|
|
547
|
+
logger.logWarn('Invalid mounting config item structure, skipping', undefined, { item });
|
|
546
548
|
}
|
|
547
549
|
}
|
|
548
550
|
|
|
@@ -570,14 +572,14 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
570
572
|
const validatedConfig = validateAndTransformWidgetConfig(config, item.key);
|
|
571
573
|
widgetConfigsRecord[item.key] = validatedConfig;
|
|
572
574
|
} catch (error) {
|
|
573
|
-
|
|
575
|
+
logger.logWarn('Invalid widget config, skipping', error, {
|
|
574
576
|
configKey: item.key,
|
|
575
577
|
config: item.config,
|
|
576
578
|
});
|
|
577
579
|
// Continue processing other configs
|
|
578
580
|
}
|
|
579
581
|
} else {
|
|
580
|
-
|
|
582
|
+
logger.logWarn('Invalid widget config item structure, skipping', undefined, { item });
|
|
581
583
|
}
|
|
582
584
|
}
|
|
583
585
|
|
|
@@ -586,7 +588,7 @@ export const validateGraphQLFrontendConfig = (data: unknown): FrontendConfig | u
|
|
|
586
588
|
|
|
587
589
|
return transformedData as FrontendConfig;
|
|
588
590
|
} catch (error) {
|
|
589
|
-
|
|
591
|
+
logger.logWarn('Failed to validate and transform GraphQL frontend config data', error, {
|
|
590
592
|
data,
|
|
591
593
|
});
|
|
592
594
|
return undefined;
|
|
@@ -17,6 +17,8 @@ const NORMALIZED_ADD_TO_CART_EVENT_NAMES = ['addtocart', 'addedtocart'];
|
|
|
17
17
|
const CHECK_DATA_LAYER_INTERVAL_MS = 500;
|
|
18
18
|
const CHECK_DATA_LAYER_MAX_ATTEMPTS = 10;
|
|
19
19
|
|
|
20
|
+
const logger = new Logger('analyticsUtils');
|
|
21
|
+
|
|
20
22
|
/**
|
|
21
23
|
* Checks if a Google Analytics event is an add_to_cart event.
|
|
22
24
|
*
|
|
@@ -90,9 +92,7 @@ export const initDataLayerWrapper = (
|
|
|
90
92
|
attempts += 1;
|
|
91
93
|
|
|
92
94
|
if (attempts >= CHECK_DATA_LAYER_MAX_ATTEMPTS) {
|
|
93
|
-
|
|
94
|
-
`[spiffy-ai] dataLayer not available after ${CHECK_DATA_LAYER_MAX_ATTEMPTS} attempts`,
|
|
95
|
-
);
|
|
95
|
+
logger.logDebug(`dataLayer not available after ${CHECK_DATA_LAYER_MAX_ATTEMPTS} attempts`);
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -100,7 +100,7 @@ export const initDataLayerWrapper = (
|
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
logger.logDebug('dataLayer is available, wrapping push function...');
|
|
104
104
|
const originalPush = window.dataLayer.push;
|
|
105
105
|
window.dataLayer.push = (...args: unknown[]) => {
|
|
106
106
|
if (isBaseEcommerceEvent(args[0]) && isAddToCartEvent((args[0] as any).event)) {
|
|
@@ -15,6 +15,8 @@ export const messageRequestToCommerceMessageRequest = (
|
|
|
15
15
|
},
|
|
16
16
|
id: data.id,
|
|
17
17
|
feature_flags: data.featureFlags,
|
|
18
|
+
override_config_version: data.overrideConfigVersion,
|
|
19
|
+
override_model_datetime: data.overrideModelDatetime,
|
|
18
20
|
user_events: data.userEvents?.map(userEvent => coreUserEventToApiUserEvent(userEvent)),
|
|
19
21
|
generation_params: {
|
|
20
22
|
model: data.generationParams?.model,
|
package/src/atoms/app/variant.ts
CHANGED
|
@@ -18,6 +18,8 @@ import { sessionStorageUtil } from 'src/atoms/atomStore';
|
|
|
18
18
|
import type { PageVariantInfo } from 'src/contexts/pageContext/types';
|
|
19
19
|
import { ShowFloatingButtonOptions } from 'src/contexts/types';
|
|
20
20
|
|
|
21
|
+
const logger = new Logger('variant');
|
|
22
|
+
|
|
21
23
|
export interface SupportedEvent extends Pick<
|
|
22
24
|
SupportedEventResponse,
|
|
23
25
|
'supported' | 'ready' | 'category' | 'collections' | 'top_category'
|
|
@@ -280,7 +282,7 @@ export const analyticsContextAtom = atom(get => {
|
|
|
280
282
|
if (variantInfo.variant === VariantTypeEnum.PageVisit) {
|
|
281
283
|
return getPageVisitContext(variantInfo.pageVisitCategory);
|
|
282
284
|
}
|
|
283
|
-
|
|
285
|
+
logger.logWarn('Invalid variantInfo', undefined, { variantInfo });
|
|
284
286
|
return {
|
|
285
287
|
page_type: 'other',
|
|
286
288
|
page_id: window.location.href,
|
|
@@ -3,6 +3,8 @@ import { atomWithStorage } from 'jotai/utils';
|
|
|
3
3
|
import Logger from 'src/application/logging/logger';
|
|
4
4
|
import { getAtomStore, sessionStorageUtil } from 'src/atoms/atomStore/atomStore';
|
|
5
5
|
|
|
6
|
+
const logger = new Logger('performanceMetrics');
|
|
7
|
+
|
|
6
8
|
export const APP_INITIAL_START_TIME_KEY = 'spiffy-app-initial-start-time';
|
|
7
9
|
export const PAGE_LOAD_OFFSET_TIME_KEY = 'spiffy-page-load-offset-time';
|
|
8
10
|
/**
|
|
@@ -68,7 +70,7 @@ export const logPerfMetricAtom = atom(null, (get, set, value: PerfMetricsEvents)
|
|
|
68
70
|
const initialTimeMs = initialTimeStorageValue ? parseInt(initialTimeStorageValue, 10) : undefined;
|
|
69
71
|
|
|
70
72
|
if (initialTimeMs == null) {
|
|
71
|
-
|
|
73
|
+
logger.logWarn(`No initial app start time found. Skipping...`, undefined);
|
|
72
74
|
return;
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -4,12 +4,14 @@ import { EnviveConfig } from 'src/contexts/types';
|
|
|
4
4
|
import { ContextSourceEnum } from '@spiffy-ai/commerce-api-client';
|
|
5
5
|
import { LocalStorageKeys } from 'src/contexts/localStorageContext';
|
|
6
6
|
|
|
7
|
+
const logger = new Logger('enviveConfig');
|
|
8
|
+
|
|
7
9
|
const internalEnviveConfigAtom = atom<EnviveConfig | undefined>(undefined);
|
|
8
10
|
|
|
9
11
|
export const enviveConfigAtom = atom(
|
|
10
12
|
get => {
|
|
11
13
|
const config = get(internalEnviveConfigAtom);
|
|
12
|
-
|
|
14
|
+
logger.logDebug('enviveConfig.ts: Accessing internalEnviveConfigAtom', config);
|
|
13
15
|
return config; // Return undefined if not set instead of throwing
|
|
14
16
|
},
|
|
15
17
|
(_, set, value: EnviveConfig) => {
|
|
@@ -64,11 +66,11 @@ export const contextSourceAtom = atom(get => {
|
|
|
64
66
|
|
|
65
67
|
export const orgLevelApiKeyAtom = atom(get => {
|
|
66
68
|
const config = get(enviveConfigAtom);
|
|
67
|
-
|
|
69
|
+
logger.logDebug('enviveConfig.ts: Accessing orgLevelApiKey', config);
|
|
68
70
|
return config?.orgLevelApiKey;
|
|
69
71
|
});
|
|
70
72
|
export const orgShortNameAtom = atom(get => {
|
|
71
73
|
const config = get(enviveConfigAtom);
|
|
72
|
-
|
|
74
|
+
logger.logDebug('enviveConfig.ts: Accessing orgShortName', config);
|
|
73
75
|
return config?.orgShortName;
|
|
74
76
|
});
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import { useLocalStorage } from 'src/contexts/localStorageContext';
|
|
10
10
|
import { orgAnalyticsGoogleAnalyticsConfigAtom } from 'src/atoms/org/orgAnalyticsConfig';
|
|
11
11
|
import { userIdAtom } from 'src/atoms/app';
|
|
12
|
-
import { useEnviveConfig } from 'src/contexts/enviveConfigContext
|
|
12
|
+
import { useEnviveConfig } from 'src/contexts/enviveConfigContext';
|
|
13
13
|
import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext/featureFlagServiceContext';
|
|
14
14
|
import {
|
|
15
15
|
AmplitudeService,
|
|
@@ -3,10 +3,11 @@ import { render, screen, waitFor } from '@testing-library/react';
|
|
|
3
3
|
import { Provider, useAtomValue } from 'jotai';
|
|
4
4
|
import { enviveConfigAtom } from 'src/atoms/envive/enviveConfig';
|
|
5
5
|
import Logger from 'src/application/logging/logger';
|
|
6
|
-
import { EnviveConfigProvider
|
|
6
|
+
import { EnviveConfigProvider } from '../enviveConfigContext';
|
|
7
|
+
import { useEnviveConfig } from '../useEnviveConfig';
|
|
7
8
|
|
|
8
9
|
// Mock the Logger to avoid console output in tests
|
|
9
|
-
vi.spyOn(Logger, 'logDebug').mockImplementation(() => {});
|
|
10
|
+
vi.spyOn(Logger.prototype, 'logDebug').mockImplementation(() => {});
|
|
10
11
|
|
|
11
12
|
// Mock component that uses the useEnviveConfig hook
|
|
12
13
|
const MockComponent: React.FC = () => {
|
|
@@ -353,7 +354,7 @@ describe('EnviveConfigProvider', () => {
|
|
|
353
354
|
|
|
354
355
|
describe('Logger Integration', () => {
|
|
355
356
|
it('should log debug message when setting config', async () => {
|
|
356
|
-
const logSpy = vi.spyOn(Logger, 'logDebug');
|
|
357
|
+
const logSpy = vi.spyOn(Logger.prototype, 'logDebug');
|
|
357
358
|
|
|
358
359
|
render(
|
|
359
360
|
<Provider>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React, { ReactNode,
|
|
2
|
-
import {
|
|
1
|
+
import React, { ReactNode, useEffect, useMemo } from 'react';
|
|
2
|
+
import { useSetAtom } from 'jotai';
|
|
3
3
|
import { enviveConfigAtom } from 'src/atoms/envive/enviveConfig';
|
|
4
4
|
import Logger from 'src/application/logging/logger';
|
|
5
5
|
import { OrgConfigFeatureGate } from 'src/application/models/api/orgConfigResults';
|
|
6
6
|
import { EnviveConfig } from '../types';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const logger = new Logger('enviveConfigContext');
|
|
9
9
|
|
|
10
10
|
interface EnviveConfigProviderProps {
|
|
11
11
|
children: ReactNode;
|
|
@@ -52,41 +52,56 @@ export const EnviveConfigProvider: React.FC<EnviveConfigProviderProps> = ({
|
|
|
52
52
|
}) => {
|
|
53
53
|
const setEnviveConfig = useSetAtom(enviveConfigAtom);
|
|
54
54
|
|
|
55
|
-
const config: EnviveConfig =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
55
|
+
const config: EnviveConfig = useMemo(
|
|
56
|
+
() => ({
|
|
57
|
+
amplitudeApiKey,
|
|
58
|
+
dataResidency,
|
|
59
|
+
env,
|
|
60
|
+
baseUrl,
|
|
61
|
+
reactAppName,
|
|
62
|
+
cdnUrl,
|
|
63
|
+
contextSource,
|
|
64
|
+
orgLevelApiKey,
|
|
65
|
+
orgShortName,
|
|
66
|
+
orgId,
|
|
67
|
+
identifyingPrefix,
|
|
68
|
+
featureOverrides,
|
|
69
|
+
variantUrlOverride,
|
|
70
|
+
variantInfoOverride,
|
|
71
|
+
show,
|
|
72
|
+
enviveOn,
|
|
73
|
+
publicKey,
|
|
74
|
+
featureGates,
|
|
75
|
+
}),
|
|
76
|
+
[
|
|
77
|
+
amplitudeApiKey,
|
|
78
|
+
dataResidency,
|
|
79
|
+
env,
|
|
80
|
+
baseUrl,
|
|
81
|
+
reactAppName,
|
|
82
|
+
cdnUrl,
|
|
83
|
+
contextSource,
|
|
84
|
+
orgLevelApiKey,
|
|
85
|
+
orgShortName,
|
|
86
|
+
orgId,
|
|
87
|
+
identifyingPrefix,
|
|
88
|
+
featureOverrides,
|
|
89
|
+
variantUrlOverride,
|
|
90
|
+
variantInfoOverride,
|
|
91
|
+
show,
|
|
92
|
+
enviveOn,
|
|
93
|
+
publicKey,
|
|
94
|
+
featureGates,
|
|
95
|
+
],
|
|
96
|
+
);
|
|
75
97
|
|
|
76
98
|
useEffect(() => {
|
|
77
99
|
setEnviveConfig(config);
|
|
78
|
-
|
|
100
|
+
logger.logDebug('EnviveConfigProvider: Setting EnviveConfig', config);
|
|
79
101
|
}, [setEnviveConfig, config]);
|
|
80
102
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export const useEnviveConfig = (): EnviveConfig => {
|
|
89
|
-
const config = useAtomValue(enviveConfigAtom);
|
|
90
|
-
|
|
91
|
-
return config || {};
|
|
103
|
+
if (!config) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return children;
|
|
92
107
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useAtomValue } from 'jotai';
|
|
2
|
+
import { enviveConfigAtom } from 'src/atoms/envive/enviveConfig';
|
|
3
|
+
import { EnviveConfig } from '../types';
|
|
4
|
+
|
|
5
|
+
export const useEnviveConfig = (): EnviveConfig => {
|
|
6
|
+
const config = useAtomValue(enviveConfigAtom);
|
|
7
|
+
|
|
8
|
+
return config || {};
|
|
9
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { ChatElementDisplayLocationV3 } from 'src/application/models/chatElementDisplayLocationV3';
|
|
3
3
|
import Logger from 'src/application/logging/logger';
|
|
4
|
-
import { useEnviveConfig } from 'src/contexts/enviveConfigContext
|
|
4
|
+
import { useEnviveConfig } from 'src/contexts/enviveConfigContext';
|
|
5
5
|
import { useSalesAgent } from 'src/contexts/salesAgentContext/salesAgentContext';
|
|
6
6
|
import { useChatToggle } from 'src/hooks/ChatToggle';
|
|
7
7
|
|
|
8
|
+
const logger = new Logger('WindowChatToggleBinder');
|
|
9
|
+
|
|
8
10
|
const attachedPrefixes = new Set<string>();
|
|
9
11
|
|
|
10
12
|
export const WindowChatToggleBinder = () => {
|
|
@@ -58,11 +60,11 @@ export const WindowChatToggleBinder = () => {
|
|
|
58
60
|
attachedPrefixes.add(spiffyAlias);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
`
|
|
63
|
+
logger.logDebug(
|
|
64
|
+
`Chat toggle attached at window["${identifyingPrefix}"] and window["${spiffyAlias}"]`,
|
|
63
65
|
);
|
|
64
66
|
} catch (e) {
|
|
65
|
-
|
|
67
|
+
logger.logError('Failed to attach Chat toggle functions', e);
|
|
66
68
|
}
|
|
67
69
|
}, [identifyingPrefix]);
|
|
68
70
|
|