@tagadapay/plugin-sdk 2.6.16 → 2.6.18
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/react/hooks/usePluginConfig.d.ts +6 -2
- package/dist/react/hooks/usePluginConfig.js +90 -9
- package/dist/v2/index.d.ts +2 -3
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/index.d.ts +1 -5
- package/dist/v2/react/index.js +0 -2
- package/dist/v2/react/providers/TagadaProvider.d.ts +2 -4
- package/dist/v2/react/providers/TagadaProvider.js +62 -57
- package/package.json +1 -1
|
@@ -30,10 +30,14 @@ export interface RawPluginConfig<TConfig = Record<string, any>> {
|
|
|
30
30
|
basePath?: string;
|
|
31
31
|
config?: TConfig;
|
|
32
32
|
}
|
|
33
|
+
export interface LocalDevConfig {
|
|
34
|
+
storeId: string;
|
|
35
|
+
accountId: string;
|
|
36
|
+
basePath: string;
|
|
37
|
+
}
|
|
33
38
|
/**
|
|
34
39
|
* Load plugin configuration (cached)
|
|
35
|
-
* Tries raw config first, then production config
|
|
36
|
-
* Note: Local dev config should be passed via rawConfig parameter
|
|
40
|
+
* Tries raw config first, then local dev config, then production config
|
|
37
41
|
*/
|
|
38
42
|
export declare const loadPluginConfig: (configVariant?: string, rawConfig?: RawPluginConfig) => Promise<PluginConfig>;
|
|
39
43
|
/**
|
|
@@ -22,6 +22,88 @@ import { useTagadaContext } from '../providers/TagadaProvider';
|
|
|
22
22
|
// Simple cache for plugin configuration
|
|
23
23
|
let cachedConfig = null;
|
|
24
24
|
let configPromise = null;
|
|
25
|
+
/**
|
|
26
|
+
* Load local development configuration
|
|
27
|
+
* Combines .local.json + config/default.tgd.json (or specified variant)
|
|
28
|
+
*/
|
|
29
|
+
const loadLocalDevConfig = async (configVariant = 'default') => {
|
|
30
|
+
try {
|
|
31
|
+
// Only try to load local config in development
|
|
32
|
+
// Use hostname-based detection for better Vite compatibility
|
|
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) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
// Load local store/account config
|
|
42
|
+
const localResponse = await fetch('/.local.json');
|
|
43
|
+
if (!localResponse.ok) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const localConfig = await localResponse.json();
|
|
47
|
+
// Load deployment config (specified variant or fallback to default)
|
|
48
|
+
let config = {};
|
|
49
|
+
let configLoaded = false;
|
|
50
|
+
try {
|
|
51
|
+
// Try .tgd.json first (new format), then fallback to .json
|
|
52
|
+
let deploymentResponse = await fetch(`/config/${configVariant}.tgd.json`);
|
|
53
|
+
if (!deploymentResponse.ok) {
|
|
54
|
+
deploymentResponse = await fetch(`/config/${configVariant}.json`);
|
|
55
|
+
}
|
|
56
|
+
if (deploymentResponse.ok) {
|
|
57
|
+
config = await deploymentResponse.json();
|
|
58
|
+
configLoaded = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Config fetch failed, will try fallback
|
|
63
|
+
}
|
|
64
|
+
// If config didn't load and it's not 'default', try fallback to default
|
|
65
|
+
if (!configLoaded && configVariant !== 'default') {
|
|
66
|
+
console.warn(`⚠️ Config variant '${configVariant}' not found, falling back to 'default'`);
|
|
67
|
+
try {
|
|
68
|
+
let defaultResponse = await fetch('/config/default.tgd.json');
|
|
69
|
+
if (!defaultResponse.ok) {
|
|
70
|
+
defaultResponse = await fetch('/config/default.json');
|
|
71
|
+
}
|
|
72
|
+
if (defaultResponse.ok) {
|
|
73
|
+
config = await defaultResponse.json();
|
|
74
|
+
configLoaded = true;
|
|
75
|
+
console.log(`✅ Fallback to 'default' config successful`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Default config also failed
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Final warning if no config was loaded
|
|
83
|
+
if (!configLoaded) {
|
|
84
|
+
if (configVariant === 'default') {
|
|
85
|
+
console.warn(`⚠️ No 'default' config found. Create /config/default.tgd.json`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.warn(`⚠️ Neither '${configVariant}' nor 'default' config found. Create /config/default.tgd.json`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
console.log('🛠️ Using local development plugin config:', {
|
|
92
|
+
configName: config.configName || configVariant,
|
|
93
|
+
local: localConfig,
|
|
94
|
+
deployment: config
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
storeId: localConfig.storeId,
|
|
98
|
+
accountId: localConfig.accountId,
|
|
99
|
+
basePath: localConfig.basePath,
|
|
100
|
+
config,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
25
107
|
/**
|
|
26
108
|
* Load production config from headers and meta tags
|
|
27
109
|
*/
|
|
@@ -53,18 +135,12 @@ const loadProductionConfig = async () => {
|
|
|
53
135
|
};
|
|
54
136
|
/**
|
|
55
137
|
* Load plugin configuration (cached)
|
|
56
|
-
* Tries raw config first, then production config
|
|
57
|
-
* Note: Local dev config should be passed via rawConfig parameter
|
|
138
|
+
* Tries raw config first, then local dev config, then production config
|
|
58
139
|
*/
|
|
59
140
|
export const loadPluginConfig = async (configVariant = 'default', rawConfig) => {
|
|
60
141
|
// If raw config is provided, use it directly
|
|
61
142
|
if (rawConfig) {
|
|
62
|
-
console.log('🛠️ Using raw plugin config:',
|
|
63
|
-
hasStoreId: !!rawConfig.storeId,
|
|
64
|
-
hasAccountId: !!rawConfig.accountId,
|
|
65
|
-
hasConfig: !!rawConfig.config,
|
|
66
|
-
configKeys: rawConfig.config ? Object.keys(rawConfig.config) : [],
|
|
67
|
-
});
|
|
143
|
+
console.log('🛠️ Using raw plugin config:', rawConfig);
|
|
68
144
|
return {
|
|
69
145
|
storeId: rawConfig.storeId,
|
|
70
146
|
accountId: rawConfig.accountId,
|
|
@@ -72,7 +148,12 @@ export const loadPluginConfig = async (configVariant = 'default', rawConfig) =>
|
|
|
72
148
|
config: rawConfig.config ?? {},
|
|
73
149
|
};
|
|
74
150
|
}
|
|
75
|
-
//
|
|
151
|
+
// Try local development config
|
|
152
|
+
const localConfig = await loadLocalDevConfig(configVariant);
|
|
153
|
+
if (localConfig) {
|
|
154
|
+
return localConfig;
|
|
155
|
+
}
|
|
156
|
+
// Fall back to production config
|
|
76
157
|
return loadProductionConfig();
|
|
77
158
|
};
|
|
78
159
|
/**
|
package/dist/v2/index.d.ts
CHANGED
|
@@ -20,6 +20,5 @@ export type { ShippingRate, ShippingRatesResponse } from './core/resources/shipp
|
|
|
20
20
|
export type { ApplyDiscountResponse, Discount, DiscountCodeValidation, RemoveDiscountResponse } from './core/resources/discounts';
|
|
21
21
|
export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './core/resources/vipOffers';
|
|
22
22
|
export type { StoreConfig } from './core/resources/storeConfig';
|
|
23
|
-
export type {
|
|
24
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency,
|
|
25
|
-
export type { StoreDiscount, TranslateFunction, TranslationText, UseTranslationOptions, UseTranslationResult } from './react';
|
|
23
|
+
export type { FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelContextUpdateRequest, FunnelContextUpdateResponse } from './core/resources/funnel';
|
|
24
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useVipOffers, useFunnel, useSimpleFunnel } from './react';
|
package/dist/v2/index.js
CHANGED
|
@@ -12,4 +12,4 @@ export * from './core/utils/currency';
|
|
|
12
12
|
export * from './core/utils/pluginConfig';
|
|
13
13
|
export * from './core/utils/products';
|
|
14
14
|
// React exports (hooks and components only, types are exported above)
|
|
15
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency,
|
|
15
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useVipOffers, useFunnel, useSimpleFunnel } from './react';
|
package/dist/v2/react/index.d.ts
CHANGED
|
@@ -12,11 +12,9 @@ export { useGeoLocation } from './hooks/useGeoLocation';
|
|
|
12
12
|
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
13
13
|
export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
|
|
14
14
|
export { usePluginConfig } from './hooks/usePluginConfig';
|
|
15
|
-
export { useTranslation } from './hooks/useTranslation';
|
|
16
15
|
export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
|
|
17
16
|
export { useCheckoutQuery as useCheckout } from './hooks/useCheckoutQuery';
|
|
18
17
|
export { useCurrency } from './hooks/useCurrency';
|
|
19
|
-
export { useDiscountQuery as useDiscount } from './hooks/useDiscountQuery';
|
|
20
18
|
export { useDiscountsQuery as useDiscounts } from './hooks/useDiscountsQuery';
|
|
21
19
|
export { useOffersQuery as useOffers } from './hooks/useOffersQuery';
|
|
22
20
|
export { useOrderBumpQuery as useOrderBump } from './hooks/useOrderBumpQuery';
|
|
@@ -39,11 +37,8 @@ export type { GeoLocationData, UseGeoLocationOptions, UseGeoLocationReturn } fro
|
|
|
39
37
|
export type { ExtractedAddress, GooglePlaceDetails, GooglePrediction, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
|
|
40
38
|
export type { ISOCountry, ISORegion, UseISODataResult } from './hooks/useISOData';
|
|
41
39
|
export type { UsePluginConfigOptions, UsePluginConfigResult } from './hooks/usePluginConfig';
|
|
42
|
-
export type { TranslateFunction, TranslationText, UseTranslationOptions, UseTranslationResult } from './hooks/useTranslation';
|
|
43
40
|
export type { UseCheckoutQueryOptions as UseCheckoutOptions, UseCheckoutQueryResult as UseCheckoutResult } from './hooks/useCheckoutQuery';
|
|
44
|
-
export type { StoreDiscount, UseDiscountQueryOptions as UseDiscountOptions, UseDiscountQueryResult as UseDiscountResult } from './hooks/useDiscountQuery';
|
|
45
41
|
export type { UseDiscountsQueryOptions as UseDiscountsOptions, UseDiscountsQueryResult as UseDiscountsResult } from './hooks/useDiscountsQuery';
|
|
46
|
-
export type { FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext, UseFunnelOptions, UseFunnelResult } from './hooks/useFunnel';
|
|
47
42
|
export type { UseOffersQueryOptions as UseOffersOptions, UseOffersQueryResult as UseOffersResult } from './hooks/useOffersQuery';
|
|
48
43
|
export type { UseOrderBumpQueryOptions as UseOrderBumpOptions, UseOrderBumpQueryResult as UseOrderBumpResult } from './hooks/useOrderBumpQuery';
|
|
49
44
|
export type { UseOrderQueryOptions as UseOrderOptions, UseOrderQueryResult as UseOrderResult } from './hooks/useOrderQuery';
|
|
@@ -55,5 +50,6 @@ export type { UseShippingRatesQueryOptions as UseShippingRatesOptions, UseShippi
|
|
|
55
50
|
export type { UseStoreConfigQueryOptions as UseStoreConfigOptions, UseStoreConfigQueryResult as UseStoreConfigResult } from './hooks/useStoreConfigQuery';
|
|
56
51
|
export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession } from './hooks/useThreeds';
|
|
57
52
|
export type { UseVipOffersQueryOptions as UseVipOffersOptions, UseVipOffersQueryResult as UseVipOffersResult } from './hooks/useVipOffersQuery';
|
|
53
|
+
export type { UseFunnelOptions, UseFunnelResult, FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from './hooks/useFunnel';
|
|
58
54
|
export { formatMoney } from '../../react/utils/money';
|
|
59
55
|
export type OrderItem = import('../core/utils/order').OrderLineItem;
|
package/dist/v2/react/index.js
CHANGED
|
@@ -15,12 +15,10 @@ export { useGeoLocation } from './hooks/useGeoLocation';
|
|
|
15
15
|
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
16
16
|
export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
|
|
17
17
|
export { usePluginConfig } from './hooks/usePluginConfig';
|
|
18
|
-
export { useTranslation } from './hooks/useTranslation';
|
|
19
18
|
// TanStack Query hooks (recommended)
|
|
20
19
|
export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
|
|
21
20
|
export { useCheckoutQuery as useCheckout } from './hooks/useCheckoutQuery';
|
|
22
21
|
export { useCurrency } from './hooks/useCurrency';
|
|
23
|
-
export { useDiscountQuery as useDiscount } from './hooks/useDiscountQuery';
|
|
24
22
|
export { useDiscountsQuery as useDiscounts } from './hooks/useDiscountsQuery';
|
|
25
23
|
export { useOffersQuery as useOffers } from './hooks/useOffersQuery';
|
|
26
24
|
export { useOrderBumpQuery as useOrderBump } from './hooks/useOrderBumpQuery';
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TagadaProvider - Main provider component for the Tagada Pay React SDK
|
|
3
|
-
*/
|
|
4
1
|
import { ReactNode } from 'react';
|
|
5
2
|
import { PluginConfig, RawPluginConfig } from '../../../react/hooks/usePluginConfig';
|
|
6
3
|
import { ApiService } from '../../../react/services/apiService';
|
|
@@ -52,11 +49,12 @@ interface TagadaProviderProps {
|
|
|
52
49
|
environment?: Environment;
|
|
53
50
|
customApiConfig?: Partial<EnvironmentConfig>;
|
|
54
51
|
debugMode?: boolean;
|
|
52
|
+
localConfig?: string;
|
|
55
53
|
blockUntilSessionReady?: boolean;
|
|
56
54
|
rawPluginConfig?: RawPluginConfig;
|
|
57
55
|
}
|
|
58
56
|
export declare function TagadaProvider({ children, environment, customApiConfig, debugMode, // Remove default, will be set based on environment
|
|
59
|
-
blockUntilSessionReady, // Default to new non-blocking behavior
|
|
57
|
+
localConfig, blockUntilSessionReady, // Default to new non-blocking behavior
|
|
60
58
|
rawPluginConfig, }: TagadaProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
61
59
|
export declare function useTagadaContext(): TagadaContextValue;
|
|
62
60
|
export {};
|
|
@@ -3,9 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
/**
|
|
4
4
|
* TagadaProvider - Main provider component for the Tagada Pay React SDK
|
|
5
5
|
*/
|
|
6
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
7
6
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
8
|
-
import {
|
|
7
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
9
8
|
import { detectEnvironment, getEnvironmentConfig } from '../../../react/config/environment';
|
|
10
9
|
import { ApiService } from '../../../react/services/apiService';
|
|
11
10
|
import { collectDeviceInfo, getBrowserLocale, getUrlParams } from '../../../react/utils/deviceInfo';
|
|
@@ -13,8 +12,9 @@ import { decodeJWTClient, isTokenExpired } from '../../../react/utils/jwtDecoder
|
|
|
13
12
|
import { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMoney, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits, } from '../../../react/utils/money';
|
|
14
13
|
import { clearClientToken, getClientToken, setClientToken } from '../../../react/utils/tokenStorage';
|
|
15
14
|
import { ApiClient } from '../../core/resources/apiClient';
|
|
16
|
-
import { setGlobalApiClient, getGlobalApiClientOrNull } from '../hooks/useApiQuery';
|
|
17
15
|
import { loadPluginConfig } from '../../core/utils/pluginConfig';
|
|
16
|
+
import { default as DebugDrawer } from '../components/DebugDrawer';
|
|
17
|
+
import { setGlobalApiClient } from '../hooks/useApiQuery';
|
|
18
18
|
// Professional, subtle loading component for initialization
|
|
19
19
|
const InitializationLoader = () => (_jsxs("div", { style: {
|
|
20
20
|
position: 'fixed',
|
|
@@ -52,7 +52,7 @@ const TagadaContext = createContext(null);
|
|
|
52
52
|
let globalTagadaInstance = null;
|
|
53
53
|
let globalTagadaInitialized = false;
|
|
54
54
|
export function TagadaProvider({ children, environment, customApiConfig, debugMode, // Remove default, will be set based on environment
|
|
55
|
-
blockUntilSessionReady = false, // Default to new non-blocking behavior
|
|
55
|
+
localConfig, blockUntilSessionReady = false, // Default to new non-blocking behavior
|
|
56
56
|
rawPluginConfig, }) {
|
|
57
57
|
// Instance tracking
|
|
58
58
|
const [instanceId] = useState(() => {
|
|
@@ -81,13 +81,20 @@ rawPluginConfig, }) {
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
}, [instanceId]);
|
|
84
|
+
// LOCAL DEV ONLY: Use localConfig override if in local development, otherwise use default
|
|
85
|
+
const isLocalDev = typeof window !== 'undefined' &&
|
|
86
|
+
(window.location.hostname === 'localhost' ||
|
|
87
|
+
window.location.hostname.includes('.localhost') ||
|
|
88
|
+
window.location.hostname.includes('127.0.0.1'));
|
|
89
|
+
const configVariant = isLocalDev ? localConfig || 'default' : 'default';
|
|
84
90
|
// Debug logging (only log once during initial render)
|
|
85
91
|
const hasLoggedRef = useRef(false);
|
|
86
92
|
if (!hasLoggedRef.current) {
|
|
87
|
-
console.log(`🔍 [TagadaProvider] Instance ${instanceId}
|
|
93
|
+
console.log(`🔍 [TagadaProvider] Instance ${instanceId} Config Debug:`, {
|
|
88
94
|
hostname: typeof window !== 'undefined' ? window.location.hostname : 'SSR',
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
isLocalDev,
|
|
96
|
+
localConfig,
|
|
97
|
+
configVariant,
|
|
91
98
|
});
|
|
92
99
|
hasLoggedRef.current = true;
|
|
93
100
|
}
|
|
@@ -95,10 +102,6 @@ rawPluginConfig, }) {
|
|
|
95
102
|
// Initialize with raw config if available to avoid empty config during loading
|
|
96
103
|
const [pluginConfig, setPluginConfig] = useState(() => {
|
|
97
104
|
if (rawPluginConfig) {
|
|
98
|
-
console.log('🛠️ [TagadaProvider] Using raw plugin config immediately:', {
|
|
99
|
-
storeId: rawPluginConfig.storeId,
|
|
100
|
-
accountId: rawPluginConfig.accountId,
|
|
101
|
-
});
|
|
102
105
|
return {
|
|
103
106
|
storeId: rawPluginConfig.storeId,
|
|
104
107
|
accountId: rawPluginConfig.accountId,
|
|
@@ -106,11 +109,9 @@ rawPluginConfig, }) {
|
|
|
106
109
|
config: rawPluginConfig.config ?? {},
|
|
107
110
|
};
|
|
108
111
|
}
|
|
109
|
-
console.log('⏳ [TagadaProvider] No raw config, will load from headers/files');
|
|
110
112
|
return { basePath: '/', config: {} };
|
|
111
113
|
});
|
|
112
114
|
const [configLoading, setConfigLoading] = useState(!rawPluginConfig);
|
|
113
|
-
const [apiClientReady, setApiClientReady] = useState(false);
|
|
114
115
|
// Load plugin config on mount with the specified variant
|
|
115
116
|
useEffect(() => {
|
|
116
117
|
// Prevent multiple config loads
|
|
@@ -120,8 +121,8 @@ rawPluginConfig, }) {
|
|
|
120
121
|
}
|
|
121
122
|
const loadConfig = async () => {
|
|
122
123
|
try {
|
|
123
|
-
// Use the v2 core loadPluginConfig function
|
|
124
|
-
const config = await loadPluginConfig(
|
|
124
|
+
// Use the v2 core loadPluginConfig function
|
|
125
|
+
const config = await loadPluginConfig(configVariant, rawPluginConfig);
|
|
125
126
|
// Ensure we have required store ID before proceeding
|
|
126
127
|
if (!config.storeId) {
|
|
127
128
|
console.warn('⚠️ No store ID found in plugin config. This may cause hooks to fail.');
|
|
@@ -132,7 +133,7 @@ rawPluginConfig, }) {
|
|
|
132
133
|
accountId: config.accountId,
|
|
133
134
|
basePath: config.basePath,
|
|
134
135
|
hasConfig: !!config.config,
|
|
135
|
-
source: rawPluginConfig ? 'raw' : '
|
|
136
|
+
source: rawPluginConfig ? 'raw' : 'file',
|
|
136
137
|
});
|
|
137
138
|
if (blockUntilSessionReady) {
|
|
138
139
|
console.log('⏳ Blocking mode: Children will render after Phase 3 (session init) completes');
|
|
@@ -150,7 +151,7 @@ rawPluginConfig, }) {
|
|
|
150
151
|
}
|
|
151
152
|
};
|
|
152
153
|
void loadConfig();
|
|
153
|
-
}, [rawPluginConfig]);
|
|
154
|
+
}, [configVariant, rawPluginConfig]);
|
|
154
155
|
// Extract store/account IDs from plugin config (only source now)
|
|
155
156
|
const storeId = pluginConfig.storeId;
|
|
156
157
|
const _accountId = pluginConfig.accountId;
|
|
@@ -206,8 +207,9 @@ rawPluginConfig, }) {
|
|
|
206
207
|
}
|
|
207
208
|
return service;
|
|
208
209
|
});
|
|
209
|
-
// Initialize TanStack Query API client
|
|
210
|
-
|
|
210
|
+
// Initialize TanStack Query API client synchronously during provider initialization
|
|
211
|
+
// This ensures the global client is available immediately for hooks that use it in useMemo
|
|
212
|
+
const [apiClient] = useState(() => {
|
|
211
213
|
const client = new ApiClient({
|
|
212
214
|
baseURL: environmentConfig.apiConfig.baseUrl,
|
|
213
215
|
headers: {
|
|
@@ -216,25 +218,40 @@ rawPluginConfig, }) {
|
|
|
216
218
|
});
|
|
217
219
|
// Set the global client for TanStack Query hooks
|
|
218
220
|
setGlobalApiClient(client);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
// Check for existing token and set it immediately
|
|
222
|
+
const existingToken = getClientToken();
|
|
223
|
+
if (existingToken && !isTokenExpired(existingToken)) {
|
|
224
|
+
client.updateToken(existingToken);
|
|
225
|
+
console.log('[SDK] ApiClient initialized with existing token:', existingToken.substring(0, 8) + '...');
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log('[SDK] ApiClient initialized with baseURL:', environmentConfig.apiConfig.baseUrl);
|
|
229
|
+
}
|
|
230
|
+
return client;
|
|
231
|
+
});
|
|
232
|
+
// Update API client when environment config changes
|
|
233
|
+
useEffect(() => {
|
|
234
|
+
apiClient.updateConfig({
|
|
235
|
+
baseURL: environmentConfig.apiConfig.baseUrl,
|
|
236
|
+
headers: {
|
|
237
|
+
'Content-Type': 'application/json',
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
console.log('[SDK] ApiClient config updated with baseURL:', environmentConfig.apiConfig.baseUrl);
|
|
241
|
+
}, [environmentConfig, apiClient]);
|
|
222
242
|
// Sync token updates between ApiService and ApiClient
|
|
223
243
|
useEffect(() => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
client.updateToken(currentToken);
|
|
230
|
-
console.log('[SDK] Token synced to ApiClient:', currentToken.substring(0, 8) + '...');
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
client.updateToken(null);
|
|
234
|
-
console.log('[SDK] Token cleared from ApiClient');
|
|
235
|
-
}
|
|
244
|
+
// Always use the token from ApiService as the source of truth
|
|
245
|
+
const currentToken = apiService.getCurrentToken();
|
|
246
|
+
if (currentToken && typeof currentToken === 'string') {
|
|
247
|
+
apiClient.updateToken(currentToken);
|
|
248
|
+
console.log('[SDK] Token synced to ApiClient:', currentToken.substring(0, 8) + '...');
|
|
236
249
|
}
|
|
237
|
-
|
|
250
|
+
else {
|
|
251
|
+
apiClient.updateToken(null);
|
|
252
|
+
console.log('[SDK] Token cleared from ApiClient');
|
|
253
|
+
}
|
|
254
|
+
}, [token, apiService, apiClient]);
|
|
238
255
|
// Update API service when config or token changes
|
|
239
256
|
useEffect(() => {
|
|
240
257
|
apiService.updateConfig(environmentConfig);
|
|
@@ -378,12 +395,6 @@ rawPluginConfig, }) {
|
|
|
378
395
|
console.debug('[SDK][DEBUG] Auth state:', authState);
|
|
379
396
|
}
|
|
380
397
|
console.debug('[SDK] Session initialized successfully');
|
|
381
|
-
// Update token to ApiClient immediately
|
|
382
|
-
const client = getGlobalApiClientOrNull();
|
|
383
|
-
if (client && token) {
|
|
384
|
-
client.updateToken(token);
|
|
385
|
-
console.log('[SDK] Token updated to ApiClient:', token.substring(0, 8) + '...');
|
|
386
|
-
}
|
|
387
398
|
setIsInitialized(true);
|
|
388
399
|
setIsSessionInitialized(true); // Mark CMS session as ready
|
|
389
400
|
setIsLoading(false);
|
|
@@ -425,6 +436,10 @@ rawPluginConfig, }) {
|
|
|
425
436
|
setClientToken(response.token);
|
|
426
437
|
// Update the API service with the new token
|
|
427
438
|
apiService.updateToken(response.token);
|
|
439
|
+
// IMPORTANT: Immediately sync token to API client before marking session as ready
|
|
440
|
+
// This ensures any queries that become enabled after isSessionInitialized=true have the token
|
|
441
|
+
apiClient.updateToken(response.token);
|
|
442
|
+
console.log('[SDK] Token immediately synced to ApiClient:', response.token.substring(0, 8) + '...');
|
|
428
443
|
// Decode the token to get session data
|
|
429
444
|
const decodedSession = decodeJWTClient(response.token);
|
|
430
445
|
if (decodedSession) {
|
|
@@ -441,12 +456,6 @@ rawPluginConfig, }) {
|
|
|
441
456
|
setIsLoading(false);
|
|
442
457
|
}
|
|
443
458
|
console.log('[SDK] ✅ Phase 3 Complete - Session initialization completed successfully');
|
|
444
|
-
// Update token to ApiClient immediately
|
|
445
|
-
const client = getGlobalApiClientOrNull();
|
|
446
|
-
if (client && token) {
|
|
447
|
-
client.updateToken(token);
|
|
448
|
-
console.log('[SDK] Token updated to ApiClient:', token.substring(0, 8) + '...');
|
|
449
|
-
}
|
|
450
459
|
setIsSessionInitialized(true); // Mark CMS session as ready
|
|
451
460
|
}
|
|
452
461
|
catch (error) {
|
|
@@ -508,6 +517,9 @@ rawPluginConfig, }) {
|
|
|
508
517
|
setToken(tokenToUse);
|
|
509
518
|
// Update the API service with the token
|
|
510
519
|
apiService.updateToken(tokenToUse);
|
|
520
|
+
// IMPORTANT: Immediately sync token to API client
|
|
521
|
+
apiClient.updateToken(tokenToUse);
|
|
522
|
+
console.log('[SDK] Token immediately synced to ApiClient:', tokenToUse.substring(0, 8) + '...');
|
|
511
523
|
// Decode token to get session data
|
|
512
524
|
const decodedSession = decodeJWTClient(tokenToUse);
|
|
513
525
|
if (decodedSession) {
|
|
@@ -669,16 +681,9 @@ rawPluginConfig, }) {
|
|
|
669
681
|
// debugCheckout removed from deps to prevent unnecessary re-renders
|
|
670
682
|
]);
|
|
671
683
|
// Determine if we should show loading
|
|
672
|
-
// Always block until
|
|
673
|
-
const shouldShowLoading = configLoading
|
|
674
|
-
const canRenderChildren = !configLoading
|
|
675
|
-
if (!hasLoggedRef.current && canRenderChildren) {
|
|
676
|
-
console.log('✅ [TagadaProvider] All initialization complete, ready to render children:', {
|
|
677
|
-
configLoading,
|
|
678
|
-
apiClientReady,
|
|
679
|
-
hasStoreId: !!pluginConfig.storeId,
|
|
680
|
-
});
|
|
681
|
-
}
|
|
684
|
+
// Always block until config is loaded (even if empty)
|
|
685
|
+
const shouldShowLoading = configLoading;
|
|
686
|
+
const canRenderChildren = !configLoading;
|
|
682
687
|
// Initialize TanStack Query client
|
|
683
688
|
const [queryClient] = useState(() => new QueryClient({
|
|
684
689
|
defaultOptions: {
|