@kasuvia/sdk 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/hooks/index.d.mts +429 -0
  2. package/dist/hooks/index.d.ts +429 -0
  3. package/dist/hooks/index.js +3073 -0
  4. package/dist/hooks/index.js.map +1 -0
  5. package/dist/hooks/index.mjs +2962 -0
  6. package/dist/hooks/index.mjs.map +1 -0
  7. package/dist/index.d.mts +250 -1161
  8. package/dist/index.d.ts +250 -1161
  9. package/dist/index.js +1544 -2359
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +1527 -2258
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/sdk-context-Cy51kEKT.d.mts +565 -0
  14. package/dist/sdk-context-Cy51kEKT.d.ts +565 -0
  15. package/package.json +6 -2
  16. package/src/config/index.ts +10 -91
  17. package/src/constants.ts +13 -0
  18. package/src/context/sdk-context.tsx +70 -0
  19. package/src/graphql/collections.graphql.ts +2 -10
  20. package/src/graphql/products.graphql.ts +215 -65
  21. package/src/graphql/wishlist.graphql.ts +7 -6
  22. package/src/hooks/index.ts +2 -0
  23. package/src/hooks/use-auth.ts +82 -158
  24. package/src/hooks/use-bespoke-availability.ts +25 -8
  25. package/src/hooks/use-cart.ts +222 -119
  26. package/src/hooks/use-cms.ts +179 -86
  27. package/src/hooks/use-collections.ts +52 -15
  28. package/src/hooks/use-consultation-stream.ts +4 -3
  29. package/src/hooks/use-consultations.ts +120 -51
  30. package/src/hooks/use-countries.ts +35 -13
  31. package/src/hooks/use-currencies.ts +26 -13
  32. package/src/hooks/use-google-translate.ts +22 -8
  33. package/src/hooks/use-languages.ts +40 -20
  34. package/src/hooks/use-mobile.ts +23 -0
  35. package/src/hooks/use-order-stream.ts +9 -5
  36. package/src/hooks/use-orders.ts +99 -44
  37. package/src/hooks/use-payment.ts +108 -40
  38. package/src/hooks/use-products.ts +251 -53
  39. package/src/hooks/use-service-booking.ts +152 -90
  40. package/src/hooks/use-states.ts +35 -15
  41. package/src/hooks/use-wishlist.ts +92 -91
  42. package/src/index.ts +26 -30
  43. package/src/services/auth.service.ts +209 -167
  44. package/src/services/bespoke.service.ts +12 -4
  45. package/src/services/cart.service.ts +172 -70
  46. package/src/services/cms.service.ts +70 -35
  47. package/src/services/collection.service.ts +22 -5
  48. package/src/services/config.service.ts +34 -14
  49. package/src/services/consultation.service.ts +72 -18
  50. package/src/services/logistics.service.ts +35 -11
  51. package/src/services/notifications.service.ts +27 -12
  52. package/src/services/order.service.ts +74 -15
  53. package/src/services/payment.service.ts +86 -31
  54. package/src/services/product.service.ts +279 -39
  55. package/src/services/service-booking.service.ts +98 -26
  56. package/src/services/wishlist.service.ts +69 -25
  57. package/src/types/auth/index.ts +6 -4
  58. package/src/types/business/index.ts +7 -2
  59. package/src/types/payments/index.ts +3 -3
  60. package/src/types/services/index.ts +2 -5
  61. package/src/types/store/index.ts +38 -3
  62. package/src/utils/error-handler.ts +10 -5
  63. package/src/utils/storage.ts +48 -26
  64. package/src/utils/validators.ts +85 -0
  65. package/src/client/authClient.ts +0 -135
  66. package/src/client/graphqlClient.ts +0 -53
  67. package/src/client/httpClient.ts +0 -298
@@ -2,6 +2,7 @@
2
2
  * CMS Hooks
3
3
  *
4
4
  * React Query hooks for CMS model and entry 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,14 +12,15 @@ import {
11
12
  updateCmsEntry,
12
13
  deleteCmsEntry,
13
14
  } from '../services/cms.service'
