@cimplify/sdk 0.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/dist/index.d.mts +2620 -0
- package/dist/index.d.ts +2620 -0
- package/dist/index.js +1500 -0
- package/dist/index.mjs +1460 -0
- package/package.json +29 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1460 @@
|
|
|
1
|
+
// src/types/common.ts
|
|
2
|
+
var CimplifyError = class extends Error {
|
|
3
|
+
constructor(code, message, retryable = false) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.retryable = retryable;
|
|
7
|
+
this.name = "CimplifyError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/catalogue.ts
|
|
12
|
+
var CatalogueQueries = class {
|
|
13
|
+
constructor(client) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
}
|
|
16
|
+
// --------------------------------------------------------------------------
|
|
17
|
+
// PRODUCTS
|
|
18
|
+
// --------------------------------------------------------------------------
|
|
19
|
+
async getProducts(options) {
|
|
20
|
+
let query2 = "products";
|
|
21
|
+
const filters = [];
|
|
22
|
+
if (options?.category) {
|
|
23
|
+
filters.push(`@.category_id=='${options.category}'`);
|
|
24
|
+
}
|
|
25
|
+
if (options?.featured !== void 0) {
|
|
26
|
+
filters.push(`@.featured==${options.featured}`);
|
|
27
|
+
}
|
|
28
|
+
if (options?.in_stock !== void 0) {
|
|
29
|
+
filters.push(`@.in_stock==${options.in_stock}`);
|
|
30
|
+
}
|
|
31
|
+
if (options?.search) {
|
|
32
|
+
filters.push(`@.name contains '${options.search}'`);
|
|
33
|
+
}
|
|
34
|
+
if (options?.min_price !== void 0) {
|
|
35
|
+
filters.push(`@.price>=${options.min_price}`);
|
|
36
|
+
}
|
|
37
|
+
if (options?.max_price !== void 0) {
|
|
38
|
+
filters.push(`@.price<=${options.max_price}`);
|
|
39
|
+
}
|
|
40
|
+
if (filters.length > 0) {
|
|
41
|
+
query2 += `[?(${filters.join(" && ")})]`;
|
|
42
|
+
}
|
|
43
|
+
if (options?.sort_by) {
|
|
44
|
+
query2 += `#sort(${options.sort_by},${options.sort_order || "asc"})`;
|
|
45
|
+
}
|
|
46
|
+
if (options?.limit) {
|
|
47
|
+
query2 += `#limit(${options.limit})`;
|
|
48
|
+
}
|
|
49
|
+
if (options?.offset) {
|
|
50
|
+
query2 += `#offset(${options.offset})`;
|
|
51
|
+
}
|
|
52
|
+
return this.client.query(query2);
|
|
53
|
+
}
|
|
54
|
+
async getProduct(id) {
|
|
55
|
+
return this.client.query(`products.${id}`);
|
|
56
|
+
}
|
|
57
|
+
async getProductBySlug(slug) {
|
|
58
|
+
const products = await this.client.query(
|
|
59
|
+
`products[?(@.slug=='${slug}')]`
|
|
60
|
+
);
|
|
61
|
+
if (!products.length) {
|
|
62
|
+
throw new Error(`Product not found: ${slug}`);
|
|
63
|
+
}
|
|
64
|
+
return products[0];
|
|
65
|
+
}
|
|
66
|
+
// --------------------------------------------------------------------------
|
|
67
|
+
// VARIANTS
|
|
68
|
+
// --------------------------------------------------------------------------
|
|
69
|
+
async getVariants(productId) {
|
|
70
|
+
return this.client.query(`products.${productId}.variants`);
|
|
71
|
+
}
|
|
72
|
+
async getVariantAxes(productId) {
|
|
73
|
+
return this.client.query(`products.${productId}.variant_axes`);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find a variant by axis selections (e.g., { "Size": "Large", "Color": "Red" })
|
|
77
|
+
* Returns the matching variant or null if no match found.
|
|
78
|
+
*/
|
|
79
|
+
async getVariantByAxisSelections(productId, selections) {
|
|
80
|
+
return this.client.query(
|
|
81
|
+
`products.${productId}.variant`,
|
|
82
|
+
{ axis_selections: selections }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get a specific variant by its ID
|
|
87
|
+
*/
|
|
88
|
+
async getVariantById(productId, variantId) {
|
|
89
|
+
return this.client.query(
|
|
90
|
+
`products.${productId}.variant.${variantId}`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
// --------------------------------------------------------------------------
|
|
94
|
+
// ADD-ONS
|
|
95
|
+
// --------------------------------------------------------------------------
|
|
96
|
+
async getAddOns(productId) {
|
|
97
|
+
return this.client.query(`products.${productId}.add_ons`);
|
|
98
|
+
}
|
|
99
|
+
// --------------------------------------------------------------------------
|
|
100
|
+
// CATEGORIES
|
|
101
|
+
// --------------------------------------------------------------------------
|
|
102
|
+
async getCategories() {
|
|
103
|
+
return this.client.query("categories");
|
|
104
|
+
}
|
|
105
|
+
async getCategory(id) {
|
|
106
|
+
return this.client.query(`categories.${id}`);
|
|
107
|
+
}
|
|
108
|
+
async getCategoryBySlug(slug) {
|
|
109
|
+
const categories = await this.client.query(
|
|
110
|
+
`categories[?(@.slug=='${slug}')]`
|
|
111
|
+
);
|
|
112
|
+
if (!categories.length) {
|
|
113
|
+
throw new Error(`Category not found: ${slug}`);
|
|
114
|
+
}
|
|
115
|
+
return categories[0];
|
|
116
|
+
}
|
|
117
|
+
async getCategoryProducts(categoryId) {
|
|
118
|
+
return this.client.query(
|
|
119
|
+
`products[?(@.category_id=='${categoryId}')]`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
// --------------------------------------------------------------------------
|
|
123
|
+
// COLLECTIONS
|
|
124
|
+
// --------------------------------------------------------------------------
|
|
125
|
+
async getCollections() {
|
|
126
|
+
return this.client.query("collections");
|
|
127
|
+
}
|
|
128
|
+
async getCollection(id) {
|
|
129
|
+
return this.client.query(`collections.${id}`);
|
|
130
|
+
}
|
|
131
|
+
async getCollectionBySlug(slug) {
|
|
132
|
+
const collections = await this.client.query(
|
|
133
|
+
`collections[?(@.slug=='${slug}')]`
|
|
134
|
+
);
|
|
135
|
+
if (!collections.length) {
|
|
136
|
+
throw new Error(`Collection not found: ${slug}`);
|
|
137
|
+
}
|
|
138
|
+
return collections[0];
|
|
139
|
+
}
|
|
140
|
+
async getCollectionProducts(collectionId) {
|
|
141
|
+
return this.client.query(`collections.${collectionId}.products`);
|
|
142
|
+
}
|
|
143
|
+
async searchCollections(query2, limit = 20) {
|
|
144
|
+
return this.client.query(
|
|
145
|
+
`collections[?(@.name contains '${query2}')]#limit(${limit})`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
// --------------------------------------------------------------------------
|
|
149
|
+
// BUNDLES
|
|
150
|
+
// --------------------------------------------------------------------------
|
|
151
|
+
async getBundles() {
|
|
152
|
+
return this.client.query("bundles");
|
|
153
|
+
}
|
|
154
|
+
async getBundle(id) {
|
|
155
|
+
return this.client.query(`bundles.${id}`);
|
|
156
|
+
}
|
|
157
|
+
async getBundleBySlug(slug) {
|
|
158
|
+
const bundles = await this.client.query(
|
|
159
|
+
`bundles[?(@.slug=='${slug}')]`
|
|
160
|
+
);
|
|
161
|
+
if (!bundles.length) {
|
|
162
|
+
throw new Error(`Bundle not found: ${slug}`);
|
|
163
|
+
}
|
|
164
|
+
return bundles[0];
|
|
165
|
+
}
|
|
166
|
+
async searchBundles(query2, limit = 20) {
|
|
167
|
+
return this.client.query(
|
|
168
|
+
`bundles[?(@.name contains '${query2}')]#limit(${limit})`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
// --------------------------------------------------------------------------
|
|
172
|
+
// COMPOSITES (Build-Your-Own)
|
|
173
|
+
// --------------------------------------------------------------------------
|
|
174
|
+
async getComposites(options) {
|
|
175
|
+
let query2 = "composites";
|
|
176
|
+
if (options?.limit) {
|
|
177
|
+
query2 += `#limit(${options.limit})`;
|
|
178
|
+
}
|
|
179
|
+
return this.client.query(query2);
|
|
180
|
+
}
|
|
181
|
+
async getComposite(id) {
|
|
182
|
+
return this.client.query(`composites.${id}`);
|
|
183
|
+
}
|
|
184
|
+
async getCompositeByProductId(productId) {
|
|
185
|
+
return this.client.query(
|
|
186
|
+
`composites.by_product.${productId}`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
async calculateCompositePrice(compositeId, selections, locationId) {
|
|
190
|
+
return this.client.call(
|
|
191
|
+
"composite.calculatePrice",
|
|
192
|
+
{
|
|
193
|
+
composite_id: compositeId,
|
|
194
|
+
selections,
|
|
195
|
+
location_id: locationId
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
// --------------------------------------------------------------------------
|
|
200
|
+
// SEARCH
|
|
201
|
+
// --------------------------------------------------------------------------
|
|
202
|
+
async search(query2, options) {
|
|
203
|
+
const limit = options?.limit ?? 20;
|
|
204
|
+
let searchQuery = `products[?(@.name contains '${query2}')]`;
|
|
205
|
+
if (options?.category) {
|
|
206
|
+
searchQuery = `products[?(@.name contains '${query2}' && @.category_id=='${options.category}')]`;
|
|
207
|
+
}
|
|
208
|
+
searchQuery += `#limit(${limit})`;
|
|
209
|
+
return this.client.query(searchQuery);
|
|
210
|
+
}
|
|
211
|
+
async searchProducts(query2, options) {
|
|
212
|
+
return this.client.call("catalogue.search", {
|
|
213
|
+
query: query2,
|
|
214
|
+
limit: options?.limit ?? 20,
|
|
215
|
+
category: options?.category
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
// --------------------------------------------------------------------------
|
|
219
|
+
// MENU (Restaurant-specific)
|
|
220
|
+
// --------------------------------------------------------------------------
|
|
221
|
+
async getMenu(options) {
|
|
222
|
+
let query2 = "menu";
|
|
223
|
+
if (options?.category) {
|
|
224
|
+
query2 = `menu[?(@.category=='${options.category}')]`;
|
|
225
|
+
}
|
|
226
|
+
if (options?.limit) {
|
|
227
|
+
query2 += `#limit(${options.limit})`;
|
|
228
|
+
}
|
|
229
|
+
return this.client.query(query2);
|
|
230
|
+
}
|
|
231
|
+
async getMenuCategory(categoryId) {
|
|
232
|
+
return this.client.query(`menu.category.${categoryId}`);
|
|
233
|
+
}
|
|
234
|
+
async getMenuItem(itemId) {
|
|
235
|
+
return this.client.query(`menu.${itemId}`);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// src/cart.ts
|
|
240
|
+
var CartOperations = class {
|
|
241
|
+
constructor(client) {
|
|
242
|
+
this.client = client;
|
|
243
|
+
}
|
|
244
|
+
// --------------------------------------------------------------------------
|
|
245
|
+
// CART QUERIES
|
|
246
|
+
// --------------------------------------------------------------------------
|
|
247
|
+
/**
|
|
248
|
+
* Get the enriched cart with product names, images, and details.
|
|
249
|
+
* This is the main method for storefront display.
|
|
250
|
+
*/
|
|
251
|
+
async get() {
|
|
252
|
+
return this.client.query("cart#enriched");
|
|
253
|
+
}
|
|
254
|
+
async getRaw() {
|
|
255
|
+
return this.client.query("cart");
|
|
256
|
+
}
|
|
257
|
+
async getItems() {
|
|
258
|
+
return this.client.query("cart_items");
|
|
259
|
+
}
|
|
260
|
+
async getCount() {
|
|
261
|
+
return this.client.query("cart#count");
|
|
262
|
+
}
|
|
263
|
+
async getTotal() {
|
|
264
|
+
return this.client.query("cart#total");
|
|
265
|
+
}
|
|
266
|
+
async getSummary() {
|
|
267
|
+
const cart = await this.get();
|
|
268
|
+
return {
|
|
269
|
+
item_count: cart.items.length,
|
|
270
|
+
total_items: cart.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
271
|
+
subtotal: cart.pricing.subtotal,
|
|
272
|
+
discount_amount: cart.pricing.total_discounts,
|
|
273
|
+
tax_amount: cart.pricing.tax_amount,
|
|
274
|
+
total: cart.pricing.total_price,
|
|
275
|
+
currency: cart.pricing.currency
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// --------------------------------------------------------------------------
|
|
279
|
+
// CART MUTATIONS
|
|
280
|
+
// --------------------------------------------------------------------------
|
|
281
|
+
async addItem(input) {
|
|
282
|
+
return this.client.call("cart.addItem", input);
|
|
283
|
+
}
|
|
284
|
+
async updateItem(cartItemId, updates) {
|
|
285
|
+
return this.client.call("cart.updateItem", {
|
|
286
|
+
cart_item_id: cartItemId,
|
|
287
|
+
...updates
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
async updateQuantity(cartItemId, quantity) {
|
|
291
|
+
return this.client.call("cart.updateItemQuantity", {
|
|
292
|
+
cart_item_id: cartItemId,
|
|
293
|
+
quantity
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
async removeItem(cartItemId) {
|
|
297
|
+
return this.client.call("cart.removeItem", {
|
|
298
|
+
cart_item_id: cartItemId
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
async clear() {
|
|
302
|
+
return this.client.call("cart.clearCart");
|
|
303
|
+
}
|
|
304
|
+
// --------------------------------------------------------------------------
|
|
305
|
+
// COUPONS & DISCOUNTS
|
|
306
|
+
// --------------------------------------------------------------------------
|
|
307
|
+
async applyCoupon(code) {
|
|
308
|
+
return this.client.call("cart.applyCoupon", {
|
|
309
|
+
coupon_code: code
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async removeCoupon() {
|
|
313
|
+
return this.client.call("cart.removeCoupon");
|
|
314
|
+
}
|
|
315
|
+
// --------------------------------------------------------------------------
|
|
316
|
+
// CONVENIENCE METHODS
|
|
317
|
+
// --------------------------------------------------------------------------
|
|
318
|
+
async isEmpty() {
|
|
319
|
+
const count = await this.getCount();
|
|
320
|
+
return count === 0;
|
|
321
|
+
}
|
|
322
|
+
async hasItem(productId, variantId) {
|
|
323
|
+
const items = await this.getItems();
|
|
324
|
+
return items.some((item) => {
|
|
325
|
+
const matchesProduct = item.item_id === productId;
|
|
326
|
+
if (!variantId) return matchesProduct;
|
|
327
|
+
const config = item.configuration;
|
|
328
|
+
if ("variant" in config && config.variant) {
|
|
329
|
+
return matchesProduct && config.variant.variant_id === variantId;
|
|
330
|
+
}
|
|
331
|
+
return matchesProduct;
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async findItem(productId, variantId) {
|
|
335
|
+
const items = await this.getItems();
|
|
336
|
+
return items.find((item) => {
|
|
337
|
+
const matchesProduct = item.item_id === productId;
|
|
338
|
+
if (!variantId) return matchesProduct;
|
|
339
|
+
const config = item.configuration;
|
|
340
|
+
if ("variant" in config && config.variant) {
|
|
341
|
+
return matchesProduct && config.variant.variant_id === variantId;
|
|
342
|
+
}
|
|
343
|
+
return matchesProduct;
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// src/constants.ts
|
|
349
|
+
var CHECKOUT_MODE = {
|
|
350
|
+
LINK: "link",
|
|
351
|
+
GUEST: "guest"
|
|
352
|
+
};
|
|
353
|
+
var ORDER_TYPE = {
|
|
354
|
+
DELIVERY: "delivery",
|
|
355
|
+
PICKUP: "pickup",
|
|
356
|
+
DINE_IN: "dine-in",
|
|
357
|
+
WALK_IN: "walk-in"
|
|
358
|
+
};
|
|
359
|
+
var PAYMENT_METHOD = {
|
|
360
|
+
MOBILE_MONEY: "mobile_money",
|
|
361
|
+
CARD: "card"
|
|
362
|
+
};
|
|
363
|
+
var CHECKOUT_STEP = {
|
|
364
|
+
AUTHENTICATION: "authentication",
|
|
365
|
+
ORDER_DETAILS: "order_details",
|
|
366
|
+
PAYMENT_METHOD: "payment_method",
|
|
367
|
+
PAYMENT: "payment",
|
|
368
|
+
CONFIRMATION: "confirmation"
|
|
369
|
+
};
|
|
370
|
+
var PAYMENT_STATE = {
|
|
371
|
+
INITIAL: "initial",
|
|
372
|
+
PREPARING: "preparing",
|
|
373
|
+
PROCESSING: "processing",
|
|
374
|
+
VERIFYING: "verifying",
|
|
375
|
+
AWAITING_AUTHORIZATION: "awaiting_authorization",
|
|
376
|
+
SUCCESS: "success",
|
|
377
|
+
ERROR: "error",
|
|
378
|
+
TIMEOUT: "timeout"
|
|
379
|
+
};
|
|
380
|
+
var PICKUP_TIME_TYPE = {
|
|
381
|
+
ASAP: "asap",
|
|
382
|
+
SCHEDULED: "scheduled"
|
|
383
|
+
};
|
|
384
|
+
var MOBILE_MONEY_PROVIDER = {
|
|
385
|
+
MTN: "mtn",
|
|
386
|
+
VODAFONE: "vodafone",
|
|
387
|
+
AIRTEL: "airtel"
|
|
388
|
+
};
|
|
389
|
+
var AUTHORIZATION_TYPE = {
|
|
390
|
+
OTP: "otp",
|
|
391
|
+
PIN: "pin",
|
|
392
|
+
PHONE: "phone",
|
|
393
|
+
BIRTHDAY: "birthday",
|
|
394
|
+
ADDRESS: "address"
|
|
395
|
+
};
|
|
396
|
+
var LINK_QUERY = {
|
|
397
|
+
DATA: "link.data",
|
|
398
|
+
ADDRESSES: "link.addresses",
|
|
399
|
+
MOBILE_MONEY: "link.mobile_money",
|
|
400
|
+
PREFERENCES: "link.preferences",
|
|
401
|
+
SESSIONS: "link.sessions"
|
|
402
|
+
};
|
|
403
|
+
var LINK_MUTATION = {
|
|
404
|
+
CHECK_STATUS: "link.check_status",
|
|
405
|
+
ENROLL: "link.enroll",
|
|
406
|
+
ENROLL_AND_LINK_ORDER: "link.enroll_and_link_order",
|
|
407
|
+
UPDATE_PREFERENCES: "link.update_preferences",
|
|
408
|
+
CREATE_ADDRESS: "link.create_address",
|
|
409
|
+
UPDATE_ADDRESS: "link.update_address",
|
|
410
|
+
DELETE_ADDRESS: "link.delete_address",
|
|
411
|
+
SET_DEFAULT_ADDRESS: "link.set_default_address",
|
|
412
|
+
TRACK_ADDRESS_USAGE: "link.track_address_usage",
|
|
413
|
+
CREATE_MOBILE_MONEY: "link.create_mobile_money",
|
|
414
|
+
DELETE_MOBILE_MONEY: "link.delete_mobile_money",
|
|
415
|
+
SET_DEFAULT_MOBILE_MONEY: "link.set_default_mobile_money",
|
|
416
|
+
TRACK_MOBILE_MONEY_USAGE: "link.track_mobile_money_usage",
|
|
417
|
+
VERIFY_MOBILE_MONEY: "link.verify_mobile_money",
|
|
418
|
+
REVOKE_SESSION: "link.revoke_session",
|
|
419
|
+
REVOKE_ALL_SESSIONS: "link.revoke_all_sessions"
|
|
420
|
+
};
|
|
421
|
+
var AUTH_MUTATION = {
|
|
422
|
+
REQUEST_OTP: "auth.request_otp",
|
|
423
|
+
VERIFY_OTP: "auth.verify_otp"
|
|
424
|
+
};
|
|
425
|
+
var CHECKOUT_MUTATION = {
|
|
426
|
+
PROCESS: "checkout.process"
|
|
427
|
+
};
|
|
428
|
+
var PAYMENT_MUTATION = {
|
|
429
|
+
SUBMIT_AUTHORIZATION: "payment.submit_authorization",
|
|
430
|
+
CHECK_STATUS: "order.poll_payment_status"
|
|
431
|
+
};
|
|
432
|
+
var ORDER_MUTATION = {
|
|
433
|
+
UPDATE_CUSTOMER: "order.update_order_customer"
|
|
434
|
+
};
|
|
435
|
+
var DEFAULT_CURRENCY = "GHS";
|
|
436
|
+
var DEFAULT_COUNTRY = "GHA";
|
|
437
|
+
|
|
438
|
+
// src/checkout.ts
|
|
439
|
+
var CheckoutService = class {
|
|
440
|
+
constructor(client) {
|
|
441
|
+
this.client = client;
|
|
442
|
+
}
|
|
443
|
+
async process(data) {
|
|
444
|
+
return this.client.call(CHECKOUT_MUTATION.PROCESS, {
|
|
445
|
+
checkout_data: data
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
async initializePayment(orderId, method) {
|
|
449
|
+
return this.client.call("order.initializePayment", {
|
|
450
|
+
order_id: orderId,
|
|
451
|
+
payment_method: method
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
async submitAuthorization(input) {
|
|
455
|
+
return this.client.call(
|
|
456
|
+
PAYMENT_MUTATION.SUBMIT_AUTHORIZATION,
|
|
457
|
+
input
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
async pollPaymentStatus(orderId) {
|
|
461
|
+
return this.client.call(
|
|
462
|
+
PAYMENT_MUTATION.CHECK_STATUS,
|
|
463
|
+
orderId
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
async updateOrderCustomer(orderId, customer) {
|
|
467
|
+
return this.client.call(ORDER_MUTATION.UPDATE_CUSTOMER, {
|
|
468
|
+
order_id: orderId,
|
|
469
|
+
...customer
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
async verifyPayment(orderId) {
|
|
473
|
+
return this.client.call("order.verifyPayment", {
|
|
474
|
+
order_id: orderId
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
// src/orders.ts
|
|
480
|
+
var OrderQueries = class {
|
|
481
|
+
constructor(client) {
|
|
482
|
+
this.client = client;
|
|
483
|
+
}
|
|
484
|
+
async list(options) {
|
|
485
|
+
let query2 = "orders";
|
|
486
|
+
if (options?.status) {
|
|
487
|
+
query2 += `[?(@.status=='${options.status}')]`;
|
|
488
|
+
}
|
|
489
|
+
query2 += "#sort(created_at,desc)";
|
|
490
|
+
if (options?.limit) {
|
|
491
|
+
query2 += `#limit(${options.limit})`;
|
|
492
|
+
}
|
|
493
|
+
if (options?.offset) {
|
|
494
|
+
query2 += `#offset(${options.offset})`;
|
|
495
|
+
}
|
|
496
|
+
return this.client.query(query2);
|
|
497
|
+
}
|
|
498
|
+
async get(orderId) {
|
|
499
|
+
return this.client.query(`orders.${orderId}`);
|
|
500
|
+
}
|
|
501
|
+
async getRecent(limit = 5) {
|
|
502
|
+
return this.client.query(
|
|
503
|
+
`orders#sort(created_at,desc)#limit(${limit})`
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
async getByStatus(status) {
|
|
507
|
+
return this.client.query(`orders[?(@.status=='${status}')]`);
|
|
508
|
+
}
|
|
509
|
+
async cancel(orderId, reason) {
|
|
510
|
+
return this.client.call("order.cancelOrder", {
|
|
511
|
+
order_id: orderId,
|
|
512
|
+
reason
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
// src/link.ts
|
|
518
|
+
var LinkService = class {
|
|
519
|
+
constructor(client) {
|
|
520
|
+
this.client = client;
|
|
521
|
+
}
|
|
522
|
+
async requestOtp(input) {
|
|
523
|
+
return this.client.linkPost("/v1/link/auth/request-otp", input);
|
|
524
|
+
}
|
|
525
|
+
async verifyOtp(input) {
|
|
526
|
+
const response = await this.client.linkPost(
|
|
527
|
+
"/v1/link/auth/verify-otp",
|
|
528
|
+
input
|
|
529
|
+
);
|
|
530
|
+
if (response.session_token) {
|
|
531
|
+
this.client.setSessionToken(response.session_token);
|
|
532
|
+
}
|
|
533
|
+
return response;
|
|
534
|
+
}
|
|
535
|
+
async logout() {
|
|
536
|
+
const result = await this.client.linkPost("/v1/link/auth/logout");
|
|
537
|
+
this.client.clearSession();
|
|
538
|
+
return result;
|
|
539
|
+
}
|
|
540
|
+
async checkStatus(contact) {
|
|
541
|
+
return this.client.call(LINK_MUTATION.CHECK_STATUS, {
|
|
542
|
+
contact
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
async getLinkData() {
|
|
546
|
+
return this.client.query(LINK_QUERY.DATA);
|
|
547
|
+
}
|
|
548
|
+
async getAddresses() {
|
|
549
|
+
return this.client.query(LINK_QUERY.ADDRESSES);
|
|
550
|
+
}
|
|
551
|
+
async getMobileMoney() {
|
|
552
|
+
return this.client.query(LINK_QUERY.MOBILE_MONEY);
|
|
553
|
+
}
|
|
554
|
+
async getPreferences() {
|
|
555
|
+
return this.client.query(LINK_QUERY.PREFERENCES);
|
|
556
|
+
}
|
|
557
|
+
async enroll(data) {
|
|
558
|
+
return this.client.call(LINK_MUTATION.ENROLL, data);
|
|
559
|
+
}
|
|
560
|
+
async enrollAndLinkOrder(data) {
|
|
561
|
+
return this.client.call(
|
|
562
|
+
LINK_MUTATION.ENROLL_AND_LINK_ORDER,
|
|
563
|
+
data
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
async updatePreferences(preferences) {
|
|
567
|
+
return this.client.call(
|
|
568
|
+
LINK_MUTATION.UPDATE_PREFERENCES,
|
|
569
|
+
preferences
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
async createAddress(input) {
|
|
573
|
+
return this.client.call(
|
|
574
|
+
LINK_MUTATION.CREATE_ADDRESS,
|
|
575
|
+
input
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
async updateAddress(input) {
|
|
579
|
+
return this.client.call(LINK_MUTATION.UPDATE_ADDRESS, input);
|
|
580
|
+
}
|
|
581
|
+
async deleteAddress(addressId) {
|
|
582
|
+
return this.client.call(
|
|
583
|
+
LINK_MUTATION.DELETE_ADDRESS,
|
|
584
|
+
addressId
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
async setDefaultAddress(addressId) {
|
|
588
|
+
return this.client.call(
|
|
589
|
+
LINK_MUTATION.SET_DEFAULT_ADDRESS,
|
|
590
|
+
addressId
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
async trackAddressUsage(addressId) {
|
|
594
|
+
return this.client.call(LINK_MUTATION.TRACK_ADDRESS_USAGE, {
|
|
595
|
+
address_id: addressId
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
async createMobileMoney(input) {
|
|
599
|
+
return this.client.call(
|
|
600
|
+
LINK_MUTATION.CREATE_MOBILE_MONEY,
|
|
601
|
+
input
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
async deleteMobileMoney(mobileMoneyId) {
|
|
605
|
+
return this.client.call(
|
|
606
|
+
LINK_MUTATION.DELETE_MOBILE_MONEY,
|
|
607
|
+
mobileMoneyId
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
async setDefaultMobileMoney(mobileMoneyId) {
|
|
611
|
+
return this.client.call(
|
|
612
|
+
LINK_MUTATION.SET_DEFAULT_MOBILE_MONEY,
|
|
613
|
+
mobileMoneyId
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
async trackMobileMoneyUsage(mobileMoneyId) {
|
|
617
|
+
return this.client.call(LINK_MUTATION.TRACK_MOBILE_MONEY_USAGE, {
|
|
618
|
+
mobile_money_id: mobileMoneyId
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
async verifyMobileMoney(mobileMoneyId) {
|
|
622
|
+
return this.client.call(
|
|
623
|
+
LINK_MUTATION.VERIFY_MOBILE_MONEY,
|
|
624
|
+
mobileMoneyId
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
async getSessions() {
|
|
628
|
+
return this.client.linkGet("/v1/link/sessions");
|
|
629
|
+
}
|
|
630
|
+
async revokeSession(sessionId) {
|
|
631
|
+
return this.client.linkDelete(
|
|
632
|
+
`/v1/link/sessions/${sessionId}`
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
async revokeAllSessions() {
|
|
636
|
+
return this.client.linkDelete("/v1/link/sessions");
|
|
637
|
+
}
|
|
638
|
+
async getAddressesRest() {
|
|
639
|
+
return this.client.linkGet("/v1/link/addresses");
|
|
640
|
+
}
|
|
641
|
+
async createAddressRest(input) {
|
|
642
|
+
return this.client.linkPost("/v1/link/addresses", input);
|
|
643
|
+
}
|
|
644
|
+
async deleteAddressRest(addressId) {
|
|
645
|
+
return this.client.linkDelete(`/v1/link/addresses/${addressId}`);
|
|
646
|
+
}
|
|
647
|
+
async setDefaultAddressRest(addressId) {
|
|
648
|
+
return this.client.linkPost(
|
|
649
|
+
`/v1/link/addresses/${addressId}/default`
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
async getMobileMoneyRest() {
|
|
653
|
+
return this.client.linkGet("/v1/link/mobile-money");
|
|
654
|
+
}
|
|
655
|
+
async createMobileMoneyRest(input) {
|
|
656
|
+
return this.client.linkPost("/v1/link/mobile-money", input);
|
|
657
|
+
}
|
|
658
|
+
async deleteMobileMoneyRest(mobileMoneyId) {
|
|
659
|
+
return this.client.linkDelete(
|
|
660
|
+
`/v1/link/mobile-money/${mobileMoneyId}`
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
async setDefaultMobileMoneyRest(mobileMoneyId) {
|
|
664
|
+
return this.client.linkPost(
|
|
665
|
+
`/v1/link/mobile-money/${mobileMoneyId}/default`
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
// src/auth.ts
|
|
671
|
+
var AuthService = class {
|
|
672
|
+
constructor(client) {
|
|
673
|
+
this.client = client;
|
|
674
|
+
}
|
|
675
|
+
// --------------------------------------------------------------------------
|
|
676
|
+
// STATUS & USER
|
|
677
|
+
// --------------------------------------------------------------------------
|
|
678
|
+
async getStatus() {
|
|
679
|
+
return this.client.query("auth");
|
|
680
|
+
}
|
|
681
|
+
async getCurrentUser() {
|
|
682
|
+
const status = await this.getStatus();
|
|
683
|
+
return status.customer || null;
|
|
684
|
+
}
|
|
685
|
+
async isAuthenticated() {
|
|
686
|
+
const status = await this.getStatus();
|
|
687
|
+
return status.is_authenticated;
|
|
688
|
+
}
|
|
689
|
+
// --------------------------------------------------------------------------
|
|
690
|
+
// OTP AUTHENTICATION
|
|
691
|
+
// --------------------------------------------------------------------------
|
|
692
|
+
async requestOtp(contact, contactType) {
|
|
693
|
+
await this.client.call(AUTH_MUTATION.REQUEST_OTP, {
|
|
694
|
+
contact,
|
|
695
|
+
contact_type: contactType
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
async verifyOtp(code, contact) {
|
|
699
|
+
return this.client.call(AUTH_MUTATION.VERIFY_OTP, {
|
|
700
|
+
otp_code: code,
|
|
701
|
+
contact
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
// --------------------------------------------------------------------------
|
|
705
|
+
// SESSION MANAGEMENT
|
|
706
|
+
// --------------------------------------------------------------------------
|
|
707
|
+
async logout() {
|
|
708
|
+
return this.client.call("auth.logout");
|
|
709
|
+
}
|
|
710
|
+
// --------------------------------------------------------------------------
|
|
711
|
+
// PROFILE MANAGEMENT
|
|
712
|
+
// --------------------------------------------------------------------------
|
|
713
|
+
async updateProfile(input) {
|
|
714
|
+
return this.client.call("auth.update_profile", input);
|
|
715
|
+
}
|
|
716
|
+
async changePassword(input) {
|
|
717
|
+
return this.client.call("auth.change_password", input);
|
|
718
|
+
}
|
|
719
|
+
async resetPassword(email) {
|
|
720
|
+
return this.client.call("auth.reset_password", { email });
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/business.ts
|
|
725
|
+
var BusinessService = class {
|
|
726
|
+
constructor(client) {
|
|
727
|
+
this.client = client;
|
|
728
|
+
}
|
|
729
|
+
// --------------------------------------------------------------------------
|
|
730
|
+
// BUSINESS INFO
|
|
731
|
+
// --------------------------------------------------------------------------
|
|
732
|
+
async getInfo() {
|
|
733
|
+
return this.client.query("business.info");
|
|
734
|
+
}
|
|
735
|
+
async getByHandle(handle) {
|
|
736
|
+
return this.client.query(`business.handle.${handle}`);
|
|
737
|
+
}
|
|
738
|
+
async getByDomain(domain) {
|
|
739
|
+
return this.client.query("business.domain", { domain });
|
|
740
|
+
}
|
|
741
|
+
async getSettings() {
|
|
742
|
+
return this.client.query("business.settings");
|
|
743
|
+
}
|
|
744
|
+
async getTheme() {
|
|
745
|
+
return this.client.query("business.theme");
|
|
746
|
+
}
|
|
747
|
+
// --------------------------------------------------------------------------
|
|
748
|
+
// LOCATIONS
|
|
749
|
+
// --------------------------------------------------------------------------
|
|
750
|
+
async getLocations() {
|
|
751
|
+
return this.client.query("business.locations");
|
|
752
|
+
}
|
|
753
|
+
async getLocation(locationId) {
|
|
754
|
+
return this.client.query(`business.locations.${locationId}`);
|
|
755
|
+
}
|
|
756
|
+
// --------------------------------------------------------------------------
|
|
757
|
+
// HOURS
|
|
758
|
+
// --------------------------------------------------------------------------
|
|
759
|
+
async getHours() {
|
|
760
|
+
return this.client.query("business.hours");
|
|
761
|
+
}
|
|
762
|
+
async getLocationHours(locationId) {
|
|
763
|
+
return this.client.query(
|
|
764
|
+
`business.locations.${locationId}.hours`
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
// --------------------------------------------------------------------------
|
|
768
|
+
// BOOTSTRAP (for storefront initialization)
|
|
769
|
+
// --------------------------------------------------------------------------
|
|
770
|
+
async getBootstrap() {
|
|
771
|
+
const [business, locations, categories] = await Promise.all([
|
|
772
|
+
this.getInfo(),
|
|
773
|
+
this.getLocations(),
|
|
774
|
+
this.client.query("categories#select(id,name,slug)")
|
|
775
|
+
]);
|
|
776
|
+
const defaultLocation = locations[0];
|
|
777
|
+
return {
|
|
778
|
+
business,
|
|
779
|
+
location: defaultLocation,
|
|
780
|
+
locations,
|
|
781
|
+
categories,
|
|
782
|
+
currency: business.default_currency,
|
|
783
|
+
is_open: defaultLocation?.accepts_online_orders ?? false,
|
|
784
|
+
accepts_orders: defaultLocation?.accepts_online_orders ?? false
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
// src/inventory.ts
|
|
790
|
+
var InventoryService = class {
|
|
791
|
+
constructor(client) {
|
|
792
|
+
this.client = client;
|
|
793
|
+
}
|
|
794
|
+
// --------------------------------------------------------------------------
|
|
795
|
+
// STOCK QUERIES
|
|
796
|
+
// --------------------------------------------------------------------------
|
|
797
|
+
async getStockLevels() {
|
|
798
|
+
return this.client.query("inventory.stock_levels");
|
|
799
|
+
}
|
|
800
|
+
async getProductStock(productId, locationId) {
|
|
801
|
+
if (locationId) {
|
|
802
|
+
return this.client.query("inventory.product", {
|
|
803
|
+
product_id: productId,
|
|
804
|
+
location_id: locationId
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
return this.client.query("inventory.product", {
|
|
808
|
+
product_id: productId
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
async getVariantStock(variantId, locationId) {
|
|
812
|
+
return this.client.query("inventory.variant", {
|
|
813
|
+
variant_id: variantId,
|
|
814
|
+
location_id: locationId
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
// --------------------------------------------------------------------------
|
|
818
|
+
// AVAILABILITY CHECKS
|
|
819
|
+
// --------------------------------------------------------------------------
|
|
820
|
+
async checkProductAvailability(productId, quantity, locationId) {
|
|
821
|
+
return this.client.query("inventory.check_availability", {
|
|
822
|
+
product_id: productId,
|
|
823
|
+
quantity,
|
|
824
|
+
location_id: locationId
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
async checkVariantAvailability(variantId, quantity, locationId) {
|
|
828
|
+
return this.client.query("inventory.check_availability", {
|
|
829
|
+
variant_id: variantId,
|
|
830
|
+
quantity,
|
|
831
|
+
location_id: locationId
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
async checkMultipleAvailability(items, locationId) {
|
|
835
|
+
const results = await Promise.all(
|
|
836
|
+
items.map(
|
|
837
|
+
(item) => item.variant_id ? this.checkVariantAvailability(item.variant_id, item.quantity, locationId) : this.checkProductAvailability(item.product_id, item.quantity, locationId)
|
|
838
|
+
)
|
|
839
|
+
);
|
|
840
|
+
return results;
|
|
841
|
+
}
|
|
842
|
+
// --------------------------------------------------------------------------
|
|
843
|
+
// SUMMARY
|
|
844
|
+
// --------------------------------------------------------------------------
|
|
845
|
+
async getSummary() {
|
|
846
|
+
return this.client.query("inventory.summary");
|
|
847
|
+
}
|
|
848
|
+
// --------------------------------------------------------------------------
|
|
849
|
+
// CONVENIENCE METHODS
|
|
850
|
+
// --------------------------------------------------------------------------
|
|
851
|
+
async isInStock(productId, locationId) {
|
|
852
|
+
const result = await this.checkProductAvailability(productId, 1, locationId);
|
|
853
|
+
return result.is_available;
|
|
854
|
+
}
|
|
855
|
+
async getAvailableQuantity(productId, locationId) {
|
|
856
|
+
const stock = await this.getProductStock(productId, locationId);
|
|
857
|
+
return stock.available_quantity;
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
// src/scheduling.ts
|
|
862
|
+
var SchedulingService = class {
|
|
863
|
+
constructor(client) {
|
|
864
|
+
this.client = client;
|
|
865
|
+
}
|
|
866
|
+
// --------------------------------------------------------------------------
|
|
867
|
+
// SERVICES
|
|
868
|
+
// --------------------------------------------------------------------------
|
|
869
|
+
async getServices() {
|
|
870
|
+
return this.client.query("scheduling.services");
|
|
871
|
+
}
|
|
872
|
+
async getService(serviceId) {
|
|
873
|
+
return this.client.query(`scheduling.services.${serviceId}`);
|
|
874
|
+
}
|
|
875
|
+
// --------------------------------------------------------------------------
|
|
876
|
+
// AVAILABILITY
|
|
877
|
+
// --------------------------------------------------------------------------
|
|
878
|
+
async getAvailableSlots(input) {
|
|
879
|
+
return this.client.query(
|
|
880
|
+
"scheduling.available_slots",
|
|
881
|
+
input
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
async checkSlotAvailability(input) {
|
|
885
|
+
return this.client.query(
|
|
886
|
+
"scheduling.check_slot",
|
|
887
|
+
input
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
async getServiceAvailability(params) {
|
|
891
|
+
return this.client.query(
|
|
892
|
+
"scheduling.service_availability",
|
|
893
|
+
params
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
// --------------------------------------------------------------------------
|
|
897
|
+
// BOOKINGS
|
|
898
|
+
// --------------------------------------------------------------------------
|
|
899
|
+
async getBooking(bookingId) {
|
|
900
|
+
return this.client.query(`scheduling.bookings.${bookingId}`);
|
|
901
|
+
}
|
|
902
|
+
async getCustomerBookings() {
|
|
903
|
+
return this.client.query("scheduling.customer_bookings");
|
|
904
|
+
}
|
|
905
|
+
async getUpcomingBookings() {
|
|
906
|
+
return this.client.query(
|
|
907
|
+
"scheduling.customer_bookings[?(@.status!='completed' && @.status!='cancelled')]#sort(start_time,asc)"
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
async getPastBookings(limit = 10) {
|
|
911
|
+
return this.client.query(
|
|
912
|
+
`scheduling.customer_bookings[?(@.status=='completed')]#sort(start_time,desc)#limit(${limit})`
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
// --------------------------------------------------------------------------
|
|
916
|
+
// BOOKING MANAGEMENT
|
|
917
|
+
// --------------------------------------------------------------------------
|
|
918
|
+
async cancelBooking(input) {
|
|
919
|
+
return this.client.call("scheduling.cancel_booking", input);
|
|
920
|
+
}
|
|
921
|
+
async rescheduleBooking(input) {
|
|
922
|
+
return this.client.call("scheduling.reschedule_booking", input);
|
|
923
|
+
}
|
|
924
|
+
// --------------------------------------------------------------------------
|
|
925
|
+
// CONVENIENCE METHODS
|
|
926
|
+
// --------------------------------------------------------------------------
|
|
927
|
+
async getNextAvailableSlot(serviceId, fromDate) {
|
|
928
|
+
const date = fromDate || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
929
|
+
const slots = await this.getAvailableSlots({
|
|
930
|
+
service_id: serviceId,
|
|
931
|
+
date
|
|
932
|
+
});
|
|
933
|
+
return slots.find((slot) => slot.is_available) || null;
|
|
934
|
+
}
|
|
935
|
+
async hasAvailabilityOn(serviceId, date) {
|
|
936
|
+
const slots = await this.getAvailableSlots({
|
|
937
|
+
service_id: serviceId,
|
|
938
|
+
date
|
|
939
|
+
});
|
|
940
|
+
return slots.some((slot) => slot.is_available);
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// src/lite.ts
|
|
945
|
+
var LiteService = class {
|
|
946
|
+
constructor(client) {
|
|
947
|
+
this.client = client;
|
|
948
|
+
}
|
|
949
|
+
// --------------------------------------------------------------------------
|
|
950
|
+
// BOOTSTRAP
|
|
951
|
+
// --------------------------------------------------------------------------
|
|
952
|
+
async getBootstrap() {
|
|
953
|
+
return this.client.query("lite.bootstrap");
|
|
954
|
+
}
|
|
955
|
+
// --------------------------------------------------------------------------
|
|
956
|
+
// TABLE MANAGEMENT
|
|
957
|
+
// --------------------------------------------------------------------------
|
|
958
|
+
async getTable(tableId) {
|
|
959
|
+
return this.client.query(`lite.table.${tableId}`);
|
|
960
|
+
}
|
|
961
|
+
async getTableByNumber(tableNumber, locationId) {
|
|
962
|
+
return this.client.query("lite.table_by_number", {
|
|
963
|
+
table_number: tableNumber,
|
|
964
|
+
location_id: locationId
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
// --------------------------------------------------------------------------
|
|
968
|
+
// KITCHEN ORDERS
|
|
969
|
+
// --------------------------------------------------------------------------
|
|
970
|
+
async sendToKitchen(tableId, items) {
|
|
971
|
+
return this.client.call("lite.send_to_kitchen", {
|
|
972
|
+
table_id: tableId,
|
|
973
|
+
items
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
async callWaiter(tableId, reason) {
|
|
977
|
+
return this.client.call("lite.call_waiter", {
|
|
978
|
+
table_id: tableId,
|
|
979
|
+
reason
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
async requestBill(tableId) {
|
|
983
|
+
return this.client.call(
|
|
984
|
+
"lite.request_bill",
|
|
985
|
+
{ table_id: tableId }
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
// --------------------------------------------------------------------------
|
|
989
|
+
// MENU (optimized for lite/QR experience)
|
|
990
|
+
// --------------------------------------------------------------------------
|
|
991
|
+
async getMenu() {
|
|
992
|
+
return this.client.query("lite.menu");
|
|
993
|
+
}
|
|
994
|
+
async getMenuByCategory(categoryId) {
|
|
995
|
+
return this.client.query(`lite.menu.category.${categoryId}`);
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// src/client.ts
|
|
1000
|
+
var SESSION_TOKEN_HEADER = "x-session-token";
|
|
1001
|
+
var SESSION_STORAGE_KEY = "cimplify_session_token";
|
|
1002
|
+
function deriveUrls() {
|
|
1003
|
+
const hostname = typeof window !== "undefined" ? window.location.hostname : "";
|
|
1004
|
+
if (hostname === "localhost" || hostname === "127.0.0.1") {
|
|
1005
|
+
const protocol = window.location.protocol;
|
|
1006
|
+
return {
|
|
1007
|
+
baseUrl: `${protocol}//${hostname}:8082`,
|
|
1008
|
+
linkApiUrl: `${protocol}//${hostname}:8080`
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
return {
|
|
1012
|
+
baseUrl: "https://storefronts.cimplify.io",
|
|
1013
|
+
linkApiUrl: "https://api.cimplify.io"
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
var CimplifyClient = class {
|
|
1017
|
+
constructor(config = {}) {
|
|
1018
|
+
this.sessionToken = null;
|
|
1019
|
+
this.publicKey = config.publicKey || "";
|
|
1020
|
+
const urls = deriveUrls();
|
|
1021
|
+
this.baseUrl = urls.baseUrl;
|
|
1022
|
+
this.linkApiUrl = urls.linkApiUrl;
|
|
1023
|
+
this.credentials = config.credentials || "include";
|
|
1024
|
+
this.sessionToken = this.loadSessionToken();
|
|
1025
|
+
}
|
|
1026
|
+
getSessionToken() {
|
|
1027
|
+
return this.sessionToken;
|
|
1028
|
+
}
|
|
1029
|
+
setSessionToken(token) {
|
|
1030
|
+
this.sessionToken = token;
|
|
1031
|
+
this.saveSessionToken(token);
|
|
1032
|
+
}
|
|
1033
|
+
clearSession() {
|
|
1034
|
+
this.sessionToken = null;
|
|
1035
|
+
this.saveSessionToken(null);
|
|
1036
|
+
}
|
|
1037
|
+
loadSessionToken() {
|
|
1038
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
1039
|
+
return localStorage.getItem(SESSION_STORAGE_KEY);
|
|
1040
|
+
}
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
saveSessionToken(token) {
|
|
1044
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
1045
|
+
if (token) {
|
|
1046
|
+
localStorage.setItem(SESSION_STORAGE_KEY, token);
|
|
1047
|
+
} else {
|
|
1048
|
+
localStorage.removeItem(SESSION_STORAGE_KEY);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
getHeaders() {
|
|
1053
|
+
const headers = {
|
|
1054
|
+
"Content-Type": "application/json",
|
|
1055
|
+
"X-API-Key": this.publicKey
|
|
1056
|
+
};
|
|
1057
|
+
if (this.sessionToken) {
|
|
1058
|
+
headers[SESSION_TOKEN_HEADER] = this.sessionToken;
|
|
1059
|
+
}
|
|
1060
|
+
return headers;
|
|
1061
|
+
}
|
|
1062
|
+
updateSessionFromResponse(response) {
|
|
1063
|
+
const newToken = response.headers.get(SESSION_TOKEN_HEADER);
|
|
1064
|
+
if (newToken && newToken !== this.sessionToken) {
|
|
1065
|
+
this.sessionToken = newToken;
|
|
1066
|
+
this.saveSessionToken(newToken);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
async query(query2, variables) {
|
|
1070
|
+
const body = { query: query2 };
|
|
1071
|
+
if (variables) {
|
|
1072
|
+
body.variables = variables;
|
|
1073
|
+
}
|
|
1074
|
+
const response = await fetch(`${this.baseUrl}/api/q`, {
|
|
1075
|
+
method: "POST",
|
|
1076
|
+
credentials: this.credentials,
|
|
1077
|
+
headers: this.getHeaders(),
|
|
1078
|
+
body: JSON.stringify(body)
|
|
1079
|
+
});
|
|
1080
|
+
this.updateSessionFromResponse(response);
|
|
1081
|
+
return this.handleResponse(response);
|
|
1082
|
+
}
|
|
1083
|
+
async call(method, args) {
|
|
1084
|
+
const body = {
|
|
1085
|
+
method,
|
|
1086
|
+
args: args !== void 0 ? [args] : []
|
|
1087
|
+
};
|
|
1088
|
+
const response = await fetch(`${this.baseUrl}/api/m`, {
|
|
1089
|
+
method: "POST",
|
|
1090
|
+
credentials: this.credentials,
|
|
1091
|
+
headers: this.getHeaders(),
|
|
1092
|
+
body: JSON.stringify(body)
|
|
1093
|
+
});
|
|
1094
|
+
this.updateSessionFromResponse(response);
|
|
1095
|
+
return this.handleResponse(response);
|
|
1096
|
+
}
|
|
1097
|
+
async get(path) {
|
|
1098
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
1099
|
+
method: "GET",
|
|
1100
|
+
credentials: this.credentials,
|
|
1101
|
+
headers: this.getHeaders()
|
|
1102
|
+
});
|
|
1103
|
+
this.updateSessionFromResponse(response);
|
|
1104
|
+
return this.handleRestResponse(response);
|
|
1105
|
+
}
|
|
1106
|
+
async post(path, body) {
|
|
1107
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
1108
|
+
method: "POST",
|
|
1109
|
+
credentials: this.credentials,
|
|
1110
|
+
headers: this.getHeaders(),
|
|
1111
|
+
body: body ? JSON.stringify(body) : void 0
|
|
1112
|
+
});
|
|
1113
|
+
this.updateSessionFromResponse(response);
|
|
1114
|
+
return this.handleRestResponse(response);
|
|
1115
|
+
}
|
|
1116
|
+
async delete(path) {
|
|
1117
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
1118
|
+
method: "DELETE",
|
|
1119
|
+
credentials: this.credentials,
|
|
1120
|
+
headers: this.getHeaders()
|
|
1121
|
+
});
|
|
1122
|
+
this.updateSessionFromResponse(response);
|
|
1123
|
+
return this.handleRestResponse(response);
|
|
1124
|
+
}
|
|
1125
|
+
async linkGet(path) {
|
|
1126
|
+
const response = await fetch(`${this.linkApiUrl}${path}`, {
|
|
1127
|
+
method: "GET",
|
|
1128
|
+
credentials: this.credentials,
|
|
1129
|
+
headers: this.getHeaders()
|
|
1130
|
+
});
|
|
1131
|
+
this.updateSessionFromResponse(response);
|
|
1132
|
+
return this.handleRestResponse(response);
|
|
1133
|
+
}
|
|
1134
|
+
async linkPost(path, body) {
|
|
1135
|
+
const response = await fetch(`${this.linkApiUrl}${path}`, {
|
|
1136
|
+
method: "POST",
|
|
1137
|
+
credentials: this.credentials,
|
|
1138
|
+
headers: this.getHeaders(),
|
|
1139
|
+
body: body ? JSON.stringify(body) : void 0
|
|
1140
|
+
});
|
|
1141
|
+
this.updateSessionFromResponse(response);
|
|
1142
|
+
return this.handleRestResponse(response);
|
|
1143
|
+
}
|
|
1144
|
+
async linkDelete(path) {
|
|
1145
|
+
const response = await fetch(`${this.linkApiUrl}${path}`, {
|
|
1146
|
+
method: "DELETE",
|
|
1147
|
+
credentials: this.credentials,
|
|
1148
|
+
headers: this.getHeaders()
|
|
1149
|
+
});
|
|
1150
|
+
this.updateSessionFromResponse(response);
|
|
1151
|
+
return this.handleRestResponse(response);
|
|
1152
|
+
}
|
|
1153
|
+
async handleRestResponse(response) {
|
|
1154
|
+
const json = await response.json();
|
|
1155
|
+
if (!response.ok) {
|
|
1156
|
+
throw new CimplifyError(
|
|
1157
|
+
json.error?.error_code || "API_ERROR",
|
|
1158
|
+
json.error?.error_message || "An error occurred",
|
|
1159
|
+
false
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
return json.data;
|
|
1163
|
+
}
|
|
1164
|
+
async handleResponse(response) {
|
|
1165
|
+
const json = await response.json();
|
|
1166
|
+
if (!json.success || json.error) {
|
|
1167
|
+
throw new CimplifyError(
|
|
1168
|
+
json.error?.code || "UNKNOWN_ERROR",
|
|
1169
|
+
json.error?.message || "An unknown error occurred",
|
|
1170
|
+
json.error?.retryable || false
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
return json.data;
|
|
1174
|
+
}
|
|
1175
|
+
get catalogue() {
|
|
1176
|
+
if (!this._catalogue) {
|
|
1177
|
+
this._catalogue = new CatalogueQueries(this);
|
|
1178
|
+
}
|
|
1179
|
+
return this._catalogue;
|
|
1180
|
+
}
|
|
1181
|
+
get cart() {
|
|
1182
|
+
if (!this._cart) {
|
|
1183
|
+
this._cart = new CartOperations(this);
|
|
1184
|
+
}
|
|
1185
|
+
return this._cart;
|
|
1186
|
+
}
|
|
1187
|
+
get checkout() {
|
|
1188
|
+
if (!this._checkout) {
|
|
1189
|
+
this._checkout = new CheckoutService(this);
|
|
1190
|
+
}
|
|
1191
|
+
return this._checkout;
|
|
1192
|
+
}
|
|
1193
|
+
get orders() {
|
|
1194
|
+
if (!this._orders) {
|
|
1195
|
+
this._orders = new OrderQueries(this);
|
|
1196
|
+
}
|
|
1197
|
+
return this._orders;
|
|
1198
|
+
}
|
|
1199
|
+
get link() {
|
|
1200
|
+
if (!this._link) {
|
|
1201
|
+
this._link = new LinkService(this);
|
|
1202
|
+
}
|
|
1203
|
+
return this._link;
|
|
1204
|
+
}
|
|
1205
|
+
get auth() {
|
|
1206
|
+
if (!this._auth) {
|
|
1207
|
+
this._auth = new AuthService(this);
|
|
1208
|
+
}
|
|
1209
|
+
return this._auth;
|
|
1210
|
+
}
|
|
1211
|
+
get business() {
|
|
1212
|
+
if (!this._business) {
|
|
1213
|
+
this._business = new BusinessService(this);
|
|
1214
|
+
}
|
|
1215
|
+
return this._business;
|
|
1216
|
+
}
|
|
1217
|
+
get inventory() {
|
|
1218
|
+
if (!this._inventory) {
|
|
1219
|
+
this._inventory = new InventoryService(this);
|
|
1220
|
+
}
|
|
1221
|
+
return this._inventory;
|
|
1222
|
+
}
|
|
1223
|
+
get scheduling() {
|
|
1224
|
+
if (!this._scheduling) {
|
|
1225
|
+
this._scheduling = new SchedulingService(this);
|
|
1226
|
+
}
|
|
1227
|
+
return this._scheduling;
|
|
1228
|
+
}
|
|
1229
|
+
get lite() {
|
|
1230
|
+
if (!this._lite) {
|
|
1231
|
+
this._lite = new LiteService(this);
|
|
1232
|
+
}
|
|
1233
|
+
return this._lite;
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
function createCimplifyClient(config) {
|
|
1237
|
+
return new CimplifyClient(config);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// src/query/builder.ts
|
|
1241
|
+
var QueryBuilder = class {
|
|
1242
|
+
constructor(entity) {
|
|
1243
|
+
this.filters = [];
|
|
1244
|
+
this.modifiers = [];
|
|
1245
|
+
this.pathSegments = [];
|
|
1246
|
+
this.entity = entity;
|
|
1247
|
+
}
|
|
1248
|
+
path(segment) {
|
|
1249
|
+
this.pathSegments.push(segment);
|
|
1250
|
+
return this;
|
|
1251
|
+
}
|
|
1252
|
+
where(field, op, value) {
|
|
1253
|
+
const v = typeof value === "string" ? `'${value}'` : value;
|
|
1254
|
+
if (op === "contains" || op === "startsWith") {
|
|
1255
|
+
this.filters.push(`@.${field} ${op} ${v}`);
|
|
1256
|
+
} else {
|
|
1257
|
+
this.filters.push(`@.${field}${op}${v}`);
|
|
1258
|
+
}
|
|
1259
|
+
return this;
|
|
1260
|
+
}
|
|
1261
|
+
and(field, op, value) {
|
|
1262
|
+
return this.where(field, op, value);
|
|
1263
|
+
}
|
|
1264
|
+
sort(field, order = "asc") {
|
|
1265
|
+
this.modifiers.push(`sort(${field},${order})`);
|
|
1266
|
+
return this;
|
|
1267
|
+
}
|
|
1268
|
+
limit(n) {
|
|
1269
|
+
this.modifiers.push(`limit(${n})`);
|
|
1270
|
+
return this;
|
|
1271
|
+
}
|
|
1272
|
+
offset(n) {
|
|
1273
|
+
this.modifiers.push(`offset(${n})`);
|
|
1274
|
+
return this;
|
|
1275
|
+
}
|
|
1276
|
+
count() {
|
|
1277
|
+
this.modifiers.push("count");
|
|
1278
|
+
return this;
|
|
1279
|
+
}
|
|
1280
|
+
enriched() {
|
|
1281
|
+
this.modifiers.push("enriched");
|
|
1282
|
+
return this;
|
|
1283
|
+
}
|
|
1284
|
+
build() {
|
|
1285
|
+
let query2 = this.entity;
|
|
1286
|
+
if (this.pathSegments.length > 0) {
|
|
1287
|
+
query2 += "." + this.pathSegments.join(".");
|
|
1288
|
+
}
|
|
1289
|
+
if (this.filters.length > 0) {
|
|
1290
|
+
query2 += `[?(${this.filters.join(" && ")})]`;
|
|
1291
|
+
}
|
|
1292
|
+
for (const mod of this.modifiers) {
|
|
1293
|
+
query2 += `#${mod}`;
|
|
1294
|
+
}
|
|
1295
|
+
return query2;
|
|
1296
|
+
}
|
|
1297
|
+
toString() {
|
|
1298
|
+
return this.build();
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
function query(entity) {
|
|
1302
|
+
return new QueryBuilder(entity);
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// src/utils/payment.ts
|
|
1306
|
+
var CURRENCY_SYMBOLS = {
|
|
1307
|
+
GHS: "GH\u20B5",
|
|
1308
|
+
USD: "$",
|
|
1309
|
+
EUR: "\u20AC",
|
|
1310
|
+
GBP: "\xA3",
|
|
1311
|
+
NGN: "\u20A6",
|
|
1312
|
+
KES: "KSh",
|
|
1313
|
+
ZAR: "R",
|
|
1314
|
+
XOF: "CFA",
|
|
1315
|
+
XAF: "FCFA"
|
|
1316
|
+
};
|
|
1317
|
+
function formatMoney(amount, currency = "GHS") {
|
|
1318
|
+
const symbol = CURRENCY_SYMBOLS[currency.toUpperCase()] || currency;
|
|
1319
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1320
|
+
return `${symbol}${numAmount.toFixed(2)}`;
|
|
1321
|
+
}
|
|
1322
|
+
function categorizePaymentError(error, errorCode) {
|
|
1323
|
+
let message = "An unexpected error occurred during payment processing. Please try again or contact support.";
|
|
1324
|
+
let recoverable = true;
|
|
1325
|
+
let code = errorCode || "PAYMENT_ERROR";
|
|
1326
|
+
const technical = error.stack;
|
|
1327
|
+
const errorMessage = error.message?.toLowerCase() || "";
|
|
1328
|
+
if (errorCode === "INSUFFICIENT_FUNDS" || errorMessage.includes("insufficient") || errorMessage.includes("funds")) {
|
|
1329
|
+
code = "INSUFFICIENT_FUNDS";
|
|
1330
|
+
message = "Your payment method has insufficient funds. Please try another payment method.";
|
|
1331
|
+
} else if (errorCode === "CARD_DECLINED" || errorMessage.includes("declined")) {
|
|
1332
|
+
code = "CARD_DECLINED";
|
|
1333
|
+
message = "Your card was declined. Please try another card or payment method.";
|
|
1334
|
+
} else if (errorMessage.includes("cancelled") || errorMessage.includes("canceled") || errorCode === "PAYMENT_CANCELLED") {
|
|
1335
|
+
code = "PAYMENT_CANCELLED";
|
|
1336
|
+
message = "Payment was cancelled. You can try again when ready.";
|
|
1337
|
+
} else if (errorMessage.includes("network") || errorMessage.includes("connection") || errorCode === "NETWORK_ERROR") {
|
|
1338
|
+
code = "NETWORK_ERROR";
|
|
1339
|
+
message = "Network connection issue. Please check your internet connection and try again.";
|
|
1340
|
+
} else if (errorMessage.includes("timeout") || errorCode === "TIMEOUT") {
|
|
1341
|
+
code = "TIMEOUT";
|
|
1342
|
+
message = "Payment processing timed out. Please try again.";
|
|
1343
|
+
} else if (errorCode === "PAYMENT_ACTION_NOT_COMPLETED") {
|
|
1344
|
+
code = "PAYMENT_ACTION_NOT_COMPLETED";
|
|
1345
|
+
message = "Payment action was not completed. Please try again.";
|
|
1346
|
+
} else if (errorCode === "AUTHORIZATION_FAILED") {
|
|
1347
|
+
code = "AUTHORIZATION_FAILED";
|
|
1348
|
+
message = "Authorization failed. Please check your code and try again.";
|
|
1349
|
+
} else if (errorCode === "INVALID_OTP") {
|
|
1350
|
+
code = "INVALID_OTP";
|
|
1351
|
+
message = "Invalid verification code. Please check and try again.";
|
|
1352
|
+
}
|
|
1353
|
+
return { code, message, recoverable, technical };
|
|
1354
|
+
}
|
|
1355
|
+
function isQuickPaymentResponse(response) {
|
|
1356
|
+
return response !== null && typeof response === "object" && "payment" in response && typeof response.payment === "object";
|
|
1357
|
+
}
|
|
1358
|
+
function isWebPaymentResponse(response) {
|
|
1359
|
+
return response !== null && typeof response === "object" && "transaction" in response && typeof response.transaction === "object";
|
|
1360
|
+
}
|
|
1361
|
+
function normalizePaymentResponse(response) {
|
|
1362
|
+
if (!response) {
|
|
1363
|
+
return {
|
|
1364
|
+
method: "unknown",
|
|
1365
|
+
provider: "unknown",
|
|
1366
|
+
requires_action: false,
|
|
1367
|
+
metadata: {}
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
if (isQuickPaymentResponse(response)) {
|
|
1371
|
+
return {
|
|
1372
|
+
method: response.payment.type?.toLowerCase() || "unknown",
|
|
1373
|
+
provider: response.payment.provider?.toLowerCase() || "unknown",
|
|
1374
|
+
requires_action: !!response.payment.redirect_url || !!response.payment.access_code,
|
|
1375
|
+
public_key: response.payment.public_key,
|
|
1376
|
+
client_secret: response.payment.access_code,
|
|
1377
|
+
access_code: response.payment.access_code,
|
|
1378
|
+
redirect_url: response.payment.redirect_url,
|
|
1379
|
+
transaction_id: response.payment.reference,
|
|
1380
|
+
order_id: response.order_id,
|
|
1381
|
+
reference: response.payment.reference,
|
|
1382
|
+
instructions: response.payment.instructions,
|
|
1383
|
+
metadata: response.payment.metadata
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
if (isWebPaymentResponse(response)) {
|
|
1387
|
+
const authType = response.authorization_type?.toLowerCase();
|
|
1388
|
+
const validAuthTypes = ["otp", "pin", "phone", "birthday", "address"];
|
|
1389
|
+
const safeAuthType = authType && validAuthTypes.includes(authType) ? authType : void 0;
|
|
1390
|
+
return {
|
|
1391
|
+
provider: response.transaction.provider_type?.toLowerCase() || "unknown",
|
|
1392
|
+
requires_action: response.requires_action || false,
|
|
1393
|
+
public_key: response.public_key,
|
|
1394
|
+
client_secret: response.client_secret,
|
|
1395
|
+
redirect_url: response.authorization_url,
|
|
1396
|
+
transaction_id: response.transaction.id,
|
|
1397
|
+
order_id: response.transaction.order_id,
|
|
1398
|
+
reference: response.transaction.provider_reference,
|
|
1399
|
+
metadata: response.transaction.metadata,
|
|
1400
|
+
method: response.transaction.payment_method?.toLowerCase() || "unknown",
|
|
1401
|
+
instructions: response.display_text,
|
|
1402
|
+
display_text: response.display_text,
|
|
1403
|
+
requires_authorization: response.requires_authorization,
|
|
1404
|
+
authorization_type: safeAuthType,
|
|
1405
|
+
provider_payment_id: response.provider_payment_id || response.transaction.provider_reference
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
return {
|
|
1409
|
+
method: "unknown",
|
|
1410
|
+
provider: "unknown",
|
|
1411
|
+
requires_action: false,
|
|
1412
|
+
metadata: {}
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
function normalizeStatusResponse(response) {
|
|
1416
|
+
if (!response || typeof response !== "object") {
|
|
1417
|
+
return {
|
|
1418
|
+
status: "pending",
|
|
1419
|
+
paid: false,
|
|
1420
|
+
message: "No status available"
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
const res = response;
|
|
1424
|
+
const status = res.status?.toLowerCase() || "";
|
|
1425
|
+
let standardStatus;
|
|
1426
|
+
if (status === "success" || status === "completed" || res.paid === true) {
|
|
1427
|
+
standardStatus = "success";
|
|
1428
|
+
} else if (status === "failed" || status === "declined" || status === "cancelled") {
|
|
1429
|
+
standardStatus = "failed";
|
|
1430
|
+
} else if (status === "processing" || status === "pending_confirmation") {
|
|
1431
|
+
standardStatus = "processing";
|
|
1432
|
+
} else {
|
|
1433
|
+
standardStatus = "pending";
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
status: standardStatus,
|
|
1437
|
+
paid: res.paid || standardStatus === "success",
|
|
1438
|
+
amount: res.amount,
|
|
1439
|
+
currency: res.currency,
|
|
1440
|
+
reference: res.reference,
|
|
1441
|
+
message: res.message || ""
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
var MOBILE_MONEY_PROVIDERS = {
|
|
1445
|
+
mtn: { name: "MTN Mobile Money", prefix: ["024", "054", "055", "059"] },
|
|
1446
|
+
vodafone: { name: "Vodafone Cash", prefix: ["020", "050"] },
|
|
1447
|
+
airtel: { name: "AirtelTigo Money", prefix: ["027", "057", "026", "056"] }
|
|
1448
|
+
};
|
|
1449
|
+
function detectMobileMoneyProvider(phoneNumber) {
|
|
1450
|
+
const cleaned = phoneNumber.replace(/\D/g, "");
|
|
1451
|
+
const prefix = cleaned.slice(-9, -6);
|
|
1452
|
+
for (const [provider, info] of Object.entries(MOBILE_MONEY_PROVIDERS)) {
|
|
1453
|
+
if (info.prefix.some((p) => prefix.startsWith(p.slice(1)))) {
|
|
1454
|
+
return provider;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
return null;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
export { AUTHORIZATION_TYPE, AUTH_MUTATION, AuthService, BusinessService, CHECKOUT_MODE, CHECKOUT_MUTATION, CHECKOUT_STEP, CURRENCY_SYMBOLS, CartOperations, CatalogueQueries, CheckoutService as CheckoutOperations, CheckoutService, CimplifyClient, CimplifyError, DEFAULT_COUNTRY, DEFAULT_CURRENCY, InventoryService, LINK_MUTATION, LINK_QUERY, LinkService, LiteService, MOBILE_MONEY_PROVIDER, MOBILE_MONEY_PROVIDERS, ORDER_MUTATION, ORDER_TYPE, OrderQueries, PAYMENT_METHOD, PAYMENT_MUTATION, PAYMENT_STATE, PICKUP_TIME_TYPE, QueryBuilder, SchedulingService, categorizePaymentError, createCimplifyClient, detectMobileMoneyProvider, formatMoney, normalizePaymentResponse, normalizeStatusResponse, query };
|