@tagadapay/plugin-sdk 2.8.10 → 3.0.1
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/README.md +14 -14
- package/dist/index.js +1 -1
- package/dist/react/hooks/usePluginConfig.d.ts +1 -0
- package/dist/react/hooks/usePluginConfig.js +69 -18
- package/dist/react/providers/TagadaProvider.js +1 -4
- package/dist/v2/core/client.d.ts +18 -0
- package/dist/v2/core/client.js +45 -0
- package/dist/v2/core/config/environment.d.ts +8 -0
- package/dist/v2/core/config/environment.js +18 -0
- package/dist/v2/core/funnelClient.d.ts +84 -0
- package/dist/v2/core/funnelClient.js +252 -0
- package/dist/v2/core/index.d.ts +2 -0
- package/dist/v2/core/index.js +3 -0
- package/dist/v2/core/resources/apiClient.js +1 -1
- package/dist/v2/core/resources/funnel.d.ts +1 -0
- package/dist/v2/core/resources/offers.d.ts +182 -8
- package/dist/v2/core/resources/offers.js +25 -0
- package/dist/v2/core/resources/products.d.ts +5 -0
- package/dist/v2/core/resources/products.js +15 -1
- package/dist/v2/core/types.d.ts +1 -0
- package/dist/v2/core/utils/funnelQueryKeys.d.ts +23 -0
- package/dist/v2/core/utils/funnelQueryKeys.js +23 -0
- package/dist/v2/core/utils/index.d.ts +2 -0
- package/dist/v2/core/utils/index.js +2 -0
- package/dist/v2/core/utils/pluginConfig.js +44 -32
- package/dist/v2/core/utils/sessionStorage.d.ts +20 -0
- package/dist/v2/core/utils/sessionStorage.js +39 -0
- package/dist/v2/index.d.ts +3 -2
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.d.ts +3 -0
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +4 -3
- package/dist/v2/react/hooks/useClubOffers.d.ts +2 -2
- package/dist/v2/react/hooks/useFunnel.d.ts +27 -39
- package/dist/v2/react/hooks/useFunnel.js +22 -659
- package/dist/v2/react/hooks/useFunnelLegacy.d.ts +52 -0
- package/dist/v2/react/hooks/useFunnelLegacy.js +733 -0
- package/dist/v2/react/hooks/useOfferQuery.d.ts +109 -0
- package/dist/v2/react/hooks/useOfferQuery.js +483 -0
- package/dist/v2/react/hooks/useOffersQuery.d.ts +9 -75
- package/dist/v2/react/hooks/useProductsQuery.d.ts +1 -0
- package/dist/v2/react/hooks/useProductsQuery.js +10 -6
- package/dist/v2/react/index.d.ts +7 -4
- package/dist/v2/react/index.js +4 -2
- package/dist/v2/react/providers/TagadaProvider.d.ts +40 -2
- package/dist/v2/react/providers/TagadaProvider.js +116 -3
- package/dist/v2/standalone/index.d.ts +20 -0
- package/dist/v2/standalone/index.js +22 -0
- package/dist/v2/vue/index.d.ts +6 -0
- package/dist/v2/vue/index.js +10 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A comprehensive React SDK for building plugins on the TagadaPay platform. Create
|
|
|
4
4
|
|
|
5
5
|
> **🚀 V2 Now Available!** The new V2 architecture features TanStack Query integration, improved TypeScript support, and better performance. [See V2 Architecture](#-v2-architecture) for details.
|
|
6
6
|
>
|
|
7
|
-
> **Recommended**: Use `@tagadapay/plugin-sdk/
|
|
7
|
+
> **Recommended**: Use `@tagadapay/plugin-sdk/v3` for new projects. V1 (`/react`) is still supported for existing projects.
|
|
8
8
|
|
|
9
9
|
## 📚 Documentation
|
|
10
10
|
|
|
@@ -146,7 +146,7 @@ import {
|
|
|
146
146
|
useISOData,
|
|
147
147
|
useCheckout,
|
|
148
148
|
formatMoney,
|
|
149
|
-
} from '@tagadapay/plugin-sdk/
|
|
149
|
+
} from '@tagadapay/plugin-sdk/v3';
|
|
150
150
|
|
|
151
151
|
function MyPlugin() {
|
|
152
152
|
const { config, storeId, accountId, basePath, loading } = usePluginConfig();
|
|
@@ -199,7 +199,7 @@ export default App;
|
|
|
199
199
|
|
|
200
200
|
### What's New in V2
|
|
201
201
|
|
|
202
|
-
The TagadaPay Plugin SDK
|
|
202
|
+
The TagadaPay Plugin SDK v3 introduces a clean architecture with significant improvements:
|
|
203
203
|
|
|
204
204
|
#### **🔄 TanStack Query Integration**
|
|
205
205
|
|
|
@@ -218,7 +218,7 @@ The TagadaPay Plugin SDK v2 introduces a clean architecture with significant imp
|
|
|
218
218
|
|
|
219
219
|
```tsx
|
|
220
220
|
// V2 (Recommended)
|
|
221
|
-
import { useCheckout, useOffers, TagadaProvider } from '@tagadapay/plugin-sdk/
|
|
221
|
+
import { useCheckout, useOffers, TagadaProvider } from '@tagadapay/plugin-sdk/v3';
|
|
222
222
|
|
|
223
223
|
// Legacy (Still supported)
|
|
224
224
|
import { useCheckout, useOffers, TagadaProvider } from '@tagadapay/plugin-sdk/react';
|
|
@@ -257,7 +257,7 @@ import {
|
|
|
257
257
|
useProducts,
|
|
258
258
|
usePluginConfig,
|
|
259
259
|
formatMoney,
|
|
260
|
-
} from '@tagadapay/plugin-sdk/
|
|
260
|
+
} from '@tagadapay/plugin-sdk/v3';
|
|
261
261
|
|
|
262
262
|
function CheckoutPage() {
|
|
263
263
|
const [checkoutToken, setCheckoutToken] = useState<string>();
|
|
@@ -355,7 +355,7 @@ function App() {
|
|
|
355
355
|
|
|
356
356
|
```tsx
|
|
357
357
|
import React from 'react';
|
|
358
|
-
import { TagadaProvider, useCheckout, useOffers, formatMoney } from '@tagadapay/plugin-sdk/
|
|
358
|
+
import { TagadaProvider, useCheckout, useOffers, formatMoney } from '@tagadapay/plugin-sdk/v3';
|
|
359
359
|
|
|
360
360
|
// Component 1: Cart Summary
|
|
361
361
|
function CartSummary({ checkoutToken }: { checkoutToken: string }) {
|
|
@@ -411,7 +411,7 @@ function CheckoutWithOffers() {
|
|
|
411
411
|
|
|
412
412
|
```tsx
|
|
413
413
|
import React from 'react';
|
|
414
|
-
import { useCheckout } from '@tagadapay/plugin-sdk/
|
|
414
|
+
import { useCheckout } from '@tagadapay/plugin-sdk/v3';
|
|
415
415
|
|
|
416
416
|
function QuantitySelector({
|
|
417
417
|
checkoutToken,
|
|
@@ -555,7 +555,7 @@ interface TagadaProviderProps {
|
|
|
555
555
|
#### V2 Enhanced Provider Features
|
|
556
556
|
|
|
557
557
|
```tsx
|
|
558
|
-
import { TagadaProvider } from '@tagadapay/plugin-sdk/
|
|
558
|
+
import { TagadaProvider } from '@tagadapay/plugin-sdk/v3';
|
|
559
559
|
|
|
560
560
|
function App() {
|
|
561
561
|
return (
|
|
@@ -577,7 +577,7 @@ function App() {
|
|
|
577
577
|
}
|
|
578
578
|
```
|
|
579
579
|
|
|
580
|
-
> **Version Compatibility:** V2 features require `@tagadapay/plugin-sdk/
|
|
580
|
+
> **Version Compatibility:** V2 features require `@tagadapay/plugin-sdk/v3`. The `blockUntilSessionReady` option was added in v2.3.0. For older versions, the blocking behavior was the default and only option.
|
|
581
581
|
|
|
582
582
|
### Development vs Production
|
|
583
583
|
|
|
@@ -729,7 +729,7 @@ const {
|
|
|
729
729
|
**Example:**
|
|
730
730
|
|
|
731
731
|
```tsx
|
|
732
|
-
import { useStoreConfig } from '@tagadapay/plugin-sdk/
|
|
732
|
+
import { useStoreConfig } from '@tagadapay/plugin-sdk/v3';
|
|
733
733
|
|
|
734
734
|
function StoreInfo() {
|
|
735
735
|
const { storeConfig, isLoading } = useStoreConfig();
|
|
@@ -808,7 +808,7 @@ import {
|
|
|
808
808
|
useInvalidateQuery,
|
|
809
809
|
usePreloadQuery,
|
|
810
810
|
queryKeys,
|
|
811
|
-
} from '@tagadapay/plugin-sdk/
|
|
811
|
+
} from '@tagadapay/plugin-sdk/v3';
|
|
812
812
|
|
|
813
813
|
// Custom API queries
|
|
814
814
|
const { data, isLoading } = useApiQuery({
|
|
@@ -838,7 +838,7 @@ preloadCheckout({
|
|
|
838
838
|
Enhanced money formatting with better TypeScript support:
|
|
839
839
|
|
|
840
840
|
```typescript
|
|
841
|
-
import { formatMoney, convertCurrency, getCurrencyInfo } from '@tagadapay/plugin-sdk/
|
|
841
|
+
import { formatMoney, convertCurrency, getCurrencyInfo } from '@tagadapay/plugin-sdk/v3';
|
|
842
842
|
|
|
843
843
|
// Format money with automatic currency detection
|
|
844
844
|
const formatted = formatMoney(2999, 'USD'); // "$29.99"
|
|
@@ -867,7 +867,7 @@ import {
|
|
|
867
867
|
ProductsResource,
|
|
868
868
|
PaymentsResource,
|
|
869
869
|
PluginConfigUtils,
|
|
870
|
-
} from '@tagadapay/plugin-sdk/
|
|
870
|
+
} from '@tagadapay/plugin-sdk/v3';
|
|
871
871
|
|
|
872
872
|
// Use core functions directly (useful for server-side or non-React contexts)
|
|
873
873
|
const checkoutResource = new CheckoutResource(apiClient);
|
|
@@ -883,7 +883,7 @@ const isValid = PluginConfigUtils.validateConfig(config);
|
|
|
883
883
|
V2 includes built-in debugging tools:
|
|
884
884
|
|
|
885
885
|
```tsx
|
|
886
|
-
import { TagadaProvider } from '@tagadapay/plugin-sdk/
|
|
886
|
+
import { TagadaProvider } from '@tagadapay/plugin-sdk/v3';
|
|
887
887
|
|
|
888
888
|
function App() {
|
|
889
889
|
return (
|
package/dist/index.js
CHANGED
|
@@ -15,5 +15,5 @@ export { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMon
|
|
|
15
15
|
// Export data utilities
|
|
16
16
|
export * from './data/iso3166';
|
|
17
17
|
export * from './data/languages';
|
|
18
|
-
// V2 exports -
|
|
18
|
+
// V2 exports - production-ready clean architecture
|
|
19
19
|
export * from './v2';
|
|
@@ -23,6 +23,7 @@ export interface PluginConfig<TConfig = Record<string, any>> {
|
|
|
23
23
|
accountId?: string;
|
|
24
24
|
basePath?: string;
|
|
25
25
|
config?: TConfig;
|
|
26
|
+
staticResources?: Record<string, any>;
|
|
26
27
|
}
|
|
27
28
|
export interface RawPluginConfig<TConfig = Record<string, any>> {
|
|
28
29
|
storeId?: string;
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* - Headers for store/account info
|
|
19
19
|
* - Meta tags for deployment config
|
|
20
20
|
*/
|
|
21
|
+
import { isLocalEnvironment } from '../../v2/core/config/environment';
|
|
21
22
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
22
23
|
// Simple cache for plugin configuration
|
|
23
24
|
let cachedConfig = null;
|
|
@@ -29,13 +30,7 @@ let configPromise = null;
|
|
|
29
30
|
const loadLocalDevConfig = async (configVariant = 'default') => {
|
|
30
31
|
try {
|
|
31
32
|
// Only try to load local config in development
|
|
32
|
-
|
|
33
|
-
const isLocalDev = typeof window !== 'undefined' &&
|
|
34
|
-
(window.location.hostname === 'localhost' ||
|
|
35
|
-
window.location.hostname.includes('ngrok-free.app') ||
|
|
36
|
-
window.location.hostname.includes('.localhost') ||
|
|
37
|
-
window.location.hostname.includes('127.0.0.1'));
|
|
38
|
-
if (!isLocalDev) {
|
|
33
|
+
if (!isLocalEnvironment()) {
|
|
39
34
|
return null;
|
|
40
35
|
}
|
|
41
36
|
// Load local store/account config
|
|
@@ -141,28 +136,89 @@ const loadProductionConfig = async () => {
|
|
|
141
136
|
return { basePath: '/', config: {} };
|
|
142
137
|
}
|
|
143
138
|
};
|
|
139
|
+
/**
|
|
140
|
+
* Load static resources for local development
|
|
141
|
+
* Loads /config/resources.static.json
|
|
142
|
+
*/
|
|
143
|
+
const loadStaticResources = async () => {
|
|
144
|
+
try {
|
|
145
|
+
// Only try to load in TRUE local development (not deployed CDN instances)
|
|
146
|
+
// Exclude CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
147
|
+
if (!isLocalEnvironment(true)) {
|
|
148
|
+
console.log('🛠️ Not in local dev environment, skipping static resources loading');
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
// Load static resources file
|
|
152
|
+
console.log('🛠️ [V1] Attempting to load /config/resources.static.json...');
|
|
153
|
+
const response = await fetch('/config/resources.static.json');
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
console.log('🛠️ [V1] resources.static.json not found or failed to load');
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const staticResources = await response.json();
|
|
159
|
+
console.log('🛠️ [V1] ✅ Loaded local static resources:', staticResources);
|
|
160
|
+
return staticResources;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error('🛠️ ❌ Error loading static resources:', error);
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
144
167
|
/**
|
|
145
168
|
* Load plugin configuration (cached)
|
|
146
169
|
* Tries raw config first, then local dev config, then production config
|
|
147
170
|
*/
|
|
148
171
|
export const loadPluginConfig = async (configVariant = 'default', rawConfig) => {
|
|
172
|
+
console.log('🔧 [V1] loadPluginConfig called with variant:', configVariant);
|
|
173
|
+
// Load static resources first (only in local dev)
|
|
174
|
+
const staticResources = await loadStaticResources();
|
|
175
|
+
console.log('🔧 [V1] Static resources loaded:', {
|
|
176
|
+
hasStaticResources: !!staticResources,
|
|
177
|
+
staticResourcesKeys: staticResources ? Object.keys(staticResources) : [],
|
|
178
|
+
});
|
|
149
179
|
// If raw config is provided, use it directly
|
|
150
180
|
if (rawConfig) {
|
|
151
|
-
console.log('🛠️ Using raw plugin config:', rawConfig);
|
|
152
|
-
|
|
181
|
+
console.log('🛠️ [V1] Using raw plugin config:', rawConfig);
|
|
182
|
+
const result = {
|
|
153
183
|
storeId: rawConfig.storeId,
|
|
154
184
|
accountId: rawConfig.accountId,
|
|
155
185
|
basePath: rawConfig.basePath ?? '/',
|
|
156
186
|
config: rawConfig.config ?? {},
|
|
187
|
+
staticResources: staticResources ?? undefined,
|
|
157
188
|
};
|
|
189
|
+
console.log('🔧 [V1] Final config (raw):', {
|
|
190
|
+
hasStoreId: !!result.storeId,
|
|
191
|
+
hasStaticResources: !!result.staticResources,
|
|
192
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
193
|
+
});
|
|
194
|
+
return result;
|
|
158
195
|
}
|
|
159
196
|
// Try local development config
|
|
160
197
|
const localConfig = await loadLocalDevConfig(configVariant);
|
|
161
198
|
if (localConfig) {
|
|
162
|
-
|
|
199
|
+
const result = {
|
|
200
|
+
...localConfig,
|
|
201
|
+
staticResources: staticResources ?? undefined,
|
|
202
|
+
};
|
|
203
|
+
console.log('🔧 [V1] Final config (local):', {
|
|
204
|
+
hasStoreId: !!result.storeId,
|
|
205
|
+
hasStaticResources: !!result.staticResources,
|
|
206
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
207
|
+
});
|
|
208
|
+
return result;
|
|
163
209
|
}
|
|
164
210
|
// Fall back to production config
|
|
165
|
-
|
|
211
|
+
const productionConfig = await loadProductionConfig();
|
|
212
|
+
const result = {
|
|
213
|
+
...productionConfig,
|
|
214
|
+
staticResources: staticResources ?? undefined,
|
|
215
|
+
};
|
|
216
|
+
console.log('🔧 [V1] Final config (production):', {
|
|
217
|
+
hasStoreId: !!result.storeId,
|
|
218
|
+
hasStaticResources: !!result.staticResources,
|
|
219
|
+
staticResourcesKeys: result.staticResources ? Object.keys(result.staticResources) : [],
|
|
220
|
+
});
|
|
221
|
+
return result;
|
|
166
222
|
};
|
|
167
223
|
/**
|
|
168
224
|
* Main hook for plugin configuration
|
|
@@ -212,13 +268,8 @@ export const clearPluginConfigCache = () => {
|
|
|
212
268
|
* Development helper to log current configuration
|
|
213
269
|
*/
|
|
214
270
|
export const debugPluginConfig = async (configVariant = 'default', rawConfig) => {
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
(window.location.hostname === 'localhost' ||
|
|
218
|
-
window.location.hostname.includes('ngrok-free.app') ||
|
|
219
|
-
window.location.hostname.includes('.localhost') ||
|
|
220
|
-
window.location.hostname.includes('127.0.0.1'));
|
|
221
|
-
if (!isLocalDev) {
|
|
271
|
+
// Check if we're in local development
|
|
272
|
+
if (!isLocalEnvironment()) {
|
|
222
273
|
return;
|
|
223
274
|
}
|
|
224
275
|
const config = await getPluginConfig(configVariant, rawConfig);
|
|
@@ -49,10 +49,7 @@ export function TagadaProvider({ children, environment, customApiConfig, debugMo
|
|
|
49
49
|
localConfig, blockUntilSessionReady = false, // Default to new non-blocking behavior
|
|
50
50
|
rawPluginConfig, }) {
|
|
51
51
|
// LOCAL DEV ONLY: Use localConfig override if in local development, otherwise use default
|
|
52
|
-
const isLocalDev =
|
|
53
|
-
(window.location.hostname === 'localhost' ||
|
|
54
|
-
window.location.hostname.includes('.localhost') ||
|
|
55
|
-
window.location.hostname.includes('127.0.0.1'));
|
|
52
|
+
const isLocalDev = detectEnvironment() === 'local';
|
|
56
53
|
const configVariant = isLocalDev ? localConfig || 'default' : 'default';
|
|
57
54
|
// Debug logging (only log once during initial render)
|
|
58
55
|
const hasLoggedRef = useRef(false);
|
package/dist/v2/core/client.d.ts
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { ApiClient } from './resources/apiClient';
|
|
2
2
|
import { PluginConfig, RawPluginConfig } from './utils/pluginConfig';
|
|
3
3
|
import { Environment, EnvironmentConfig, Session, AuthState, Customer, Store, Locale, Currency } from './types';
|
|
4
|
+
import { FunnelClient } from './funnelClient';
|
|
4
5
|
export interface TagadaClientConfig {
|
|
5
6
|
environment?: Environment;
|
|
6
7
|
debugMode?: boolean;
|
|
7
8
|
localConfig?: string;
|
|
8
9
|
rawPluginConfig?: RawPluginConfig;
|
|
9
10
|
blockUntilSessionReady?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Optional feature flags to enable/disable subsystems.
|
|
13
|
+
* By default all features are enabled.
|
|
14
|
+
*/
|
|
15
|
+
features?: {
|
|
16
|
+
/**
|
|
17
|
+
* Funnel session + navigation layer.
|
|
18
|
+
* Set to false to completely disable funnel behaviour.
|
|
19
|
+
*/
|
|
20
|
+
funnel?: boolean;
|
|
21
|
+
};
|
|
10
22
|
}
|
|
11
23
|
export interface TagadaState {
|
|
12
24
|
auth: AuthState;
|
|
@@ -27,6 +39,12 @@ export interface TagadaState {
|
|
|
27
39
|
export declare class TagadaClient {
|
|
28
40
|
apiClient: ApiClient;
|
|
29
41
|
state: TagadaState;
|
|
42
|
+
/**
|
|
43
|
+
* Optional funnel client.
|
|
44
|
+
* Exposed so higher-level SDKs (React, Standalone, Vue) can reuse the same
|
|
45
|
+
* low-level logic without instantiating a second client.
|
|
46
|
+
*/
|
|
47
|
+
funnel?: FunnelClient;
|
|
30
48
|
private eventDispatcher;
|
|
31
49
|
private tokenPromise;
|
|
32
50
|
private tokenResolver;
|
package/dist/v2/core/client.js
CHANGED
|
@@ -5,6 +5,7 @@ import { collectDeviceInfo, getBrowserLocale, getUrlParams } from './utils/devic
|
|
|
5
5
|
import { decodeJWTClient, isTokenExpired } from './utils/jwtDecoder';
|
|
6
6
|
import { getClientToken, setClientToken } from './utils/tokenStorage';
|
|
7
7
|
import { EventDispatcher } from './utils/eventDispatcher';
|
|
8
|
+
import { FunnelClient } from './funnelClient';
|
|
8
9
|
export class TagadaClient {
|
|
9
10
|
constructor(config = {}) {
|
|
10
11
|
this.eventDispatcher = new EventDispatcher();
|
|
@@ -58,6 +59,16 @@ export class TagadaClient {
|
|
|
58
59
|
this.apiClient = new ApiClient({
|
|
59
60
|
baseURL: envConfig.apiConfig.baseUrl,
|
|
60
61
|
});
|
|
62
|
+
// Initialize optional funnel client (feature-flagged)
|
|
63
|
+
const funnelEnabled = config.features?.funnel !== false;
|
|
64
|
+
if (funnelEnabled) {
|
|
65
|
+
this.funnel = new FunnelClient({
|
|
66
|
+
apiClient: this.apiClient,
|
|
67
|
+
debugMode: this.state.debugMode,
|
|
68
|
+
pluginConfig: this.state.pluginConfig,
|
|
69
|
+
environment: this.state.environment,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
61
72
|
// Setup token waiting mechanism
|
|
62
73
|
this.apiClient.setTokenProvider(this.waitForToken.bind(this));
|
|
63
74
|
// Listen for storage changes (cross-tab sync)
|
|
@@ -172,6 +183,13 @@ export class TagadaClient {
|
|
|
172
183
|
pluginConfig: config,
|
|
173
184
|
pluginConfigLoading: false,
|
|
174
185
|
});
|
|
186
|
+
// Keep funnel client in sync with latest plugin config / environment
|
|
187
|
+
if (this.funnel) {
|
|
188
|
+
this.funnel.setConfig({
|
|
189
|
+
pluginConfig: config,
|
|
190
|
+
environment: this.state.environment,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
175
193
|
if (this.state.debugMode) {
|
|
176
194
|
console.log('[TagadaClient] Plugin config loaded:', config);
|
|
177
195
|
}
|
|
@@ -379,6 +397,8 @@ export class TagadaClient {
|
|
|
379
397
|
const storeData = response.store;
|
|
380
398
|
const storeConfig = {
|
|
381
399
|
...response.store,
|
|
400
|
+
// Ensure accountId is included - fallback to plugin config or session accountId
|
|
401
|
+
accountId: storeData.accountId || this.state.pluginConfig?.accountId || sessionData.accountId || '',
|
|
382
402
|
presentmentCurrencies: storeData.presentmentCurrencies || [response.store.currency || 'USD'],
|
|
383
403
|
chargeCurrencies: storeData.chargeCurrencies || [response.store.currency || 'USD'],
|
|
384
404
|
};
|
|
@@ -412,6 +432,31 @@ export class TagadaClient {
|
|
|
412
432
|
customer: response.customer ?? null,
|
|
413
433
|
auth: authState
|
|
414
434
|
});
|
|
435
|
+
// Auto-initialize funnel if enabled
|
|
436
|
+
// This runs after we have all required data: auth.session, store, accountId
|
|
437
|
+
if (this.funnel && sessionData.customerId && response.store?.id) {
|
|
438
|
+
const accountId = response.store.accountId || this.state.pluginConfig?.accountId || sessionData.accountId || '';
|
|
439
|
+
if (accountId) {
|
|
440
|
+
// Get funnelId from URL or config
|
|
441
|
+
const urlParams = new URLSearchParams(typeof window !== 'undefined' ? window.location.search : '');
|
|
442
|
+
const funnelId = urlParams.get('funnelId') || undefined;
|
|
443
|
+
if (this.state.debugMode) {
|
|
444
|
+
console.log('[TagadaClient] Auto-initializing funnel...', {
|
|
445
|
+
customerId: sessionData.customerId,
|
|
446
|
+
storeId: response.store.id,
|
|
447
|
+
accountId,
|
|
448
|
+
funnelId: funnelId || 'auto-detect',
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
// Auto-initialize funnel in background (don't block session init)
|
|
452
|
+
this.funnel.autoInitialize({ customerId: sessionData.customerId, sessionId: sessionData.sessionId }, { id: response.store.id, accountId }, funnelId).catch((err) => {
|
|
453
|
+
console.error('[TagadaClient] Funnel auto-initialization failed:', err);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
console.warn('[TagadaClient] Cannot auto-initialize funnel: accountId is missing');
|
|
458
|
+
}
|
|
459
|
+
}
|
|
415
460
|
}
|
|
416
461
|
// Helper methods
|
|
417
462
|
getCurrencySymbol(code) {
|
|
@@ -34,3 +34,11 @@ export declare function getEndpointUrl(config: EnvironmentConfig, category: keyo
|
|
|
34
34
|
* .env variables are ONLY used for local development via window.__TAGADA_ENV__
|
|
35
35
|
*/
|
|
36
36
|
export declare function detectEnvironment(): Environment;
|
|
37
|
+
/**
|
|
38
|
+
* Check if we're running in local development environment
|
|
39
|
+
* Uses centralized detectEnvironment() for consistency
|
|
40
|
+
*
|
|
41
|
+
* @param excludeCdn - If true, excludes CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
42
|
+
* @returns true if in local environment (excluding CDN if specified)
|
|
43
|
+
*/
|
|
44
|
+
export declare function isLocalEnvironment(excludeCdn?: boolean): boolean;
|
|
@@ -153,3 +153,21 @@ export function detectEnvironment() {
|
|
|
153
153
|
console.warn(`[SDK] Unknown domain: ${hostname}, defaulting to production`);
|
|
154
154
|
return 'production';
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if we're running in local development environment
|
|
158
|
+
* Uses centralized detectEnvironment() for consistency
|
|
159
|
+
*
|
|
160
|
+
* @param excludeCdn - If true, excludes CDN subdomains (e.g., instance-id.cdn.localhost)
|
|
161
|
+
* @returns true if in local environment (excluding CDN if specified)
|
|
162
|
+
*/
|
|
163
|
+
export function isLocalEnvironment(excludeCdn = false) {
|
|
164
|
+
const env = detectEnvironment();
|
|
165
|
+
if (env !== 'local') {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
// If we need to exclude CDN subdomains
|
|
169
|
+
if (excludeCdn && typeof window !== 'undefined') {
|
|
170
|
+
return !window.location.hostname.includes('.cdn.');
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ApiClient } from './resources/apiClient';
|
|
2
|
+
import { SimpleFunnelContext, FunnelAction, FunnelNavigationResult } from './resources/funnel';
|
|
3
|
+
import { PluginConfig } from './utils/pluginConfig';
|
|
4
|
+
export interface FunnelClientConfig {
|
|
5
|
+
apiClient: ApiClient;
|
|
6
|
+
debugMode?: boolean;
|
|
7
|
+
pluginConfig?: PluginConfig;
|
|
8
|
+
environment?: {
|
|
9
|
+
environment: 'local' | 'development' | 'production' | 'staging';
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Automatically redirect to result.url after navigation (default: true)
|
|
13
|
+
* Set to false if you want to handle navigation manually
|
|
14
|
+
*/
|
|
15
|
+
autoRedirect?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface FunnelState {
|
|
18
|
+
context: SimpleFunnelContext | null;
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
isInitialized: boolean;
|
|
21
|
+
isNavigating: boolean;
|
|
22
|
+
error: Error | null;
|
|
23
|
+
sessionError: Error | null;
|
|
24
|
+
}
|
|
25
|
+
export declare class FunnelClient {
|
|
26
|
+
state: FunnelState;
|
|
27
|
+
private resource;
|
|
28
|
+
private eventDispatcher;
|
|
29
|
+
private config;
|
|
30
|
+
private isInitializing;
|
|
31
|
+
private initializationAttempted;
|
|
32
|
+
constructor(config: FunnelClientConfig);
|
|
33
|
+
/**
|
|
34
|
+
* Update configuration (e.g. when plugin config loads)
|
|
35
|
+
*/
|
|
36
|
+
setConfig(config: Partial<FunnelClientConfig>): void;
|
|
37
|
+
/**
|
|
38
|
+
* Subscribe to state changes
|
|
39
|
+
*/
|
|
40
|
+
subscribe(listener: (state: FunnelState) => void): () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Get current state
|
|
43
|
+
*/
|
|
44
|
+
getState(): FunnelState;
|
|
45
|
+
/**
|
|
46
|
+
* Initialize session with automatic detection (cookies, URL, etc.)
|
|
47
|
+
*/
|
|
48
|
+
autoInitialize(authSession: {
|
|
49
|
+
customerId: string;
|
|
50
|
+
sessionId: string;
|
|
51
|
+
}, store: {
|
|
52
|
+
id: string;
|
|
53
|
+
accountId: string;
|
|
54
|
+
}, funnelId?: string): Promise<SimpleFunnelContext | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Manual initialization
|
|
57
|
+
*/
|
|
58
|
+
initialize(authSession: {
|
|
59
|
+
customerId: string;
|
|
60
|
+
sessionId: string;
|
|
61
|
+
}, store: {
|
|
62
|
+
id: string;
|
|
63
|
+
accountId: string;
|
|
64
|
+
}, funnelId?: string, entryStepId?: string): Promise<SimpleFunnelContext<{}>>;
|
|
65
|
+
/**
|
|
66
|
+
* Navigate
|
|
67
|
+
*/
|
|
68
|
+
navigate(event: FunnelAction): Promise<FunnelNavigationResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Refresh session data
|
|
71
|
+
*/
|
|
72
|
+
refreshSession(): Promise<SimpleFunnelContext<{}> | undefined>;
|
|
73
|
+
/**
|
|
74
|
+
* Update context data
|
|
75
|
+
*/
|
|
76
|
+
updateContext(updates: Partial<SimpleFunnelContext>): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* End session
|
|
79
|
+
*/
|
|
80
|
+
endSession(): Promise<void>;
|
|
81
|
+
private updateState;
|
|
82
|
+
private handleSessionSuccess;
|
|
83
|
+
private enrichContext;
|
|
84
|
+
}
|