@cimplify/sdk 0.1.0 → 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/dist/index.d.mts +351 -3
- package/dist/index.d.ts +351 -3
- package/dist/index.js +351 -4
- package/dist/index.mjs +336 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1304,23 +1304,354 @@ function query(entity) {
|
|
|
1304
1304
|
return new QueryBuilder(entity);
|
|
1305
1305
|
}
|
|
1306
1306
|
|
|
1307
|
-
// src/utils/
|
|
1307
|
+
// src/utils/price.ts
|
|
1308
1308
|
var CURRENCY_SYMBOLS = {
|
|
1309
|
-
|
|
1309
|
+
// Major world currencies
|
|
1310
1310
|
USD: "$",
|
|
1311
1311
|
EUR: "\u20AC",
|
|
1312
1312
|
GBP: "\xA3",
|
|
1313
|
+
JPY: "\xA5",
|
|
1314
|
+
CNY: "\xA5",
|
|
1315
|
+
CHF: "CHF",
|
|
1316
|
+
CAD: "C$",
|
|
1317
|
+
AUD: "A$",
|
|
1318
|
+
NZD: "NZ$",
|
|
1319
|
+
HKD: "HK$",
|
|
1320
|
+
SGD: "S$",
|
|
1321
|
+
INR: "\u20B9",
|
|
1322
|
+
BRL: "R$",
|
|
1323
|
+
MXN: "MX$",
|
|
1324
|
+
KRW: "\u20A9",
|
|
1325
|
+
RUB: "\u20BD",
|
|
1326
|
+
TRY: "\u20BA",
|
|
1327
|
+
THB: "\u0E3F",
|
|
1328
|
+
PLN: "z\u0142",
|
|
1329
|
+
SEK: "kr",
|
|
1330
|
+
NOK: "kr",
|
|
1331
|
+
DKK: "kr",
|
|
1332
|
+
CZK: "K\u010D",
|
|
1333
|
+
HUF: "Ft",
|
|
1334
|
+
ILS: "\u20AA",
|
|
1335
|
+
AED: "\u062F.\u0625",
|
|
1336
|
+
SAR: "\uFDFC",
|
|
1337
|
+
MYR: "RM",
|
|
1338
|
+
PHP: "\u20B1",
|
|
1339
|
+
IDR: "Rp",
|
|
1340
|
+
VND: "\u20AB",
|
|
1341
|
+
TWD: "NT$",
|
|
1342
|
+
// African currencies
|
|
1343
|
+
GHS: "GH\u20B5",
|
|
1313
1344
|
NGN: "\u20A6",
|
|
1314
1345
|
KES: "KSh",
|
|
1315
1346
|
ZAR: "R",
|
|
1316
1347
|
XOF: "CFA",
|
|
1317
|
-
XAF: "FCFA"
|
|
1348
|
+
XAF: "FCFA",
|
|
1349
|
+
EGP: "E\xA3",
|
|
1350
|
+
MAD: "MAD",
|
|
1351
|
+
TZS: "TSh",
|
|
1352
|
+
UGX: "USh",
|
|
1353
|
+
RWF: "FRw",
|
|
1354
|
+
ETB: "Br",
|
|
1355
|
+
ZMW: "ZK",
|
|
1356
|
+
BWP: "P",
|
|
1357
|
+
MUR: "\u20A8",
|
|
1358
|
+
SCR: "\u20A8",
|
|
1359
|
+
NAD: "N$",
|
|
1360
|
+
SZL: "E",
|
|
1361
|
+
LSL: "L",
|
|
1362
|
+
MWK: "MK",
|
|
1363
|
+
AOA: "Kz",
|
|
1364
|
+
CDF: "FC",
|
|
1365
|
+
GMD: "D",
|
|
1366
|
+
GNF: "FG",
|
|
1367
|
+
LRD: "L$",
|
|
1368
|
+
SLL: "Le",
|
|
1369
|
+
MZN: "MT",
|
|
1370
|
+
SDG: "SDG",
|
|
1371
|
+
SSP: "SSP",
|
|
1372
|
+
SOS: "Sh.So.",
|
|
1373
|
+
DJF: "Fdj",
|
|
1374
|
+
ERN: "Nfk",
|
|
1375
|
+
CVE: "$",
|
|
1376
|
+
STN: "Db",
|
|
1377
|
+
KMF: "CF",
|
|
1378
|
+
BIF: "FBu"
|
|
1318
1379
|
};
|
|
1380
|
+
function getCurrencySymbol(currencyCode) {
|
|
1381
|
+
return CURRENCY_SYMBOLS[currencyCode.toUpperCase()] || currencyCode;
|
|
1382
|
+
}
|
|
1383
|
+
function formatNumberCompact(value, decimals = 1) {
|
|
1384
|
+
const absValue = Math.abs(value);
|
|
1385
|
+
const sign = value < 0 ? "-" : "";
|
|
1386
|
+
if (absValue >= 1e9) {
|
|
1387
|
+
return `${sign}${(absValue / 1e9).toFixed(decimals)}B`;
|
|
1388
|
+
}
|
|
1389
|
+
if (absValue >= 1e6) {
|
|
1390
|
+
return `${sign}${(absValue / 1e6).toFixed(decimals)}M`;
|
|
1391
|
+
}
|
|
1392
|
+
if (absValue >= 1e3) {
|
|
1393
|
+
return `${sign}${(absValue / 1e3).toFixed(decimals)}K`;
|
|
1394
|
+
}
|
|
1395
|
+
return `${sign}${absValue.toFixed(decimals)}`;
|
|
1396
|
+
}
|
|
1397
|
+
function formatPrice(amount, currency = "GHS", locale = "en-US") {
|
|
1398
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1399
|
+
if (isNaN(numAmount)) {
|
|
1400
|
+
return `${getCurrencySymbol(currency)}0.00`;
|
|
1401
|
+
}
|
|
1402
|
+
try {
|
|
1403
|
+
return new Intl.NumberFormat(locale, {
|
|
1404
|
+
style: "currency",
|
|
1405
|
+
currency: currency.toUpperCase(),
|
|
1406
|
+
minimumFractionDigits: 2,
|
|
1407
|
+
maximumFractionDigits: 2
|
|
1408
|
+
}).format(numAmount);
|
|
1409
|
+
} catch {
|
|
1410
|
+
return `${getCurrencySymbol(currency)}${numAmount.toFixed(2)}`;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
function formatPriceAdjustment(amount, currency = "GHS", locale = "en-US") {
|
|
1414
|
+
const formatted = formatPrice(Math.abs(amount), currency, locale);
|
|
1415
|
+
if (amount > 0) {
|
|
1416
|
+
return `+${formatted}`;
|
|
1417
|
+
} else if (amount < 0) {
|
|
1418
|
+
return `-${formatted}`;
|
|
1419
|
+
}
|
|
1420
|
+
return formatted;
|
|
1421
|
+
}
|
|
1422
|
+
function formatPriceCompact(amount, currency = "GHS", decimals = 1) {
|
|
1423
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1424
|
+
if (isNaN(numAmount)) {
|
|
1425
|
+
return `${getCurrencySymbol(currency)}0`;
|
|
1426
|
+
}
|
|
1427
|
+
const symbol = getCurrencySymbol(currency);
|
|
1428
|
+
if (Math.abs(numAmount) < 1e3) {
|
|
1429
|
+
return `${symbol}${numAmount.toFixed(2)}`;
|
|
1430
|
+
}
|
|
1431
|
+
return `${symbol}${formatNumberCompact(numAmount, decimals)}`;
|
|
1432
|
+
}
|
|
1319
1433
|
function formatMoney(amount, currency = "GHS") {
|
|
1320
|
-
const symbol =
|
|
1434
|
+
const symbol = getCurrencySymbol(currency);
|
|
1321
1435
|
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
1436
|
+
if (isNaN(numAmount)) {
|
|
1437
|
+
return `${symbol}0.00`;
|
|
1438
|
+
}
|
|
1322
1439
|
return `${symbol}${numAmount.toFixed(2)}`;
|
|
1323
1440
|
}
|
|
1441
|
+
function parsePrice(value) {
|
|
1442
|
+
if (value === void 0 || value === null) {
|
|
1443
|
+
return 0;
|
|
1444
|
+
}
|
|
1445
|
+
if (typeof value === "number") {
|
|
1446
|
+
return isNaN(value) ? 0 : value;
|
|
1447
|
+
}
|
|
1448
|
+
const cleaned = value.replace(/[^\d.-]/g, "");
|
|
1449
|
+
const parsed = parseFloat(cleaned);
|
|
1450
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
1451
|
+
}
|
|
1452
|
+
function parseTaxInfo(taxInfoStr) {
|
|
1453
|
+
try {
|
|
1454
|
+
const parts = taxInfoStr.split(":");
|
|
1455
|
+
if (parts.length < 4 || parts[0] !== "T") {
|
|
1456
|
+
return void 0;
|
|
1457
|
+
}
|
|
1458
|
+
const taxRate = parseFloat(parts[1]);
|
|
1459
|
+
const taxAmount = parseFloat(parts[2]);
|
|
1460
|
+
const isInclusive = parts[3] === "I";
|
|
1461
|
+
const components = [];
|
|
1462
|
+
if (parts.length > 4 && parts[4]) {
|
|
1463
|
+
const componentPairs = parts[4].split(",");
|
|
1464
|
+
for (const pair of componentPairs) {
|
|
1465
|
+
const [name, rateStr] = pair.split(":");
|
|
1466
|
+
if (name && rateStr) {
|
|
1467
|
+
components.push({
|
|
1468
|
+
name: name.trim(),
|
|
1469
|
+
rate: parseFloat(rateStr)
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
return {
|
|
1475
|
+
taxRate,
|
|
1476
|
+
taxAmount,
|
|
1477
|
+
isInclusive,
|
|
1478
|
+
components
|
|
1479
|
+
};
|
|
1480
|
+
} catch {
|
|
1481
|
+
return void 0;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
function parsePricePath(signedPricePath) {
|
|
1485
|
+
if (!signedPricePath) {
|
|
1486
|
+
return {
|
|
1487
|
+
basePrice: 0,
|
|
1488
|
+
finalPrice: 0,
|
|
1489
|
+
currency: "GHS",
|
|
1490
|
+
decisionPath: "",
|
|
1491
|
+
isValid: false,
|
|
1492
|
+
isExpired: false
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
try {
|
|
1496
|
+
const parts = signedPricePath.split("\xA7");
|
|
1497
|
+
if (parts.length !== 3) {
|
|
1498
|
+
return {
|
|
1499
|
+
basePrice: 0,
|
|
1500
|
+
finalPrice: 0,
|
|
1501
|
+
currency: "GHS",
|
|
1502
|
+
decisionPath: "",
|
|
1503
|
+
isValid: false,
|
|
1504
|
+
isExpired: false
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
const [pricePath, expiryStr, signature] = parts;
|
|
1508
|
+
const expiryTimestamp = parseInt(expiryStr, 10);
|
|
1509
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1510
|
+
const isExpired = now > expiryTimestamp;
|
|
1511
|
+
const priceComponents = pricePath.split("|");
|
|
1512
|
+
if (priceComponents.length < 5) {
|
|
1513
|
+
return {
|
|
1514
|
+
basePrice: 0,
|
|
1515
|
+
finalPrice: 0,
|
|
1516
|
+
currency: "GHS",
|
|
1517
|
+
decisionPath: "",
|
|
1518
|
+
isValid: false,
|
|
1519
|
+
isExpired
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
const basePrice = parseFloat(priceComponents[0]);
|
|
1523
|
+
const finalPrice = parseFloat(priceComponents[1]);
|
|
1524
|
+
const currency = priceComponents[2];
|
|
1525
|
+
const taxInfoStr = priceComponents[3];
|
|
1526
|
+
const decisionPath = priceComponents.slice(4).join("|");
|
|
1527
|
+
let taxInfo;
|
|
1528
|
+
if (taxInfoStr && taxInfoStr.startsWith("T:")) {
|
|
1529
|
+
taxInfo = parseTaxInfo(taxInfoStr);
|
|
1530
|
+
} else if (taxInfoStr === "0" || !taxInfoStr) {
|
|
1531
|
+
taxInfo = {
|
|
1532
|
+
taxRate: 0,
|
|
1533
|
+
taxAmount: 0,
|
|
1534
|
+
isInclusive: false,
|
|
1535
|
+
components: []
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
let markupPercentage;
|
|
1539
|
+
let markupAmount;
|
|
1540
|
+
let discountPercentage;
|
|
1541
|
+
if (decisionPath) {
|
|
1542
|
+
const pathParts = decisionPath.split(":");
|
|
1543
|
+
if (pathParts.length > 1 && pathParts[1]) {
|
|
1544
|
+
const adjustments = pathParts[1].split(",");
|
|
1545
|
+
for (const adj of adjustments) {
|
|
1546
|
+
const adjParts = adj.split("|");
|
|
1547
|
+
if (adjParts[0] && adjParts[0].startsWith("ch")) {
|
|
1548
|
+
markupAmount = parseFloat(adjParts[1]) || 0;
|
|
1549
|
+
markupPercentage = parseFloat(adjParts[2]) || 0;
|
|
1550
|
+
break;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
if (markupAmount === void 0 && finalPrice > basePrice) {
|
|
1556
|
+
markupAmount = finalPrice - basePrice;
|
|
1557
|
+
markupPercentage = basePrice > 0 ? markupAmount / basePrice * 100 : 0;
|
|
1558
|
+
} else if (basePrice > finalPrice) {
|
|
1559
|
+
discountPercentage = basePrice > 0 ? (basePrice - finalPrice) / basePrice * 100 : 0;
|
|
1560
|
+
}
|
|
1561
|
+
return {
|
|
1562
|
+
basePrice,
|
|
1563
|
+
finalPrice,
|
|
1564
|
+
currency,
|
|
1565
|
+
decisionPath,
|
|
1566
|
+
discountPercentage,
|
|
1567
|
+
markupPercentage,
|
|
1568
|
+
markupAmount,
|
|
1569
|
+
taxInfo,
|
|
1570
|
+
isValid: !isExpired && signature.length > 0,
|
|
1571
|
+
isExpired,
|
|
1572
|
+
expiryTimestamp
|
|
1573
|
+
};
|
|
1574
|
+
} catch {
|
|
1575
|
+
return {
|
|
1576
|
+
basePrice: 0,
|
|
1577
|
+
finalPrice: 0,
|
|
1578
|
+
currency: "GHS",
|
|
1579
|
+
decisionPath: "",
|
|
1580
|
+
isValid: false,
|
|
1581
|
+
isExpired: false
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
function parsedPriceToPriceInfo(parsedPrice) {
|
|
1586
|
+
return {
|
|
1587
|
+
base_price: parsedPrice.basePrice,
|
|
1588
|
+
final_price: parsedPrice.finalPrice,
|
|
1589
|
+
markup_percentage: parsedPrice.markupPercentage,
|
|
1590
|
+
markup_amount: parsedPrice.markupAmount,
|
|
1591
|
+
currency: parsedPrice.currency,
|
|
1592
|
+
tax_info: parsedPrice.taxInfo,
|
|
1593
|
+
decision_path: parsedPrice.decisionPath
|
|
1594
|
+
};
|
|
1595
|
+
}
|
|
1596
|
+
function extractPriceInfo(signedPricePath) {
|
|
1597
|
+
const parsed = parsePricePath(signedPricePath);
|
|
1598
|
+
return parsedPriceToPriceInfo(parsed);
|
|
1599
|
+
}
|
|
1600
|
+
function getDisplayPrice(product) {
|
|
1601
|
+
if (product.price_path) {
|
|
1602
|
+
const priceInfo = extractPriceInfo(product.price_path);
|
|
1603
|
+
return priceInfo.final_price;
|
|
1604
|
+
} else if (product.price_info) {
|
|
1605
|
+
return product.price_info.final_price;
|
|
1606
|
+
}
|
|
1607
|
+
return 0;
|
|
1608
|
+
}
|
|
1609
|
+
function getBasePrice(product) {
|
|
1610
|
+
if (product.price_path) {
|
|
1611
|
+
const priceInfo = extractPriceInfo(product.price_path);
|
|
1612
|
+
return priceInfo.base_price;
|
|
1613
|
+
} else if (product.price_info) {
|
|
1614
|
+
return product.price_info.base_price;
|
|
1615
|
+
}
|
|
1616
|
+
return 0;
|
|
1617
|
+
}
|
|
1618
|
+
function isOnSale(product) {
|
|
1619
|
+
const basePrice = getBasePrice(product);
|
|
1620
|
+
const finalPrice = getDisplayPrice(product);
|
|
1621
|
+
return basePrice > finalPrice && basePrice > 0;
|
|
1622
|
+
}
|
|
1623
|
+
function getDiscountPercentage(product) {
|
|
1624
|
+
const basePrice = getBasePrice(product);
|
|
1625
|
+
const finalPrice = getDisplayPrice(product);
|
|
1626
|
+
if (basePrice > finalPrice && basePrice > 0) {
|
|
1627
|
+
return Math.round((basePrice - finalPrice) / basePrice * 100);
|
|
1628
|
+
}
|
|
1629
|
+
return 0;
|
|
1630
|
+
}
|
|
1631
|
+
function getMarkupPercentage(product) {
|
|
1632
|
+
const basePrice = getBasePrice(product);
|
|
1633
|
+
const finalPrice = getDisplayPrice(product);
|
|
1634
|
+
if (finalPrice > basePrice && basePrice > 0) {
|
|
1635
|
+
return Math.round((finalPrice - basePrice) / basePrice * 100);
|
|
1636
|
+
}
|
|
1637
|
+
return 0;
|
|
1638
|
+
}
|
|
1639
|
+
function getProductCurrency(product) {
|
|
1640
|
+
if (product.price_path) {
|
|
1641
|
+
const parsed = parsePricePath(product.price_path);
|
|
1642
|
+
return parsed.currency || "GHS";
|
|
1643
|
+
} else if (product.price_info?.currency) {
|
|
1644
|
+
return product.price_info.currency;
|
|
1645
|
+
}
|
|
1646
|
+
return "GHS";
|
|
1647
|
+
}
|
|
1648
|
+
function formatProductPrice(product, locale = "en-US") {
|
|
1649
|
+
const price = getDisplayPrice(product);
|
|
1650
|
+
const currency = getProductCurrency(product);
|
|
1651
|
+
return formatPrice(price, currency, locale);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
// src/utils/payment.ts
|
|
1324
1655
|
function categorizePaymentError(error, errorCode) {
|
|
1325
1656
|
let message = "An unexpected error occurred during payment processing. Please try again or contact support.";
|
|
1326
1657
|
let recoverable = true;
|
|
@@ -1494,7 +1825,23 @@ exports.SchedulingService = SchedulingService;
|
|
|
1494
1825
|
exports.categorizePaymentError = categorizePaymentError;
|
|
1495
1826
|
exports.createCimplifyClient = createCimplifyClient;
|
|
1496
1827
|
exports.detectMobileMoneyProvider = detectMobileMoneyProvider;
|
|
1828
|
+
exports.extractPriceInfo = extractPriceInfo;
|
|
1497
1829
|
exports.formatMoney = formatMoney;
|
|
1830
|
+
exports.formatNumberCompact = formatNumberCompact;
|
|
1831
|
+
exports.formatPrice = formatPrice;
|
|
1832
|
+
exports.formatPriceAdjustment = formatPriceAdjustment;
|
|
1833
|
+
exports.formatPriceCompact = formatPriceCompact;
|
|
1834
|
+
exports.formatProductPrice = formatProductPrice;
|
|
1835
|
+
exports.getBasePrice = getBasePrice;
|
|
1836
|
+
exports.getCurrencySymbol = getCurrencySymbol;
|
|
1837
|
+
exports.getDiscountPercentage = getDiscountPercentage;
|
|
1838
|
+
exports.getDisplayPrice = getDisplayPrice;
|
|
1839
|
+
exports.getMarkupPercentage = getMarkupPercentage;
|
|
1840
|
+
exports.getProductCurrency = getProductCurrency;
|
|
1841
|
+
exports.isOnSale = isOnSale;
|
|
1498
1842
|
exports.normalizePaymentResponse = normalizePaymentResponse;
|
|
1499
1843
|
exports.normalizeStatusResponse = normalizeStatusResponse;
|
|
1844
|
+
exports.parsePrice = parsePrice;
|
|
1845
|
+
exports.parsePricePath = parsePricePath;
|
|
1846
|
+
exports.parsedPriceToPriceInfo = parsedPriceToPriceInfo;
|
|
1500
1847
|
exports.query = query;
|