@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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kasuvia/sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Kasuvia SDK - Core data fetching, authentication, and API client layer",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -10,6 +10,11 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.mjs",
12
12
  "require": "./dist/index.js"
13
+ },
14
+ "./hooks": {
15
+ "types": "./dist/hooks/index.d.ts",
16
+ "import": "./dist/hooks/index.mjs",
17
+ "require": "./dist/hooks/index.js"
13
18
  }
14
19
  },
15
20
  "files": [
@@ -22,7 +27,6 @@
22
27
  "dependencies": {
23
28
  "@microsoft/fetch-event-source": "^2.0.1",
24
29
  "@tanstack/react-query": "^5.100.13",
25
- "axios": "^1.16.1",
26
30
  "graphql": "^16.14.0",
27
31
  "graphql-request": "^7.4.0",
28
32
  "react-use-websocket": "^4.13.0",
@@ -1,102 +1,21 @@
1
1
  /**
2
2
  * Kasuvia SDK Configuration
3
3
  *
4
- * This module manages SDK initialization and runtime configuration.
5
- * The SDK is client-based and runs in the browser.
6
- * All backend URLs are bundled with the SDK.
4
+ * Stateless configuration - no module-scoped state.
5
+ * All configuration is passed as parameters to SDK functions.
7
6
  *
8
- * SECURITY NOTE: The storefront API key has limited permissions - it only provides
9
- * customer-based resources from a business owner to customers, not full platform access.
10
- * This key is safe to expose to the browser as a NEXT_PUBLIC_ environment variable.
7
+ * SECURITY NOTE: Backend URLs should never be exposed to the browser.
8
+ * They should only be used on the server side or in Next.js API routes.
11
9
  */
12
10
 
13
- import { logger, setEnvironmentMode, setLoggerEnvironmentMode } from "../utils"
14
-
15
11
  export interface SdkConfig {
16
12
  businessId: string
17
13
  storefrontApiKey: string
18
- }
19
-
20
- interface SdkRuntimeConfig {
21
- businessId: string
22
- storefrontApiKey: string
23
- }
24
-
25
- let runtimeConfig: SdkRuntimeConfig | null = null
26
-
27
- /**
28
- * Backend URLs - bundled with the SDK
29
- * These are the complete URLs (including API version) that the SDK uses internally.
30
- * The storefront never sees or configures these URLs.
31
- *
32
- * Currently set to localhost development URLs.
33
- * Update to production URLs when ready for deployment.
34
- */
35
- const BACKEND_URLS = {
36
- auth: 'https://127.0.0.1:8000/api/v1',
37
- store: 'https://127.0.0.1:8001/api/v1',
38
- payment: 'https://127.0.0.1:8002/api/v1',
39
- notifications: 'https://127.0.0.1:8007/api/v1',
40
- cms: 'https://127.0.0.1:8009/api/v1',
41
- } as const
42
-
43
- /**
44
- * Initialize the SDK with runtime credentials
45
- * This must be called before any SDK operations
46
- *
47
- * IMPORTANT: In Next.js, this should be called in layout.tsx (server component)
48
- * using private environment variables (kasuvia_BUSINESS_ID, kasuvia_STOREFRONT_API_KEY).
49
- * The config is stored in module scope and will be available to client components
50
- * through the SDK's bundled code.
51
- *
52
- * @param config - SDK configuration including credentials
53
- */
54
- export function initSdk(config: SdkConfig): void {
55
- runtimeConfig = {
56
- businessId: config.businessId,
57
- storefrontApiKey: config.storefrontApiKey,
14
+ backendUrls: {
15
+ auth: string
16
+ store: string
17
+ payment: string
18
+ notifications: string
19
+ cms: string
58
20
  }
59
-
60
- // Determine environment from NODE_ENV for logging/cache behavior
61
- // In browser (window exists), default to production behavior
62
- // In Node.js (window undefined), check NODE_ENV
63
- const isDevelopment = typeof window === 'undefined' &&
64
- (globalThis as any).process?.env?.NODE_ENV === 'development'
65
- setEnvironmentMode(isDevelopment)
66
- setLoggerEnvironmentMode(isDevelopment)
67
-
68
- logger.log('SDK initialized with businessId:', config.businessId)
69
- }
70
-
71
- /**
72
- * Get the current runtime configuration
73
- * Throws if SDK is not initialized
74
- */
75
- export function getRuntimeConfig(): SdkRuntimeConfig {
76
- if (!runtimeConfig) {
77
- throw new Error('SDK not initialized. Call initSdk() before using SDK functions.')
78
- }
79
- return runtimeConfig
80
- }
81
-
82
- /**
83
- * Get backend URL for a specific service
84
- * Internal use only - never exposed to storefront
85
- */
86
- export function getBackendUrl(service: 'auth' | 'store' | 'payment' | 'notifications' | 'cms'): string {
87
- return BACKEND_URLS[service]
88
- }
89
-
90
- /**
91
- * Check if SDK is initialized
92
- */
93
- export function isInitialized(): boolean {
94
- return runtimeConfig !== null
95
- }
96
-
97
- /**
98
- * Reset SDK configuration (mainly for testing)
99
- */
100
- export function resetConfig(): void {
101
- runtimeConfig = null
102
21
  }