14
- import { isInitialized } from '../config'
15
+ import type { SdkConfig } from '../config'
15
16
  import type {
16
17
  CmsEntry,
17
- CmsEntryListResponse,
18
18
  CreateCmsEntryParams,
19
19
  UpdateCmsEntryParams,
20
20
  ListCmsEntriesParams,
21
21
  } from '../types/cms'
22
+ import { logger } from '../utils'
23
+ import { useSdkContext, resolveHookArgs } from '../context/sdk-context'
22
24
 
23
25
  export interface UseCmsEntriesReturn {
24
26
  entries: CmsEntry[]
@@ -32,25 +34,57 @@ export interface UseCmsEntriesReturn {
32
34
 
33
35
  /**
34
36
  * Hook to list CMS entries for a specific model.
37
+ * Signature can be:
38
+ * useCmsEntries(config, modelSlug, params)
39
+ * useCmsEntries(modelSlug, params)
35
40
  */
36
41
  export function useCmsEntries(
37
- modelSlug: string,
38
- params?: ListCmsEntriesParams
42
+ configOrModelSlug: SdkConfig | string,
43
+ modelSlugOrParams?: string | ListCmsEntriesParams,
44
+ maybeParams?: ListCmsEntriesParams
39
45
  ): UseCmsEntriesReturn {
40
- const query = useQuery({
41
- queryKey: ['cms-entries', modelSlug, params],
42
- queryFn: () => listCmsEntries(modelSlug, params),
43
- enabled: isInitialized() && !!modelSlug,
44
- })
45
-
46
- return {
47
- entries: query.data?.entries || [],
48
- total: query.data?.total || 0,
49
- page: query.data?.page || 1,
50
- page_size: query.data?.page_size || 50,
51
- isLoading: query.isLoading,
52
- error: query.error as Error | null,
53
- refetch: query.refetch,
46
+ const ctx = useSdkContext()
47
+ let cfg: SdkConfig
48
+ let slug: string
49
+ let params: ListCmsEntriesParams | undefined
50
+
51
+ if (typeof configOrModelSlug === 'string') {
52
+ slug = configOrModelSlug
53
+ params = modelSlugOrParams as ListCmsEntriesParams | undefined
54
+ cfg = resolveHookArgs(undefined, undefined, ctx).config
55
+ } else {
56
+ cfg = configOrModelSlug
57
+ slug = modelSlugOrParams as string
58
+ params = maybeParams
59
+ }
60
+
61
+ try {
62
+ const query = useQuery({
63
+ queryKey: ['cms-entries', slug, params],
64
+ queryFn: () => listCmsEntries(cfg, slug, params),
65
+ enabled: !!slug,
66
+ })
67
+
68
+ return {
69
+ entries: query.data?.entries || [],
70
+ total: query.data?.total || 0,
71
+ page: query.data?.page || 1,
72
+ page_size: query.data?.page_size || 50,
73
+ isLoading: query.isLoading,
74
+ error: query.error as Error | null,
75
+ refetch: query.refetch,
76
+ }
77
+ } catch (error) {
78
+ logger.warn('[useCmsEntries] Called outside QueryClientProvider, returning empty list')
79
+ return {
80
+ entries: [],
81
+ total: 0,
82
+ page: 1,
83
+ page_size: 50,
84
+ isLoading: false,
85
+ error: null,
86
+ refetch: () => {},
87
+ }
54
88
  }
55
89
  }
56
90
 
@@ -63,22 +97,51 @@ export interface UseCmsEntryReturn {
63
97
 
64
98
  /**
65
99
  * Hook to get a single CMS entry by ID.
100
+ * Signature can be:
101
+ * useCmsEntry(config, modelSlug, entryId)
102
+ * useCmsEntry(modelSlug, entryId)
66
103
  */
67
104
  export function useCmsEntry(
68
- modelSlug: string,
69
- entryId: string
105
+ configOrModelSlug: SdkConfig | string,
106
+ modelSlugOrEntryId: string,
107
+ maybeEntryId?: string
70
108
  ): UseCmsEntryReturn {
71
- const query = useQuery({
72
- queryKey: ['cms-entry', modelSlug, entryId],
73
- queryFn: () => getCmsEntry(modelSlug, entryId),
74
- enabled: isInitialized() && !!modelSlug && !!entryId,
75
- })
76
-
77
- return {
78
- entry: query.data,
79
- isLoading: query.isLoading,
80
- error: query.error as Error | null,
81
- refetch: query.refetch,
109
+ const ctx = useSdkContext()
110
+ let cfg: SdkConfig
111
+ let slug: string
112
+ let entryId: string
113
+
114
+ if (maybeEntryId !== undefined) {
115
+ cfg = configOrModelSlug as SdkConfig
116
+ slug = modelSlugOrEntryId
117
+ entryId = maybeEntryId
118
+ } else {
119
+ cfg = resolveHookArgs(undefined, undefined, ctx).config
120
+ slug = configOrModelSlug as string
121
+ entryId = modelSlugOrEntryId
122
+ }
123
+
124
+ try {
125
+ const query = useQuery({
126
+ queryKey: ['cms-entry', slug, entryId],
127
+ queryFn: () => getCmsEntry(cfg, slug, entryId),
128
+ enabled: !!slug && !!entryId,
129
+ })
130
+
131
+ return {
132
+ entry: query.data,
133
+ isLoading: query.isLoading,
134
+ error: query.error as Error | null,
135
+ refetch: query.refetch,
136
+ }
137
+ } catch (error) {
138
+ logger.warn('[useCmsEntry] Called outside QueryClientProvider, returning undefined')
139
+ return {
140
+ entry: undefined,
141
+ isLoading: false,
142
+ error: null,
143
+ refetch: () => {},
144
+ }
82
145
  }
83
146
  }
84
147
 
@@ -88,23 +151,32 @@ export interface UseCreateCmsEntryReturn {
88
151
  error: Error | null
89
152
  }
90
153
 
91
- /**
92
- * Hook to create a new CMS entry.
93
- */
94
- export function useCreateCmsEntry(modelSlug: string): UseCreateCmsEntryReturn {
95
- const queryClient = useQueryClient()
96
-
97
- const mutation = useMutation({
98
- mutationFn: (params: CreateCmsEntryParams) => createCmsEntry(modelSlug, params),
99
- onSuccess: () => {
100
- queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
101
- },
102
- })
103
-
104
- return {
105
- createEntry: mutation.mutate,
106
- isLoading: mutation.isPending,
107
- error: mutation.error as Error | null,
154
+ export function useCreateCmsEntry(config?: SdkConfig, accessToken?: string | null, modelSlug?: string): UseCreateCmsEntryReturn {
155
+ const ctx = useSdkContext()
156
+ try {
157
+ const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
158
+ const queryClient = useQueryClient()
159
+
160
+ const mutation = useMutation({
161
+ mutationFn: (params: CreateCmsEntryParams) =>
162
+ token && modelSlug ? createCmsEntry(cfg, token, modelSlug, params) : Promise.reject('No access token or modelSlug'),
163
+ onSuccess: () => {
164
+ if (modelSlug) queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
165
+ },
166
+ })
167
+
168
+ return {
169
+ createEntry: mutation.mutate,
170
+ isLoading: mutation.isPending,
171
+ error: mutation.error as Error | null,
172
+ }
173
+ } catch (error) {
174
+ logger.warn('[useCreateCmsEntry] Called outside QueryClientProvider, returning no-op mutation')
175
+ return {
176
+ createEntry: () => {},
177
+ isLoading: false,
178
+ error: null,
179
+ }
108
180
  }
109
181
  }
110
182
 
@@ -114,26 +186,36 @@ export interface UseUpdateCmsEntryReturn {
114
186
  error: Error | null
115
187
  }
116
188
 
117
- /**
118
- * Hook to update an existing CMS entry.
119
- */
120
- export function useUpdateCmsEntry(modelSlug: string): UseUpdateCmsEntryReturn {
121
- const queryClient = useQueryClient()
122
-
123
- const mutation = useMutation({
124
- mutationFn: ({ entryId, params }: { entryId: string; params: UpdateCmsEntryParams }) =>
125
- updateCmsEntry(modelSlug, entryId, params),
126
- onSuccess: () => {
127
- queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
128
- queryClient.invalidateQueries({ queryKey: ['cms-entry', modelSlug] })
129
- },
130
- })
131
-
132
- return {
133
- updateEntry: (entryId: string, params: UpdateCmsEntryParams) =>
134
- mutation.mutate({ entryId, params }),
135
- isLoading: mutation.isPending,
136
- error: mutation.error as Error | null,
189
+ export function useUpdateCmsEntry(config?: SdkConfig, accessToken?: string | null, modelSlug?: string): UseUpdateCmsEntryReturn {
190
+ const ctx = useSdkContext()
191
+ try {
192
+ const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
193
+ const queryClient = useQueryClient()
194
+
195
+ const mutation = useMutation({
196
+ mutationFn: ({ entryId, params }: { entryId: string; params: UpdateCmsEntryParams }) =>
197
+ token && modelSlug ? updateCmsEntry(cfg, token, modelSlug, entryId, params) : Promise.reject('No access token or modelSlug'),
198
+ onSuccess: () => {
199
+ if (modelSlug) {
200
+ queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
201
+ queryClient.invalidateQueries({ queryKey: ['cms-entry', modelSlug] })
202
+ }
203
+ },
204
+ })
205
+
206
+ return {
207
+ updateEntry: (entryId: string, params: UpdateCmsEntryParams) =>
208
+ mutation.mutate({ entryId, params }),
209
+ isLoading: mutation.isPending,
210
+ error: mutation.error as Error | null,
211
+ }
212
+ } catch (error) {
213
+ logger.warn('[useUpdateCmsEntry] Called outside QueryClientProvider, returning no-op mutation')
214
+ return {
215
+ updateEntry: () => {},
216
+ isLoading: false,
217
+ error: null,
218
+ }
137
219
  }
138
220
  }
139
221
 
@@ -143,23 +225,34 @@ export interface UseDeleteCmsEntryReturn {
143
225
  error: Error | null
144
226
  }
145
227
 
146
- /**
147
- * Hook to delete a CMS entry.
148
- */
149
- export function useDeleteCmsEntry(modelSlug: string): UseDeleteCmsEntryReturn {
150
- const queryClient = useQueryClient()
151
-
152
- const mutation = useMutation({
153
- mutationFn: (entryId: string) => deleteCmsEntry(modelSlug, entryId),
154
- onSuccess: () => {
155
- queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
156
- queryClient.invalidateQueries({ queryKey: ['cms-entry', modelSlug] })
157
- },
158
- })
159
-
160
- return {
161
- deleteEntry: mutation.mutate,
162
- isLoading: mutation.isPending,
163
- error: mutation.error as Error | null,
228
+ export function useDeleteCmsEntry(config?: SdkConfig, accessToken?: string | null, modelSlug?: string): UseDeleteCmsEntryReturn {
229
+ const ctx = useSdkContext()
230
+ try {
231
+ const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
232
+ const queryClient = useQueryClient()
233
+
234
+ const mutation = useMutation({
235
+ mutationFn: (entryId: string) =>
236
+ token && modelSlug ? deleteCmsEntry(cfg, token, modelSlug, entryId) : Promise.reject('No access token or modelSlug'),
237
+ onSuccess: () => {
238
+ if (modelSlug) {
239
+ queryClient.invalidateQueries({ queryKey: ['cms-entries', modelSlug] })
240
+ queryClient.invalidateQueries({ queryKey: ['cms-entry', modelSlug] })
241
+ }
242
+ },
243
+ })
244
+
245
+ return {
246
+ deleteEntry: mutation.mutate,
247
+ isLoading: mutation.isPending,
248
+ error: mutation.error as Error | null,
249
+ }
250
+ } catch (error) {
251
+ logger.warn('[useDeleteCmsEntry] Called outside QueryClientProvider, returning no-op mutation')
252
+ return {
253
+ deleteEntry: () => {},
254
+ isLoading: false,
255
+ error: null,
256
+ }
164
257
  }
165
258
  }
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * Collections Hooks
3
3
  *
4
- * React Query hooks for fetching collections.
4
+ * React Query hooks for fetching collections via Next.js API routes.
5
+ * Client-side hooks fetch from API routes to avoid exposing backend URLs to browser.
5
6
  */
6
7
  import { useQuery } from '@tanstack/react-query'
7
- import { getStorefrontCollections, getStorefrontCollectionBySlug } from '../services/collection.service'
8
8
  import type { ListParams } from '../types/store'
9
9
  import { getCacheTier } from '../utils/cache'
10
+ import { logger } from '../utils'
10
11
 
11
12
  export const collectionKeys = {
12
13
  all: ['core', 'collections'] as const,
@@ -16,25 +17,61 @@ export const collectionKeys = {
16
17
 
17
18
  /**
18
19
  * Hook to fetch paginated collections for the storefront.
20
+ * Fetches from Next.js API route to avoid exposing backend URLs.
19
21
  */
20
22
  export function useStorefrontCollections(params?: ListParams) {
21
- return useQuery({
22
- queryKey: collectionKeys.list(params),
23
- queryFn: () => getStorefrontCollections(params),
24
- // medium — collections change infrequently
25
- ...getCacheTier('medium'),
26
- })
23
+ try {
24
+ const queryParams = new URLSearchParams()
25
+ if (params?.page) queryParams.set('page', params.page.toString())
26
+ if (params?.pageSize) queryParams.set('pageSize', params.pageSize.toString())
27
+
28
+ return useQuery({
29
+ queryKey: collectionKeys.list(params),
30
+ queryFn: async () => {
31
+ const response = await fetch(`/api/collections?${queryParams.toString()}`)
32
+ if (!response.ok) throw new Error('Failed to fetch collections')
33
+ return response.json()
34
+ },
35
+ // medium — collections change infrequently
36
+ ...getCacheTier('medium'),
37
+ })
38
+ } catch (error) {
39
+ logger.warn('[useStorefrontCollections] Called outside QueryClientProvider, returning empty list')
40
+ return {
41
+ data: undefined,
42
+ isLoading: false,
43
+ error: null,
44
+ isFetching: false,
45
+ refetch: () => Promise.resolve({ data: undefined }),
46
+ } as any
47
+ }
27
48
  }
28
49
 
29
50
  /**
30
51
  * Hook to fetch a single collection by slug for the storefront.
52
+ * Fetches from Next.js API route to avoid exposing backend URLs.
31
53
  */
32
54
  export function useStorefrontCollection(slug: string) {
33
- return useQuery({
34
- queryKey: collectionKeys.slug(slug),
35
- queryFn: () => getStorefrontCollectionBySlug(slug),
36
- // medium — collection details change infrequently
37
- ...getCacheTier('medium'),
38
- enabled: !!slug,
39
- })
55
+ try {
56
+ return useQuery({
57
+ queryKey: collectionKeys.slug(slug),
58
+ queryFn: async () => {
59
+ const response = await fetch(`/api/collections/${slug}`)
60
+ if (!response.ok) throw new Error('Failed to fetch collection')
61
+ return response.json()
62
+ },
63
+ // medium — collection details change infrequently
64
+ ...getCacheTier('medium'),
65
+ enabled: !!slug,
66
+ })
67
+ } catch (error) {
68
+ logger.warn('[useStorefrontCollection] Called outside QueryClientProvider, returning undefined')
69
+ return {
70
+ data: undefined,
71
+ isLoading: false,
72
+ error: null,
73
+ isFetching: false,
74
+ refetch: () => Promise.resolve({ data: undefined }),
75
+ } as any
76
+ }
40
77
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useEffect, useRef, useState } from 'react';
4
4
  import { fetchEventSource, EventSourceMessage } from '@microsoft/fetch-event-source';
5
- import { getBackendUrl } from '../config';
5
+ import type { SdkConfig } from '../config';
6
6
  import { logger } from '../utils';
7
7
 
8
8
  interface ConsultationMessageData {
@@ -39,6 +39,7 @@ interface ConsultationStatusData {
39
39
  }
40
40
 
41
41
  interface UseConsultationStreamOptions {
42
+ config: SdkConfig;
42
43
  consultationId: string;
43
44
  onMessage?: (data: ConsultationMessageData) => void;
44
45
  onQuote?: (data: ConsultationQuoteData) => void;
@@ -47,6 +48,7 @@ interface UseConsultationStreamOptions {
47
48
  }
48
49
 
49
50
  export function useConsultationStream({
51
+ config,
50
52
  consultationId,
51
53
  onMessage,
52
54
  onQuote,
@@ -65,8 +67,7 @@ export function useConsultationStream({
65
67
  const abortController = new AbortController();
66
68
  abortControllerRef.current = abortController;
67
69
 
68
- const paymentUrl = getBackendUrl('payment');
69
- const streamUrl = `${paymentUrl}/events/stream/consultation/${consultationId}`;
70
+ const streamUrl = `${config.backendUrls.payment}/events/stream/consultation/${consultationId}`;
70
71
 
71
72
  fetchEventSource(streamUrl, {
72
73
  method: 'GET',
@@ -1,76 +1,145 @@
1
1
  /**
2
2
  * Consultations Hooks
3
- *
3
+ *
4
4
  * React Query hooks for consultation 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
- import { consultationService } from '../services/consultation.service'
8
+ import {
9
+ getConsultations,
10
+ getConsultation,
11
+ createConsultation,
12
+ sendMessage,
13
+ acceptQuote,
14
+ rejectQuote,
15
+ } from '../services/consultation.service'
16
+ import type { SdkConfig } from '../config'
8
17
  import type {
9
- Consultation,
10
18
  ConsultationCreatePayload,
11
19
  ConsultationMessagePayload,
12
20
  ConsultationQuoteAcceptPayload,
13
21
  } from '../types/consultations'
22
+ import { logger } from '../utils'
23
+ import { useSdkContext, resolveHookArgs } from '../context/sdk-context'
14
24
 
15
- export function useConsultations() {
16
- return useQuery({
17
- queryKey: ['consultations'],
18
- queryFn: () => consultationService.getConsultations(),
19
- })
25
+ export function useConsultations(config?: SdkConfig, accessToken?: string | null) {
26
+ const ctx = useSdkContext()
27
+ try {
28
+ const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
29
+ return useQuery({
30
+ queryKey: ['consultations'],
31
+ queryFn: () => token ? getConsultations(cfg, token) : Promise.resolve([]),
32
+ enabled: !!token,
33
+ })
34
+ } catch (error) {
35
+ logger.warn('[useConsultations] Called outside QueryClientProvider, returning empty list')
36
+ return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
37
+ }
20
38
  }
21
39
 
22
- export function useConsultation(id: string) {
23
- return useQuery({
24
- queryKey: ['consultation', id],
25
- queryFn: () => consultationService.getConsultation(id),
26
- enabled: !!id,
27
- })
28
- }
40
+ export function useConsultation(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
41
+ const ctx = useSdkContext()
42
+ const isArg1Config = typeof arg1 === 'object' && arg1 !== null
43
+ const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
44
+ const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
45
+ const id = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
29
46
 
30
- export function useCreateConsultation() {
31
- const queryClient = useQueryClient()
47
+ try {
48
+ const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
49
+ return useQuery({
50
+ queryKey: ['consultation', id],
51
+ queryFn: () => token && id ? getConsultation(cfg, token, id) : Promise.resolve(undefined),
52
+ enabled: !!id && !!token,
53
+ })
54
+ } catch (error) {
55
+ logger.warn('[useConsultation] Called outside QueryClientProvider, returning undefined')
56
+ return { data: undefined, isLoading: false, error: null, isFetching: false, refetch: () => Promise.resolve({ data: undefined }) } as any
57
+ }
58
+ }
32
59
 
33
- return useMutation({
34
- mutationFn: (payload: ConsultationCreatePayload) =>
35
- consultationService.createConsultation(payload),
36
- onSuccess: () => {
37
- queryClient.invalidateQueries({ queryKey: ['consultations'] })
38
- },
39
- })
60
+ export function useCreateConsultation(config?: SdkConfig, accessToken?: string | null) {
61
+ const ctx = useSdkContext()
62
+ try {
63
+ const { config: cfg, accessToken: token } = resolveHookArgs(config, accessToken, ctx)
64
+ const queryClient = useQueryClient()
65
+ return useMutation({
66
+ mutationFn: (payload: ConsultationCreatePayload) =>
67
+ token ? createConsultation(cfg, token, payload) : Promise.reject('No access token'),
68
+ onSuccess: () => {
69
+ queryClient.invalidateQueries({ queryKey: ['consultations'] })
70
+ },
71
+ })
72
+ } catch (error) {
73
+ logger.warn('[useCreateConsultation] Called outside QueryClientProvider, returning no-op mutation')
74
+ return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
75
+ }
40
76
  }
41
77
 
42
- export function useSendMessage(consultationId: string) {
43
- const queryClient = useQueryClient()
78
+ export function useSendMessage(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
79
+ const ctx = useSdkContext()
80
+ const isArg1Config = typeof arg1 === 'object' && arg1 !== null
81
+ const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
82
+ const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
83
+ const consultationId = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
44
84
 
45
- return useMutation({
46
- mutationFn: (payload: ConsultationMessagePayload) =>
47
- consultationService.sendMessage(consultationId, payload),
48
- onSuccess: () => {
49
- queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
50
- },
51
- })
85
+ try {
86
+ const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
87
+ const queryClient = useQueryClient()
88
+ return useMutation({
89
+ mutationFn: (payload: ConsultationMessagePayload) =>
90
+ token && consultationId ? sendMessage(cfg, token, consultationId, payload) : Promise.reject('No access token'),
91
+ onSuccess: () => {
92
+ queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
93
+ },
94
+ })
95
+ } catch (error) {
96
+ logger.warn('[useSendMessage] Called outside QueryClientProvider, returning no-op mutation')
97
+ return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
98
+ }
52
99
  }
53
100
 
54
- export function useAcceptQuote(consultationId: string) {
55
- const queryClient = useQueryClient()
101
+ export function useAcceptQuote(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
102
+ const ctx = useSdkContext()
103
+ const isArg1Config = typeof arg1 === 'object' && arg1 !== null
104
+ const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
105
+ const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
106
+ const consultationId = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
56
107
 
57
- return useMutation({
58
- mutationFn: (payload: ConsultationQuoteAcceptPayload) =>
59
- consultationService.acceptQuote(consultationId, payload),
60
- onSuccess: () => {
61
- queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
62
- },
63
- })
108
+ try {
109
+ const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
110
+ const queryClient = useQueryClient()
111
+ return useMutation({
112
+ mutationFn: (payload: ConsultationQuoteAcceptPayload) =>
113
+ token && consultationId ? acceptQuote(cfg, token, consultationId, payload) : Promise.reject('No access token'),
114
+ onSuccess: () => {
115
+ queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
116
+ },
117
+ })
118
+ } catch (error) {
119
+ logger.warn('[useAcceptQuote] Called outside QueryClientProvider, returning no-op mutation')
120
+ return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
121
+ }
64
122
  }
65
123
 
66
- export function useRejectQuote(consultationId: string) {
67
- const queryClient = useQueryClient()
124
+ export function useRejectQuote(arg1?: SdkConfig | string, arg2?: string | null, arg3?: string) {
125
+ const ctx = useSdkContext()
126
+ const isArg1Config = typeof arg1 === 'object' && arg1 !== null
127
+ const explicitConfig = isArg1Config ? (arg1 as SdkConfig) : undefined
128
+ const explicitToken = isArg1Config ? (arg2 as string | null) : undefined
129
+ const consultationId = isArg1Config ? arg3 : (typeof arg1 === 'string' ? arg1 : undefined)
68
130
 
69
- return useMutation({
70
- mutationFn: (reason?: string) =>
71
- consultationService.rejectQuote(consultationId, reason),
72
- onSuccess: () => {
73
- queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
74
- },
75
- })
131
+ try {
132
+ const { config: cfg, accessToken: token } = resolveHookArgs(explicitConfig, explicitToken, ctx)
133
+ const queryClient = useQueryClient()
134
+ return useMutation({
135
+ mutationFn: (reason?: string) =>
136
+ token && consultationId ? rejectQuote(cfg, token, consultationId, reason) : Promise.reject('No access token'),
137
+ onSuccess: () => {
138
+ queryClient.invalidateQueries({ queryKey: ['consultation', consultationId] })
139
+ },
140
+ })
141
+ } catch (error) {
142
+ logger.warn('[useRejectQuote] Called outside QueryClientProvider, returning no-op mutation')
143
+ return { mutate: () => {}, mutateAsync: () => Promise.resolve(undefined) } as any
144
+ }
76
145
  }