@mitumba/sdk 0.2.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 +166 -0
- package/dist/index.d.mts +456 -0
- package/dist/index.d.ts +456 -0
- package/dist/index.js +469 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +454 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @mitumba/sdk
|
|
2
|
+
|
|
3
|
+
The official isomorphic TypeScript SDK for the Mitumba marketplace platform.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/Mitumba-Ltd/mitumba-sdk/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/@mitumba/sdk)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Perfectly Typed**: 100% written in strict TypeScript. Zero `any` types.
|
|
11
|
+
- **Isomorphic**: Runs natively in Node.js, Cloudflare Workers, Next.js, and the Browser using the native `fetch` API.
|
|
12
|
+
- **Zero Dependencies**: Lightweight and extremely fast.
|
|
13
|
+
- **Auto-Token Rotation**: Automatically handles refresh tokens under the hood.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @mitumba/sdk
|
|
19
|
+
# or
|
|
20
|
+
yarn add @mitumba/sdk
|
|
21
|
+
# or
|
|
22
|
+
pnpm add @mitumba/sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
Initialize the client with the environment's base URL:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { MitumbaClient } from '@mitumba/sdk'
|
|
31
|
+
|
|
32
|
+
const mitumba = new MitumbaClient({
|
|
33
|
+
baseUrl: 'https://api.mitumba.stanl.ink'
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If you already have a token (e.g. from local storage), pass it to the client:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
mitumba.setToken('eyJhbGciOiJIUzI1...', 'my-refresh-token-hex')
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API Overview
|
|
44
|
+
|
|
45
|
+
The SDK is split into 5 core modules representing the marketplace domains.
|
|
46
|
+
|
|
47
|
+
### 1. Auth Module (`mitumba.auth`)
|
|
48
|
+
|
|
49
|
+
Mitumba supports dual-mode authentication: Email + Password, or Phone OTP (SMS). The SDK strongly types both inputs.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Email Login
|
|
53
|
+
const tokens = await mitumba.auth.login({
|
|
54
|
+
email: 'user@example.com',
|
|
55
|
+
password: 'password123'
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// OTP Login
|
|
59
|
+
const { message } = await mitumba.auth.login({ phone: '+254700000000' })
|
|
60
|
+
const tokens = await mitumba.auth.verifyOtp({ phone: '+254700000000', code: '123456' })
|
|
61
|
+
|
|
62
|
+
// Provide the tokens to the client to authenticate future requests
|
|
63
|
+
mitumba.setToken(tokens.access_token, tokens.refresh_token)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Listings Module (`mitumba.listings`)
|
|
67
|
+
|
|
68
|
+
Browse, search, and manage inventory.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Fetch the marketplace feed with filters
|
|
72
|
+
const feed = await mitumba.listings.getFeed({
|
|
73
|
+
city_id: 'nbi_01',
|
|
74
|
+
condition: 'like_new',
|
|
75
|
+
sort: 'recency'
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// Create a new listing (requires seller role)
|
|
79
|
+
const listing = await mitumba.listings.create({
|
|
80
|
+
title: 'Vintage Denim Jacket',
|
|
81
|
+
category_id: 'cat_outerwear',
|
|
82
|
+
city_id: 'nbi_01',
|
|
83
|
+
price: 2500,
|
|
84
|
+
condition: 'good'
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Search Module (`mitumba.search`)
|
|
89
|
+
|
|
90
|
+
AI-powered full-text search.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Search with ranking
|
|
94
|
+
const results = await mitumba.search.search({
|
|
95
|
+
q: 'vintage jacket',
|
|
96
|
+
sort: 'relevance'
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// Get trending search terms
|
|
100
|
+
const trending = await mitumba.search.getTrending('nbi_01')
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 4. Orders & Pay Modules (`mitumba.orders`, `mitumba.pay`)
|
|
104
|
+
|
|
105
|
+
End-to-end checkout and M-Pesa integration.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// 1. Create an order
|
|
109
|
+
const { order_id, total } = await mitumba.orders.create({ listing_id: 'lst_123' })
|
|
110
|
+
|
|
111
|
+
// 2. Initiate M-Pesa STK Push
|
|
112
|
+
await mitumba.pay.initiateStkPush({ order_id, phone: '+254700000000' })
|
|
113
|
+
|
|
114
|
+
// 3. Poll for payment status
|
|
115
|
+
const status = await mitumba.pay.getStatus(order_id)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 5. Vazi Module (`mitumba.vazi`)
|
|
119
|
+
|
|
120
|
+
AI-assembled outfit feeds.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Browse the curated outfits feed
|
|
124
|
+
const feed = await mitumba.vazi.getFeed({ limit: 10, offset: 0 })
|
|
125
|
+
|
|
126
|
+
// Get a full outfit built around a specific seed item
|
|
127
|
+
const { outfits } = await mitumba.vazi.completeOutfit('lst_123')
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Error Handling
|
|
131
|
+
|
|
132
|
+
All API errors are wrapped in a standard `APIError` object.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { APIError } from '@mitumba/sdk'
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
await mitumba.auth.login({ email: 'bad', password: 'bad' })
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (error instanceof APIError) {
|
|
141
|
+
console.error(error.code) // e.g. "invalid_credentials"
|
|
142
|
+
console.error(error.status) // e.g. 401
|
|
143
|
+
console.error(error.message) // "Wrong email or password"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Contributing & Releasing
|
|
155
|
+
|
|
156
|
+
We use [Changesets](https://github.com/changesets/changesets) for automated versioning and changelog generation.
|
|
157
|
+
|
|
158
|
+
When submitting a PR that requires a package version bump, run:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx changeset
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Select the appropriate version bump (`patch`, `minor`, `major`) and provide a description of your changes. Commit the generated markdown file along with your PR.
|
|
165
|
+
|
|
166
|
+
When your PR is merged, the automated workflow will handle updating the version, aggregating the changelog, and publishing to NPM.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
interface AuthTokens {
|
|
2
|
+
access_token: string;
|
|
3
|
+
refresh_token: string;
|
|
4
|
+
expires_in: number;
|
|
5
|
+
}
|
|
6
|
+
interface MessageResponse {
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
interface EmailRegisterInput {
|
|
10
|
+
email: string;
|
|
11
|
+
password: string;
|
|
12
|
+
display_name?: string;
|
|
13
|
+
}
|
|
14
|
+
interface PhoneRegisterInput {
|
|
15
|
+
phone: string;
|
|
16
|
+
}
|
|
17
|
+
type RegisterInput = EmailRegisterInput | PhoneRegisterInput;
|
|
18
|
+
interface EmailLoginInput {
|
|
19
|
+
email: string;
|
|
20
|
+
password: string;
|
|
21
|
+
}
|
|
22
|
+
interface PhoneLoginInput {
|
|
23
|
+
phone: string;
|
|
24
|
+
}
|
|
25
|
+
type LoginInput = EmailLoginInput | PhoneLoginInput;
|
|
26
|
+
interface SendOtpInput {
|
|
27
|
+
phone: string;
|
|
28
|
+
}
|
|
29
|
+
interface VerifyOtpInput {
|
|
30
|
+
phone: string;
|
|
31
|
+
code: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare const CONDITIONS: readonly ["new", "like_new", "good", "fair"];
|
|
35
|
+
type Condition = typeof CONDITIONS[number];
|
|
36
|
+
declare const LISTING_STATUSES: readonly ["draft", "active", "sold", "removed"];
|
|
37
|
+
type ListingStatus = typeof LISTING_STATUSES[number];
|
|
38
|
+
interface ListingImage {
|
|
39
|
+
id: string;
|
|
40
|
+
listing_id: string;
|
|
41
|
+
url: string;
|
|
42
|
+
position: number;
|
|
43
|
+
created_at: string;
|
|
44
|
+
}
|
|
45
|
+
interface SellerProfile {
|
|
46
|
+
id: string;
|
|
47
|
+
sti_score: number;
|
|
48
|
+
verification_status: string;
|
|
49
|
+
seller_type: 'individual' | 'bale';
|
|
50
|
+
}
|
|
51
|
+
interface Listing {
|
|
52
|
+
id: string;
|
|
53
|
+
seller_id: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string | null;
|
|
56
|
+
category_id: string;
|
|
57
|
+
city_id: string;
|
|
58
|
+
price: number;
|
|
59
|
+
condition: Condition;
|
|
60
|
+
status: ListingStatus;
|
|
61
|
+
photo_verified: boolean;
|
|
62
|
+
vazi_eligible: boolean;
|
|
63
|
+
created_at: string;
|
|
64
|
+
updated_at: string;
|
|
65
|
+
sti_score: number;
|
|
66
|
+
verification_status: string;
|
|
67
|
+
seller_type: 'individual' | 'bale';
|
|
68
|
+
images?: ListingImage[];
|
|
69
|
+
}
|
|
70
|
+
interface ListingsFeedParams {
|
|
71
|
+
city_id?: string;
|
|
72
|
+
category_id?: string;
|
|
73
|
+
min_price?: number;
|
|
74
|
+
max_price?: number;
|
|
75
|
+
condition?: Condition;
|
|
76
|
+
sort?: 'recency' | 'price_asc' | 'price_desc';
|
|
77
|
+
page?: number;
|
|
78
|
+
page_size?: number;
|
|
79
|
+
}
|
|
80
|
+
interface CreateListingInput {
|
|
81
|
+
title: string;
|
|
82
|
+
description?: string;
|
|
83
|
+
category_id: string;
|
|
84
|
+
city_id: string;
|
|
85
|
+
price: number;
|
|
86
|
+
condition: Condition;
|
|
87
|
+
}
|
|
88
|
+
type UpdateListingInput = Partial<CreateListingInput>;
|
|
89
|
+
interface Category {
|
|
90
|
+
id: string;
|
|
91
|
+
name: string;
|
|
92
|
+
slug: string;
|
|
93
|
+
}
|
|
94
|
+
interface City {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
delivery_fee: number;
|
|
98
|
+
}
|
|
99
|
+
interface SellerStorefront {
|
|
100
|
+
seller: SellerProfile;
|
|
101
|
+
listings: Listing[];
|
|
102
|
+
total: number;
|
|
103
|
+
page: number;
|
|
104
|
+
page_size: number;
|
|
105
|
+
has_more: boolean;
|
|
106
|
+
}
|
|
107
|
+
interface PresignImageResponse {
|
|
108
|
+
upload_url: string;
|
|
109
|
+
image_id: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface SearchParams {
|
|
113
|
+
q: string;
|
|
114
|
+
city_id?: string;
|
|
115
|
+
category_id?: string;
|
|
116
|
+
min_price?: number;
|
|
117
|
+
max_price?: number;
|
|
118
|
+
condition?: Condition;
|
|
119
|
+
sort?: 'relevance' | 'recency' | 'price_asc' | 'price_desc' | 'sti';
|
|
120
|
+
page?: number;
|
|
121
|
+
page_size?: number;
|
|
122
|
+
}
|
|
123
|
+
interface SearchResult extends Omit<Listing, 'images'> {
|
|
124
|
+
rank: number;
|
|
125
|
+
}
|
|
126
|
+
interface TrendingTerm {
|
|
127
|
+
term: string;
|
|
128
|
+
count: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
declare const ORDER_STATUSES: readonly ["created", "payment_pending", "paid", "seller_confirmed", "shipped", "delivered", "completed", "cancelled", "disputed"];
|
|
132
|
+
type OrderStatus = typeof ORDER_STATUSES[number];
|
|
133
|
+
interface OrderEvent {
|
|
134
|
+
id: string;
|
|
135
|
+
order_id: string;
|
|
136
|
+
actor: string;
|
|
137
|
+
old_status: string;
|
|
138
|
+
new_status: string;
|
|
139
|
+
note: string | null;
|
|
140
|
+
created_at: string;
|
|
141
|
+
}
|
|
142
|
+
interface Order {
|
|
143
|
+
id: string;
|
|
144
|
+
buyer_id: string;
|
|
145
|
+
seller_id: string;
|
|
146
|
+
listing_id: string;
|
|
147
|
+
amount: number;
|
|
148
|
+
delivery_fee: number;
|
|
149
|
+
total: number;
|
|
150
|
+
status: OrderStatus;
|
|
151
|
+
city_id: string;
|
|
152
|
+
created_at: string;
|
|
153
|
+
updated_at: string;
|
|
154
|
+
events?: OrderEvent[];
|
|
155
|
+
}
|
|
156
|
+
interface CreateOrderInput {
|
|
157
|
+
listing_id: string;
|
|
158
|
+
}
|
|
159
|
+
interface TransitionOrderInput {
|
|
160
|
+
status: OrderStatus;
|
|
161
|
+
note?: string;
|
|
162
|
+
}
|
|
163
|
+
interface OrderHistoryParams {
|
|
164
|
+
role?: 'buyer' | 'seller';
|
|
165
|
+
page?: number;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface StkPushInput {
|
|
169
|
+
order_id: string;
|
|
170
|
+
phone: string;
|
|
171
|
+
}
|
|
172
|
+
interface StkPushResponse {
|
|
173
|
+
payment_id: string;
|
|
174
|
+
provider: string;
|
|
175
|
+
}
|
|
176
|
+
declare const PAYMENT_STATUSES: readonly ["initiated", "funded", "failed", "refunded", "cancelled"];
|
|
177
|
+
type PaymentStatus = typeof PAYMENT_STATUSES[number];
|
|
178
|
+
interface PaymentStatusResponse {
|
|
179
|
+
id: string;
|
|
180
|
+
status: PaymentStatus;
|
|
181
|
+
total: number;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
declare const GARMENT_TYPES: readonly ["top", "bottom", "shoes", "accessory", "dress", "outerwear", "bag", "kids"];
|
|
185
|
+
type GarmentType = typeof GARMENT_TYPES[number];
|
|
186
|
+
interface VAZIOutfitItem {
|
|
187
|
+
listing_id: string;
|
|
188
|
+
garment_type: GarmentType;
|
|
189
|
+
price_kes: number;
|
|
190
|
+
seller_id: string;
|
|
191
|
+
seller_sti: number;
|
|
192
|
+
seller_city: string;
|
|
193
|
+
image_url: string | null;
|
|
194
|
+
is_seed: boolean;
|
|
195
|
+
final_score: number;
|
|
196
|
+
}
|
|
197
|
+
interface VAZIOutfit {
|
|
198
|
+
id: string;
|
|
199
|
+
name: string;
|
|
200
|
+
items: VAZIOutfitItem[];
|
|
201
|
+
total_price_kes: number;
|
|
202
|
+
sellers_count: number;
|
|
203
|
+
is_multi_city: boolean;
|
|
204
|
+
assembled_at: string;
|
|
205
|
+
}
|
|
206
|
+
interface VaziFeedParams {
|
|
207
|
+
limit?: number;
|
|
208
|
+
offset?: number;
|
|
209
|
+
}
|
|
210
|
+
interface VaziFeedResponse {
|
|
211
|
+
outfits: VAZIOutfit[];
|
|
212
|
+
total: number;
|
|
213
|
+
limit: number;
|
|
214
|
+
offset: number;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
interface MitumbaClientConfig {
|
|
218
|
+
baseUrl: string;
|
|
219
|
+
debug?: boolean;
|
|
220
|
+
maxRetries?: number;
|
|
221
|
+
/**
|
|
222
|
+
* Optional access token for authenticated requests.
|
|
223
|
+
*/
|
|
224
|
+
token?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Optional refresh token. If provided, the client can automatically refresh
|
|
227
|
+
* the access token when encountering a 401 response.
|
|
228
|
+
*/
|
|
229
|
+
refreshToken?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Callback invoked when the token is automatically refreshed.
|
|
232
|
+
* Useful for persisting the new tokens.
|
|
233
|
+
*/
|
|
234
|
+
onTokenRefresh?: (tokens: {
|
|
235
|
+
token: string;
|
|
236
|
+
refreshToken: string;
|
|
237
|
+
}) => void;
|
|
238
|
+
}
|
|
239
|
+
interface APIErrorResponse {
|
|
240
|
+
error: string;
|
|
241
|
+
message?: string;
|
|
242
|
+
details?: unknown;
|
|
243
|
+
}
|
|
244
|
+
interface PaginatedResponse<T> {
|
|
245
|
+
data: T[];
|
|
246
|
+
total: number;
|
|
247
|
+
page: number;
|
|
248
|
+
page_size: number;
|
|
249
|
+
has_more: boolean;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface RequestOptions {
|
|
253
|
+
signal?: AbortSignal;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
declare class APIError extends Error {
|
|
257
|
+
readonly code: string;
|
|
258
|
+
readonly status: number;
|
|
259
|
+
readonly details?: unknown;
|
|
260
|
+
constructor(status: number, data: APIErrorResponse);
|
|
261
|
+
}
|
|
262
|
+
declare class APIClient {
|
|
263
|
+
private config;
|
|
264
|
+
private isRefreshing;
|
|
265
|
+
private refreshPromise;
|
|
266
|
+
constructor(config: MitumbaClientConfig);
|
|
267
|
+
setToken(token: string, refreshToken?: string): void;
|
|
268
|
+
clearToken(): void;
|
|
269
|
+
private request;
|
|
270
|
+
private handleTokenRefresh;
|
|
271
|
+
get<T>(path: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<T>;
|
|
272
|
+
post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
273
|
+
put<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
274
|
+
patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
275
|
+
delete<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
declare class AuthModule {
|
|
279
|
+
private readonly client;
|
|
280
|
+
constructor(client: APIClient);
|
|
281
|
+
/**
|
|
282
|
+
* Register a new account.
|
|
283
|
+
* If using EmailRegisterInput, returns AuthTokens.
|
|
284
|
+
* If using PhoneRegisterInput, returns MessageResponse (OTP sent).
|
|
285
|
+
*/
|
|
286
|
+
register(input: RegisterInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse>;
|
|
287
|
+
/**
|
|
288
|
+
* Log in to an existing account.
|
|
289
|
+
* If using EmailLoginInput, returns AuthTokens.
|
|
290
|
+
* If using PhoneLoginInput, returns MessageResponse (OTP sent).
|
|
291
|
+
*/
|
|
292
|
+
login(input: LoginInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse>;
|
|
293
|
+
/**
|
|
294
|
+
* Send an OTP code to a phone number.
|
|
295
|
+
*/
|
|
296
|
+
sendOtp(input: SendOtpInput, options?: RequestOptions): Promise<MessageResponse>;
|
|
297
|
+
/**
|
|
298
|
+
* Verify an OTP code.
|
|
299
|
+
*/
|
|
300
|
+
verifyOtp(input: VerifyOtpInput, options?: RequestOptions): Promise<AuthTokens>;
|
|
301
|
+
/**
|
|
302
|
+
* Refresh the access token using a refresh token.
|
|
303
|
+
*/
|
|
304
|
+
refresh(refreshToken: string, options?: RequestOptions): Promise<AuthTokens>;
|
|
305
|
+
/**
|
|
306
|
+
* Revoke the refresh token and log out.
|
|
307
|
+
*/
|
|
308
|
+
logout(refreshToken: string, options?: RequestOptions): Promise<{
|
|
309
|
+
ok: boolean;
|
|
310
|
+
}>;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
declare class ListingsModule {
|
|
314
|
+
private readonly client;
|
|
315
|
+
constructor(client: APIClient);
|
|
316
|
+
/**
|
|
317
|
+
* Browse the marketplace feed with optional filters.
|
|
318
|
+
*/
|
|
319
|
+
getFeed(params?: ListingsFeedParams, options?: RequestOptions): Promise<PaginatedResponse<Listing>>;
|
|
320
|
+
/**
|
|
321
|
+
* Get full details of a single listing, including its images.
|
|
322
|
+
*/
|
|
323
|
+
getById(id: string, options?: RequestOptions): Promise<Listing>;
|
|
324
|
+
/**
|
|
325
|
+
* Create a new listing (requires seller role).
|
|
326
|
+
*/
|
|
327
|
+
create(input: CreateListingInput, options?: RequestOptions): Promise<Listing>;
|
|
328
|
+
/**
|
|
329
|
+
* Update an existing listing.
|
|
330
|
+
*/
|
|
331
|
+
update(id: string, input: UpdateListingInput, options?: RequestOptions): Promise<Listing>;
|
|
332
|
+
/**
|
|
333
|
+
* Change the status of a listing.
|
|
334
|
+
*/
|
|
335
|
+
updateStatus(id: string, status: ListingStatus, options?: RequestOptions): Promise<Listing>;
|
|
336
|
+
/**
|
|
337
|
+
* Soft delete a listing (sets status to 'removed').
|
|
338
|
+
*/
|
|
339
|
+
delete(id: string, options?: RequestOptions): Promise<{
|
|
340
|
+
ok: boolean;
|
|
341
|
+
}>;
|
|
342
|
+
/**
|
|
343
|
+
* Get a seller's public storefront.
|
|
344
|
+
*/
|
|
345
|
+
getSellerStorefront(sellerId: string, params?: {
|
|
346
|
+
page?: number;
|
|
347
|
+
page_size?: number;
|
|
348
|
+
}, options?: RequestOptions): Promise<SellerStorefront>;
|
|
349
|
+
/**
|
|
350
|
+
* List all supported categories.
|
|
351
|
+
*/
|
|
352
|
+
getCategories(options?: RequestOptions): Promise<Category[]>;
|
|
353
|
+
/**
|
|
354
|
+
* List all supported cities.
|
|
355
|
+
*/
|
|
356
|
+
getCities(options?: RequestOptions): Promise<City[]>;
|
|
357
|
+
/**
|
|
358
|
+
* Get a presigned upload URL for a listing image.
|
|
359
|
+
* Index should be between 0 and 9.
|
|
360
|
+
*/
|
|
361
|
+
presignImage(listingId: string, index: number, options?: RequestOptions): Promise<PresignImageResponse>;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
declare class SearchModule {
|
|
365
|
+
private readonly client;
|
|
366
|
+
constructor(client: APIClient);
|
|
367
|
+
/**
|
|
368
|
+
* Perform a full-text search with optional filters.
|
|
369
|
+
*/
|
|
370
|
+
search(params: SearchParams, options?: RequestOptions): Promise<PaginatedResponse<SearchResult>>;
|
|
371
|
+
/**
|
|
372
|
+
* Get trending search terms.
|
|
373
|
+
*/
|
|
374
|
+
getTrending(cityId?: string, options?: RequestOptions): Promise<{
|
|
375
|
+
terms: TrendingTerm[];
|
|
376
|
+
}>;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
declare class OrdersModule {
|
|
380
|
+
private readonly client;
|
|
381
|
+
constructor(client: APIClient);
|
|
382
|
+
/**
|
|
383
|
+
* Create a new order from a listing.
|
|
384
|
+
*/
|
|
385
|
+
create(input: CreateOrderInput, options?: RequestOptions): Promise<{
|
|
386
|
+
order_id: string;
|
|
387
|
+
total: number;
|
|
388
|
+
delivery_fee: number;
|
|
389
|
+
}>;
|
|
390
|
+
/**
|
|
391
|
+
* Get full details of an order, including its event timeline.
|
|
392
|
+
*/
|
|
393
|
+
getById(id: string, options?: RequestOptions): Promise<Order>;
|
|
394
|
+
/**
|
|
395
|
+
* Transition the status of an order.
|
|
396
|
+
*/
|
|
397
|
+
transition(id: string, input: TransitionOrderInput, options?: RequestOptions): Promise<Order>;
|
|
398
|
+
/**
|
|
399
|
+
* Get the order history for the current authenticated user.
|
|
400
|
+
*/
|
|
401
|
+
getHistory(params?: OrderHistoryParams, options?: RequestOptions): Promise<{
|
|
402
|
+
data: Order[];
|
|
403
|
+
page: number;
|
|
404
|
+
page_size: number;
|
|
405
|
+
}>;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
declare class PayModule {
|
|
409
|
+
private readonly client;
|
|
410
|
+
constructor(client: APIClient);
|
|
411
|
+
/**
|
|
412
|
+
* Initiate an M-Pesa STK Push payment for an order.
|
|
413
|
+
*/
|
|
414
|
+
initiateStkPush(input: StkPushInput, options?: RequestOptions): Promise<StkPushResponse>;
|
|
415
|
+
/**
|
|
416
|
+
* Poll for the current status of a payment by its order ID.
|
|
417
|
+
*/
|
|
418
|
+
getStatus(orderId: string, options?: RequestOptions): Promise<PaymentStatusResponse>;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
declare class VaziModule {
|
|
422
|
+
private readonly client;
|
|
423
|
+
constructor(client: APIClient);
|
|
424
|
+
/**
|
|
425
|
+
* Browse the AI-curated outfit feed.
|
|
426
|
+
*/
|
|
427
|
+
getFeed(params?: VaziFeedParams, options?: RequestOptions): Promise<VaziFeedResponse>;
|
|
428
|
+
/**
|
|
429
|
+
* Get a complete outfit built around a specific seed listing.
|
|
430
|
+
*/
|
|
431
|
+
completeOutfit(listingId: string, options?: RequestOptions): Promise<{
|
|
432
|
+
outfits: VAZIOutfit[];
|
|
433
|
+
}>;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
declare class MitumbaClient {
|
|
437
|
+
readonly api: APIClient;
|
|
438
|
+
readonly auth: AuthModule;
|
|
439
|
+
readonly listings: ListingsModule;
|
|
440
|
+
readonly search: SearchModule;
|
|
441
|
+
readonly orders: OrdersModule;
|
|
442
|
+
readonly pay: PayModule;
|
|
443
|
+
readonly vazi: VaziModule;
|
|
444
|
+
constructor(config: MitumbaClientConfig);
|
|
445
|
+
/**
|
|
446
|
+
* Set the access token for authenticated requests.
|
|
447
|
+
* Optionally pass a refresh token to enable automatic token rotation.
|
|
448
|
+
*/
|
|
449
|
+
setToken(token: string, refreshToken?: string): void;
|
|
450
|
+
/**
|
|
451
|
+
* Clear the current tokens.
|
|
452
|
+
*/
|
|
453
|
+
clearToken(): void;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
export { APIClient, APIError, type APIErrorResponse, AuthModule, type AuthTokens, CONDITIONS, type Category, type City, type Condition, type CreateListingInput, type CreateOrderInput, type EmailLoginInput, type EmailRegisterInput, GARMENT_TYPES, type GarmentType, LISTING_STATUSES, type Listing, type ListingImage, type ListingStatus, type ListingsFeedParams, ListingsModule, type LoginInput, type MessageResponse, MitumbaClient, type MitumbaClientConfig, ORDER_STATUSES, type Order, type OrderEvent, type OrderHistoryParams, type OrderStatus, OrdersModule, PAYMENT_STATUSES, type PaginatedResponse, PayModule, type PaymentStatus, type PaymentStatusResponse, type PhoneLoginInput, type PhoneRegisterInput, type PresignImageResponse, type RegisterInput, type RequestOptions, SearchModule, type SearchParams, type SearchResult, type SellerProfile, type SellerStorefront, type SendOtpInput, type StkPushInput, type StkPushResponse, type TransitionOrderInput, type TrendingTerm, type UpdateListingInput, type VAZIOutfit, type VAZIOutfitItem, type VaziFeedParams, type VaziFeedResponse, VaziModule, type VerifyOtpInput };
|