@sazito/client-sdk 1.1.0
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/README.md +459 -0
- package/dist/index.d.ts +1812 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +95 -0
package/README.md
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# Sazito Client SDK
|
|
2
|
+
|
|
3
|
+
Official JavaScript/TypeScript SDK for Sazito storefronts.
|
|
4
|
+
|
|
5
|
+
This SDK is built for application developers who want a typed, framework-agnostic client with:
|
|
6
|
+
- automatic request/response key transformation
|
|
7
|
+
- unified response objects (`{ data, error }`)
|
|
8
|
+
- configurable retry/timeout/cache behavior
|
|
9
|
+
- guest checkout credential handling
|
|
10
|
+
- modular API access for products, checkout, user, CMS, analytics, and more
|
|
11
|
+
|
|
12
|
+
## Package
|
|
13
|
+
|
|
14
|
+
- Name: `@sazito/client-sdk`
|
|
15
|
+
- Version: `1.0.1`
|
|
16
|
+
- License: `MIT`
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Node.js 18+ (recommended) or any runtime with `fetch`
|
|
21
|
+
- Browser environments with `fetch`
|
|
22
|
+
|
|
23
|
+
The SDK sends requests to `http://api.sazito.com:8080` and includes your store domain in the `x-forwarded-host` header.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @sazito/client-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn add @sazito/client-sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add @sazito/client-sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { createSazitoClient } from '@sazito/client-sdk';
|
|
43
|
+
|
|
44
|
+
const sazito = createSazitoClient({
|
|
45
|
+
domain: 'mystore.sazito.com'
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const res = await sazito.products.list({
|
|
49
|
+
page: 1,
|
|
50
|
+
pageSize: 20,
|
|
51
|
+
sort: 'newest'
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (res.error) {
|
|
55
|
+
console.error(res.error.message, res.error.status);
|
|
56
|
+
} else {
|
|
57
|
+
console.log(res.data.items);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Core Response Model
|
|
62
|
+
|
|
63
|
+
All SDK methods return a `SazitoResponse<T>`:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
type SazitoResponse<T> = {
|
|
67
|
+
data?: T;
|
|
68
|
+
error?: {
|
|
69
|
+
status?: number;
|
|
70
|
+
message: string;
|
|
71
|
+
type: 'network' | 'api' | 'validation';
|
|
72
|
+
details?: any;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Typical usage:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const response = await sazito.categories.get(110);
|
|
81
|
+
|
|
82
|
+
if (response.error) {
|
|
83
|
+
// API/network/validation issue
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// success path
|
|
88
|
+
console.log(response.data);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { createSazitoClient } from '@sazito/client-sdk';
|
|
95
|
+
|
|
96
|
+
const sazito = createSazitoClient({
|
|
97
|
+
domain: 'mystore.sazito.com',
|
|
98
|
+
timeout: 30000,
|
|
99
|
+
debug: false,
|
|
100
|
+
retry: {
|
|
101
|
+
enabled: true,
|
|
102
|
+
retries: 3,
|
|
103
|
+
retryDelay: 1000
|
|
104
|
+
},
|
|
105
|
+
cache: {
|
|
106
|
+
products: { enabled: true, ttl: 600000 },
|
|
107
|
+
categories: { enabled: true, ttl: 600000 },
|
|
108
|
+
cart: { enabled: false },
|
|
109
|
+
orders: { enabled: false },
|
|
110
|
+
search: { enabled: true, ttl: 300000 },
|
|
111
|
+
cms: { enabled: true, ttl: 600000 },
|
|
112
|
+
tags: { enabled: true, ttl: 600000 },
|
|
113
|
+
entityRoutes: { enabled: true, ttl: 600000 }
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Config Fields
|
|
119
|
+
|
|
120
|
+
| Field | Type | Required | Notes |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
| `domain` | `string` | Yes | Store domain without protocol |
|
|
123
|
+
| `timeout` | `number` | No | Global request timeout in ms (default `30000`) |
|
|
124
|
+
| `retry` | object | No | Retry policy for 5xx responses |
|
|
125
|
+
| `cache` | object | No | Per-module cache strategy |
|
|
126
|
+
| `customFetchApi` | `typeof fetch` | No | Override fetch implementation |
|
|
127
|
+
| `debug` | `boolean` | No | Enables SDK debug logging |
|
|
128
|
+
|
|
129
|
+
## Per-Request Overrides
|
|
130
|
+
|
|
131
|
+
Any API call can receive `RequestOptions`:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const response = await sazito.products.get('/product/sample-slug', {
|
|
135
|
+
cache: false,
|
|
136
|
+
timeout: 5000,
|
|
137
|
+
retries: 1,
|
|
138
|
+
headers: {
|
|
139
|
+
'X-Request-ID': 'req-123'
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Supported request options:
|
|
145
|
+
- `retries`
|
|
146
|
+
- `timeout`
|
|
147
|
+
- `cache`
|
|
148
|
+
- `headers`
|
|
149
|
+
- `signal`
|
|
150
|
+
|
|
151
|
+
## Authentication
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
sazito.setAuthToken('<jwt>');
|
|
155
|
+
|
|
156
|
+
const isLoggedIn = sazito.isAuthenticated();
|
|
157
|
+
const token = sazito.getAuthToken();
|
|
158
|
+
|
|
159
|
+
sazito.clearAuth();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Auth token behavior:
|
|
163
|
+
- SDK injects `Authorization` header automatically when a token exists.
|
|
164
|
+
- Token is sent as raw JWT (not `Bearer <token>`).
|
|
165
|
+
- Token is persisted under `user_id_token` in `localStorage` (with cookie fallback).
|
|
166
|
+
|
|
167
|
+
## Cache and Credential Utilities
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
sazito.clearCache();
|
|
171
|
+
sazito.clearCredentials();
|
|
172
|
+
sazito.clearAll();
|
|
173
|
+
|
|
174
|
+
sazito.cart.clearCart();
|
|
175
|
+
sazito.invoices.clearInvoice();
|
|
176
|
+
sazito.shipping.clearAddress();
|
|
177
|
+
sazito.payments.clearPayment();
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API Surface
|
|
181
|
+
|
|
182
|
+
### Client Modules
|
|
183
|
+
|
|
184
|
+
The client instance exposes:
|
|
185
|
+
- `products`
|
|
186
|
+
- `categories`
|
|
187
|
+
- `cart`
|
|
188
|
+
- `orders`
|
|
189
|
+
- `invoices`
|
|
190
|
+
- `shipping`
|
|
191
|
+
- `payments`
|
|
192
|
+
- `users`
|
|
193
|
+
- `search`
|
|
194
|
+
- `feedbacks`
|
|
195
|
+
- `wallet`
|
|
196
|
+
- `cms`
|
|
197
|
+
- `images`
|
|
198
|
+
- `visits`
|
|
199
|
+
- `booking`
|
|
200
|
+
- `entityRoutes`
|
|
201
|
+
- `menu`
|
|
202
|
+
- `general`
|
|
203
|
+
|
|
204
|
+
### Methods by Module
|
|
205
|
+
|
|
206
|
+
| Module | Methods |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `products` | `get`, `list`, `search` |
|
|
209
|
+
| `categories` | `get`, `list` |
|
|
210
|
+
| `cart` | `get`, `create`, `addItem`, `updateItem`, `removeItem`, `clearCart` |
|
|
211
|
+
| `orders` | `list`, `get` |
|
|
212
|
+
| `invoices` | `get`, `create`, `refresh`, `addShippingAddress`, `addDiscountCode`, `assignShippingMethod`, `addDetails`, `getApplicableShippingMethods`, `clearInvoice` |
|
|
213
|
+
| `shipping` | `createAddress`, `updateAddress`, `getAddress`, `getMethods`, `clearAddress` |
|
|
214
|
+
| `payments` | `getMethods`, `create`, `initialize`, `processStep`, `clearPayment` |
|
|
215
|
+
| `users` | `login`, `requestMobileOTP`, `verifyMobileOTP`, `requestEmailLogin`, `register`, `getCurrentUser`, `updateProfile`, `requestMobilePhoneUpdate`, `verifyMobilePhoneUpdate`, `forgotPassword`, `revivePassword`, `mergeUser` |
|
|
216
|
+
| `search` | `search` |
|
|
217
|
+
| `feedbacks` | `list`, `create`, `get` |
|
|
218
|
+
| `wallet` | `getBalance`, `applyCredit`, `removeCredit`, `listTransactions` |
|
|
219
|
+
| `cms` | `getPage`, `listPages`, `getBlogPost`, `listBlogPosts`, `listAll` |
|
|
220
|
+
| `images` | `upload`, `delete` |
|
|
221
|
+
| `visits` | `track`, `trackProduct`, `trackCategory` |
|
|
222
|
+
| `booking` | `listEvents`, `getEvent`, `createBooking`, `listBookings`, `cancelBooking` |
|
|
223
|
+
| `entityRoutes` | `resolve` |
|
|
224
|
+
| `menu` | `getHeaderMenu` |
|
|
225
|
+
| `general` | `getInfo`, `getFeatures`, `getCheckoutConfig`, `getWalletConfig`, `getTajrobeConfig` |
|
|
226
|
+
|
|
227
|
+
## Usage Examples
|
|
228
|
+
|
|
229
|
+
### Products and Search
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const product = await sazito.products.get('/product/some-product-slug');
|
|
233
|
+
|
|
234
|
+
const list = await sazito.products.list({
|
|
235
|
+
categories: [73, 94],
|
|
236
|
+
priceMin: 100000,
|
|
237
|
+
priceMax: 900000,
|
|
238
|
+
availableOnly: true,
|
|
239
|
+
discountedOnly: true,
|
|
240
|
+
sort: '!price',
|
|
241
|
+
page: 1,
|
|
242
|
+
pageSize: 12
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const search = await sazito.search.query('shoes', {
|
|
246
|
+
categoryId: 73,
|
|
247
|
+
minPrice: 100000,
|
|
248
|
+
maxPrice: 900000,
|
|
249
|
+
page: 1,
|
|
250
|
+
pageSize: 10
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Guest Checkout Flow
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
// 1) Add product to cart (creates guest cart automatically if needed)
|
|
258
|
+
await sazito.cart.addItem(12345, 2);
|
|
259
|
+
|
|
260
|
+
// 2) Create invoice from cart
|
|
261
|
+
const invoiceRes = await sazito.invoices.create();
|
|
262
|
+
if (invoiceRes.error) throw new Error(invoiceRes.error.message);
|
|
263
|
+
|
|
264
|
+
// 3) Add shipping address
|
|
265
|
+
const addrRes = await sazito.shipping.createAddress({
|
|
266
|
+
firstName: 'John',
|
|
267
|
+
lastName: 'Doe',
|
|
268
|
+
mobilePhone: '09123456789',
|
|
269
|
+
regionId: 1,
|
|
270
|
+
cityId: 10,
|
|
271
|
+
address: 'No. 10, Example St',
|
|
272
|
+
postalCode: '1234567890'
|
|
273
|
+
});
|
|
274
|
+
if (addrRes.error) throw new Error(addrRes.error.message);
|
|
275
|
+
|
|
276
|
+
// 4) Attach shipping address to invoice
|
|
277
|
+
await sazito.invoices.addShippingAddress(addrRes.data.id, addrRes.data.identifier);
|
|
278
|
+
|
|
279
|
+
// 5) Fetch methods and assign shipping
|
|
280
|
+
const methodsRes = await sazito.invoices.getApplicableShippingMethods();
|
|
281
|
+
if (methodsRes.data?.length) {
|
|
282
|
+
const firstRate = methodsRes.data[0]?.rates?.[0];
|
|
283
|
+
const currentInvoice = await sazito.invoices.get();
|
|
284
|
+
|
|
285
|
+
if (firstRate && currentInvoice.data) {
|
|
286
|
+
await sazito.invoices.assignShippingMethod([
|
|
287
|
+
{
|
|
288
|
+
rateId: firstRate.id,
|
|
289
|
+
invoiceItemIds: currentInvoice.data.items.map(i => i.id)
|
|
290
|
+
}
|
|
291
|
+
]);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// 6) Payment
|
|
296
|
+
const paymentMethods = await sazito.payments.getMethods();
|
|
297
|
+
if (paymentMethods.data?.length) {
|
|
298
|
+
await sazito.payments.create(paymentMethods.data[0].id);
|
|
299
|
+
const action = await sazito.payments.initialize();
|
|
300
|
+
console.log(action.data);
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Users/Auth
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const login = await sazito.users.login({
|
|
308
|
+
email: 'dev@example.com',
|
|
309
|
+
password: 'strong-password'
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
if (login.data?.jwt) {
|
|
313
|
+
sazito.setAuthToken(login.data.jwt);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const me = await sazito.users.getCurrentUser();
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### CMS and Entity Routes
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
const route = await sazito.entityRoutes.resolve('/product/some-product-slug');
|
|
323
|
+
const page = await sazito.cms.getPage('/about-us');
|
|
324
|
+
const blog = await sazito.cms.getBlogPost('/blog/how-to-buy');
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Menu and General Config
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
const menu = await sazito.menu.getHeaderMenu();
|
|
331
|
+
const info = await sazito.general.getInfo();
|
|
332
|
+
const features = await sazito.general.getFeatures();
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Analytics Visits
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
await sazito.visits.track();
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Data Transformation Behavior
|
|
342
|
+
|
|
343
|
+
The SDK transforms request and response keys to improve developer ergonomics.
|
|
344
|
+
|
|
345
|
+
Common examples:
|
|
346
|
+
- `no_of_items` -> `quantity`
|
|
347
|
+
- `single_item_price` -> `unitPrice`
|
|
348
|
+
- `product_variant_id` -> `variantId`
|
|
349
|
+
- `first_name` -> `firstName`
|
|
350
|
+
- `postal_code` -> `postalCode`
|
|
351
|
+
|
|
352
|
+
Notes:
|
|
353
|
+
- Request payloads are transformed before being sent.
|
|
354
|
+
- Response payloads are transformed before being returned.
|
|
355
|
+
- Some APIs accept both SDK-friendly and raw fields for backward compatibility.
|
|
356
|
+
|
|
357
|
+
## Visual API Playground
|
|
358
|
+
|
|
359
|
+
Run the local visual playground:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
yarn visual:apis
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Then open:
|
|
366
|
+
- `http://127.0.0.1:4173`
|
|
367
|
+
|
|
368
|
+
Files:
|
|
369
|
+
- `/Users/rezamahmoudi/sazito-sdk/scripts/visual-docs-server.js`
|
|
370
|
+
- `/Users/rezamahmoudi/sazito-sdk/scripts/visual-api-playground/public/index.html`
|
|
371
|
+
- `/Users/rezamahmoudi/sazito-sdk/scripts/visual-api-playground/public/app.js`
|
|
372
|
+
- `/Users/rezamahmoudi/sazito-sdk/scripts/visual-api-playground/public/styles.css`
|
|
373
|
+
|
|
374
|
+
## Development
|
|
375
|
+
|
|
376
|
+
Project scripts:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
yarn build # Build dist outputs
|
|
380
|
+
yarn dev # Rollup watch mode
|
|
381
|
+
yarn typecheck # TypeScript check (no emit)
|
|
382
|
+
yarn lint # ESLint on src/
|
|
383
|
+
yarn validate # typecheck + lint
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## Fumadocs Documentation Site
|
|
387
|
+
|
|
388
|
+
SDK docs are implemented as a separate Fumadocs app in `/Users/rezamahmoudi/sazito-sdk/docs`.
|
|
389
|
+
|
|
390
|
+
Run docs locally from the repository root:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
yarn docs:install
|
|
394
|
+
yarn docs:dev
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Build/start docs:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
yarn docs:build
|
|
401
|
+
yarn docs:start
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
This docs app is tracked in GitHub, but it is not included in the published npm package.
|
|
405
|
+
Publishing is controlled by the root `files` list in `/Users/rezamahmoudi/sazito-sdk/package.json`, which only ships:
|
|
406
|
+
- `dist/`
|
|
407
|
+
- `README.md`
|
|
408
|
+
- `LICENSE`
|
|
409
|
+
|
|
410
|
+
Output formats:
|
|
411
|
+
- `dist/index.js` (CJS)
|
|
412
|
+
- `dist/index.esm.js` (ESM)
|
|
413
|
+
- `dist/index.umd.js` (UMD)
|
|
414
|
+
- `dist/index.d.ts` (types)
|
|
415
|
+
|
|
416
|
+
## Repository Structure
|
|
417
|
+
|
|
418
|
+
```txt
|
|
419
|
+
src/
|
|
420
|
+
api/ API modules
|
|
421
|
+
core/ client, config, HTTP layer, cache
|
|
422
|
+
constants/ endpoint constants
|
|
423
|
+
types/ exported SDK types
|
|
424
|
+
utils/ token storage, credentials, transformers
|
|
425
|
+
scripts/
|
|
426
|
+
visual-docs-server.js
|
|
427
|
+
visual-api-playground/public/
|
|
428
|
+
docs/
|
|
429
|
+
app/ Next.js routes and layouts
|
|
430
|
+
content/docs/ MDX documentation pages
|
|
431
|
+
lib/ Fumadocs source/layout config
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
## Troubleshooting
|
|
435
|
+
|
|
436
|
+
### `error.type === 'validation'`
|
|
437
|
+
Usually means prerequisite state is missing (for example no cart/invoice credentials in guest flow). Initialize earlier steps first.
|
|
438
|
+
|
|
439
|
+
### `error.type === 'network'`
|
|
440
|
+
Check connectivity, runtime `fetch` support, and request timeout.
|
|
441
|
+
|
|
442
|
+
### Authentication issues
|
|
443
|
+
Make sure token is set with `setAuthToken` and that your backend accepts raw JWT in `Authorization`.
|
|
444
|
+
|
|
445
|
+
### CMS helpers may throw
|
|
446
|
+
`cms.getPage` / `cms.getBlogPost` validate entity type and can throw when URL resolves to another entity type. Wrap these calls in `try/catch`.
|
|
447
|
+
|
|
448
|
+
## Minimal TypeScript Example
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
import { createSazitoClient, SazitoResponse, Product } from '@sazito/client-sdk';
|
|
452
|
+
|
|
453
|
+
const client = createSazitoClient({ domain: 'mystore.sazito.com' });
|
|
454
|
+
|
|
455
|
+
async function getProduct(path: string): Promise<Product | null> {
|
|
456
|
+
const res: SazitoResponse<Product> = await client.products.get(path);
|
|
457
|
+
return res.data ?? null;
|
|
458
|
+
}
|
|
459
|
+
```
|