@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
@@ -0,0 +1,565 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Shipping and delivery types for the storefront
5
+ */
6
+ interface ShippingRate {
7
+ id: string;
8
+ carrier_name: string;
9
+ carrier_logo: string;
10
+ carrier_rate_description: string;
11
+ carrier_slug: string;
12
+ amount: number;
13
+ currency: string;
14
+ delivery_time: string;
15
+ delivery_eta: number;
16
+ pickup_time: string;
17
+ pickup_eta: number;
18
+ pickup_available: boolean;
19
+ dropoff_available?: boolean;
20
+ dropoff_required?: boolean;
21
+ }
22
+ interface ShippingRatesResponse {
23
+ status: boolean;
24
+ message: string;
25
+ data: ShippingRate[];
26
+ }
27
+ interface DeliveryAddress {
28
+ first_name: string;
29
+ last_name: string;
30
+ phone: string;
31
+ street: string;
32
+ city: string;
33
+ state: string;
34
+ lga: string;
35
+ country: string;
36
+ postal: string;
37
+ }
38
+
39
+ type ProductType = "physical" | "digital" | "service" | "bespoke";
40
+ declare enum ServiceTypeEnum {
41
+ APPOINTMENT = "appointment",
42
+ PROJECT = "project",
43
+ RECURRING = "recurring"
44
+ }
45
+ type ServiceType = ServiceTypeEnum | 'appointment' | 'project' | 'recurring';
46
+ declare enum ServiceLocationTypeEnum {
47
+ REMOTE = "remote",
48
+ PHYSICAL = "physical",
49
+ BOTH = "both"
50
+ }
51
+ type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | 'physical' | 'both';
52
+ declare enum ServiceRecurringIntervalEnum {
53
+ WEEKLY = "weekly",
54
+ MONTHLY = "monthly",
55
+ YEARLY = "yearly"
56
+ }
57
+ type ServiceRecurringInterval = ServiceRecurringIntervalEnum | 'weekly' | 'monthly' | 'yearly' | '';
58
+ interface Address {
59
+ street: string;
60
+ city: string;
61
+ state: string;
62
+ country: string;
63
+ zip?: string;
64
+ }
65
+ interface Collection {
66
+ id: string;
67
+ business_id?: string;
68
+ name: string;
69
+ slug: string;
70
+ description?: string;
71
+ image?: string;
72
+ collection_type?: string;
73
+ rules?: Record<string, unknown>;
74
+ status?: string;
75
+ sort_order?: number;
76
+ created_at: string;
77
+ updated_at: string;
78
+ }
79
+ interface Inventory {
80
+ id: string;
81
+ product_id: string;
82
+ variant_id?: string;
83
+ quantity: number;
84
+ reserved: number;
85
+ reorder_point: number;
86
+ reorder_quantity: number;
87
+ track_quantity: boolean;
88
+ allow_backorder: boolean;
89
+ available: number;
90
+ is_in_stock: boolean;
91
+ is_low_stock: boolean;
92
+ updated_at: string;
93
+ }
94
+ interface ProductVariant {
95
+ id: string;
96
+ product_id: string;
97
+ sku?: string;
98
+ attributes: Record<string, string>;
99
+ price?: number;
100
+ images: string[];
101
+ weight_kg?: number;
102
+ is_active: boolean;
103
+ inventory?: Inventory;
104
+ created_at: string;
105
+ updated_at: string;
106
+ }
107
+ interface CustomField {
108
+ label: string;
109
+ unit?: string;
110
+ required: boolean;
111
+ type?: string;
112
+ key?: string;
113
+ placeholder?: string;
114
+ }
115
+ interface Product {
116
+ id: string;
117
+ business_id: string;
118
+ name: string;
119
+ slug: string;
120
+ description?: string;
121
+ brand?: string;
122
+ product_type: ProductType;
123
+ requires_shipping: boolean;
124
+ is_consumable: boolean;
125
+ is_bespoke: boolean;
126
+ is_physical?: boolean | null;
127
+ base_price: number;
128
+ currency: string;
129
+ sale_price?: number;
130
+ sale_start?: string;
131
+ sale_end?: string;
132
+ images: string[];
133
+ tags: string[];
134
+ custom_fields: CustomField[];
135
+ is_published: boolean;
136
+ is_featured: boolean;
137
+ is_popular: boolean;
138
+ is_new: boolean;
139
+ is_temporary: boolean;
140
+ digital_file_key?: string;
141
+ download_limit?: number;
142
+ download_expires_at?: string;
143
+ service_type?: ServiceType | null;
144
+ service_duration_minutes?: number | null;
145
+ service_location_type?: ServiceLocationType | null;
146
+ service_requires_consultation?: boolean;
147
+ service_max_capacity_per_slot?: number | null;
148
+ service_buffer_minutes?: number;
149
+ service_is_recurring?: boolean;
150
+ service_recurring_interval?: ServiceRecurringInterval | null;
151
+ service_project_based?: boolean;
152
+ weight_kg: number;
153
+ length_cm?: number;
154
+ width_cm?: number;
155
+ height_cm?: number;
156
+ created_at: string;
157
+ updated_at: string;
158
+ variants: ProductVariant[];
159
+ collections: Collection[];
160
+ }
161
+ interface ListParams {
162
+ page?: number;
163
+ pageSize?: number;
164
+ search?: string;
165
+ ordering?: string;
166
+ collectionSlug?: string;
167
+ excludeProductId?: string;
168
+ }
169
+ interface PaginatedResponse<T> {
170
+ items: T[];
171
+ total: number;
172
+ page: number;
173
+ page_size: number;
174
+ total_pages: number;
175
+ }
176
+ interface CartItem {
177
+ id: string;
178
+ product_id: string;
179
+ product_slug: string;
180
+ product_name: string;
181
+ image?: string;
182
+ variant_id?: string;
183
+ variant_attributes?: string | Record<string, string>;
184
+ unit_price: number;
185
+ quantity: number;
186
+ custom_measurements?: string;
187
+ is_bespoke: boolean;
188
+ created_at: string;
189
+ updated_at: string;
190
+ }
191
+ interface CartResponse {
192
+ items: CartItem[];
193
+ subtotal: number;
194
+ total: number;
195
+ item_count: number;
196
+ product_type?: string;
197
+ }
198
+ interface WishlistItem {
199
+ id: string;
200
+ product_id: string;
201
+ notes?: string;
202
+ created_at: string;
203
+ product_name?: string;
204
+ product_slug?: string;
205
+ product_price?: number;
206
+ product_image?: string;
207
+ }
208
+ interface WishlistListResponse {
209
+ items: WishlistItem[];
210
+ total: number;
211
+ page: number;
212
+ page_size: number;
213
+ total_pages: number;
214
+ }
215
+ interface WishlistCheckResponse {
216
+ in_wishlist: boolean;
217
+ }
218
+ type OrderStatus = 'pending' | 'confirmed' | 'processing' | 'packed' | 'picked_up' | 'in_transit' | 'shipped' | 'delivered' | 'voided' | 'refunded' | 'failed';
219
+ type BespokeStageKey = "received" | "development" | "finished" | "dispatched";
220
+ interface OrderItem {
221
+ id: string;
222
+ productName: string;
223
+ image: string;
224
+ quantity: number;
225
+ price: number;
226
+ }
227
+ interface Order {
228
+ id: string;
229
+ display_id?: string;
230
+ items: OrderItem[];
231
+ total: number;
232
+ status: OrderStatus;
233
+ customerEmail: string;
234
+ customerName: string;
235
+ createdAt: number;
236
+ updatedAt: number;
237
+ deliveryMethod?: string;
238
+ trackingNumber?: string;
239
+ deliveryAddress?: string;
240
+ shippingAddress?: DeliveryAddress;
241
+ cancellationReason?: string;
242
+ hasBespoke?: boolean;
243
+ bespokeStage?: BespokeStageKey;
244
+ bespokeBrief?: string;
245
+ deliveryStatus?: string;
246
+ carrierName?: string;
247
+ terminalShipmentId?: string;
248
+ guestToken?: string;
249
+ guestEmail?: string;
250
+ guestPhone?: string;
251
+ guestName?: string;
252
+ }
253
+ interface CheckoutCustomer {
254
+ first_name: string;
255
+ last_name: string;
256
+ email: string;
257
+ phone: string;
258
+ }
259
+ interface ShippingLocation {
260
+ street: string;
261
+ city: string;
262
+ state: string;
263
+ lga: string;
264
+ country: string;
265
+ postal: string;
266
+ }
267
+ interface FindOrderParams {
268
+ email: string;
269
+ order_id: string;
270
+ }
271
+ interface CreateOrderParams {
272
+ customer_id?: string | null;
273
+ status?: string;
274
+ shipping_address?: DeliveryAddress;
275
+ checkout_session_id?: string;
276
+ items: Array<{
277
+ product_id: string;
278
+ product_name: string;
279
+ quantity: number;
280
+ unit_price: number;
281
+ variant_id?: string;
282
+ variant_details?: Record<string, unknown>;
283
+ custom_measurements?: Record<string, unknown>;
284
+ }>;
285
+ delivery_method?: string;
286
+ delivery_address?: string;
287
+ total?: number;
288
+ payment_method?: string;
289
+ shipping_rate_id?: string;
290
+ guest_token?: string;
291
+ guest_email?: string;
292
+ guest_phone?: string;
293
+ guest_name?: string;
294
+ product_type?: string;
295
+ bespoke_brief?: string;
296
+ bespoke_reference_images?: string[];
297
+ bespoke_measurements?: Record<string, string>;
298
+ bespoke_preferred_timeline?: string;
299
+ bespoke_special_instructions?: string;
300
+ }
301
+
302
+ /**
303
+ * Kasuvia SDK Configuration
304
+ *
305
+ * Stateless configuration - no module-scoped state.
306
+ * All configuration is passed as parameters to SDK functions.
307
+ *
308
+ * SECURITY NOTE: Backend URLs should never be exposed to the browser.
309
+ * They should only be used on the server side or in Next.js API routes.
310
+ */
311
+ interface SdkConfig {
312
+ businessId: string;
313
+ storefrontApiKey: string;
314
+ backendUrls: {
315
+ auth: string;
316
+ store: string;
317
+ payment: string;
318
+ notifications: string;
319
+ cms: string;
320
+ };
321
+ }
322
+
323
+ type Theme = "light" | "dark";
324
+ type LangCode = "en" | "ha" | "yo" | "ig" | "fr";
325
+ interface AppState {
326
+ theme: Theme;
327
+ lang: LangCode;
328
+ currency: string;
329
+ }
330
+ interface AppContextValue extends AppState {
331
+ setTheme: (t: Theme) => void;
332
+ setLang: (l: LangCode) => void;
333
+ setCurrency: (c: string) => void;
334
+ formatPrice: (amount: number, fromCurrency?: string) => string;
335
+ resetAppState: () => void;
336
+ t: (text: string) => string;
337
+ translate: (text: string) => Promise<string>;
338
+ }
339
+ interface Country {
340
+ name: string;
341
+ code: string;
342
+ dial_code: string;
343
+ min_age: number;
344
+ }
345
+ interface State {
346
+ name: string;
347
+ code: string;
348
+ full_iso_code: string;
349
+ type: string;
350
+ }
351
+
352
+ /**
353
+ * @file types/payments/index.ts
354
+ * @description All customer-facing payment types for the Kasuvia Payment System.
355
+ *
356
+ * Auth model:
357
+ * - X-Storefront-Key → identifies the business storefront
358
+ * - X-Business-ID → tenant context
359
+ * No business-owner JWT used here — these are CUSTOMER-facing types.
360
+ *
361
+ * Payment flow:
362
+ * Customer → Business Owner : Monnify (NGN) | Flutterwave (non-NGN)
363
+ * Business Owner → Kasuvia : Subscription (separate, JWT-auth)
364
+ * Kasuvia → Business Owner : Payout (separate, JWT-auth)
365
+ */
366
+ interface Currency {
367
+ code: string;
368
+ name: string;
369
+ symbol: string;
370
+ decimals: number;
371
+ is_active: boolean;
372
+ }
373
+ interface SupportedCurrenciesResponse {
374
+ currencies: Currency[];
375
+ }
376
+ interface BackendLanguage {
377
+ code: string;
378
+ label: string;
379
+ flag: string;
380
+ }
381
+ interface SupportedLang {
382
+ code: string;
383
+ appCode: string;
384
+ label: string;
385
+ native: string;
386
+ flag: string;
387
+ }
388
+ interface SupportedLanguagesResponse {
389
+ languages: BackendLanguage[];
390
+ }
391
+ interface DVACreateRequest {
392
+ order_id?: string;
393
+ amount: number;
394
+ customer_email: string;
395
+ customer_name?: string;
396
+ /** Defaults to NGN — DVA is Monnify-only */
397
+ currency?: string;
398
+ /** Idempotency key to prevent duplicate DVA creation */
399
+ idempotency_key?: string;
400
+ }
401
+ interface PaymentInitiateRequest {
402
+ amount: number;
403
+ currency: string;
404
+ customer_email: string;
405
+ customer_name?: string;
406
+ order_id?: string;
407
+ quote_id?: string;
408
+ /** Window origin of the storefront — used as gateway redirect base URL */
409
+ storefront_origin?: string;
410
+ metadata?: Record<string, string | number | boolean>;
411
+ /** Idempotency key to prevent duplicate payment initiation */
412
+ idempotency_key?: string;
413
+ }
414
+ interface ConversionQuote {
415
+ id: string;
416
+ business_id: string;
417
+ from_currency: string;
418
+ to_currency: string;
419
+ rate: number;
420
+ original_amount: number;
421
+ converted_amount: number;
422
+ is_used: boolean;
423
+ expires_at: string;
424
+ created_at: string;
425
+ }
426
+ interface DVADetails {
427
+ account_number: string;
428
+ bank_name: string;
429
+ account_name: string;
430
+ reference: string;
431
+ amount: number;
432
+ transaction_id: string;
433
+ expires_at: string;
434
+ }
435
+ interface PaymentInitiateResponse {
436
+ id: string;
437
+ gateway_ref: string;
438
+ gateway: string;
439
+ status: string;
440
+ /** Normalised top-level checkout URL for gateway redirect */
441
+ checkout_url: string;
442
+ }
443
+ interface TransactionVerifyResponse {
444
+ id: string;
445
+ status: string;
446
+ amount: number;
447
+ currency: string;
448
+ gateway_ref: string;
449
+ gateway?: string;
450
+ order_id?: string;
451
+ escrow_status?: string;
452
+ escrow_release_date?: string;
453
+ metadata_json?: Record<string, unknown>;
454
+ }
455
+
456
+ /**
457
+ * CMS Types
458
+ *
459
+ * Types for kasuvia-cms integration - dynamic content models and entries
460
+ */
461
+ interface CmsField {
462
+ name: string;
463
+ label: string;
464
+ type: string;
465
+ required: boolean;
466
+ config: Record<string, any>;
467
+ sub_fields?: CmsField[];
468
+ }
469
+ interface CmsModelPermissions {
470
+ read: boolean;
471
+ create: boolean;
472
+ update: boolean;
473
+ delete: boolean;
474
+ }
475
+ interface CmsModelPublicApiPermissions {
476
+ public_api: CmsModelPermissions;
477
+ }
478
+ interface CmsModel {
479
+ id: string;
480
+ business_id: string;
481
+ model_slug: string;
482
+ display_name: string;
483
+ description: string | null;
484
+ fields: CmsField[];
485
+ permissions: CmsModelPublicApiPermissions;
486
+ }
487
+ interface CmsEntry {
488
+ id: string;
489
+ business_id: string;
490
+ model_slug: string;
491
+ data: Record<string, any>;
492
+ created_at: string;
493
+ updated_at: string;
494
+ created_by: string | null;
495
+ }
496
+ interface CmsEntryListResponse {
497
+ entries: CmsEntry[];
498
+ total: number;
499
+ page: number;
500
+ page_size: number;
501
+ }
502
+ interface CmsIcon {
503
+ id: string;
504
+ name: string;
505
+ category: string;
506
+ tags: string[];
507
+ }
508
+ interface CmsIconListResponse {
509
+ icons: CmsIcon[];
510
+ total: number;
511
+ }
512
+ interface ListCmsEntriesParams {
513
+ page?: number;
514
+ page_size?: number;
515
+ }
516
+ interface CreateCmsEntryParams {
517
+ data: Record<string, any>;
518
+ }
519
+ interface UpdateCmsEntryParams {
520
+ data: Record<string, any>;
521
+ }
522
+
523
+ /**
524
+ * SdkContext
525
+ *
526
+ * Provides SdkConfig and the current access token to all SDK hooks
527
+ * in the component tree, so individual hooks do not require explicit
528
+ * config/accessToken parameters when called from client components.
529
+ *
530
+ * Usage in storefront:
531
+ * // In your AuthProvider or root layout:
532
+ * <SdkProvider config={sdkConfig} accessToken={accessToken}>
533
+ * {children}
534
+ * </SdkProvider>
535
+ *
536
+ * // In any client component:
537
+ * const { items, addItem } = useCart() // no args needed
538
+ */
539
+
540
+ interface SdkContextValue {
541
+ config: SdkConfig;
542
+ accessToken: string | null;
543
+ }
544
+ interface SdkProviderProps {
545
+ config: SdkConfig;
546
+ accessToken: string | null;
547
+ children: ReactNode;
548
+ }
549
+ declare function SdkProvider({ config, accessToken, children }: SdkProviderProps): React.JSX.Element;
550
+ /**
551
+ * Returns the SdkContext value, or null if no SdkProvider is present.
552
+ * SDK hooks use this internally to fall back to context when explicit
553
+ * parameters are not provided.
554
+ */
555
+ declare function useSdkContext(): SdkContextValue | null;
556
+ /**
557
+ * Resolves config and accessToken from explicit arguments or SdkContext.
558
+ * Throws if neither source is available.
559
+ */
560
+ declare function resolveHookArgs(explicitConfig: SdkConfig | undefined, explicitToken: string | null | undefined, ctx: SdkContextValue | null): {
561
+ config: SdkConfig;
562
+ accessToken: string | null;
563
+ };
564
+
565
+ export { type Inventory as $, type SupportedCurrenciesResponse as A, type CmsEntryListResponse as B, type CartResponse as C, type DVACreateRequest as D, type CheckoutCustomer as E, type FindOrderParams as F, type ShippingLocation as G, type DeliveryAddress as H, type Address as I, type AppContextValue as J, type AppState as K, type ListParams as L, type BackendLanguage as M, type BespokeStageKey as N, type Order as O, type Product as P, type CmsField as Q, type CmsIcon as R, type SdkConfig as S, type TransactionVerifyResponse as T, type UpdateCmsEntryParams as U, type CmsIconListResponse as V, type WishlistItem as W, type CmsModel as X, type CmsModelPermissions as Y, type CmsModelPublicApiPermissions as Z, type CustomField as _, type CartItem as a, type LangCode as a0, type OrderItem as a1, type OrderStatus as a2, type ProductType as a3, ServiceLocationTypeEnum as a4, type ServiceRecurringInterval as a5, ServiceRecurringIntervalEnum as a6, type ServiceType as a7, ServiceTypeEnum as a8, type ShippingRate as a9, type Theme as aa, type Country as b, type State as c, type SupportedLang as d, type Currency as e, type CmsEntry as f, type CreateCmsEntryParams as g, type ListCmsEntriesParams as h, type SdkContextValue as i, SdkProvider as j, type SdkProviderProps as k, type ServiceLocationType as l, type CreateOrderParams as m, type PaginatedResponse as n, type Collection as o, type WishlistCheckResponse as p, type WishlistListResponse as q, resolveHookArgs as r, type DVADetails as s, type PaymentInitiateRequest as t, useSdkContext as u, type PaymentInitiateResponse as v, type ConversionQuote as w, type ProductVariant as x, type ShippingRatesResponse as y, type SupportedLanguagesResponse as z };