@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
|
@@ -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.
|
|
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",
|
package/src/config/index.ts
CHANGED
|
@@ -1,102 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Kasuvia SDK Configuration
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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:
|
|
9
|
-
*
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
}
|