@envive-ai/react-hooks 0.3.38 → 0.3.40
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 +3 -2
- package/dist/application/commerce-api.js +3 -2
- package/dist/application/models/api/orgConfigResults.d.cts +13 -2
- package/dist/application/models/api/orgConfigResults.d.ts +13 -2
- package/dist/application/models/featureGates.cjs +2 -1
- package/dist/application/models/featureGates.d.cts +2 -1
- package/dist/application/models/featureGates.d.ts +2 -1
- package/dist/application/models/featureGates.js +2 -1
- package/dist/application/models/graphql/queries/getWidgetConfigQuery.cjs +23 -0
- package/dist/application/models/graphql/queries/getWidgetConfigQuery.js +22 -0
- package/dist/application/models/index.d.cts +2 -2
- package/dist/application/models/index.d.ts +2 -2
- package/dist/application/utils/index.cjs +0 -2
- package/dist/application/utils/index.d.cts +1 -2
- package/dist/application/utils/index.d.ts +1 -2
- package/dist/application/utils/index.js +1 -2
- package/dist/atoms/app/index.d.cts +7 -7
- package/dist/atoms/app/index.d.ts +6 -6
- package/dist/atoms/chat/chatState.d.cts +18 -18
- package/dist/atoms/chat/chatState.d.ts +19 -19
- 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 +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 +6 -6
- 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 +2 -2
- package/dist/atoms/chat/replies.d.cts +2 -2
- package/dist/atoms/chat/replies.d.ts +2 -2
- package/dist/atoms/chat/suggestions.d.cts +2 -2
- package/dist/atoms/chat/suggestions.d.ts +2 -2
- package/dist/atoms/envive/enviveConfig.d.ts +13 -13
- package/dist/atoms/envive/resolvedBaseConfigVersion.cjs +9 -0
- package/dist/atoms/envive/resolvedBaseConfigVersion.js +8 -0
- 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 +4 -4
- package/dist/atoms/org/orgAnalyticsConfig.d.ts +4 -4
- 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.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/enviveContext/enviveContext.cjs +11 -3
- package/dist/contexts/enviveContext/enviveContext.js +11 -3
- package/dist/contexts/graphqlContext/graphqlContext.cjs +1 -1
- package/dist/contexts/graphqlContext/graphqlContext.d.cts +3 -1
- package/dist/contexts/graphqlContext/graphqlContext.d.ts +3 -1
- package/dist/contexts/graphqlContext/graphqlContext.js +1 -1
- package/dist/contexts/salesAgentContext/salesAgentService.cjs +9 -3
- package/dist/contexts/salesAgentContext/salesAgentService.js +9 -3
- 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/hooks/SystemSettingsContext/useSystemSettingsContext.d.cts +2 -2
- package/dist/hooks/utils.d.cts +1 -1
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/services/amplitudeService/amplitudeService.cjs +17 -2
- package/dist/services/amplitudeService/amplitudeService.d.cts +3 -1
- package/dist/services/amplitudeService/amplitudeService.d.ts +3 -1
- package/dist/services/amplitudeService/amplitudeService.js +17 -2
- package/dist/services/enviveConfigService/enviveConfigService.cjs +9 -3
- package/dist/services/enviveConfigService/enviveConfigService.d.cts +3 -2
- package/dist/services/enviveConfigService/enviveConfigService.d.ts +3 -2
- package/dist/services/enviveConfigService/enviveConfigService.js +10 -4
- package/dist/services/enviveConfigService/fetchGraphQLConfig.cjs +78 -39
- package/dist/services/enviveConfigService/fetchGraphQLConfig.js +78 -40
- package/dist/services/ga4ProjectionService/ga4ProjectionService.cjs +3 -3
- package/dist/services/ga4ProjectionService/ga4ProjectionService.js +3 -3
- package/dist/services/hardcopyService/hardcopyService.cjs +4 -2
- package/dist/services/hardcopyService/hardcopyService.js +4 -2
- package/dist/types/config-versions.cjs +3 -1
- package/dist/types/config-versions.js +3 -2
- package/dist/types/customerService.cjs +2 -1
- package/dist/types/customerService.d.cts +2 -1
- package/dist/types/customerService.d.ts +2 -1
- package/dist/types/customerService.js +2 -1
- package/package.json +1 -1
- package/src/application/commerce-api.ts +5 -1
- package/src/application/models/api/orgConfigResults.ts +27 -0
- package/src/application/models/featureGates.ts +5 -0
- package/src/application/models/graphql/queries/getWidgetConfigQuery.ts +34 -0
- package/src/application/utils/__tests__/elementObserver.test.ts +200 -0
- package/src/application/utils/index.ts +0 -1
- package/src/atoms/envive/resolvedBaseConfigVersion.ts +11 -0
- package/src/contexts/enviveContext/enviveContext.tsx +20 -0
- package/src/contexts/graphqlContext/graphqlContext.tsx +5 -0
- package/src/contexts/salesAgentContext/salesAgentService.ts +4 -1
- package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +95 -0
- package/src/services/amplitudeService/amplitudeService.ts +31 -1
- package/src/services/enviveConfigService/__tests__/fetchGraphQLConfig.test.ts +107 -1
- package/src/services/enviveConfigService/enviveConfigService.ts +35 -7
- package/src/services/enviveConfigService/fetchGraphQLConfig.ts +119 -57
- package/src/services/ga4ProjectionService/ga4ProjectionService.ts +2 -2
- package/src/services/hardcopyService/__tests__/hardcopyService.test.ts +35 -1
- package/src/services/hardcopyService/hardcopyService.ts +6 -1
- package/src/types/config-versions.ts +8 -0
- package/src/types/customerService.ts +1 -0
- package/dist/application/utils/merchantUtils.cjs +0 -18
- package/dist/application/utils/merchantUtils.d.cts +0 -5
- package/dist/application/utils/merchantUtils.d.ts +0 -5
- package/dist/application/utils/merchantUtils.js +0 -17
- package/src/application/utils/merchantUtils.ts +0 -16
|
@@ -9,10 +9,13 @@ import { FrontendConfigV3 } from 'src/application/models/frontendConfigV3';
|
|
|
9
9
|
import { ColorMappingV3 } from 'src/application/models/colorsConfigV3';
|
|
10
10
|
import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
|
|
11
11
|
import { getColorsAndFrontendQuery } from 'src/application/models/graphql/queries/getColorsAndFrontendQuery';
|
|
12
|
+
import { getWidgetConfigQuery } from 'src/application/models/graphql/queries/getWidgetConfigQuery';
|
|
12
13
|
import { mockV3ColorsConfig, mockV3FrontendConfig } from 'src/contexts/graphqlContext/mockV3Config';
|
|
13
14
|
import { WidgetConfigV3 } from 'src/contexts/typesV3';
|
|
14
15
|
import { PageVariantConfig, PageVariantTestType, WidgetMountingConfig } from 'src/contexts/types';
|
|
15
16
|
import { GraphQlConfigValues } from 'src/contexts/graphqlContext';
|
|
17
|
+
import { configVersionOverride } from 'src/types/config-versions';
|
|
18
|
+
import { ExperimentConfigResolutionMetadata } from 'src/application/models/api/orgConfigResults';
|
|
16
19
|
|
|
17
20
|
const logger = new Logger('fetchGraphQLConfig');
|
|
18
21
|
|
|
@@ -131,6 +134,80 @@ const v3FrontendConfigCleanup = (
|
|
|
131
134
|
};
|
|
132
135
|
};
|
|
133
136
|
|
|
137
|
+
// Turns a raw productsConfig payload (from getProductsConfigByVersion or
|
|
138
|
+
// getWidgetConfig) into the camelCase GraphQlConfigValues shape the rest of
|
|
139
|
+
// the toolkit consumes. Returns mock config when colors are absent.
|
|
140
|
+
const transformV3ProductsConfig = (
|
|
141
|
+
productsConfig:
|
|
142
|
+
| {
|
|
143
|
+
frontend?: { values?: { merchant_override_css?: string } };
|
|
144
|
+
v_three_config?: { values?: any };
|
|
145
|
+
}
|
|
146
|
+
| undefined,
|
|
147
|
+
): GraphQlConfigValues => {
|
|
148
|
+
const v3RootConfig = productsConfig?.v_three_config?.values;
|
|
149
|
+
const frontendValues = productsConfig?.frontend?.values;
|
|
150
|
+
|
|
151
|
+
if (!v3RootConfig?.colors) {
|
|
152
|
+
logger.logDebug('transformV3ProductsConfig | No colors found, returning mock config');
|
|
153
|
+
return {
|
|
154
|
+
colorsConfig: mockV3ColorsConfig,
|
|
155
|
+
frontendConfig: mockV3FrontendConfig as FrontendConfigV3Response,
|
|
156
|
+
orgPageConfig: {
|
|
157
|
+
pageVariants: DEFAULT_PAGE_VARIANTS,
|
|
158
|
+
widgetConfigs: {},
|
|
159
|
+
mountingConfigs: {},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const v3FrontendConfig = v3FrontendConfigCleanup(
|
|
165
|
+
transformSnakeToCamel(v3RootConfig) as FrontendConfigV3Response,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const merchantOverrideCss =
|
|
169
|
+
v3FrontendConfig.uiConfigs?.merchantOverrideCss || frontendValues?.merchant_override_css;
|
|
170
|
+
|
|
171
|
+
const v3MountingConfigsArray = (transformSnakeToCamel(v3RootConfig?.mounting_configs) ??
|
|
172
|
+
[]) as unknown as { key: string; config: WidgetMountingConfig }[];
|
|
173
|
+
const v3MountingConfigs = v3MountingConfigsArray.reduce(
|
|
174
|
+
(acc, { key, config }) => {
|
|
175
|
+
acc[key] = validateAndTransformMountingConfig(config, key);
|
|
176
|
+
return acc;
|
|
177
|
+
},
|
|
178
|
+
{} as Record<string, WidgetMountingConfig>,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const v3WidgetConfigsArray = (transformSnakeToCamel(v3RootConfig?.widget_configs) ??
|
|
182
|
+
[]) as unknown as WidgetConfigV3[];
|
|
183
|
+
const v3WidgetConfigs = Object.fromEntries(
|
|
184
|
+
v3WidgetConfigsArray?.map(({ widgetConfigId, ...rest }: WidgetConfigV3) => [
|
|
185
|
+
widgetConfigId,
|
|
186
|
+
{ widgetConfigId, ...rest } as WidgetConfigV3,
|
|
187
|
+
]),
|
|
188
|
+
) as Record<string, WidgetConfigV3>;
|
|
189
|
+
|
|
190
|
+
const v3pageVariants: PageVariantConfig[] = Array.isArray(v3RootConfig?.page_variants)
|
|
191
|
+
? v3RootConfig.page_variants.map(validateAndTransformPageVariants)
|
|
192
|
+
: DEFAULT_PAGE_VARIANTS;
|
|
193
|
+
|
|
194
|
+
const v3ColorsConfig = transformSnakeToCamel(v3RootConfig?.colors?.values);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
colorsConfig: v3ColorsConfig as ColorsConfigV3Response,
|
|
198
|
+
frontendConfig: {
|
|
199
|
+
...(v3FrontendConfig as FrontendConfigV3Response),
|
|
200
|
+
merchantOverrideCss,
|
|
201
|
+
widgetConfigs: v3WidgetConfigs,
|
|
202
|
+
},
|
|
203
|
+
orgPageConfig: {
|
|
204
|
+
pageVariants: v3pageVariants,
|
|
205
|
+
widgetConfigs: v3WidgetConfigs,
|
|
206
|
+
mountingConfigs: v3MountingConfigs,
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
|
|
134
211
|
export const fetchGraphQLConfig = async (
|
|
135
212
|
baseUrl: string,
|
|
136
213
|
apiKey: string,
|
|
@@ -155,71 +232,56 @@ export const fetchGraphQLConfig = async (
|
|
|
155
232
|
throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`);
|
|
156
233
|
}
|
|
157
234
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
frontendConfig: mockV3FrontendConfig as FrontendConfigV3Response,
|
|
166
|
-
orgPageConfig: {
|
|
167
|
-
pageVariants: DEFAULT_PAGE_VARIANTS,
|
|
168
|
-
widgetConfigs: {},
|
|
169
|
-
mountingConfigs: {},
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const v3FrontendConfig = v3FrontendConfigCleanup(
|
|
175
|
-
transformSnakeToCamel(v3RootConfig) as FrontendConfigV3Response,
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
const merchantOverrideCss =
|
|
179
|
-
v3FrontendConfig.uiConfigs?.merchantOverrideCss || frontendValues?.merchant_override_css;
|
|
235
|
+
logger.logDebug('fetchGraphQLConfig | Returning v3 config');
|
|
236
|
+
return transformV3ProductsConfig(result.data.me.getProductsConfigByVersion);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
logger.logError('fetchGraphQLConfig | Error fetching GraphQL config', err);
|
|
239
|
+
return { colorsConfig: undefined, frontendConfig: undefined };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
180
242
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
243
|
+
// Statsig-experiment-aware unified config path. Called when the
|
|
244
|
+
// `use_unified_config` Statsig gate is on. Returns the same shape as
|
|
245
|
+
// fetchGraphQLConfig with the resolution metadata pymono used to pick the
|
|
246
|
+
// version attached — callers thread `resolution.baseVersion` into downstream
|
|
247
|
+
// inference requests so inference is scoped to the version that produced
|
|
248
|
+
// the widgets the user is rendering. A `spiffy_config_version` /
|
|
249
|
+
// `envive_config_version` URL param, when present, is threaded through as
|
|
250
|
+
// the `version` variable to pin a specific config version (matches the
|
|
251
|
+
// legacy path's debug/rollback affordance).
|
|
252
|
+
export const fetchUnifiedGraphQLConfig = async (
|
|
253
|
+
baseUrl: string,
|
|
254
|
+
apiKey: string,
|
|
255
|
+
userId: string,
|
|
256
|
+
): Promise<GraphQlConfigValues> => {
|
|
257
|
+
try {
|
|
258
|
+
const query = getWidgetConfigQuery();
|
|
259
|
+
const version = configVersionOverride();
|
|
260
|
+
const response = await fetch(`${baseUrl}/v1/graphql`, {
|
|
261
|
+
method: 'POST',
|
|
262
|
+
headers: {
|
|
263
|
+
'Content-Type': 'application/json',
|
|
264
|
+
Authorization: `Bearer ${apiKey}`,
|
|
187
265
|
},
|
|
188
|
-
{
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
const v3widgetConfigsArray = (transformSnakeToCamel(v3RootConfig?.widget_configs) ??
|
|
192
|
-
[]) as unknown as WidgetConfigV3[];
|
|
193
|
-
const v3WidgetConfigs = Object.fromEntries(
|
|
194
|
-
v3widgetConfigsArray?.map(({ widgetConfigId, ...rest }: WidgetConfigV3) => [
|
|
195
|
-
widgetConfigId,
|
|
196
|
-
{ widgetConfigId, ...rest } as WidgetConfigV3,
|
|
197
|
-
]),
|
|
198
|
-
) as Record<string, WidgetConfigV3>;
|
|
199
|
-
|
|
200
|
-
const v3pageVariants: PageVariantConfig[] = Array.isArray(v3RootConfig?.page_variants)
|
|
201
|
-
? v3RootConfig.page_variants.map(validateAndTransformPageVariants)
|
|
202
|
-
: DEFAULT_PAGE_VARIANTS;
|
|
266
|
+
body: JSON.stringify({ query, variables: { userId, version } }),
|
|
267
|
+
});
|
|
203
268
|
|
|
204
|
-
|
|
269
|
+
if (!response.ok) {
|
|
270
|
+
throw new Error(`GraphQL request failed: ${response.statusText}`);
|
|
271
|
+
}
|
|
205
272
|
|
|
206
|
-
|
|
273
|
+
const result = await response.json();
|
|
274
|
+
if (result.errors) {
|
|
275
|
+
throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`);
|
|
276
|
+
}
|
|
207
277
|
|
|
278
|
+
const widgetConfig = result.data.me.getWidgetConfig;
|
|
208
279
|
return {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
...(v3FrontendConfig as FrontendConfigV3Response),
|
|
212
|
-
merchantOverrideCss,
|
|
213
|
-
widgetConfigs: v3WidgetConfigs,
|
|
214
|
-
},
|
|
215
|
-
orgPageConfig: {
|
|
216
|
-
pageVariants: v3pageVariants,
|
|
217
|
-
widgetConfigs: v3WidgetConfigs,
|
|
218
|
-
mountingConfigs: v3MountingConfigs,
|
|
219
|
-
},
|
|
280
|
+
...transformV3ProductsConfig(widgetConfig?.productsConfig),
|
|
281
|
+
resolution: widgetConfig?.resolution as ExperimentConfigResolutionMetadata | undefined,
|
|
220
282
|
};
|
|
221
283
|
} catch (err) {
|
|
222
|
-
logger.logError('
|
|
284
|
+
logger.logError('fetchUnifiedGraphQLConfig | Error fetching unified GraphQL config', err);
|
|
223
285
|
return { colorsConfig: undefined, frontendConfig: undefined };
|
|
224
286
|
}
|
|
225
287
|
};
|
|
@@ -70,12 +70,12 @@ const flattenDotKeys = (obj: Record<string, unknown>): Record<string, unknown> =
|
|
|
70
70
|
// We want to omit all but pdp and plp page types to provide a clear, consistent interface for merchants.
|
|
71
71
|
// Handles both dot-notation keys (allowedFields path) and renamed GA4 keys (fieldProjections path).
|
|
72
72
|
const sanitizePageId = (filtered: Record<string, unknown>): Record<string, unknown> => {
|
|
73
|
-
const pageType = filtered
|
|
73
|
+
const pageType = filtered.page_type ?? filtered['context.page_type'];
|
|
74
74
|
if (pageType === 'pdp' || pageType === 'plp') {
|
|
75
75
|
return filtered;
|
|
76
76
|
}
|
|
77
77
|
const rest = { ...filtered };
|
|
78
|
-
delete rest
|
|
78
|
+
delete rest.page_id;
|
|
79
79
|
delete rest['context.page_id'];
|
|
80
80
|
return rest;
|
|
81
81
|
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { HardcopyService, MockHardcopyService, MOCK_HARDCOPY_RESPONSE } from '../hardcopyService';
|
|
2
1
|
import { WidgetTypeV3 } from 'src/contexts/typesV3';
|
|
3
2
|
import type { WidgetText } from 'src/application/models/api/widgetText';
|
|
4
3
|
import type { AppDetails } from 'src/atoms/app';
|
|
5
4
|
import { EnviveMetricsEventName } from 'src/services/amplitudeService';
|
|
5
|
+
import { getAtomStore } from 'src/atoms/atomStore/atomStore';
|
|
6
|
+
import { resolvedBaseConfigVersionAtom } from 'src/atoms/envive/resolvedBaseConfigVersion';
|
|
7
|
+
import { HardcopyService, MOCK_HARDCOPY_RESPONSE, MockHardcopyService } from '../hardcopyService';
|
|
6
8
|
|
|
7
9
|
const { MockLogger, mockGetHardcopy, mockGetQueryParam } = vi.hoisted(() => {
|
|
8
10
|
const MockLogger = vi.fn(function () {
|
|
@@ -54,6 +56,7 @@ const makeWidgetTextResponse = (overrides: Partial<WidgetText> = {}): WidgetText
|
|
|
54
56
|
beforeEach(() => {
|
|
55
57
|
vi.clearAllMocks();
|
|
56
58
|
mockGetQueryParam.mockReturnValue(null);
|
|
59
|
+
getAtomStore().set(resolvedBaseConfigVersionAtom, undefined);
|
|
57
60
|
Object.defineProperty(navigator, 'languages', {
|
|
58
61
|
value: ['en-US'],
|
|
59
62
|
configurable: true,
|
|
@@ -177,6 +180,37 @@ describe('HardcopyService', () => {
|
|
|
177
180
|
);
|
|
178
181
|
});
|
|
179
182
|
|
|
183
|
+
it('falls back to the resolvedBaseConfigVersionAtom when no URL params are set', async () => {
|
|
184
|
+
getAtomStore().set(resolvedBaseConfigVersionAtom, '1.0.670');
|
|
185
|
+
mockGetHardcopy.mockResolvedValueOnce(makeWidgetTextResponse());
|
|
186
|
+
|
|
187
|
+
await makeService().getHardcopy({
|
|
188
|
+
widgetType: WidgetTypeV3.PromptCarouselV3,
|
|
189
|
+
userEvent: {} as any,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(mockGetHardcopy).toHaveBeenCalledWith(
|
|
193
|
+
expect.objectContaining({ overrideConfigVersion: '1.0.670' }),
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('prefers spiffy_config_version URL param over the resolvedBaseConfigVersionAtom', async () => {
|
|
198
|
+
mockGetQueryParam.mockImplementation((key: string) =>
|
|
199
|
+
key === 'spiffy_config_version' ? 'url-override' : null,
|
|
200
|
+
);
|
|
201
|
+
getAtomStore().set(resolvedBaseConfigVersionAtom, '1.0.670');
|
|
202
|
+
mockGetHardcopy.mockResolvedValueOnce(makeWidgetTextResponse());
|
|
203
|
+
|
|
204
|
+
await makeService().getHardcopy({
|
|
205
|
+
widgetType: WidgetTypeV3.PromptCarouselV3,
|
|
206
|
+
userEvent: {} as any,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
expect(mockGetHardcopy).toHaveBeenCalledWith(
|
|
210
|
+
expect.objectContaining({ overrideConfigVersion: 'url-override' }),
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
|
|
180
214
|
it('uses the first navigator language as the request language', async () => {
|
|
181
215
|
Object.defineProperty(navigator, 'languages', {
|
|
182
216
|
value: ['fr-FR', 'en-US'],
|
|
@@ -7,6 +7,8 @@ import { getQueryParam } from 'src/application/utils';
|
|
|
7
7
|
import { UserEvent } from 'src/application/models';
|
|
8
8
|
import Logger from 'src/application/logging/logger';
|
|
9
9
|
import { AppDetails } from 'src/atoms/app';
|
|
10
|
+
import { getAtomStore } from 'src/atoms/atomStore/atomStore';
|
|
11
|
+
import { resolvedBaseConfigVersionAtom } from 'src/atoms/envive/resolvedBaseConfigVersion';
|
|
10
12
|
import { WidgetTypeV3 } from 'src/contexts/typesV3';
|
|
11
13
|
import { EnviveMetricsEventName, TrackEventParams } from '../amplitudeService';
|
|
12
14
|
|
|
@@ -200,7 +202,10 @@ export class HardcopyService implements IHardcopyService {
|
|
|
200
202
|
|
|
201
203
|
async getHardcopy(request: HardcopyRequest): Promise<HardcopyResponse> {
|
|
202
204
|
const overrideConfigVersion =
|
|
203
|
-
getQueryParam('spiffy_config_version') ||
|
|
205
|
+
getQueryParam('spiffy_config_version') ||
|
|
206
|
+
getQueryParam('envive_config_version') ||
|
|
207
|
+
getAtomStore().get(resolvedBaseConfigVersionAtom) ||
|
|
208
|
+
undefined;
|
|
204
209
|
|
|
205
210
|
const widgetTextRequest: WidgetTextRequest = {
|
|
206
211
|
requestId: uuid(),
|
|
@@ -2,3 +2,11 @@ import { getQueryParam } from 'src/application/utils/urlsParser';
|
|
|
2
2
|
|
|
3
3
|
export const configVersion = () =>
|
|
4
4
|
getQueryParam('spiffy_config_version') || getQueryParam('envive_config_version') || 'deployed';
|
|
5
|
+
|
|
6
|
+
// Unlike `configVersion()`, this returns undefined when no override is present
|
|
7
|
+
// so callers can pass it through GraphQL `version` arguments where omission
|
|
8
|
+
// means "let the resolver pick" (e.g. Statsig-driven resolution on the
|
|
9
|
+
// unified getWidgetConfig path). Passing 'deployed' here would force a
|
|
10
|
+
// version override and bypass Statsig bucketing.
|
|
11
|
+
export const configVersionOverride = (): string | undefined =>
|
|
12
|
+
getQueryParam('spiffy_config_version') || getQueryParam('envive_config_version') || undefined;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/application/utils/merchantUtils.ts
|
|
3
|
-
const prepareMerchantPage = () => {
|
|
4
|
-
let metaViewport = document.querySelector("meta[name='viewport']");
|
|
5
|
-
if (metaViewport) {
|
|
6
|
-
const content = metaViewport.getAttribute("content");
|
|
7
|
-
if (!content?.includes("maximum-scale=1")) metaViewport.setAttribute("content", `${content}, maximum-scale=1`);
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
metaViewport = document.createElement("meta");
|
|
11
|
-
metaViewport.setAttribute("name", "viewport");
|
|
12
|
-
metaViewport.setAttribute("content", "width=device-width, initial-scale=1, maximum-scale=1");
|
|
13
|
-
document.head.appendChild(metaViewport);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
//#endregion
|
|
17
|
-
exports.prepareMerchantPage = prepareMerchantPage;
|
|
18
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyY2hhbnRVdGlscy5janMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL21lcmNoYW50VXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHByZXBhcmVNZXJjaGFudFBhZ2UgPSAoKSA9PiB7XG4gIGxldCBtZXRhVmlld3BvcnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwibWV0YVtuYW1lPSd2aWV3cG9ydCddXCIpO1xuICBpZiAobWV0YVZpZXdwb3J0KSB7XG4gICAgY29uc3QgY29udGVudCA9IG1ldGFWaWV3cG9ydC5nZXRBdHRyaWJ1dGUoJ2NvbnRlbnQnKTtcbiAgICBjb25zdCBoYXNNYXhpbXVtU2NhbGUgPSBjb250ZW50Py5pbmNsdWRlcygnbWF4aW11bS1zY2FsZT0xJyk7XG4gICAgaWYgKCFoYXNNYXhpbXVtU2NhbGUpIHtcbiAgICAgIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnQnLCBgJHtjb250ZW50fSwgbWF4aW11bS1zY2FsZT0xYCk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21ldGEnKTtcbiAgbWV0YVZpZXdwb3J0LnNldEF0dHJpYnV0ZSgnbmFtZScsICd2aWV3cG9ydCcpO1xuICBtZXRhVmlld3BvcnQuc2V0QXR0cmlidXRlKCdjb250ZW50JywgJ3dpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLCBtYXhpbXVtLXNjYWxlPTEnKTtcbiAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChtZXRhVmlld3BvcnQpO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFhLDRCQUE0QjtDQUN2QyxJQUFJLGVBQWUsU0FBUyxjQUFjLHdCQUF3QjtBQUNsRSxLQUFJLGNBQWM7RUFDaEIsTUFBTSxVQUFVLGFBQWEsYUFBYSxVQUFVO0FBRXBELE1BQUksQ0FEb0IsU0FBUyxTQUFTLGtCQUFrQixDQUUxRCxjQUFhLGFBQWEsV0FBVyxHQUFHLFFBQVEsbUJBQW1CO0FBRXJFOztBQUdGLGdCQUFlLFNBQVMsY0FBYyxPQUFPO0FBQzdDLGNBQWEsYUFBYSxRQUFRLFdBQVc7QUFDN0MsY0FBYSxhQUFhLFdBQVcsdURBQXVEO0FBQzVGLFVBQVMsS0FBSyxZQUFZLGFBQWEifQ==
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
//#region src/application/utils/merchantUtils.d.ts
|
|
2
|
-
declare const prepareMerchantPage: () => void;
|
|
3
|
-
//#endregion
|
|
4
|
-
export { prepareMerchantPage };
|
|
5
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyY2hhbnRVdGlscy5kLmN0cyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVyY2hhbnRVdGlscy5kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWNsYXJlIGNvbnN0IHByZXBhcmVNZXJjaGFudFBhZ2U6ICgpID0+IHZvaWQ7XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxJQUFXLHNCQUFzQixDQUFDLElBQUkifQ==
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
//#region src/application/utils/merchantUtils.d.ts
|
|
2
|
-
declare const prepareMerchantPage: () => void;
|
|
3
|
-
//#endregion
|
|
4
|
-
export { prepareMerchantPage };
|
|
5
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyY2hhbnRVdGlscy5kLnRzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9tZXJjaGFudFV0aWxzLmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlY2xhcmUgY29uc3QgcHJlcGFyZU1lcmNoYW50UGFnZTogKCkgPT4gdm9pZDtcbiJdLCJtYXBwaW5ncyI6IjtBQUFBLElBQVcsc0JBQXNCLENBQUMsSUFBSSJ9
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//#region src/application/utils/merchantUtils.ts
|
|
2
|
-
const prepareMerchantPage = () => {
|
|
3
|
-
let metaViewport = document.querySelector("meta[name='viewport']");
|
|
4
|
-
if (metaViewport) {
|
|
5
|
-
const content = metaViewport.getAttribute("content");
|
|
6
|
-
if (!content?.includes("maximum-scale=1")) metaViewport.setAttribute("content", `${content}, maximum-scale=1`);
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
metaViewport = document.createElement("meta");
|
|
10
|
-
metaViewport.setAttribute("name", "viewport");
|
|
11
|
-
metaViewport.setAttribute("content", "width=device-width, initial-scale=1, maximum-scale=1");
|
|
12
|
-
document.head.appendChild(metaViewport);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
//#endregion
|
|
16
|
-
export { prepareMerchantPage };
|
|
17
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyY2hhbnRVdGlscy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVyY2hhbnRVdGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgcHJlcGFyZU1lcmNoYW50UGFnZSA9ICgpID0+IHtcbiAgbGV0IG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtZXRhW25hbWU9J3ZpZXdwb3J0J11cIik7XG4gIGlmIChtZXRhVmlld3BvcnQpIHtcbiAgICBjb25zdCBjb250ZW50ID0gbWV0YVZpZXdwb3J0LmdldEF0dHJpYnV0ZSgnY29udGVudCcpO1xuICAgIGNvbnN0IGhhc01heGltdW1TY2FsZSA9IGNvbnRlbnQ/LmluY2x1ZGVzKCdtYXhpbXVtLXNjYWxlPTEnKTtcbiAgICBpZiAoIWhhc01heGltdW1TY2FsZSkge1xuICAgICAgbWV0YVZpZXdwb3J0LnNldEF0dHJpYnV0ZSgnY29udGVudCcsIGAke2NvbnRlbnR9LCBtYXhpbXVtLXNjYWxlPTFgKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbWV0YScpO1xuICBtZXRhVmlld3BvcnQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3ZpZXdwb3J0Jyk7XG4gIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnQnLCAnd2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MScpO1xuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGFWaWV3cG9ydCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiO0FBQUEsTUFBYSw0QkFBNEI7Q0FDdkMsSUFBSSxlQUFlLFNBQVMsY0FBYyx3QkFBd0I7QUFDbEUsS0FBSSxjQUFjO0VBQ2hCLE1BQU0sVUFBVSxhQUFhLGFBQWEsVUFBVTtBQUVwRCxNQUFJLENBRG9CLFNBQVMsU0FBUyxrQkFBa0IsQ0FFMUQsY0FBYSxhQUFhLFdBQVcsR0FBRyxRQUFRLG1CQUFtQjtBQUVyRTs7QUFHRixnQkFBZSxTQUFTLGNBQWMsT0FBTztBQUM3QyxjQUFhLGFBQWEsUUFBUSxXQUFXO0FBQzdDLGNBQWEsYUFBYSxXQUFXLHVEQUF1RDtBQUM1RixVQUFTLEtBQUssWUFBWSxhQUFhIn0=
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export const prepareMerchantPage = () => {
|
|
2
|
-
let metaViewport = document.querySelector("meta[name='viewport']");
|
|
3
|
-
if (metaViewport) {
|
|
4
|
-
const content = metaViewport.getAttribute('content');
|
|
5
|
-
const hasMaximumScale = content?.includes('maximum-scale=1');
|
|
6
|
-
if (!hasMaximumScale) {
|
|
7
|
-
metaViewport.setAttribute('content', `${content}, maximum-scale=1`);
|
|
8
|
-
}
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
metaViewport = document.createElement('meta');
|
|
13
|
-
metaViewport.setAttribute('name', 'viewport');
|
|
14
|
-
metaViewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1');
|
|
15
|
-
document.head.appendChild(metaViewport);
|
|
16
|
-
};
|