mnotify-ts-sdk
Version:
Modern, zero-dependency TypeScript SDK for mNotify BMS API - Type-safe SMS, contacts, and account management with Railway-Oriented Programming
152 lines • 5.03 kB
JavaScript
;
/**
* Functional programming utilities for the SDK
* Pure functions for common operations
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.chunk = exports.isValidPhone = exports.normalizePhone = exports.compact = exports.omit = exports.pick = exports.toArray = exports.safeJsonParse = exports.sleep = exports.retry = exports.pipe = void 0;
/**
* Pipes functions from left to right (first to last)
* @param fns - Functions to pipe
* @returns Piped function
*/
const pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);
exports.pipe = pipe;
/**
* Retries a function with exponential backoff
* @param fn - Async function to retry
* @param maxRetries - Maximum number of retries
* @param delay - Initial delay in milliseconds
* @returns Promise that resolves with the function result
*/
const retry = (fn_1, ...args_1) => __awaiter(void 0, [fn_1, ...args_1], void 0, function* (fn, maxRetries = 3, delay = 1000) {
for (let i = 0; i <= maxRetries; i++) {
try {
return yield fn();
}
catch (error) {
if (i === maxRetries) {
throw error instanceof Error ? error : new Error(String(error));
}
yield (0, exports.sleep)(delay * Math.pow(2, i)); // Exponential backoff
}
}
// This line should never be reached, but TypeScript requires a return
throw new Error('Retry failed');
});
exports.retry = retry;
/**
* Sleep utility
* @param ms - Milliseconds to sleep
*/
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
exports.sleep = sleep;
/**
* Safely parses JSON with a fallback value
* @param json - JSON string to parse
* @param fallback - Fallback value if parsing fails
* @returns Parsed object or fallback
*/
const safeJsonParse = (json, fallback) => {
try {
return JSON.parse(json);
}
catch (_a) {
return fallback;
}
};
exports.safeJsonParse = safeJsonParse;
/**
* Converts a value to an array if it isn't already
* @param value - Value to convert
* @returns Array
*/
const toArray = (value) => Array.isArray(value) ? value : [value];
exports.toArray = toArray;
/**
* Picks specific keys from an object
* @param obj - Source object
* @param keys - Keys to pick
* @returns New object with only the specified keys
*/
const pick = (obj, keys) => keys.reduce((acc, key) => {
if (key in obj) {
acc[key] = obj[key];
}
return acc;
}, {});
exports.pick = pick;
/**
* Omits specific keys from an object
* @param obj - Source object
* @param keys - Keys to omit
* @returns New object without the specified keys
*/
const omit = (obj, keys) => {
const result = Object.assign({}, obj);
keys.forEach(key => delete result[key]);
return result;
};
exports.omit = omit;
/**
* Filters out null and undefined values from an object
* @param obj - Source object
* @returns New object without null/undefined values
*/
const compact = (obj) => Object.entries(obj).reduce((acc, [key, value]) => {
if (value !== null && value !== undefined) {
acc[key] = value;
}
return acc;
}, {});
exports.compact = compact;
/**
* Validates and normalizes phone numbers
* @param phone - Phone number to normalize
* @returns Normalized phone number
*/
const normalizePhone = (phone) => {
// Remove all non-digit characters
const digits = phone.replace(/\D/g, '');
// If starts with 0, replace with country code (233 for Ghana)
if (digits.startsWith('0')) {
return '233' + digits.slice(1);
}
return digits;
};
exports.normalizePhone = normalizePhone;
/**
* Validates phone number format
* @param phone - Phone number to validate
* @returns True if valid
*/
const isValidPhone = (phone) => {
const normalized = (0, exports.normalizePhone)(phone);
// Should be at least 10 digits
return /^\d{10,15}$/.test(normalized);
};
exports.isValidPhone = isValidPhone;
/**
* Chunks an array into smaller arrays
* @param array - Array to chunk
* @param size - Chunk size
* @returns Array of chunks
*/
const chunk = (array, size) => {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
};
exports.chunk = chunk;
//# sourceMappingURL=helpers.js.map