@tagadapay/plugin-sdk 3.1.22 → 3.1.24

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.
Files changed (76) hide show
  1. package/build-cdn.js +274 -6
  2. package/dist/external-tracker.js +236 -3906
  3. package/dist/external-tracker.min.js +2 -25
  4. package/dist/external-tracker.min.js.map +4 -4
  5. package/dist/react/config/payment.d.ts +14 -4
  6. package/dist/react/config/payment.js +47 -9
  7. package/dist/react/hooks/useCheckout.d.ts +3 -0
  8. package/dist/react/hooks/useCheckout.js +4 -1
  9. package/dist/react/hooks/usePluginConfig.js +9 -10
  10. package/dist/react/providers/TagadaProvider.js +1 -1
  11. package/dist/tagada-react-sdk-minimal.min.js +36 -0
  12. package/dist/tagada-react-sdk-minimal.min.js.map +7 -0
  13. package/dist/tagada-react-sdk.js +37821 -0
  14. package/dist/tagada-react-sdk.min.js +78 -0
  15. package/dist/tagada-react-sdk.min.js.map +7 -0
  16. package/dist/tagada-sdk.js +10309 -6331
  17. package/dist/tagada-sdk.min.js +4 -22
  18. package/dist/tagada-sdk.min.js.map +4 -4
  19. package/dist/v2/cdn-react-minimal.d.ts +23 -0
  20. package/dist/v2/cdn-react-minimal.js +26 -0
  21. package/dist/v2/core/client.js +1 -1
  22. package/dist/v2/core/config/environment.js +2 -1
  23. package/dist/v2/core/funnelClient.d.ts +98 -10
  24. package/dist/v2/core/funnelClient.js +121 -27
  25. package/dist/v2/core/index.d.ts +0 -1
  26. package/dist/v2/core/index.js +0 -2
  27. package/dist/v2/core/isoData.d.ts +4 -4
  28. package/dist/v2/core/isoData.js +7 -7
  29. package/dist/v2/core/pixelMapping.js +64 -26
  30. package/dist/v2/core/resources/checkout.d.ts +10 -0
  31. package/dist/v2/core/resources/checkout.js +6 -0
  32. package/dist/v2/core/resources/expressPaymentMethods.d.ts +1 -0
  33. package/dist/v2/core/resources/payments.d.ts +7 -2
  34. package/dist/v2/core/resources/payments.js +1 -0
  35. package/dist/v2/core/resources/postPurchases.d.ts +17 -0
  36. package/dist/v2/core/resources/postPurchases.js +20 -0
  37. package/dist/v2/core/utils/deviceInfo.d.ts +0 -10
  38. package/dist/v2/core/utils/deviceInfo.js +152 -76
  39. package/dist/v2/core/utils/order.d.ts +2 -0
  40. package/dist/v2/core/utils/pluginConfig.js +18 -22
  41. package/dist/v2/index.d.ts +4 -3
  42. package/dist/v2/index.js +4 -2
  43. package/dist/v2/react/components/FunnelScriptInjector.js +145 -77
  44. package/dist/v2/react/components/StripeExpressButton.d.ts +13 -0
  45. package/dist/v2/react/components/StripeExpressButton.js +171 -0
  46. package/dist/v2/react/components/WhopCheckout.js +7 -1
  47. package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.js +21 -3
  48. package/dist/v2/react/hooks/useApplePayCheckout.js +8 -8
  49. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +10 -0
  50. package/dist/v2/react/hooks/useCheckoutQuery.js +21 -13
  51. package/dist/v2/react/hooks/useFunnel.d.ts +15 -4
  52. package/dist/v2/react/hooks/useFunnel.js +8 -4
  53. package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +2 -0
  54. package/dist/v2/react/hooks/useGoogleAutocomplete.js +29 -15
  55. package/dist/v2/react/hooks/useISOData.d.ts +2 -5
  56. package/dist/v2/react/hooks/useISOData.js +25 -26
  57. package/dist/v2/react/hooks/usePaymentPolling.d.ts +2 -2
  58. package/dist/v2/react/hooks/usePixelTracking.js +151 -70
  59. package/dist/v2/react/hooks/usePostPurchasesQuery.js +34 -2
  60. package/dist/v2/react/hooks/useRemappableParams.d.ts +2 -6
  61. package/dist/v2/react/hooks/useRemappableParams.js +23 -23
  62. package/dist/v2/react/hooks/useSetPaymentMethod.d.ts +16 -0
  63. package/dist/v2/react/hooks/useSetPaymentMethod.js +33 -0
  64. package/dist/v2/react/hooks/useStepConfig.d.ts +23 -6
  65. package/dist/v2/react/hooks/useStepConfig.js +14 -7
  66. package/dist/v2/react/hooks/useTranslation.js +23 -8
  67. package/dist/v2/react/index.d.ts +8 -1
  68. package/dist/v2/react/index.js +3 -0
  69. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +1 -0
  70. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +9 -1
  71. package/dist/v2/react/providers/TagadaProvider.js +4 -4
  72. package/dist/v2/standalone/index.d.ts +21 -3
  73. package/dist/v2/standalone/index.js +25 -3
  74. package/dist/v2/standalone/payment-service.d.ts +134 -0
  75. package/dist/v2/standalone/payment-service.js +928 -0
  76. package/package.json +4 -2
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Minimal React SDK for CDN
3
+ *
4
+ * This is a slim bundle for use with TagadaStudio's esbuild mode.
5
+ * Only includes essential hooks needed for checkout pages.
6
+ *
7
+ * Full SDK is much larger due to TanStack Query, ISO data, etc.
8
+ * This minimal version keeps the bundle small (~100KB vs ~9MB).
9
+ */
10
+ export { TagadaProvider, useTagadaContext } from './react/providers/TagadaProvider';
11
+ export { useCheckoutQuery as useCheckout } from './react/hooks/useCheckoutQuery';
12
+ export { useShippingRatesQuery as useShippingRates } from './react/hooks/useShippingRatesQuery';
13
+ export { useDiscountsQuery as useDiscounts } from './react/hooks/useDiscountsQuery';
14
+ export { useOrderBumpQuery as useOrderBump } from './react/hooks/useOrderBumpQuery';
15
+ export { useOrderQuery as useOrder } from './react/hooks/useOrderQuery';
16
+ export { usePostPurchasesQuery as usePostPurchases } from './react/hooks/usePostPurchasesQuery';
17
+ export { usePaymentQuery as usePayment } from './react/hooks/usePaymentQuery';
18
+ export { useThreeds } from './react/hooks/useThreeds';
19
+ export { useCurrency } from './react/hooks/useCurrency';
20
+ export { usePluginConfig } from './react/hooks/usePluginConfig';
21
+ export { useFunnel } from './react/hooks/useFunnel';
22
+ export { formatMoney } from './core/utils/currency';
23
+ export type { FunnelContextValue } from './react/hooks/useFunnel';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimal React SDK for CDN
3
+ *
4
+ * This is a slim bundle for use with TagadaStudio's esbuild mode.
5
+ * Only includes essential hooks needed for checkout pages.
6
+ *
7
+ * Full SDK is much larger due to TanStack Query, ISO data, etc.
8
+ * This minimal version keeps the bundle small (~100KB vs ~9MB).
9
+ */
10
+ // Provider (essential)
11
+ export { TagadaProvider, useTagadaContext } from './react/providers/TagadaProvider';
12
+ // Core checkout hooks (essential for commerce)
13
+ export { useCheckoutQuery as useCheckout } from './react/hooks/useCheckoutQuery';
14
+ export { useShippingRatesQuery as useShippingRates } from './react/hooks/useShippingRatesQuery';
15
+ export { useDiscountsQuery as useDiscounts } from './react/hooks/useDiscountsQuery';
16
+ export { useOrderBumpQuery as useOrderBump } from './react/hooks/useOrderBumpQuery';
17
+ export { useOrderQuery as useOrder } from './react/hooks/useOrderQuery';
18
+ export { usePostPurchasesQuery as usePostPurchases } from './react/hooks/usePostPurchasesQuery';
19
+ export { usePaymentQuery as usePayment } from './react/hooks/usePaymentQuery';
20
+ export { useThreeds } from './react/hooks/useThreeds';
21
+ // Utility hooks (commonly used)
22
+ export { useCurrency } from './react/hooks/useCurrency';
23
+ export { usePluginConfig } from './react/hooks/usePluginConfig';
24
+ export { useFunnel } from './react/hooks/useFunnel';
25
+ // Essential utilities
26
+ export { formatMoney } from './core/utils/currency';
@@ -506,7 +506,7 @@ export class TagadaClient {
506
506
  if (this.state.debugMode) {
507
507
  console.log(`[TagadaClient ${this.instanceId}] Initializing session...`, { sessionId: sessionData.sessionId });
508
508
  }
509
- const deviceInfo = collectDeviceInfo();
509
+ const deviceInfo = await collectDeviceInfo();
510
510
  const urlParams = getUrlParams();
511
511
  const browserLocale = getBrowserLocale();
512
512
  // 🎯 Check draft mode from URL, localStorage, or cookie
@@ -199,7 +199,8 @@ export function detectEnvironment() {
199
199
  hostname.includes('ngrok-free.dev') ||
200
200
  hostname.includes('ngrok-free.app') ||
201
201
  hostname.includes('ngrok.io') ||
202
- hostname.includes('ngrok.app')) {
202
+ hostname.includes('ngrok.app') ||
203
+ hostname.includes('.loclx.io')) {
203
204
  console.log('[SDK] detectEnvironment() - returning LOCAL');
204
205
  // For local development, allow override via window.__TAGADA_ENV__ (injected by dev server)
205
206
  if (typeof window !== 'undefined' && window?.__TAGADA_ENV__?.TAGADA_ENVIRONMENT) {
@@ -85,14 +85,79 @@ export type PixelsConfig = {
85
85
  [TrackingProvider.GTM]?: GTMTrackingConfig[];
86
86
  };
87
87
  /**
88
- * Runtime step configuration injected from the CRM
89
- * Contains payment flows, static resources, scripts, and tracking configs
88
+ * Payment method configuration entry.
89
+ *
90
+ * Key pattern in paymentSetupConfig:
91
+ * "{method}" or "{method}:{provider}"
92
+ * e.g. "card", "apple_pay:stripe", "paypal:tagada", "klarna:stripe"
93
+ *
94
+ * `method` = what (universal payment method: card, apple_pay, klarna, ideal...)
95
+ * `provider` = who (processor family: tagada, stripe, airwallex, adyen...)
96
+ *
97
+ * @deprecated PaymentSetupMethod — use PaymentMethodConfig instead
90
98
  */
99
+ export interface ExpressMethodState {
100
+ enabled: boolean;
101
+ }
102
+ export type PaymentSetupMethod = PaymentMethodConfig;
103
+ export interface PaymentMethodConfig {
104
+ enabled: boolean;
105
+ /** Universal payment method identifier */
106
+ method: string;
107
+ /** Provider / processor family */
108
+ provider: string;
109
+ /** Render as express checkout button above the form */
110
+ express?: boolean;
111
+ /** Card routing via payment flow (cascade, fraud, processor selection) */
112
+ paymentFlowId?: string;
113
+ /** Direct processor routing for APMs and express methods */
114
+ processorId?: string;
115
+ /** Tagada integration record ID for native integrations */
116
+ integrationId?: string;
117
+ supportedCountries?: string[];
118
+ presentmentCurrencies?: string[];
119
+ recurring?: boolean;
120
+ /** Present only on express_checkout:proc_id entries */
121
+ publishableKey?: string;
122
+ /** Present only on express_checkout:proc_id entries — map of apmKey → state */
123
+ methods?: Record<string, ExpressMethodState>;
124
+ /** Present only on crypto integration entries — map of providerId → provider state */
125
+ providers?: Record<string, {
126
+ enabled?: boolean;
127
+ label?: string;
128
+ min?: number;
129
+ note?: string;
130
+ }>;
131
+ metadata?: Record<string, any>;
132
+ }
133
+ export type PaymentSetupConfig = Record<string, PaymentMethodConfig>;
134
+ /** Get all enabled entries from a paymentSetupConfig */
135
+ export declare function getEnabledMethods(config: PaymentSetupConfig | undefined): PaymentMethodConfig[];
136
+ /** Get all express methods (for rendering above the payment form) */
137
+ export declare function getExpressMethods(config: PaymentSetupConfig | undefined): PaymentMethodConfig[];
138
+ /** Group enabled express methods by processorId (one Express Element per processor) */
139
+ export declare function getExpressMethodsByProcessor(config: PaymentSetupConfig | undefined): Record<string, PaymentMethodConfig[]>;
140
+ /** Find a specific method entry by method name (returns first match) */
141
+ export declare function findMethod(config: PaymentSetupConfig | undefined, method: string): PaymentMethodConfig | undefined;
142
+ /** Check if a specific method is enabled (any provider) */
143
+ export declare function isMethodEnabled(config: PaymentSetupConfig | undefined, method: string): boolean;
91
144
  export interface RuntimeStepConfig {
92
145
  payment?: {
93
146
  paymentFlowId?: string;
94
147
  };
148
+ paymentSetupConfig?: PaymentSetupConfig;
149
+ orderBumps?: {
150
+ mode: 'inherit' | 'custom';
151
+ enabledOfferIds?: string[];
152
+ };
153
+ upsellOffers?: {
154
+ mode: 'inherit' | 'custom';
155
+ enabledUpsellIds?: string[];
156
+ };
157
+ /** @deprecated Use `resources` instead */
95
158
  staticResources?: Record<string, string>;
159
+ /** Typed resource bindings (replaces staticResources) */
160
+ resources?: Record<string, string>;
96
161
  scripts?: Array<{
97
162
  name: string;
98
163
  enabled: boolean;
@@ -110,14 +175,20 @@ export interface LocalFunnelConfig {
110
175
  funnelId?: string;
111
176
  /** Step ID to simulate */
112
177
  stepId?: string;
113
- /** Static resources (offer ID, product ID, etc.) */
178
+ /** @deprecated Use `resources` instead */
114
179
  staticResources?: Record<string, string>;
180
+ /** Resource bindings (offer ID, product ID, etc.) */
181
+ resources?: Record<string, string>;
115
182
  /** Payment flow ID override */
116
183
  paymentFlowId?: string;
117
184
  /** Custom scripts for local testing */
118
185
  scripts?: RuntimeStepConfig['scripts'];
119
186
  /** Pixel tracking config */
120
187
  pixels?: RuntimeStepConfig['pixels'];
188
+ /** Order bump filtering config for local testing */
189
+ orderBumps?: RuntimeStepConfig['orderBumps'];
190
+ /** Upsell offer filtering config for local testing */
191
+ upsellOffers?: RuntimeStepConfig['upsellOffers'];
121
192
  }
122
193
  /**
123
194
  * Load local funnel config from /config/funnel.local.json (for local dev only)
@@ -154,13 +225,22 @@ export declare function getLocalFunnelConfig(): LocalFunnelConfig | null;
154
225
  */
155
226
  export declare function getAssignedStepConfig(): RuntimeStepConfig | undefined;
156
227
  /**
157
- * Get the assigned payment flow ID from step config or legacy injection
158
- * Returns undefined if not available
228
+ * Get the assigned payment flow ID from step config or legacy injection.
229
+ * Resolution order:
230
+ * 1. paymentSetupConfig.card.paymentFlowId (per-method, most specific)
231
+ * 2. stepConfig.payment.paymentFlowId (per-step level)
232
+ * 3. window.__TGD_PAYMENT_FLOW_ID__ (legacy injection)
233
+ * 4. meta[name="x-payment-flow-id"] (legacy meta tag)
159
234
  */
160
235
  export declare function getAssignedPaymentFlowId(): string | undefined;
161
236
  /**
162
- * Get the assigned static resources from step config
163
- * Returns undefined if not available
237
+ * Get resource bindings from step config.
238
+ * Reads from `resources` (new) with `staticResources` (legacy) as fallback, merged.
239
+ */
240
+ export declare function getAssignedResources(): Record<string, string> | undefined;
241
+ /**
242
+ * @deprecated Use `getAssignedResources()` instead.
243
+ * Kept for backward compatibility — reads from both `resources` and `staticResources`.
164
244
  */
165
245
  export declare function getAssignedStaticResources(): Record<string, string> | undefined;
166
246
  /**
@@ -168,11 +248,19 @@ export declare function getAssignedStaticResources(): Record<string, string> | u
168
248
  * Returns only enabled scripts, filtered by position if specified
169
249
  */
170
250
  export declare function getAssignedScripts(position?: 'head-start' | 'head-end' | 'body-start' | 'body-end'): RuntimeStepConfig['scripts'];
251
+ export declare function getAssignedPixels(): PixelsConfig | undefined;
171
252
  /**
172
- * Get assigned pixel tracking configuration (normalized to arrays)
173
- * Always returns arrays of PixelConfig for consistent consumption.
253
+ * Get the enabled order bump offer IDs from step config.
254
+ * Returns undefined when mode is 'inherit' (use all store bumps).
255
+ * Returns the explicit list when mode is 'custom'.
174
256
  */
175
- export declare function getAssignedPixels(): PixelsConfig | undefined;
257
+ export declare function getAssignedOrderBumpOfferIds(): string[] | undefined;
258
+ /**
259
+ * Get the enabled upsell offer IDs from step config.
260
+ * Returns undefined when mode is 'inherit' (use all store upsells).
261
+ * Returns the explicit list when mode is 'custom'.
262
+ */
263
+ export declare function getAssignedUpsellOfferIds(): string[] | undefined;
176
264
  export interface FunnelClientConfig {
177
265
  apiClient: ApiClient;
178
266
  debugMode?: boolean;
@@ -2,7 +2,7 @@ import { detectEnvironment } from './config/environment';
2
2
  import { FunnelActionType, FunnelResource } from './resources/funnel';
3
3
  import { EventDispatcher } from './utils/eventDispatcher';
4
4
  import { getSDKParams } from './utils/previewMode';
5
- import { injectPreviewModeIndicator } from './utils/previewModeIndicator';
5
+ const lazyInjectPreviewIndicator = () => import('./utils/previewModeIndicator').then(m => m.injectPreviewModeIndicator());
6
6
  import { getFunnelSessionCookie, setFunnelSessionCookie } from './utils/sessionStorage';
7
7
  /**
8
8
  * Tracking providers supported by the SDK.
@@ -16,6 +16,41 @@ export var TrackingProvider;
16
16
  TrackingProvider["PINTEREST"] = "pinterest";
17
17
  TrackingProvider["GTM"] = "gtm";
18
18
  })(TrackingProvider || (TrackingProvider = {}));
19
+ /** Get all enabled entries from a paymentSetupConfig */
20
+ export function getEnabledMethods(config) {
21
+ if (!config)
22
+ return [];
23
+ return Object.values(config).filter(m => m.enabled);
24
+ }
25
+ /** Get all express methods (for rendering above the payment form) */
26
+ export function getExpressMethods(config) {
27
+ return getEnabledMethods(config).filter(m => m.express);
28
+ }
29
+ /** Group enabled express methods by processorId (one Express Element per processor) */
30
+ export function getExpressMethodsByProcessor(config) {
31
+ const groups = {};
32
+ for (const m of getExpressMethods(config)) {
33
+ const key = m.processorId || m.integrationId || m.provider;
34
+ if (!groups[key])
35
+ groups[key] = [];
36
+ groups[key].push(m);
37
+ }
38
+ return groups;
39
+ }
40
+ /** Find a specific method entry by method name (returns first match) */
41
+ export function findMethod(config, method) {
42
+ if (!config)
43
+ return undefined;
44
+ for (const entry of Object.values(config)) {
45
+ if (entry.method === method && entry.enabled)
46
+ return entry;
47
+ }
48
+ return undefined;
49
+ }
50
+ /** Check if a specific method is enabled (any provider) */
51
+ export function isMethodEnabled(config, method) {
52
+ return !!findMethod(config, method);
53
+ }
19
54
  /**
20
55
  * Get the funnel ID from the injected HTML
21
56
  * Returns undefined if not available
@@ -183,11 +218,14 @@ export function getLocalFunnelConfig() {
183
218
  * Convert LocalFunnelConfig to RuntimeStepConfig
184
219
  */
185
220
  function localConfigToStepConfig(local) {
221
+ const merged = { ...local.staticResources, ...local.resources };
186
222
  return {
187
223
  payment: local.paymentFlowId ? { paymentFlowId: local.paymentFlowId } : undefined,
188
- staticResources: local.staticResources,
224
+ resources: Object.keys(merged).length > 0 ? merged : undefined,
189
225
  scripts: local.scripts,
190
226
  pixels: local.pixels,
227
+ orderBumps: local.orderBumps,
228
+ upsellOffers: local.upsellOffers,
191
229
  };
192
230
  }
193
231
  /**
@@ -207,7 +245,6 @@ export function getAssignedStepConfig() {
207
245
  if (typeof window === 'undefined')
208
246
  return undefined;
209
247
  // Method 1: Local dev override (HIGHEST PRIORITY in local dev)
210
- // Allows developers to test different configurations without redeploying
211
248
  const localConfig = getLocalFunnelConfig();
212
249
  if (localConfig) {
213
250
  console.log('🛠️ [SDK] Using local funnel.local.json (overrides injected)');
@@ -233,22 +270,29 @@ export function getAssignedStepConfig() {
233
270
  return undefined;
234
271
  }
235
272
  /**
236
- * Get the assigned payment flow ID from step config or legacy injection
237
- * Returns undefined if not available
273
+ * Get the assigned payment flow ID from step config or legacy injection.
274
+ * Resolution order:
275
+ * 1. paymentSetupConfig.card.paymentFlowId (per-method, most specific)
276
+ * 2. stepConfig.payment.paymentFlowId (per-step level)
277
+ * 3. window.__TGD_PAYMENT_FLOW_ID__ (legacy injection)
278
+ * 4. meta[name="x-payment-flow-id"] (legacy meta tag)
238
279
  */
239
280
  export function getAssignedPaymentFlowId() {
240
- // Method 1: New stepConfig (preferred)
241
281
  const stepConfig = getAssignedStepConfig();
282
+ // Method 1: Per-method config — card entry in paymentSetupConfig
283
+ const cardConfig = stepConfig?.paymentSetupConfig?.card;
284
+ if (cardConfig?.paymentFlowId) {
285
+ return cardConfig.paymentFlowId;
286
+ }
287
+ // Method 2: Per-step config (legacy but still supported)
242
288
  if (stepConfig?.payment?.paymentFlowId) {
243
289
  return stepConfig.payment.paymentFlowId;
244
290
  }
245
- // Method 2: Legacy direct injection (backward compatibility)
291
+ // Method 3: Legacy direct injection (backward compatibility)
246
292
  if (typeof window !== 'undefined') {
247
- // Legacy window variable
248
293
  if (window.__TGD_PAYMENT_FLOW_ID__) {
249
294
  return window.__TGD_PAYMENT_FLOW_ID__;
250
295
  }
251
- // Legacy meta tag
252
296
  if (typeof document !== 'undefined') {
253
297
  const meta = document.querySelector('meta[name="x-payment-flow-id"]');
254
298
  return meta?.getAttribute('content') || undefined;
@@ -257,12 +301,23 @@ export function getAssignedPaymentFlowId() {
257
301
  return undefined;
258
302
  }
259
303
  /**
260
- * Get the assigned static resources from step config
261
- * Returns undefined if not available
304
+ * Get resource bindings from step config.
305
+ * Reads from `resources` (new) with `staticResources` (legacy) as fallback, merged.
262
306
  */
263
- export function getAssignedStaticResources() {
307
+ export function getAssignedResources() {
264
308
  const stepConfig = getAssignedStepConfig();
265
- return stepConfig?.staticResources;
309
+ const legacy = stepConfig?.staticResources;
310
+ const current = stepConfig?.resources;
311
+ if (!legacy && !current)
312
+ return undefined;
313
+ return { ...legacy, ...current };
314
+ }
315
+ /**
316
+ * @deprecated Use `getAssignedResources()` instead.
317
+ * Kept for backward compatibility — reads from both `resources` and `staticResources`.
318
+ */
319
+ export function getAssignedStaticResources() {
320
+ return getAssignedResources();
266
321
  }
267
322
  /**
268
323
  * Get the assigned scripts from step config
@@ -284,6 +339,21 @@ export function getAssignedScripts(position) {
284
339
  * Get assigned pixel tracking configuration (normalized to arrays)
285
340
  * Always returns arrays of PixelConfig for consistent consumption.
286
341
  */
342
+ /**
343
+ * Split a pixel config with semicolon/comma-separated IDs into individual configs.
344
+ * Handles cases where the CRM stores "ID1; ID2; ID3" as a single pixelId or containerId.
345
+ */
346
+ function splitPixelConfig(px) {
347
+ // GTM configs use containerId
348
+ const idField = 'containerId' in px ? 'containerId' : 'pixelId';
349
+ const rawId = px[idField];
350
+ if (!rawId || !rawId.includes(';') && !rawId.includes(','))
351
+ return [px];
352
+ const ids = rawId.split(/[;,]/).map((id) => id.trim()).filter((id) => id.length > 0);
353
+ if (ids.length <= 1)
354
+ return [px];
355
+ return ids.map((id) => ({ ...px, [idField]: id }));
356
+ }
287
357
  export function getAssignedPixels() {
288
358
  const stepConfig = getAssignedStepConfig();
289
359
  const rawPixels = stepConfig?.pixels;
@@ -294,17 +364,43 @@ export function getAssignedPixels() {
294
364
  if (!value)
295
365
  continue;
296
366
  if (Array.isArray(value)) {
297
- // Already an array
298
- normalized[key] = value;
367
+ // Expand any entries with semicolon/comma-separated pixelIds into separate configs
368
+ normalized[key] = value.flatMap((px) => splitPixelConfig(px));
299
369
  }
300
370
  else if (typeof value === 'object') {
301
- // Single object - wrap in array
302
- normalized[key] = [value];
371
+ // Single object - wrap in array, splitting if needed
372
+ normalized[key] = splitPixelConfig(value);
303
373
  }
304
374
  // Skip invalid entries
305
375
  }
306
376
  return Object.keys(normalized).length > 0 ? normalized : undefined;
307
377
  }
378
+ /**
379
+ * Get the enabled order bump offer IDs from step config.
380
+ * Returns undefined when mode is 'inherit' (use all store bumps).
381
+ * Returns the explicit list when mode is 'custom'.
382
+ */
383
+ export function getAssignedOrderBumpOfferIds() {
384
+ const stepConfig = getAssignedStepConfig();
385
+ if (!stepConfig?.orderBumps)
386
+ return undefined;
387
+ if (stepConfig.orderBumps.mode !== 'custom')
388
+ return undefined;
389
+ return stepConfig.orderBumps.enabledOfferIds;
390
+ }
391
+ /**
392
+ * Get the enabled upsell offer IDs from step config.
393
+ * Returns undefined when mode is 'inherit' (use all store upsells).
394
+ * Returns the explicit list when mode is 'custom'.
395
+ */
396
+ export function getAssignedUpsellOfferIds() {
397
+ const stepConfig = getAssignedStepConfig();
398
+ if (!stepConfig?.upsellOffers)
399
+ return undefined;
400
+ if (stepConfig.upsellOffers.mode !== 'custom')
401
+ return undefined;
402
+ return stepConfig.upsellOffers.enabledUpsellIds;
403
+ }
308
404
  export class FunnelClient {
309
405
  constructor(config) {
310
406
  this.eventDispatcher = new EventDispatcher();
@@ -444,8 +540,7 @@ export class FunnelClient {
444
540
  if (response.success && response.context) {
445
541
  const enriched = this.enrichContext(response.context);
446
542
  this.handleSessionSuccess(enriched);
447
- // 🔍 Auto-inject preview mode indicator if in preview/dev mode
448
- injectPreviewModeIndicator();
543
+ lazyInjectPreviewIndicator();
449
544
  return enriched;
450
545
  }
451
546
  else {
@@ -495,8 +590,7 @@ export class FunnelClient {
495
590
  if (response.success && response.context) {
496
591
  const enriched = this.enrichContext(response.context);
497
592
  this.handleSessionSuccess(enriched);
498
- // 🔍 Auto-inject preview mode indicator if in preview/dev mode
499
- injectPreviewModeIndicator();
593
+ lazyInjectPreviewIndicator();
500
594
  return enriched;
501
595
  }
502
596
  else {
@@ -608,12 +702,12 @@ export class FunnelClient {
608
702
  : this.config.autoRedirect !== false; // Default to true
609
703
  // Skip refreshSession if auto-redirecting (next page will initialize with fresh state)
610
704
  // Only refresh if staying on same page (autoRedirect: false)
611
- if (!shouldAutoRedirect) {
612
- if (this.config.debugMode) {
613
- console.log('🔄 [FunnelClient] Refreshing session (no auto-redirect)');
614
- }
615
- await this.refreshSession();
616
- }
705
+ // if (!shouldAutoRedirect) {
706
+ // if (this.config.debugMode) {
707
+ // console.log('🔄 [FunnelClient] Refreshing session (no auto-redirect)');
708
+ // }
709
+ // await this.refreshSession();
710
+ // }
617
711
  this.updateState({ isNavigating: false, isLoading: false });
618
712
  // Auto-redirect if enabled and result has a URL
619
713
  if (shouldAutoRedirect && result?.url && typeof window !== 'undefined') {
@@ -7,6 +7,5 @@ export * from './resources';
7
7
  export * from './client';
8
8
  export * from './funnelClient';
9
9
  export * from './pathRemapping';
10
- export * from './pixelMapping';
11
10
  export * from './googleAutocomplete';
12
11
  export * from './isoData';
@@ -11,8 +11,6 @@ export * from './client';
11
11
  export * from './funnelClient';
12
12
  // Export path remapping helpers (framework-agnostic)
13
13
  export * from './pathRemapping';
14
- // Export pixel mapping (framework-agnostic, shared by React + standalone)
15
- export * from './pixelMapping';
16
14
  // Export legacy files that are still needed
17
15
  export * from './googleAutocomplete';
18
16
  export * from './isoData';
@@ -1,7 +1,6 @@
1
1
  /**
2
- * ISO Data Core
3
- * Pure functions for country and region data management
4
- * Uses the existing iso3166 data functions
2
+ * ISO Data Core — CDN-backed country/region data (pure functions, no React).
3
+ * Call ensureLoaded() before using synchronous getters.
5
4
  */
6
5
  import { type SupportedLanguage } from '../../data/iso3166';
7
6
  export interface ISOCountry {
@@ -44,7 +43,8 @@ export declare class ISODataCore {
44
43
  */
45
44
  static importLanguage(language: SupportedLanguage): Promise<void>;
46
45
  /**
47
- * Get available languages for ISO data
46
+ * Fetch countries + regions from CDN for a language (call before sync getters)
48
47
  */
48
+ static ensureLoaded(language?: SupportedLanguage): Promise<void>;
49
49
  static getAvailableLanguages(): SupportedLanguage[];
50
50
  }
@@ -1,10 +1,8 @@
1
1
  /**
2
- * ISO Data Core
3
- * Pure functions for country and region data management
4
- * Uses the existing iso3166 data functions
2
+ * ISO Data Core — CDN-backed country/region data (pure functions, no React).
3
+ * Call ensureLoaded() before using synchronous getters.
5
4
  */
6
- // Import the pre-built ISO data functions
7
- import { getCountries, getStatesForCountry, importLanguage, isLanguageRegistered, getRegisteredLanguages } from '../../data/iso3166';
5
+ import { getCountries, getStatesForCountry, ensureGeoDataLoaded, importLanguage, isLanguageRegistered, getRegisteredLanguages } from '../../data/iso3166';
8
6
  export class ISODataCore {
9
7
  /**
10
8
  * Get countries data for a specific language
@@ -94,10 +92,12 @@ export class ISODataCore {
94
92
  return importLanguage(language);
95
93
  }
96
94
  /**
97
- * Get available languages for ISO data
95
+ * Fetch countries + regions from CDN for a language (call before sync getters)
98
96
  */
97
+ static async ensureLoaded(language = 'en') {
98
+ return ensureGeoDataLoaded(language);
99
+ }
99
100
  static getAvailableLanguages() {
100
- // Return all available languages (not just registered ones)
101
101
  return ['en', 'ru', 'de', 'fr', 'es', 'zh', 'hi', 'pt', 'ja', 'ar', 'it', 'he'];
102
102
  }
103
103
  }