@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.
- package/dist/hooks/index.d.mts +429 -0
- package/dist/hooks/index.d.ts +429 -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.d.mts +250 -1161
- package/dist/index.d.ts +250 -1161
- 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-Cy51kEKT.d.mts +565 -0
- package/dist/sdk-context-Cy51kEKT.d.ts +565 -0
- package/package.json +6 -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
|
@@ -2,12 +2,24 @@
|
|
|
2
2
|
* Product Service
|
|
3
3
|
*
|
|
4
4
|
* Handles product operations using GraphQL.
|
|
5
|
+
* Stateless - all configuration passed as parameters.
|
|
5
6
|
*/
|
|
6
|
-
import {
|
|
7
|
+
import { GraphQLClient } from 'graphql-request'
|
|
7
8
|
import type { Product, PaginatedResponse, ListParams } from '../types/store'
|
|
9
|
+
import type { SdkConfig } from '../config'
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Create GraphQL client with provided config
|
|
13
|
+
*/
|
|
14
|
+
function createGraphQLClient(config: SdkConfig): GraphQLClient {
|
|
15
|
+
const headers: Record<string, string> = {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
'Accept': 'application/json',
|
|
18
|
+
'X-Storefront-Key': config.storefrontApiKey,
|
|
19
|
+
'X-Business-ID': config.businessId,
|
|
20
|
+
}
|
|
21
|
+
return new GraphQLClient(`${config.backendUrls.store}/graphql`, { headers })
|
|
22
|
+
}
|
|
11
23
|
|
|
12
24
|
const GET_STOREFRONT_PRODUCTS = `
|
|
13
25
|
query GetStorefrontProducts($page: Int!, $pageSize: Int!, $collectionSlug: String, $search: String) {
|
|
@@ -25,7 +37,7 @@ const GET_STOREFRONT_PRODUCTS = `
|
|
|
25
37
|
is_bespoke
|
|
26
38
|
base_price
|
|
27
39
|
currency
|
|
28
|
-
images
|
|
40
|
+
images
|
|
29
41
|
tags
|
|
30
42
|
custom_fields { label unit required }
|
|
31
43
|
is_published
|
|
@@ -48,7 +60,7 @@ const GET_STOREFRONT_PRODUCTS = `
|
|
|
48
60
|
sku
|
|
49
61
|
attributes
|
|
50
62
|
price
|
|
51
|
-
images
|
|
63
|
+
images
|
|
52
64
|
weight_kg
|
|
53
65
|
is_active
|
|
54
66
|
inventory {
|
|
@@ -75,7 +87,7 @@ const GET_STOREFRONT_PRODUCTS = `
|
|
|
75
87
|
name
|
|
76
88
|
slug
|
|
77
89
|
description
|
|
78
|
-
image
|
|
90
|
+
image
|
|
79
91
|
collection_type
|
|
80
92
|
rules
|
|
81
93
|
status
|
|
@@ -107,7 +119,7 @@ const GET_STOREFRONT_PRODUCT_BY_SLUG = `
|
|
|
107
119
|
is_bespoke
|
|
108
120
|
base_price
|
|
109
121
|
currency
|
|
110
|
-
images
|
|
122
|
+
images
|
|
111
123
|
tags
|
|
112
124
|
custom_fields { label unit required }
|
|
113
125
|
is_published
|
|
@@ -130,7 +142,7 @@ const GET_STOREFRONT_PRODUCT_BY_SLUG = `
|
|
|
130
142
|
sku
|
|
131
143
|
attributes
|
|
132
144
|
price
|
|
133
|
-
images
|
|
145
|
+
images
|
|
134
146
|
weight_kg
|
|
135
147
|
is_active
|
|
136
148
|
inventory {
|
|
@@ -157,7 +169,7 @@ const GET_STOREFRONT_PRODUCT_BY_SLUG = `
|
|
|
157
169
|
name
|
|
158
170
|
slug
|
|
159
171
|
description
|
|
160
|
-
image
|
|
172
|
+
image
|
|
161
173
|
collection_type
|
|
162
174
|
rules
|
|
163
175
|
status
|
|
@@ -185,7 +197,7 @@ const GET_STOREFRONT_LATEST = `
|
|
|
185
197
|
is_bespoke
|
|
186
198
|
base_price
|
|
187
199
|
currency
|
|
188
|
-
images
|
|
200
|
+
images
|
|
189
201
|
tags
|
|
190
202
|
custom_fields { label unit required }
|
|
191
203
|
is_published
|
|
@@ -208,7 +220,7 @@ const GET_STOREFRONT_LATEST = `
|
|
|
208
220
|
sku
|
|
209
221
|
attributes
|
|
210
222
|
price
|
|
211
|
-
images
|
|
223
|
+
images
|
|
212
224
|
weight_kg
|
|
213
225
|
is_active
|
|
214
226
|
inventory {
|
|
@@ -235,7 +247,7 @@ const GET_STOREFRONT_LATEST = `
|
|
|
235
247
|
name
|
|
236
248
|
slug
|
|
237
249
|
description
|
|
238
|
-
image
|
|
250
|
+
image
|
|
239
251
|
collection_type
|
|
240
252
|
rules
|
|
241
253
|
status
|
|
@@ -268,7 +280,7 @@ const GET_STOREFRONT_POPULAR = `
|
|
|
268
280
|
is_bespoke
|
|
269
281
|
base_price
|
|
270
282
|
currency
|
|
271
|
-
images
|
|
283
|
+
images
|
|
272
284
|
tags
|
|
273
285
|
custom_fields { label unit required }
|
|
274
286
|
is_published
|
|
@@ -291,7 +303,7 @@ const GET_STOREFRONT_POPULAR = `
|
|
|
291
303
|
sku
|
|
292
304
|
attributes
|
|
293
305
|
price
|
|
294
|
-
images
|
|
306
|
+
images
|
|
295
307
|
weight_kg
|
|
296
308
|
is_active
|
|
297
309
|
inventory {
|
|
@@ -318,7 +330,7 @@ const GET_STOREFRONT_POPULAR = `
|
|
|
318
330
|
name
|
|
319
331
|
slug
|
|
320
332
|
description
|
|
321
|
-
image
|
|
333
|
+
image
|
|
322
334
|
collection_type
|
|
323
335
|
rules
|
|
324
336
|
status
|
|
@@ -351,7 +363,7 @@ const GET_STOREFRONT_FEATURED = `
|
|
|
351
363
|
is_bespoke
|
|
352
364
|
base_price
|
|
353
365
|
currency
|
|
354
|
-
images
|
|
366
|
+
images
|
|
355
367
|
tags
|
|
356
368
|
custom_fields { label unit required }
|
|
357
369
|
is_published
|
|
@@ -374,7 +386,7 @@ const GET_STOREFRONT_FEATURED = `
|
|
|
374
386
|
sku
|
|
375
387
|
attributes
|
|
376
388
|
price
|
|
377
|
-
images
|
|
389
|
+
images
|
|
378
390
|
weight_kg
|
|
379
391
|
is_active
|
|
380
392
|
inventory {
|
|
@@ -401,7 +413,7 @@ const GET_STOREFRONT_FEATURED = `
|
|
|
401
413
|
name
|
|
402
414
|
slug
|
|
403
415
|
description
|
|
404
|
-
image
|
|
416
|
+
image
|
|
405
417
|
collection_type
|
|
406
418
|
rules
|
|
407
419
|
status
|
|
@@ -434,7 +446,96 @@ const GET_STOREFRONT_NEW = `
|
|
|
434
446
|
is_bespoke
|
|
435
447
|
base_price
|
|
436
448
|
currency
|
|
437
|
-
|
|
449
|
+
sale_price
|
|
450
|
+
sale_start
|
|
451
|
+
sale_end
|
|
452
|
+
images
|
|
453
|
+
tags
|
|
454
|
+
custom_fields { label unit required }
|
|
455
|
+
is_published
|
|
456
|
+
is_featured
|
|
457
|
+
is_popular
|
|
458
|
+
is_new
|
|
459
|
+
is_temporary
|
|
460
|
+
digital_file_key
|
|
461
|
+
download_limit
|
|
462
|
+
download_expires_at
|
|
463
|
+
weight_kg
|
|
464
|
+
length_cm
|
|
465
|
+
width_cm
|
|
466
|
+
height_cm
|
|
467
|
+
created_at
|
|
468
|
+
updated_at
|
|
469
|
+
variants {
|
|
470
|
+
id
|
|
471
|
+
product_id
|
|
472
|
+
sku
|
|
473
|
+
attributes
|
|
474
|
+
price
|
|
475
|
+
images
|
|
476
|
+
weight_kg
|
|
477
|
+
is_active
|
|
478
|
+
inventory {
|
|
479
|
+
id
|
|
480
|
+
product_id
|
|
481
|
+
variant_id
|
|
482
|
+
quantity
|
|
483
|
+
reserved
|
|
484
|
+
reorder_point
|
|
485
|
+
reorder_quantity
|
|
486
|
+
track_quantity
|
|
487
|
+
allow_backorder
|
|
488
|
+
available
|
|
489
|
+
is_in_stock
|
|
490
|
+
is_low_stock
|
|
491
|
+
updated_at
|
|
492
|
+
}
|
|
493
|
+
created_at
|
|
494
|
+
updated_at
|
|
495
|
+
}
|
|
496
|
+
collections {
|
|
497
|
+
id
|
|
498
|
+
business_id
|
|
499
|
+
name
|
|
500
|
+
slug
|
|
501
|
+
description
|
|
502
|
+
image
|
|
503
|
+
collection_type
|
|
504
|
+
rules
|
|
505
|
+
status
|
|
506
|
+
sort_order
|
|
507
|
+
created_at
|
|
508
|
+
updated_at
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
total
|
|
512
|
+
page
|
|
513
|
+
page_size
|
|
514
|
+
total_pages
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
`
|
|
518
|
+
|
|
519
|
+
const GET_STOREFRONT_ON_SALE = `
|
|
520
|
+
query GetStorefrontOnSale($page: Int!, $pageSize: Int!) {
|
|
521
|
+
storefront_on_sale(page: $page, pageSize: $pageSize) {
|
|
522
|
+
items {
|
|
523
|
+
id
|
|
524
|
+
business_id
|
|
525
|
+
name
|
|
526
|
+
slug
|
|
527
|
+
description
|
|
528
|
+
brand
|
|
529
|
+
product_type
|
|
530
|
+
requires_shipping
|
|
531
|
+
is_consumable
|
|
532
|
+
is_bespoke
|
|
533
|
+
base_price
|
|
534
|
+
currency
|
|
535
|
+
sale_price
|
|
536
|
+
sale_start
|
|
537
|
+
sale_end
|
|
538
|
+
images
|
|
438
539
|
tags
|
|
439
540
|
custom_fields { label unit required }
|
|
440
541
|
is_published
|
|
@@ -457,7 +558,7 @@ const GET_STOREFRONT_NEW = `
|
|
|
457
558
|
sku
|
|
458
559
|
attributes
|
|
459
560
|
price
|
|
460
|
-
images
|
|
561
|
+
images
|
|
461
562
|
weight_kg
|
|
462
563
|
is_active
|
|
463
564
|
inventory {
|
|
@@ -484,7 +585,93 @@ const GET_STOREFRONT_NEW = `
|
|
|
484
585
|
name
|
|
485
586
|
slug
|
|
486
587
|
description
|
|
487
|
-
image
|
|
588
|
+
image
|
|
589
|
+
collection_type
|
|
590
|
+
rules
|
|
591
|
+
status
|
|
592
|
+
sort_order
|
|
593
|
+
created_at
|
|
594
|
+
updated_at
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
total
|
|
598
|
+
page
|
|
599
|
+
page_size
|
|
600
|
+
total_pages
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
`
|
|
604
|
+
|
|
605
|
+
const GET_STOREFRONT_LOW_STOCK = `
|
|
606
|
+
query GetStorefrontLowStock($page: Int!, $pageSize: Int!) {
|
|
607
|
+
storefront_low_stock(page: $page, pageSize: $pageSize) {
|
|
608
|
+
items {
|
|
609
|
+
id
|
|
610
|
+
business_id
|
|
611
|
+
name
|
|
612
|
+
slug
|
|
613
|
+
description
|
|
614
|
+
brand
|
|
615
|
+
product_type
|
|
616
|
+
requires_shipping
|
|
617
|
+
is_consumable
|
|
618
|
+
is_bespoke
|
|
619
|
+
base_price
|
|
620
|
+
currency
|
|
621
|
+
sale_price
|
|
622
|
+
sale_start
|
|
623
|
+
sale_end
|
|
624
|
+
images
|
|
625
|
+
tags
|
|
626
|
+
custom_fields { label unit required }
|
|
627
|
+
is_published
|
|
628
|
+
is_featured
|
|
629
|
+
is_popular
|
|
630
|
+
is_new
|
|
631
|
+
is_temporary
|
|
632
|
+
digital_file_key
|
|
633
|
+
download_limit
|
|
634
|
+
download_expires_at
|
|
635
|
+
weight_kg
|
|
636
|
+
length_cm
|
|
637
|
+
width_cm
|
|
638
|
+
height_cm
|
|
639
|
+
created_at
|
|
640
|
+
updated_at
|
|
641
|
+
variants {
|
|
642
|
+
id
|
|
643
|
+
product_id
|
|
644
|
+
sku
|
|
645
|
+
attributes
|
|
646
|
+
price
|
|
647
|
+
images
|
|
648
|
+
weight_kg
|
|
649
|
+
is_active
|
|
650
|
+
inventory {
|
|
651
|
+
id
|
|
652
|
+
product_id
|
|
653
|
+
variant_id
|
|
654
|
+
quantity
|
|
655
|
+
reserved
|
|
656
|
+
reorder_point
|
|
657
|
+
reorder_quantity
|
|
658
|
+
track_quantity
|
|
659
|
+
allow_backorder
|
|
660
|
+
available
|
|
661
|
+
is_in_stock
|
|
662
|
+
is_low_stock
|
|
663
|
+
updated_at
|
|
664
|
+
}
|
|
665
|
+
created_at
|
|
666
|
+
updated_at
|
|
667
|
+
}
|
|
668
|
+
collections {
|
|
669
|
+
id
|
|
670
|
+
business_id
|
|
671
|
+
name
|
|
672
|
+
slug
|
|
673
|
+
description
|
|
674
|
+
image
|
|
488
675
|
collection_type
|
|
489
676
|
rules
|
|
490
677
|
status
|
|
@@ -517,7 +704,7 @@ const GET_STOREFRONT_RECOMMENDED = `
|
|
|
517
704
|
is_bespoke
|
|
518
705
|
base_price
|
|
519
706
|
currency
|
|
520
|
-
images
|
|
707
|
+
images
|
|
521
708
|
tags
|
|
522
709
|
custom_fields { label unit required }
|
|
523
710
|
is_published
|
|
@@ -540,7 +727,7 @@ const GET_STOREFRONT_RECOMMENDED = `
|
|
|
540
727
|
sku
|
|
541
728
|
attributes
|
|
542
729
|
price
|
|
543
|
-
images
|
|
730
|
+
images
|
|
544
731
|
weight_kg
|
|
545
732
|
is_active
|
|
546
733
|
inventory {
|
|
@@ -567,7 +754,7 @@ const GET_STOREFRONT_RECOMMENDED = `
|
|
|
567
754
|
name
|
|
568
755
|
slug
|
|
569
756
|
description
|
|
570
|
-
image
|
|
757
|
+
image
|
|
571
758
|
collection_type
|
|
572
759
|
rules
|
|
573
760
|
status
|
|
@@ -587,8 +774,11 @@ const GET_STOREFRONT_RECOMMENDED = `
|
|
|
587
774
|
/**
|
|
588
775
|
* Fetch all active products for the storefront.
|
|
589
776
|
*/
|
|
590
|
-
export async function getStorefrontProducts(
|
|
591
|
-
|
|
777
|
+
export async function getStorefrontProducts(
|
|
778
|
+
config: SdkConfig,
|
|
779
|
+
params?: ListParams
|
|
780
|
+
): Promise<PaginatedResponse<Product>> {
|
|
781
|
+
const client = createGraphQLClient(config)
|
|
592
782
|
const variables = {
|
|
593
783
|
page: params?.page || 1,
|
|
594
784
|
pageSize: params?.pageSize || 20,
|
|
@@ -602,8 +792,11 @@ export async function getStorefrontProducts(params?: ListParams): Promise<Pagina
|
|
|
602
792
|
/**
|
|
603
793
|
* Fetch a single product by slug for the storefront.
|
|
604
794
|
*/
|
|
605
|
-
export async function getStorefrontProductBySlug(
|
|
606
|
-
|
|
795
|
+
export async function getStorefrontProductBySlug(
|
|
796
|
+
config: SdkConfig,
|
|
797
|
+
slug: string
|
|
798
|
+
): Promise<Product> {
|
|
799
|
+
const client = createGraphQLClient(config)
|
|
607
800
|
const data = await client.request(GET_STOREFRONT_PRODUCT_BY_SLUG, { slug })
|
|
608
801
|
return data.storefront_product_by_slug
|
|
609
802
|
}
|
|
@@ -611,8 +804,11 @@ export async function getStorefrontProductBySlug(slug: string): Promise<Product>
|
|
|
611
804
|
/**
|
|
612
805
|
* Fetch latest products for the storefront.
|
|
613
806
|
*/
|
|
614
|
-
export async function getLatestProducts(
|
|
615
|
-
|
|
807
|
+
export async function getLatestProducts(
|
|
808
|
+
config: SdkConfig,
|
|
809
|
+
params?: ListParams
|
|
810
|
+
): Promise<PaginatedResponse<Product>> {
|
|
811
|
+
const client = createGraphQLClient(config)
|
|
616
812
|
const variables = {
|
|
617
813
|
page: params?.page || 1,
|
|
618
814
|
pageSize: params?.pageSize || 4,
|
|
@@ -624,8 +820,11 @@ export async function getLatestProducts(params?: ListParams): Promise<PaginatedR
|
|
|
624
820
|
/**
|
|
625
821
|
* Fetch popular products for the storefront.
|
|
626
822
|
*/
|
|
627
|
-
export async function getPopularProducts(
|
|
628
|
-
|
|
823
|
+
export async function getPopularProducts(
|
|
824
|
+
config: SdkConfig,
|
|
825
|
+
params?: ListParams
|
|
826
|
+
): Promise<PaginatedResponse<Product>> {
|
|
827
|
+
const client = createGraphQLClient(config)
|
|
629
828
|
const variables = {
|
|
630
829
|
page: params?.page || 1,
|
|
631
830
|
pageSize: params?.pageSize || 4,
|
|
@@ -637,8 +836,11 @@ export async function getPopularProducts(params?: ListParams): Promise<Paginated
|
|
|
637
836
|
/**
|
|
638
837
|
* Fetch featured products for the storefront.
|
|
639
838
|
*/
|
|
640
|
-
export async function getFeaturedProducts(
|
|
641
|
-
|
|
839
|
+
export async function getFeaturedProducts(
|
|
840
|
+
config: SdkConfig,
|
|
841
|
+
params?: ListParams
|
|
842
|
+
): Promise<PaginatedResponse<Product>> {
|
|
843
|
+
const client = createGraphQLClient(config)
|
|
642
844
|
const variables = {
|
|
643
845
|
page: params?.page || 1,
|
|
644
846
|
pageSize: params?.pageSize || 4,
|
|
@@ -650,8 +852,11 @@ export async function getFeaturedProducts(params?: ListParams): Promise<Paginate
|
|
|
650
852
|
/**
|
|
651
853
|
* Fetch new products for the storefront.
|
|
652
854
|
*/
|
|
653
|
-
export async function getNewProducts(
|
|
654
|
-
|
|
855
|
+
export async function getNewProducts(
|
|
856
|
+
config: SdkConfig,
|
|
857
|
+
params?: ListParams
|
|
858
|
+
): Promise<PaginatedResponse<Product>> {
|
|
859
|
+
const client = createGraphQLClient(config)
|
|
655
860
|
const variables = {
|
|
656
861
|
page: params?.page || 1,
|
|
657
862
|
pageSize: params?.pageSize || 4,
|
|
@@ -660,13 +865,48 @@ export async function getNewProducts(params?: ListParams): Promise<PaginatedResp
|
|
|
660
865
|
return data.storefront_new
|
|
661
866
|
}
|
|
662
867
|
|
|
868
|
+
/**
|
|
869
|
+
* Fetch products currently on sale for the storefront.
|
|
870
|
+
*/
|
|
871
|
+
export async function getOnSaleProducts(
|
|
872
|
+
config: SdkConfig,
|
|
873
|
+
params?: ListParams
|
|
874
|
+
): Promise<PaginatedResponse<Product>> {
|
|
875
|
+
const client = createGraphQLClient(config)
|
|
876
|
+
const variables = {
|
|
877
|
+
page: params?.page || 1,
|
|
878
|
+
pageSize: params?.pageSize || 4,
|
|
879
|
+
}
|
|
880
|
+
const data = await client.request(GET_STOREFRONT_ON_SALE, variables)
|
|
881
|
+
return data.storefront_on_sale
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Fetch products with low stock for the storefront.
|
|
886
|
+
*/
|
|
887
|
+
export async function getLowStockProducts(
|
|
888
|
+
config: SdkConfig,
|
|
889
|
+
params?: ListParams
|
|
890
|
+
): Promise<PaginatedResponse<Product>> {
|
|
891
|
+
const client = createGraphQLClient(config)
|
|
892
|
+
const variables = {
|
|
893
|
+
page: params?.page || 1,
|
|
894
|
+
pageSize: params?.pageSize || 4,
|
|
895
|
+
}
|
|
896
|
+
const data = await client.request(GET_STOREFRONT_LOW_STOCK, variables)
|
|
897
|
+
return data.storefront_low_stock
|
|
898
|
+
}
|
|
899
|
+
|
|
663
900
|
/**
|
|
664
901
|
* Fetch recommended products for the storefront.
|
|
665
902
|
* Returns featured, popular, and new products.
|
|
666
903
|
* Optionally excludes a specific product ID.
|
|
667
904
|
*/
|
|
668
|
-
export async function getRecommendedProducts(
|
|
669
|
-
|
|
905
|
+
export async function getRecommendedProducts(
|
|
906
|
+
config: SdkConfig,
|
|
907
|
+
params?: ListParams & { excludeProductId?: string }
|
|
908
|
+
): Promise<PaginatedResponse<Product>> {
|
|
909
|
+
const client = createGraphQLClient(config)
|
|
670
910
|
const variables = {
|
|
671
911
|
page: params?.page || 1,
|
|
672
912
|
pageSize: params?.pageSize || 4,
|
|
@@ -675,4 +915,4 @@ export async function getRecommendedProducts(params?: ListParams & { excludeProd
|
|
|
675
915
|
const data = await client.request(GET_STOREFRONT_RECOMMENDED, variables)
|
|
676
916
|
return data.storefront_recommended
|
|
677
917
|
}
|
|
678
|
-
|
|
918
|
+
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Service Booking Service
|
|
3
3
|
*
|
|
4
4
|
* Handles service appointments and deliverables.
|
|
5
|
+
* Stateless - all configuration passed as parameters.
|
|
5
6
|
*/
|
|
6
|
-
import {
|
|
7
|
+
import type { SdkConfig } from '../config'
|
|
7
8
|
import type {
|
|
8
9
|
ServiceAppointment,
|
|
9
10
|
ServiceAppointmentCreatePayload,
|
|
@@ -13,64 +14,135 @@ import type {
|
|
|
13
14
|
} from '../types/services'
|
|
14
15
|
|
|
15
16
|
export async function getAvailableSlots(
|
|
17
|
+
config: SdkConfig,
|
|
16
18
|
product_id: string,
|
|
17
19
|
date_from: string,
|
|
18
20
|
date_to: string
|
|
19
21
|
): Promise<AvailableSlot[]> {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
{
|
|
22
|
+
const response = await fetch(
|
|
23
|
+
`${config.backendUrls.store}/service/available-slots/${product_id}?date_from=${date_from}&date_to=${date_to}`,
|
|
24
|
+
{
|
|
25
|
+
headers: {
|
|
26
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
27
|
+
"X-Business-ID": config.businessId,
|
|
28
|
+
},
|
|
29
|
+
}
|
|
23
30
|
)
|
|
24
|
-
|
|
31
|
+
if (!response.ok) throw new Error('Failed to get available slots')
|
|
32
|
+
return response.json()
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
export async function bookAppointment(
|
|
36
|
+
config: SdkConfig,
|
|
37
|
+
accessToken: string,
|
|
28
38
|
payload: ServiceAppointmentCreatePayload
|
|
29
39
|
): Promise<ServiceAppointment> {
|
|
30
|
-
const
|
|
31
|
-
|
|
40
|
+
const response = await fetch(`${config.backendUrls.store}/service/appointments/`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: {
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
45
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
46
|
+
"X-Business-ID": config.businessId,
|
|
47
|
+
},
|
|
48
|
+
body: JSON.stringify(payload),
|
|
49
|
+
})
|
|
50
|
+
if (!response.ok) throw new Error('Failed to book appointment')
|
|
51
|
+
return response.json()
|
|
32
52
|
}
|
|
33
53
|
|
|
34
|
-
export async function getAppointments(): Promise<ServiceAppointment[]> {
|
|
35
|
-
const
|
|
36
|
-
|
|
54
|
+
export async function getAppointments(config: SdkConfig, accessToken: string): Promise<ServiceAppointment[]> {
|
|
55
|
+
const response = await fetch(`${config.backendUrls.store}/service/bookings/my`, {
|
|
56
|
+
headers: {
|
|
57
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
58
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
59
|
+
"X-Business-ID": config.businessId,
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
if (!response.ok) throw new Error('Failed to get appointments')
|
|
63
|
+
return response.json()
|
|
37
64
|
}
|
|
38
65
|
|
|
39
|
-
export async function getAppointment(id: string): Promise<ServiceAppointment> {
|
|
40
|
-
const
|
|
41
|
-
|
|
66
|
+
export async function getAppointment(config: SdkConfig, accessToken: string, id: string): Promise<ServiceAppointment> {
|
|
67
|
+
const response = await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {
|
|
68
|
+
headers: {
|
|
69
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
70
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
71
|
+
"X-Business-ID": config.businessId,
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
if (!response.ok) throw new Error('Failed to get appointment')
|
|
75
|
+
return response.json()
|
|
42
76
|
}
|
|
43
77
|
|
|
44
|
-
export async function cancelAppointment(id: string): Promise<void> {
|
|
45
|
-
await
|
|
78
|
+
export async function cancelAppointment(config: SdkConfig, accessToken: string, id: string): Promise<void> {
|
|
79
|
+
await fetch(`${config.backendUrls.store}/service/bookings/${id}`, {
|
|
80
|
+
method: 'DELETE',
|
|
81
|
+
headers: {
|
|
82
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
83
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
84
|
+
"X-Business-ID": config.businessId,
|
|
85
|
+
},
|
|
86
|
+
})
|
|
46
87
|
}
|
|
47
88
|
|
|
48
|
-
export async function getDeliverables(order_id: string): Promise<ServiceDeliverable[]> {
|
|
49
|
-
const
|
|
50
|
-
|
|
89
|
+
export async function getDeliverables(config: SdkConfig, accessToken: string, order_id: string): Promise<ServiceDeliverable[]> {
|
|
90
|
+
const response = await fetch(`${config.backendUrls.store}/service/projects/${order_id}/deliverables/`, {
|
|
91
|
+
headers: {
|
|
92
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
93
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
94
|
+
"X-Business-ID": config.businessId,
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
if (!response.ok) throw new Error('Failed to get deliverables')
|
|
98
|
+
return response.json()
|
|
51
99
|
}
|
|
52
100
|
|
|
53
101
|
export async function approveDeliverable(
|
|
102
|
+
config: SdkConfig,
|
|
103
|
+
accessToken: string,
|
|
54
104
|
order_id: string,
|
|
55
105
|
deliverable_id: string
|
|
56
106
|
): Promise<ServiceDeliverable> {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
{
|
|
107
|
+
const response = await fetch(
|
|
108
|
+
`${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/approve`,
|
|
109
|
+
{
|
|
110
|
+
method: 'POST',
|
|
111
|
+
headers: {
|
|
112
|
+
'Content-Type': 'application/json',
|
|
113
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
114
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
115
|
+
"X-Business-ID": config.businessId,
|
|
116
|
+
},
|
|
117
|
+
body: JSON.stringify({ approved: true }),
|
|
118
|
+
}
|
|
60
119
|
)
|
|
61
|
-
|
|
120
|
+
if (!response.ok) throw new Error('Failed to approve deliverable')
|
|
121
|
+
return response.json()
|
|
62
122
|
}
|
|
63
123
|
|
|
64
124
|
export async function requestRevision(
|
|
125
|
+
config: SdkConfig,
|
|
126
|
+
accessToken: string,
|
|
65
127
|
order_id: string,
|
|
66
128
|
deliverable_id: string,
|
|
67
129
|
feedback: string
|
|
68
130
|
): Promise<ServiceDeliverable> {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
{
|
|
131
|
+
const response = await fetch(
|
|
132
|
+
`${config.backendUrls.store}/service/projects/${order_id}/deliverables/${deliverable_id}/revision`,
|
|
133
|
+
{
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
138
|
+
"X-Storefront-Key": config.storefrontApiKey,
|
|
139
|
+
"X-Business-ID": config.businessId,
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify({ approved: false, feedback }),
|
|
142
|
+
}
|
|
72
143
|
)
|
|
73
|
-
|
|
144
|
+
if (!response.ok) throw new Error('Failed to request revision')
|
|
145
|
+
return response.json()
|
|
74
146
|
}
|
|
75
147
|
|
|
76
148
|
// Service object export for backward compatibility
|