@kasuvia/sdk 0.0.2 → 0.0.5
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/hooks/index.d.mts +430 -0
- package/dist/hooks/index.d.ts +430 -0
- package/dist/hooks/index.js +3073 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +2962 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index-CxNLI4nw.d.ts +786 -0
- package/dist/index-CzVMyUs4.d.mts +492 -0
- package/dist/index-CzVMyUs4.d.ts +492 -0
- package/dist/index-Dowl5224.d.mts +786 -0
- package/dist/index.d.mts +48 -1739
- package/dist/index.d.ts +48 -1739
- package/dist/index.js +1544 -2359
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1527 -2258
- package/dist/index.mjs.map +1 -1
- package/dist/sdk-context-BuarJbeb.d.ts +75 -0
- package/dist/sdk-context-Db8kf1Tv.d.mts +75 -0
- package/dist/services/index.d.mts +2 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +2369 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/index.mjs +2252 -0
- package/dist/services/index.mjs.map +1 -0
- package/package.json +11 -2
- package/src/config/index.ts +10 -91
- package/src/constants.ts +13 -0
- package/src/context/sdk-context.tsx +70 -0
- package/src/graphql/collections.graphql.ts +2 -10
- package/src/graphql/products.graphql.ts +215 -65
- package/src/graphql/wishlist.graphql.ts +7 -6
- package/src/hooks/index.ts +2 -0
- package/src/hooks/use-auth.ts +82 -158
- package/src/hooks/use-bespoke-availability.ts +25 -8
- package/src/hooks/use-cart.ts +222 -119
- package/src/hooks/use-cms.ts +179 -86
- package/src/hooks/use-collections.ts +52 -15
- package/src/hooks/use-consultation-stream.ts +4 -3
- package/src/hooks/use-consultations.ts +120 -51
- package/src/hooks/use-countries.ts +35 -13
- package/src/hooks/use-currencies.ts +26 -13
- package/src/hooks/use-google-translate.ts +22 -8
- package/src/hooks/use-languages.ts +40 -20
- package/src/hooks/use-mobile.ts +23 -0
- package/src/hooks/use-order-stream.ts +9 -5
- package/src/hooks/use-orders.ts +99 -44
- package/src/hooks/use-payment.ts +108 -40
- package/src/hooks/use-products.ts +251 -53
- package/src/hooks/use-service-booking.ts +152 -90
- package/src/hooks/use-states.ts +35 -15
- package/src/hooks/use-wishlist.ts +92 -91
- package/src/index.ts +26 -30
- package/src/services/auth.service.ts +209 -167
- package/src/services/bespoke.service.ts +12 -4
- package/src/services/cart.service.ts +172 -70
- package/src/services/cms.service.ts +70 -35
- package/src/services/collection.service.ts +22 -5
- package/src/services/config.service.ts +34 -14
- package/src/services/consultation.service.ts +72 -18
- package/src/services/logistics.service.ts +35 -11
- package/src/services/notifications.service.ts +27 -12
- package/src/services/order.service.ts +74 -15
- package/src/services/payment.service.ts +86 -31
- package/src/services/product.service.ts +279 -39
- package/src/services/service-booking.service.ts +98 -26
- package/src/services/wishlist.service.ts +69 -25
- package/src/types/auth/index.ts +6 -4
- package/src/types/business/index.ts +7 -2
- package/src/types/payments/index.ts +3 -3
- package/src/types/services/index.ts +2 -5
- package/src/types/store/index.ts +38 -3
- package/src/utils/error-handler.ts +10 -5
- package/src/utils/storage.ts +48 -26
- package/src/utils/validators.ts +85 -0
- package/src/client/authClient.ts +0 -135
- package/src/client/graphqlClient.ts +0 -53
- package/src/client/httpClient.ts +0 -298
|
@@ -1,118 +1,180 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Service Booking Hooks
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* React Query hooks for service bookings.
|
|
5
|
+
* config and accessToken are optional — if omitted, they are read from SdkContext.
|
|
5
6
|
*/
|
|
6
7
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getAvailableSlots,
|
|
10
|
+
bookAppointment,
|
|
11
|
+
getAppointments,
|
|
12
|
+
getAppointment,
|
|
13
|
+
cancelAppointment,
|
|
14
|
+
getDeliverables,
|
|
15
|
+
approveDeliverable,
|
|
16
|
+
requestRevision,
|
|
17
|
+
} from '../services/service-booking.service'
|
|
18
|
+
import type { SdkConfig } from '../config'
|
|
8
19
|
import type {
|
|
9
|
-
ServiceAppointment,
|
|
10
20
|
ServiceAppointmentCreatePayload,
|
|
11
|
-
ServiceDeliverable,
|
|
12
21
|
} from '../types/services'
|
|
22
|
+
import { logger } from '../utils'
|
|
23
|
+
import { useSdkContext, resolveHookArgs } from '../context/sdk-context'
|
|
13
24
|
|
|
14
|
-
/**
|
|
15
|
-
* Get available slots for a service product
|
|
16
|
-
*/
|
|
17
25
|
export function useAvailableSlots(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
arg1?: SdkConfig | string,
|
|
27
|
+
arg2?: string,
|
|
28
|
+
arg3?: string,
|
|
29
|
+
arg4?: string
|
|
21
30
|
) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Book a service appointment
|
|
32
|
-
*/
|
|
33
|
-
export function useBookAppointment() {
|
|
34
|
-
const queryClient = useQueryClient()
|
|
31
|
+
const ctx = useSdkContext()
|
|
32
|
+
const isArg1Config = typeof arg1 === 'object' && arg1 !== null && 'businessId' in arg1
|
|
33
|
+
const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
|
|
34
|
+
const product_id = isArg1Config ? arg2 : (typeof arg1 === 'string' ? arg1 : undefined)
|
|
35
|
+
const date_from = isArg1Config ? arg3 : (typeof arg2 === 'string' ? arg2 : undefined)
|
|
36
|
+
const date_to = isArg1Config ? arg4 : (typeof arg3 === 'string' ? arg3 : undefined)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
try {
|
|
39
|
+
const { config: cfg } = resolveHookArgs(explicitConfig, undefined, ctx)
|
|
40
|
+
return useQuery({
|
|
41
|
+
queryKey: ["available-slots", product_id, date_from, date_to],
|
|
42
|
+
queryFn: () => getAvailableSlots(cfg, product_id!, date_from!, date_to!),
|
|
43
|
+
enabled: !!product_id && !!date_from && !!date_to,
|
|
44
|
+
})
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.warn('[useAvailableSlots] Called outside QueryClientProvider, returning undefined')
|
|
47
|
+
return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
|
|
48
|
+
}
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
export function useBookAppointment(config?: SdkConfig, accessToken?: string | null) {
|
|
52
|
+
const ctx = useSdkContext()
|
|
53
|
+
try {
|
|
54
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
55
|
+
const queryClient = useQueryClient()
|
|
56
|
+
return useMutation({
|
|
57
|
+
mutationFn: (payload: ServiceAppointmentCreatePayload) =>
|
|
58
|
+
token ? bookAppointment(cfg, token, payload) : Promise.reject('No access token'),
|
|
59
|
+
onSuccess: () => {
|
|
60
|
+
queryClient.invalidateQueries({ queryKey: ["appointments"] })
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
} catch (error) {
|
|
64
|
+
logger.warn('[useBookAppointment] Called outside QueryClientProvider, returning no-op mutation')
|
|
65
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
66
|
+
}
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
export function useAppointments(config?: SdkConfig, accessToken?: string | null) {
|
|
70
|
+
const ctx = useSdkContext()
|
|
71
|
+
try {
|
|
72
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
73
|
+
return useQuery({
|
|
74
|
+
queryKey: ["appointments"],
|
|
75
|
+
queryFn: () => token ? getAppointments(cfg, token) : Promise.resolve([]),
|
|
76
|
+
enabled: !!token,
|
|
77
|
+
})
|
|
78
|
+
} catch (error) {
|
|
79
|
+
logger.warn('[useAppointments] Called outside QueryClientProvider, returning empty list')
|
|
80
|
+
return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
|
|
81
|
+
}
|
|
63
82
|
}
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
84
|
+
export function useAppointment(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
|
|
85
|
+
const ctx = useSdkContext()
|
|
86
|
+
const isArg1Config = typeof arg1 === 'object' && arg1 !== null && 'businessId' in arg1
|
|
87
|
+
const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
|
|
88
|
+
const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
|
|
89
|
+
const id = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
|
|
70
90
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
try {
|
|
92
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
|
|
93
|
+
return useQuery({
|
|
94
|
+
queryKey: ["appointment", id],
|
|
95
|
+
queryFn: () => token && id ? getAppointment(cfg, token, id) : Promise.resolve(undefined),
|
|
96
|
+
enabled: !!id && !!token,
|
|
97
|
+
})
|
|
98
|
+
} catch (error) {
|
|
99
|
+
logger.warn('[useAppointment] Called outside QueryClientProvider, returning undefined')
|
|
100
|
+
return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
|
|
101
|
+
}
|
|
77
102
|
}
|
|
78
103
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
104
|
+
export function useCancelAppointment(config?: SdkConfig, accessToken?: string | null) {
|
|
105
|
+
const ctx = useSdkContext()
|
|
106
|
+
try {
|
|
107
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
108
|
+
const queryClient = useQueryClient()
|
|
109
|
+
return useMutation({
|
|
110
|
+
mutationFn: (id: string) =>
|
|
111
|
+
token ? cancelAppointment(cfg, token, id) : Promise.reject('No access token'),
|
|
112
|
+
onSuccess: () => {
|
|
113
|
+
queryClient.invalidateQueries({ queryKey: ["appointments"] })
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
} catch (error) {
|
|
117
|
+
logger.warn('[useCancelAppointment] Called outside QueryClientProvider, returning no-op mutation')
|
|
118
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
119
|
+
}
|
|
88
120
|
}
|
|
89
121
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
122
|
+
export function useDeliverables(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
|
|
123
|
+
const ctx = useSdkContext()
|
|
124
|
+
const isArg1Config = typeof arg1 === 'object' && arg1 !== null && 'businessId' in arg1
|
|
125
|
+
const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
|
|
126
|
+
const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
|
|
127
|
+
const order_id = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
|
|
95
128
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
try {
|
|
130
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
|
|
131
|
+
return useQuery({
|
|
132
|
+
queryKey: ["deliverables", order_id],
|
|
133
|
+
queryFn: () => token && order_id ? getDeliverables(cfg, token, order_id) : Promise.resolve([]),
|
|
134
|
+
enabled: !!order_id && !!token,
|
|
135
|
+
})
|
|
136
|
+
} catch (error) {
|
|
137
|
+
logger.warn('[useDeliverables] Called outside QueryClientProvider, returning empty list')
|
|
138
|
+
return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
|
|
139
|
+
}
|
|
103
140
|
}
|
|
104
141
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
142
|
+
export function useApproveDeliverable(config?: SdkConfig, accessToken?: string | null, order_id?: string, deliverable_id?: string) {
|
|
143
|
+
const ctx = useSdkContext()
|
|
144
|
+
try {
|
|
145
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
146
|
+
const queryClient = useQueryClient()
|
|
147
|
+
return useMutation({
|
|
148
|
+
mutationFn: () =>
|
|
149
|
+
token && order_id && deliverable_id
|
|
150
|
+
? approveDeliverable(cfg, token, order_id, deliverable_id)
|
|
151
|
+
: Promise.reject('No access token'),
|
|
152
|
+
onSuccess: () => {
|
|
153
|
+
queryClient.invalidateQueries({ queryKey: ["deliverables", order_id] })
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
} catch (error) {
|
|
157
|
+
logger.warn('[useApproveDeliverable] Called outside QueryClientProvider, returning no-op mutation')
|
|
158
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
159
|
+
}
|
|
160
|
+
}
|
|
110
161
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
162
|
+
export function useRequestRevision(config?: SdkConfig, accessToken?: string | null, order_id?: string, deliverable_id?: string) {
|
|
163
|
+
const ctx = useSdkContext()
|
|
164
|
+
try {
|
|
165
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
166
|
+
const queryClient = useQueryClient()
|
|
167
|
+
return useMutation({
|
|
168
|
+
mutationFn: (feedback: string) =>
|
|
169
|
+
token && order_id && deliverable_id
|
|
170
|
+
? requestRevision(cfg, token, order_id, deliverable_id, feedback)
|
|
171
|
+
: Promise.reject('No access token'),
|
|
172
|
+
onSuccess: () => {
|
|
173
|
+
queryClient.invalidateQueries({ queryKey: ["deliverables", order_id] })
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
} catch (error) {
|
|
177
|
+
logger.warn('[useRequestRevision] Called outside QueryClientProvider, returning no-op mutation')
|
|
178
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
179
|
+
}
|
|
118
180
|
}
|
package/src/hooks/use-states.ts
CHANGED
|
@@ -2,27 +2,47 @@
|
|
|
2
2
|
* States Hook
|
|
3
3
|
*
|
|
4
4
|
* React Query hook for fetching states for a country.
|
|
5
|
+
* Stateless - requires config parameter.
|
|
5
6
|
*/
|
|
6
7
|
import { useQuery } from '@tanstack/react-query'
|
|
7
|
-
import {
|
|
8
|
+
import type { SdkConfig } from '../config'
|
|
8
9
|
import type { State } from '../types/ui'
|
|
10
|
+
import { logger } from '../utils'
|
|
11
|
+
import { useSdkContext, resolveHookArgs } from '../context/sdk-context'
|
|
9
12
|
|
|
10
|
-
export async function getStates(countryIso: string): Promise<State[]> {
|
|
13
|
+
export async function getStates(config: SdkConfig, countryIso: string): Promise<State[]> {
|
|
11
14
|
if (!countryIso) return []
|
|
12
|
-
const
|
|
13
|
-
|
|
15
|
+
const response = await fetch(`${config.backendUrls.auth}/auth/countries/?iso=${countryIso}`, {
|
|
16
|
+
headers: {
|
|
17
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
18
|
+
"X-Business-ID": config.businessId,
|
|
19
|
+
},
|
|
14
20
|
})
|
|
15
|
-
|
|
21
|
+
if (!response.ok) throw new Error('Failed to fetch states')
|
|
22
|
+
return response.json()
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
export function useStates(countryIso: string) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
export function useStates(countryIso: string, config?: SdkConfig) {
|
|
26
|
+
const ctx = useSdkContext()
|
|
27
|
+
try {
|
|
28
|
+
const { config: cfg } = resolveHookArgs(config, undefined, ctx)
|
|
29
|
+
return useQuery({
|
|
30
|
+
queryKey: ['states', countryIso],
|
|
31
|
+
queryFn: () => getStates(cfg, countryIso),
|
|
32
|
+
enabled: !!countryIso,
|
|
33
|
+
retry: 1,
|
|
34
|
+
refetchOnWindowFocus: false,
|
|
35
|
+
refetchOnReconnect: false,
|
|
36
|
+
staleTime: 24 * 60 * 60 * 1000,
|
|
37
|
+
})
|
|
38
|
+
} catch (error) {
|
|
39
|
+
logger.warn('[useStates] Called outside QueryClientProvider, returning empty list')
|
|
40
|
+
return {
|
|
41
|
+
data: [],
|
|
42
|
+
isLoading: false,
|
|
43
|
+
error: null,
|
|
44
|
+
isFetching: false,
|
|
45
|
+
refetch: () => Promise.resolve({ data: [] }),
|
|
46
|
+
} as any
|
|
47
|
+
}
|
|
28
48
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wishlist Hooks
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* React Query hooks for wishlist operations.
|
|
5
|
+
* config and accessToken are optional — if omitted, they are read from SdkContext.
|
|
5
6
|
*/
|
|
6
7
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
7
8
|
import {
|
|
@@ -11,7 +12,9 @@ import {
|
|
|
11
12
|
removeProductFromWishlist,
|
|
12
13
|
checkInWishlist,
|
|
13
14
|
} from '../services/wishlist.service'
|
|
15
|
+
import type { SdkConfig } from '../config'
|
|
14
16
|
import { getCacheTier } from '../utils/cache'
|
|
17
|
+
import { useSdkContext, resolveHookArgs } from '../context/sdk-context'
|
|
15
18
|
|
|
16
19
|
export const wishlistKeys = {
|
|
17
20
|
all: ["wishlist"] as const,
|
|
@@ -19,103 +22,101 @@ export const wishlistKeys = {
|
|
|
19
22
|
check: (productId: string) => [...wishlistKeys.all, "check", productId] as const,
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
queryKey: [...wishlistKeys.list(), params],
|
|
29
|
-
queryFn: () => getWishlist(params),
|
|
30
|
-
// medium — wishlist changes infrequently
|
|
31
|
-
...getCacheTier('medium'),
|
|
32
|
-
})
|
|
33
|
-
}
|
|
25
|
+
export function useWishlist(arg1?: SdkConfig | { page?: number; pageSize?: number }, arg2?: string | null, arg3?: { page?: number; pageSize?: number }) {
|
|
26
|
+
const ctx = useSdkContext()
|
|
27
|
+
const isArg1Config = typeof arg1 === 'object' && arg1 !== null && 'businessId' in arg1
|
|
28
|
+
const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
|
|
29
|
+
const explicitToken = isArg1Config ? arg2 : undefined
|
|
30
|
+
const params = isArg1Config ? arg3 : (arg1 as { page?: number; pageSize?: number } | undefined)
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
32
|
+
try {
|
|
33
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
|
|
34
|
+
return useQuery({
|
|
35
|
+
queryKey: [...wishlistKeys.list(), params],
|
|
36
|
+
queryFn: () => token ? getWishlist(cfg, token, params) : Promise.resolve(undefined),
|
|
37
|
+
enabled: !!token,
|
|
38
|
+
...getCacheTier('medium'),
|
|
39
|
+
})
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.warn('[useWishlist] Called outside QueryClientProvider, returning empty wishlist')
|
|
42
|
+
return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
|
|
43
|
+
}
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
return useMutation({
|
|
57
|
-
mutationFn: ({ productId, notes }: { productId: string; notes?: string }) => {
|
|
58
|
-
return addToWishlist(productId, notes)
|
|
59
|
-
},
|
|
60
|
-
onSuccess: () => {
|
|
61
|
-
// Invalidate all wishlist queries to ensure cache is updated
|
|
62
|
-
queryClient.invalidateQueries({ queryKey: wishlistKeys.all })
|
|
63
|
-
// Also invalidate specific check queries for all products
|
|
64
|
-
queryClient.invalidateQueries({ queryKey: ['wishlist', 'check'] })
|
|
65
|
-
},
|
|
66
|
-
})
|
|
67
|
-
}
|
|
46
|
+
export function useCheckInWishlist(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
|
|
47
|
+
const ctx = useSdkContext()
|
|
48
|
+
const isArg1Config = typeof arg1 === 'object' && arg1 !== null && 'businessId' in arg1
|
|
49
|
+
const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
|
|
50
|
+
const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
|
|
51
|
+
const productId = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
|
|
68
52
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
queryClient.invalidateQueries({ queryKey: wishlistKeys.all })
|
|
82
|
-
// Also invalidate specific check queries for all products
|
|
83
|
-
queryClient.invalidateQueries({ queryKey: ['wishlist', 'check'] })
|
|
84
|
-
},
|
|
85
|
-
})
|
|
53
|
+
try {
|
|
54
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
|
|
55
|
+
return useQuery({
|
|
56
|
+
queryKey: wishlistKeys.check(productId ?? ''),
|
|
57
|
+
queryFn: () => token && productId ? checkInWishlist(cfg, token, productId) : Promise.resolve({ in_wishlist: false }),
|
|
58
|
+
...getCacheTier('low'),
|
|
59
|
+
enabled: !!productId && !!token,
|
|
60
|
+
})
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn('[useCheckInWishlist] Called outside QueryClientProvider, returning false')
|
|
63
|
+
return { data: false, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: false }) } as any
|
|
64
|
+
}
|
|
86
65
|
}
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
},
|
|
104
|
-
}
|
|
67
|
+
export function useAddToWishlist(config?: SdkConfig, accessToken?: string | null) {
|
|
68
|
+
const ctx = useSdkContext()
|
|
69
|
+
try {
|
|
70
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
71
|
+
const queryClient = useQueryClient()
|
|
72
|
+
return useMutation({
|
|
73
|
+
mutationFn: ({ productId, notes }: { productId: string; notes?: string }) =>
|
|
74
|
+
token ? addToWishlist(cfg, token, productId, notes) : Promise.reject('No access token'),
|
|
75
|
+
onSuccess: () => {
|
|
76
|
+
queryClient.invalidateQueries({ queryKey: wishlistKeys.all })
|
|
77
|
+
queryClient.invalidateQueries({ queryKey: ['wishlist', 'check'] })
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.warn('[useAddToWishlist] Called outside QueryClientProvider, returning no-op mutation')
|
|
82
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
83
|
+
}
|
|
105
84
|
}
|
|
106
85
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
86
|
+
export function useRemoveFromWishlist(config?: SdkConfig, accessToken?: string | null) {
|
|
87
|
+
const ctx = useSdkContext()
|
|
88
|
+
try {
|
|
89
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
90
|
+
const queryClient = useQueryClient()
|
|
91
|
+
return useMutation({
|
|
92
|
+
mutationFn: (itemId: string) =>
|
|
93
|
+
token ? removeFromWishlist(cfg, token, itemId) : Promise.reject('No access token'),
|
|
94
|
+
onSuccess: () => {
|
|
95
|
+
queryClient.invalidateQueries({ queryKey: wishlistKeys.all })
|
|
96
|
+
queryClient.invalidateQueries({ queryKey: ['wishlist', 'check'] })
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.warn('[useRemoveFromWishlist] Called outside QueryClientProvider, returning no-op mutation')
|
|
101
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
102
|
+
}
|
|
103
|
+
}
|
|
119
104
|
|
|
120
|
-
|
|
105
|
+
export function useRemoveProductFromWishlist(config?: SdkConfig, accessToken?: string | null) {
|
|
106
|
+
const ctx = useSdkContext()
|
|
107
|
+
try {
|
|
108
|
+
const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
|
|
109
|
+
const queryClient = useQueryClient()
|
|
110
|
+
return useMutation({
|
|
111
|
+
mutationFn: (productId: string) =>
|
|
112
|
+
token ? removeProductFromWishlist(cfg, token, productId) : Promise.reject('No access token'),
|
|
113
|
+
onSuccess: () => {
|
|
114
|
+
queryClient.invalidateQueries({ queryKey: wishlistKeys.all })
|
|
115
|
+
queryClient.invalidateQueries({ queryKey: ['wishlist', 'check'] })
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.warn('[useRemoveProductFromWishlist] Called outside QueryClientProvider, returning no-op mutation')
|
|
120
|
+
return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
|
|
121
|
+
}
|
|
121
122
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,22 +2,29 @@
|
|
|
2
2
|
* @kasuvia/sdk
|
|
3
3
|
*
|
|
4
4
|
* Kasuvia SDK - Core data fetching, authentication, and API client layer
|
|
5
|
+
* Stateless architecture - no global state, all configuration passed as parameters.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```ts
|
|
8
|
-
* import {
|
|
9
|
+
* import { getStorefrontProductBySlug } from '@kasuvia/sdk'
|
|
10
|
+
* import { useCart, useAuth } from '@kasuvia/sdk/hooks'
|
|
11
|
+
* import type { SdkConfig } from '@kasuvia/sdk'
|
|
9
12
|
*
|
|
10
|
-
* //
|
|
11
|
-
*
|
|
13
|
+
* // Use in server components
|
|
14
|
+
* const config: SdkConfig = {
|
|
12
15
|
* businessId: 'B-123ABC',
|
|
13
16
|
* storefrontApiKey: 'your-api-key',
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* backendUrls: {
|
|
18
|
+
* auth: 'http://...',
|
|
19
|
+
* store: 'http://...',
|
|
20
|
+
* payment: 'http://...',
|
|
21
|
+
* notifications: 'http://...',
|
|
22
|
+
* cms: 'http://...',
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* const product = await getStorefrontProductBySlug(config, 'slug')
|
|
19
26
|
*
|
|
20
|
-
* // Use in components
|
|
27
|
+
* // Use in client components
|
|
21
28
|
* function Cart() {
|
|
22
29
|
* const { cart, addToCart } = useCart()
|
|
23
30
|
* // ...
|
|
@@ -26,33 +33,19 @@
|
|
|
26
33
|
*/
|
|
27
34
|
|
|
28
35
|
// Configuration
|
|
29
|
-
export { initSdk, getRuntimeConfig, getBackendUrl, isInitialized, resetConfig } from './config'
|
|
30
36
|
export type { SdkConfig } from './config'
|
|
37
|
+
export { SdkProvider, useSdkContext } from './context/sdk-context'
|
|
38
|
+
export type { SdkContextValue, SdkProviderProps } from './context/sdk-context'
|
|
31
39
|
|
|
32
|
-
//
|
|
33
|
-
export {
|
|
34
|
-
storeManagementAxios,
|
|
35
|
-
publicStoreAxios,
|
|
36
|
-
authAxios,
|
|
37
|
-
paymentAxios,
|
|
38
|
-
cmsAxios,
|
|
39
|
-
getOrCreateGuestSessionId,
|
|
40
|
-
getGuestSessionId,
|
|
41
|
-
clearGuestSessionId,
|
|
42
|
-
configureHttpClients,
|
|
43
|
-
} from './client/httpClient'
|
|
44
|
-
export { tokenStore, refreshToken } from './client/authClient'
|
|
45
|
-
export { getGraphQLClient, resetGraphQLClient } from './client/graphqlClient'
|
|
40
|
+
// Constants
|
|
41
|
+
export { STORAGE_KEYS } from './constants'
|
|
46
42
|
|
|
47
43
|
// Types
|
|
48
44
|
export * from './types'
|
|
49
45
|
|
|
50
|
-
// Services
|
|
46
|
+
// Services (for server components)
|
|
51
47
|
export * from './services'
|
|
52
48
|
|
|
53
|
-
// React Hooks
|
|
54
|
-
export * from './hooks'
|
|
55
|
-
|
|
56
49
|
// Utils
|
|
57
50
|
export { getCacheTier, setEnvironmentMode } from './utils/cache'
|
|
58
51
|
export { logger, setLoggerEnvironmentMode } from './utils/logger'
|
|
@@ -61,8 +54,11 @@ export * from './utils/customer'
|
|
|
61
54
|
export * from './utils/checkout'
|
|
62
55
|
export * from './utils/error-handler'
|
|
63
56
|
export { sessionStore, localStore } from './utils/storage'
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
export * from './utils/validators'
|
|
66
58
|
|
|
67
59
|
// App service functions
|
|
68
60
|
export { googleTranslate } from './services/app.service'
|
|
61
|
+
|
|
62
|
+
// Note: React hooks are exported separately via '@kasuvia/sdk/hooks' to avoid
|
|
63
|
+
// importing them in server components. Use:
|
|
64
|
+
// import { useCart, useAuth } from '@kasuvia/sdk/hooks'
|