@tagadapay/plugin-sdk 2.8.7 → 2.8.9
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/config/environment.d.ts +1 -22
- package/dist/react/config/environment.js +1 -132
- package/dist/react/utils/deviceInfo.d.ts +1 -39
- package/dist/react/utils/deviceInfo.js +1 -163
- package/dist/react/utils/jwtDecoder.d.ts +1 -14
- package/dist/react/utils/jwtDecoder.js +1 -86
- package/dist/react/utils/tokenStorage.d.ts +1 -16
- package/dist/react/utils/tokenStorage.js +1 -53
- package/dist/v2/core/client.d.ts +92 -0
- package/dist/v2/core/client.js +386 -0
- package/dist/v2/core/config/environment.d.ts +22 -0
- package/dist/v2/core/config/environment.js +140 -0
- package/dist/v2/core/pathRemapping.js +61 -3
- package/dist/v2/core/resources/apiClient.d.ts +8 -0
- package/dist/v2/core/resources/apiClient.js +30 -9
- package/dist/v2/core/resources/funnel.d.ts +253 -16
- package/dist/v2/core/resources/payments.d.ts +23 -0
- package/dist/v2/core/types.d.ts +271 -0
- package/dist/v2/core/types.js +4 -0
- package/dist/v2/core/utils/deviceInfo.d.ts +39 -0
- package/dist/v2/core/utils/deviceInfo.js +162 -0
- package/dist/v2/core/utils/eventDispatcher.d.ts +10 -0
- package/dist/v2/core/utils/eventDispatcher.js +24 -0
- package/dist/v2/core/utils/jwtDecoder.d.ts +14 -0
- package/dist/v2/core/utils/jwtDecoder.js +85 -0
- package/dist/v2/core/utils/pluginConfig.js +6 -0
- package/dist/v2/core/utils/tokenStorage.d.ts +19 -0
- package/dist/v2/core/utils/tokenStorage.js +52 -0
- package/dist/v2/index.d.ts +2 -1
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/components/DebugDrawer.js +90 -1
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.d.ts +12 -0
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +54 -0
- package/dist/v2/react/hooks/useFunnel.d.ts +2 -2
- package/dist/v2/react/hooks/useFunnel.js +209 -32
- package/dist/v2/react/hooks/useGoogleAutocomplete.js +26 -18
- package/dist/v2/react/hooks/useISOData.js +4 -2
- package/dist/v2/react/hooks/useOffersQuery.d.ts +24 -29
- package/dist/v2/react/hooks/useOffersQuery.js +164 -204
- package/dist/v2/react/hooks/usePaymentQuery.js +99 -6
- package/dist/v2/react/providers/TagadaProvider.d.ts +8 -21
- package/dist/v2/react/providers/TagadaProvider.js +79 -673
- package/package.json +1 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Tagada Pay SDK Core
|
|
3
|
+
*/
|
|
4
|
+
export type Environment = 'production' | 'development' | 'local';
|
|
5
|
+
export interface ApiConfig {
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
endpoints: {
|
|
8
|
+
checkout: {
|
|
9
|
+
sessionInit: string;
|
|
10
|
+
sessionStatus: string;
|
|
11
|
+
};
|
|
12
|
+
customer: {
|
|
13
|
+
profile: string;
|
|
14
|
+
session: string;
|
|
15
|
+
};
|
|
16
|
+
store: {
|
|
17
|
+
config: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface EnvironmentConfig {
|
|
22
|
+
environment: Environment;
|
|
23
|
+
apiConfig: ApiConfig;
|
|
24
|
+
}
|
|
25
|
+
export interface Customer {
|
|
26
|
+
id: string;
|
|
27
|
+
email?: string;
|
|
28
|
+
firstName?: string;
|
|
29
|
+
lastName?: string;
|
|
30
|
+
phone?: string;
|
|
31
|
+
isAuthenticated: boolean;
|
|
32
|
+
role: 'authenticated' | 'anonymous';
|
|
33
|
+
}
|
|
34
|
+
export type SessionRole = 'authenticated' | 'anonymous';
|
|
35
|
+
export interface Session {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
storeId: string;
|
|
38
|
+
accountId: string;
|
|
39
|
+
customerId: string;
|
|
40
|
+
role: SessionRole;
|
|
41
|
+
isValid: boolean;
|
|
42
|
+
isLoading: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface AuthState {
|
|
45
|
+
isAuthenticated: boolean;
|
|
46
|
+
isLoading: boolean;
|
|
47
|
+
customer: Customer | null;
|
|
48
|
+
session: Session | null;
|
|
49
|
+
}
|
|
50
|
+
export interface Locale {
|
|
51
|
+
locale: string;
|
|
52
|
+
language: string;
|
|
53
|
+
region: string;
|
|
54
|
+
messages?: Record<string, string>;
|
|
55
|
+
}
|
|
56
|
+
export interface Currency {
|
|
57
|
+
code: string;
|
|
58
|
+
symbol: string;
|
|
59
|
+
name: string;
|
|
60
|
+
}
|
|
61
|
+
export interface Store {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
domain: string;
|
|
65
|
+
currency: string;
|
|
66
|
+
locale: string;
|
|
67
|
+
presentmentCurrencies: string[];
|
|
68
|
+
chargeCurrencies: string[];
|
|
69
|
+
}
|
|
70
|
+
export interface PickupPoint {
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
country: string;
|
|
74
|
+
postal_code: string;
|
|
75
|
+
city: string;
|
|
76
|
+
address: string;
|
|
77
|
+
address2?: string;
|
|
78
|
+
house_number?: string;
|
|
79
|
+
phone?: string;
|
|
80
|
+
email?: string;
|
|
81
|
+
latitude?: number;
|
|
82
|
+
longitude?: number;
|
|
83
|
+
opening_hours?: string;
|
|
84
|
+
extra_info?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface OrderItem {
|
|
87
|
+
id: string;
|
|
88
|
+
productId: string;
|
|
89
|
+
variantId: string;
|
|
90
|
+
quantity: number;
|
|
91
|
+
unitAmount: number;
|
|
92
|
+
amount: number;
|
|
93
|
+
adjustedAmount: number;
|
|
94
|
+
currency: string;
|
|
95
|
+
recurring?: boolean;
|
|
96
|
+
interval?: 'day' | 'week' | 'month' | 'year' | null;
|
|
97
|
+
intervalCount?: number | null;
|
|
98
|
+
orderLineItemProduct?: {
|
|
99
|
+
name: string;
|
|
100
|
+
};
|
|
101
|
+
orderLineItemVariant?: {
|
|
102
|
+
name: string;
|
|
103
|
+
imageUrl: string | null;
|
|
104
|
+
};
|
|
105
|
+
subscriptionSettings?: {
|
|
106
|
+
trial?: boolean;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export interface OrderSummary {
|
|
110
|
+
currency: string;
|
|
111
|
+
totalPromotionAmount: number;
|
|
112
|
+
totalTaxAmount: number;
|
|
113
|
+
shippingCost: number;
|
|
114
|
+
shippingCostIsFree: boolean;
|
|
115
|
+
subtotalAmount: number;
|
|
116
|
+
subtotalAdjustedAmount: number;
|
|
117
|
+
totalAdjustedAmount: number;
|
|
118
|
+
adjustments?: {
|
|
119
|
+
type: string;
|
|
120
|
+
amount: number;
|
|
121
|
+
description: string;
|
|
122
|
+
}[];
|
|
123
|
+
}
|
|
124
|
+
export interface OrderAddress {
|
|
125
|
+
firstName: string;
|
|
126
|
+
lastName: string;
|
|
127
|
+
address1: string;
|
|
128
|
+
address2?: string;
|
|
129
|
+
city: string;
|
|
130
|
+
state: string;
|
|
131
|
+
postal: string;
|
|
132
|
+
country: string;
|
|
133
|
+
phone?: string;
|
|
134
|
+
}
|
|
135
|
+
export interface Order {
|
|
136
|
+
id: string;
|
|
137
|
+
currency: string;
|
|
138
|
+
paidAmount: number;
|
|
139
|
+
status: string;
|
|
140
|
+
createdAt: string;
|
|
141
|
+
metadata?: Record<string, any>;
|
|
142
|
+
items: OrderItem[];
|
|
143
|
+
summaries?: OrderSummary[];
|
|
144
|
+
shippingAddress?: OrderAddress;
|
|
145
|
+
billingAddress?: OrderAddress;
|
|
146
|
+
pickupAddress?: PickupPoint;
|
|
147
|
+
checkoutSession?: {
|
|
148
|
+
returnUrl?: string;
|
|
149
|
+
[key: string]: any;
|
|
150
|
+
};
|
|
151
|
+
relatedOrders?: Order[];
|
|
152
|
+
}
|
|
153
|
+
export interface PaymentSummary {
|
|
154
|
+
id: string;
|
|
155
|
+
status: string;
|
|
156
|
+
amount: number;
|
|
157
|
+
currency: string;
|
|
158
|
+
createdAt: string;
|
|
159
|
+
updatedAt?: string;
|
|
160
|
+
provider?: string;
|
|
161
|
+
metadata?: Record<string, any>;
|
|
162
|
+
}
|
|
163
|
+
export interface PromotionSummary {
|
|
164
|
+
id: string;
|
|
165
|
+
code?: string | null;
|
|
166
|
+
type?: string;
|
|
167
|
+
amount?: number;
|
|
168
|
+
description?: string | null;
|
|
169
|
+
}
|
|
170
|
+
export interface OrderAdjustmentSummary {
|
|
171
|
+
type: string;
|
|
172
|
+
amount: number;
|
|
173
|
+
description: string;
|
|
174
|
+
}
|
|
175
|
+
export interface OrderWithRelations extends Order {
|
|
176
|
+
customer?: Customer;
|
|
177
|
+
store?: Store;
|
|
178
|
+
account?: {
|
|
179
|
+
id: string;
|
|
180
|
+
name?: string;
|
|
181
|
+
} | undefined;
|
|
182
|
+
items: OrderItem[];
|
|
183
|
+
payments?: PaymentSummary[];
|
|
184
|
+
summaries: OrderSummary[];
|
|
185
|
+
checkoutSession?: {
|
|
186
|
+
id?: string;
|
|
187
|
+
returnUrl?: string;
|
|
188
|
+
[key: string]: any;
|
|
189
|
+
};
|
|
190
|
+
promotions?: PromotionSummary[];
|
|
191
|
+
subscriptions?: any[];
|
|
192
|
+
adjustments: OrderAdjustmentSummary[];
|
|
193
|
+
}
|
|
194
|
+
export interface CustomerAddress {
|
|
195
|
+
company?: string;
|
|
196
|
+
firstName: string;
|
|
197
|
+
lastName: string;
|
|
198
|
+
address1: string;
|
|
199
|
+
city: string;
|
|
200
|
+
country: string;
|
|
201
|
+
state: string;
|
|
202
|
+
postal: string;
|
|
203
|
+
phone?: string;
|
|
204
|
+
email?: string;
|
|
205
|
+
}
|
|
206
|
+
export interface CustomerOrderSummary {
|
|
207
|
+
id: string;
|
|
208
|
+
storeId: string;
|
|
209
|
+
accountId: string;
|
|
210
|
+
createdAt: string;
|
|
211
|
+
updatedAt: string;
|
|
212
|
+
status: string;
|
|
213
|
+
cancelledAt: string | null;
|
|
214
|
+
cancelledReason: string | null;
|
|
215
|
+
paidAt: string | null;
|
|
216
|
+
paidAmount: number | null;
|
|
217
|
+
openAt: string | null;
|
|
218
|
+
abandonedAt: string | null;
|
|
219
|
+
currency: string;
|
|
220
|
+
externalCustomerType: string | null;
|
|
221
|
+
externalCustomerId: string | null;
|
|
222
|
+
externalOrderId: string | null;
|
|
223
|
+
billingAddress: CustomerAddress;
|
|
224
|
+
shippingAddress: Omit<CustomerAddress, 'email'>;
|
|
225
|
+
pickupAddress: any | null;
|
|
226
|
+
taxesIncluded: boolean;
|
|
227
|
+
draft: boolean;
|
|
228
|
+
checkoutSessionId: string | null;
|
|
229
|
+
sessionHash: string | null;
|
|
230
|
+
customerId: string;
|
|
231
|
+
createdFrom: string | null;
|
|
232
|
+
paymentInstrumentId: string | null;
|
|
233
|
+
refundedAt: string | null;
|
|
234
|
+
refundedAmount: number | null;
|
|
235
|
+
metadata?: Record<string, any>;
|
|
236
|
+
}
|
|
237
|
+
export interface CustomerInfos {
|
|
238
|
+
customer: {
|
|
239
|
+
id: string;
|
|
240
|
+
email: string | null;
|
|
241
|
+
firstName: string | null;
|
|
242
|
+
lastName: string | null;
|
|
243
|
+
externalCustomerId: string | null;
|
|
244
|
+
lastOrderId: string | null;
|
|
245
|
+
accountId: string;
|
|
246
|
+
storeId: string;
|
|
247
|
+
billingAddress: CustomerAddress | null;
|
|
248
|
+
shippingAddress: Omit<CustomerAddress, 'email'> | null;
|
|
249
|
+
currency: string | null;
|
|
250
|
+
locale: string | null;
|
|
251
|
+
draft: boolean;
|
|
252
|
+
acceptsMarketing: boolean;
|
|
253
|
+
createdAt: string;
|
|
254
|
+
updatedAt: string;
|
|
255
|
+
metadata: Record<string, any>;
|
|
256
|
+
device: any | null;
|
|
257
|
+
orders: CustomerOrderSummary[];
|
|
258
|
+
subscriptions: any[];
|
|
259
|
+
};
|
|
260
|
+
promotionCodes: any[];
|
|
261
|
+
}
|
|
262
|
+
export interface SessionInitResponse {
|
|
263
|
+
store: Store;
|
|
264
|
+
locale: string;
|
|
265
|
+
messages?: Record<string, string>;
|
|
266
|
+
customer?: Customer;
|
|
267
|
+
session?: Session;
|
|
268
|
+
}
|
|
269
|
+
export interface AnonymousTokenResponse {
|
|
270
|
+
token: string;
|
|
271
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface DeviceInfo {
|
|
2
|
+
userAgent: {
|
|
3
|
+
browser: {
|
|
4
|
+
name: string;
|
|
5
|
+
version: string;
|
|
6
|
+
};
|
|
7
|
+
os: {
|
|
8
|
+
name: string;
|
|
9
|
+
version: string;
|
|
10
|
+
};
|
|
11
|
+
device?: {
|
|
12
|
+
type: string;
|
|
13
|
+
model: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
screenResolution: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
timeZone: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get browser locale
|
|
24
|
+
*/
|
|
25
|
+
export declare function getBrowserLocale(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Collect all device information
|
|
28
|
+
*/
|
|
29
|
+
export declare function collectDeviceInfo(): DeviceInfo;
|
|
30
|
+
/**
|
|
31
|
+
* Get URL parameters for session initialization
|
|
32
|
+
*/
|
|
33
|
+
export declare function getUrlParams(): {
|
|
34
|
+
locale?: string;
|
|
35
|
+
currency?: string;
|
|
36
|
+
utmSource?: string;
|
|
37
|
+
utmMedium?: string;
|
|
38
|
+
utmCampaign?: string;
|
|
39
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get basic browser information from user agent
|
|
3
|
+
*/
|
|
4
|
+
function getBrowserInfo() {
|
|
5
|
+
const userAgent = navigator.userAgent;
|
|
6
|
+
// Chrome
|
|
7
|
+
if (userAgent.includes('Chrome')) {
|
|
8
|
+
const match = /Chrome\/(\d+)/.exec(userAgent);
|
|
9
|
+
return { name: 'Chrome', version: match ? match[1] : 'unknown' };
|
|
10
|
+
}
|
|
11
|
+
// Firefox
|
|
12
|
+
if (userAgent.includes('Firefox')) {
|
|
13
|
+
const match = /Firefox\/(\d+)/.exec(userAgent);
|
|
14
|
+
return { name: 'Firefox', version: match ? match[1] : 'unknown' };
|
|
15
|
+
}
|
|
16
|
+
// Safari
|
|
17
|
+
if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) {
|
|
18
|
+
const match = /Version\/(\d+)/.exec(userAgent);
|
|
19
|
+
return { name: 'Safari', version: match ? match[1] : 'unknown' };
|
|
20
|
+
}
|
|
21
|
+
// Edge
|
|
22
|
+
if (userAgent.includes('Edge')) {
|
|
23
|
+
const match = /Edge\/(\d+)/.exec(userAgent);
|
|
24
|
+
return { name: 'Edge', version: match ? match[1] : 'unknown' };
|
|
25
|
+
}
|
|
26
|
+
return { name: 'unknown', version: 'unknown' };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get basic OS information from user agent
|
|
30
|
+
*/
|
|
31
|
+
function getOSInfo() {
|
|
32
|
+
const userAgent = navigator.userAgent;
|
|
33
|
+
// Windows
|
|
34
|
+
if (userAgent.includes('Windows')) {
|
|
35
|
+
if (userAgent.includes('Windows NT 10.0'))
|
|
36
|
+
return { name: 'Windows', version: '10' };
|
|
37
|
+
if (userAgent.includes('Windows NT 6.3'))
|
|
38
|
+
return { name: 'Windows', version: '8.1' };
|
|
39
|
+
if (userAgent.includes('Windows NT 6.2'))
|
|
40
|
+
return { name: 'Windows', version: '8' };
|
|
41
|
+
if (userAgent.includes('Windows NT 6.1'))
|
|
42
|
+
return { name: 'Windows', version: '7' };
|
|
43
|
+
return { name: 'Windows', version: 'unknown' };
|
|
44
|
+
}
|
|
45
|
+
// macOS
|
|
46
|
+
if (userAgent.includes('Mac OS X')) {
|
|
47
|
+
const match = /Mac OS X (\d+[._]\d+)/.exec(userAgent);
|
|
48
|
+
return { name: 'macOS', version: match ? match[1].replace('_', '.') : 'unknown' };
|
|
49
|
+
}
|
|
50
|
+
// iOS
|
|
51
|
+
if (userAgent.includes('iPhone') || userAgent.includes('iPad')) {
|
|
52
|
+
const match = /OS (\d+[._]\d+)/.exec(userAgent);
|
|
53
|
+
return { name: 'iOS', version: match ? match[1].replace('_', '.') : 'unknown' };
|
|
54
|
+
}
|
|
55
|
+
// Android
|
|
56
|
+
if (userAgent.includes('Android')) {
|
|
57
|
+
const match = /Android (\d+[.\d]*)/.exec(userAgent);
|
|
58
|
+
return { name: 'Android', version: match ? match[1] : 'unknown' };
|
|
59
|
+
}
|
|
60
|
+
// Linux
|
|
61
|
+
if (userAgent.includes('Linux')) {
|
|
62
|
+
return { name: 'Linux', version: 'unknown' };
|
|
63
|
+
}
|
|
64
|
+
return { name: 'unknown', version: 'unknown' };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get device information
|
|
68
|
+
*/
|
|
69
|
+
function getDeviceInfo() {
|
|
70
|
+
const userAgent = navigator.userAgent;
|
|
71
|
+
// Mobile devices
|
|
72
|
+
if (userAgent.includes('iPhone')) {
|
|
73
|
+
return { type: 'mobile', model: 'iPhone' };
|
|
74
|
+
}
|
|
75
|
+
if (userAgent.includes('iPad')) {
|
|
76
|
+
return { type: 'tablet', model: 'iPad' };
|
|
77
|
+
}
|
|
78
|
+
if (userAgent.includes('Android')) {
|
|
79
|
+
if (userAgent.includes('Mobile')) {
|
|
80
|
+
return { type: 'mobile', model: 'Android' };
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return { type: 'tablet', model: 'Android' };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Desktop (no specific device info)
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get screen resolution
|
|
91
|
+
*/
|
|
92
|
+
function getScreenResolution() {
|
|
93
|
+
return {
|
|
94
|
+
width: window.screen.width,
|
|
95
|
+
height: window.screen.height,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get timezone
|
|
100
|
+
*/
|
|
101
|
+
function getTimeZone() {
|
|
102
|
+
try {
|
|
103
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error('Failed to get timezone:', error);
|
|
107
|
+
return 'UTC';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get browser locale
|
|
112
|
+
*/
|
|
113
|
+
export function getBrowserLocale() {
|
|
114
|
+
try {
|
|
115
|
+
return navigator.language || 'en-US';
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error('Failed to get browser locale:', error);
|
|
119
|
+
return 'en-US';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Collect all device information
|
|
124
|
+
*/
|
|
125
|
+
export function collectDeviceInfo() {
|
|
126
|
+
if (typeof window === 'undefined') {
|
|
127
|
+
// Server-side fallback
|
|
128
|
+
return {
|
|
129
|
+
userAgent: {
|
|
130
|
+
browser: { name: 'unknown', version: 'unknown' },
|
|
131
|
+
os: { name: 'unknown', version: 'unknown' },
|
|
132
|
+
},
|
|
133
|
+
screenResolution: { width: 0, height: 0 },
|
|
134
|
+
timeZone: 'UTC',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
userAgent: {
|
|
139
|
+
browser: getBrowserInfo(),
|
|
140
|
+
os: getOSInfo(),
|
|
141
|
+
device: getDeviceInfo(),
|
|
142
|
+
},
|
|
143
|
+
screenResolution: getScreenResolution(),
|
|
144
|
+
timeZone: getTimeZone(),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get URL parameters for session initialization
|
|
149
|
+
*/
|
|
150
|
+
export function getUrlParams() {
|
|
151
|
+
if (typeof window === 'undefined') {
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
154
|
+
const params = new URLSearchParams(window.location.search);
|
|
155
|
+
return {
|
|
156
|
+
locale: params.get('locale') || undefined,
|
|
157
|
+
currency: params.get('currency') || undefined,
|
|
158
|
+
utmSource: params.get('utm_source') || undefined,
|
|
159
|
+
utmMedium: params.get('utm_medium') || undefined,
|
|
160
|
+
utmCampaign: params.get('utm_campaign') || undefined,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple event dispatcher for handling state changes in the SDK
|
|
3
|
+
*/
|
|
4
|
+
export type Listener<T> = (data: T) => void;
|
|
5
|
+
export declare class EventDispatcher<T> {
|
|
6
|
+
private listeners;
|
|
7
|
+
subscribe(listener: Listener<T>): () => void;
|
|
8
|
+
notify(data: T): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class EventDispatcher {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.listeners = new Set();
|
|
4
|
+
}
|
|
5
|
+
subscribe(listener) {
|
|
6
|
+
this.listeners.add(listener);
|
|
7
|
+
return () => {
|
|
8
|
+
this.listeners.delete(listener);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
notify(data) {
|
|
12
|
+
this.listeners.forEach((listener) => {
|
|
13
|
+
try {
|
|
14
|
+
listener(data);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error('Error in event listener:', error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
clear() {
|
|
22
|
+
this.listeners.clear();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Session } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Decode a JWT token to extract session information
|
|
4
|
+
* This is a simple client-side decoder - do not use for security validation
|
|
5
|
+
*/
|
|
6
|
+
export declare function decodeJWTClient(token: string): Session | null;
|
|
7
|
+
/**
|
|
8
|
+
* Check if a JWT token is expired
|
|
9
|
+
*/
|
|
10
|
+
export declare function isTokenExpired(token: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Get token expiration time
|
|
13
|
+
*/
|
|
14
|
+
export declare function getTokenExpiration(token: string): Date | null;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decode a JWT token to extract session information
|
|
3
|
+
* This is a simple client-side decoder - do not use for security validation
|
|
4
|
+
*/
|
|
5
|
+
export function decodeJWTClient(token) {
|
|
6
|
+
try {
|
|
7
|
+
// Split the token into parts
|
|
8
|
+
const parts = token.split('.');
|
|
9
|
+
if (parts.length !== 3) {
|
|
10
|
+
console.error('Invalid JWT token format');
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
// Decode the payload (second part)
|
|
14
|
+
const payload = parts[1];
|
|
15
|
+
// Add padding if needed
|
|
16
|
+
const paddedPayload = payload + '='.repeat((4 - (payload.length % 4)) % 4);
|
|
17
|
+
// Decode base64
|
|
18
|
+
const decoded = atob(paddedPayload);
|
|
19
|
+
// Parse JSON
|
|
20
|
+
const parsedPayload = JSON.parse(decoded);
|
|
21
|
+
// Check if token is expired
|
|
22
|
+
if (parsedPayload.exp && Date.now() >= parsedPayload.exp * 1000) {
|
|
23
|
+
console.warn('JWT token is expired');
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// Return session data
|
|
27
|
+
return {
|
|
28
|
+
sessionId: parsedPayload.sessionId,
|
|
29
|
+
storeId: parsedPayload.storeId,
|
|
30
|
+
accountId: parsedPayload.accountId,
|
|
31
|
+
customerId: parsedPayload.customerId,
|
|
32
|
+
role: parsedPayload.role,
|
|
33
|
+
isValid: true,
|
|
34
|
+
isLoading: false,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error('Failed to decode JWT token:', error);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check if a JWT token is expired
|
|
44
|
+
*/
|
|
45
|
+
export function isTokenExpired(token) {
|
|
46
|
+
try {
|
|
47
|
+
const parts = token.split('.');
|
|
48
|
+
if (parts.length !== 3)
|
|
49
|
+
return true;
|
|
50
|
+
const payload = parts[1];
|
|
51
|
+
const paddedPayload = payload + '='.repeat((4 - (payload.length % 4)) % 4);
|
|
52
|
+
const decoded = atob(paddedPayload);
|
|
53
|
+
const parsedPayload = JSON.parse(decoded);
|
|
54
|
+
if (parsedPayload.exp) {
|
|
55
|
+
return Date.now() >= parsedPayload.exp * 1000;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Failed to check token expiration:', error);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get token expiration time
|
|
66
|
+
*/
|
|
67
|
+
export function getTokenExpiration(token) {
|
|
68
|
+
try {
|
|
69
|
+
const parts = token.split('.');
|
|
70
|
+
if (parts.length !== 3)
|
|
71
|
+
return null;
|
|
72
|
+
const payload = parts[1];
|
|
73
|
+
const paddedPayload = payload + '='.repeat((4 - (payload.length % 4)) % 4);
|
|
74
|
+
const decoded = atob(paddedPayload);
|
|
75
|
+
const parsedPayload = JSON.parse(decoded);
|
|
76
|
+
if (parsedPayload.exp) {
|
|
77
|
+
return new Date(parsedPayload.exp * 1000);
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error('Failed to get token expiration:', error);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -8,6 +8,12 @@ import { resolveEnvValue } from './env';
|
|
|
8
8
|
*/
|
|
9
9
|
const loadLocalDevConfig = async (configVariant = 'default') => {
|
|
10
10
|
try {
|
|
11
|
+
// Check for explicit environment override
|
|
12
|
+
const env = resolveEnvValue('TAGADA_ENV') || resolveEnvValue('TAGADA_ENVIRONMENT');
|
|
13
|
+
if (env === 'production') {
|
|
14
|
+
// Skip local config loading if explicitly in production mode
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
11
17
|
// Only try to load local config in development
|
|
12
18
|
// Use hostname-based detection for better Vite compatibility
|
|
13
19
|
const isLocalDev = typeof window !== 'undefined' &&
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side token storage utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Set the CMS token in localStorage
|
|
6
|
+
*/
|
|
7
|
+
export declare function setClientToken(token: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Get the CMS token from localStorage
|
|
10
|
+
*/
|
|
11
|
+
export declare function getClientToken(): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Clear the CMS token from localStorage
|
|
14
|
+
*/
|
|
15
|
+
export declare function clearClientToken(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a token exists in localStorage
|
|
18
|
+
*/
|
|
19
|
+
export declare function hasClientToken(): boolean;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side token storage utilities
|
|
3
|
+
*/
|
|
4
|
+
const TOKEN_KEY = 'cms_token';
|
|
5
|
+
/**
|
|
6
|
+
* Set the CMS token in localStorage
|
|
7
|
+
*/
|
|
8
|
+
export function setClientToken(token) {
|
|
9
|
+
if (typeof window !== 'undefined') {
|
|
10
|
+
try {
|
|
11
|
+
localStorage.setItem(TOKEN_KEY, token);
|
|
12
|
+
window.dispatchEvent(new Event('storage'));
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
console.error('Failed to save token to localStorage:', error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the CMS token from localStorage
|
|
21
|
+
*/
|
|
22
|
+
export function getClientToken() {
|
|
23
|
+
if (typeof window !== 'undefined') {
|
|
24
|
+
try {
|
|
25
|
+
return localStorage.getItem(TOKEN_KEY);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error('Failed to get token from localStorage:', error);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Clear the CMS token from localStorage
|
|
36
|
+
*/
|
|
37
|
+
export function clearClientToken() {
|
|
38
|
+
if (typeof window !== 'undefined') {
|
|
39
|
+
try {
|
|
40
|
+
localStorage.removeItem(TOKEN_KEY);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error('Failed to clear token from localStorage:', error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a token exists in localStorage
|
|
49
|
+
*/
|
|
50
|
+
export function hasClientToken() {
|
|
51
|
+
return !!getClientToken();
|
|
52
|
+
}
|