@esimplified/core
v0.2.5
Published
Shared TypeScript types, API client, and utilities for eSIMplified platforms
Readme
@esimplified/core
Shared TypeScript package for eSIMplified platforms. Extracts platform-agnostic backend domain code so it can be reused across our web app, GoPay mini app, and future consumers.
What's Inside
- Types — TypeScript types for everything our backend sends and expects (packages, orders, eSIMs, countries, customers, payments, etc.)
- API Client — A typed
createApiClient()factory that works in any JS environment (not tied to Next.js) - Utilities — Pure helper functions for formatting currency, data sizes, dates, and discounts
- Constants — API path strings, payment statuses, order types, header keys
Install
npm install @esimplified/coreFor local development against an unpublished change, use npm link:
cd /path/to/esimplified-core && npm link
cd /path/to/your-project && npm link @esimplified/coreQuick Start
import {
createApiClient,
type Package,
type Country,
format_currency,
format_data_gb,
PAYMENT_STATUS,
} from "@esimplified/core";
// 1. Create the client — configure auth and headers for your platform
const api = createApiClient({
baseUrl: "https://api.esimplified.com",
getToken: async () => {
const token = await getMyAuthToken(); // your auth logic
return token ? { type: "Bearer", value: token } : null;
},
getHeaders: async () => ({
"accept-currency": "USD",
"accept-language": "en",
}),
});
// 2. Use typed API methods
const packages = await api.packages.getByCountry("japan");
const countries = await api.countries.getAll();
const esims = await api.esims.getCustomerEsims();
const order = await api.orders.getOrderDetails("order-uuid");
// 3. Use utility functions
format_currency("en-US", 9.99, { iso: "USD", symbol: "$" }); // "$9.99"
format_data_gb("1.5"); // "1.5 GB"API Client Modules
| Module | Methods |
|--------|---------|
| api.countries | search, getAll, getBySlug, getAllDestinations, getDestination, getRegions, getRegionalBundles, getSiteMap |
| api.packages | getByCountry, getTopUpPackages, getPromoPackages |
| api.esims | getCustomerEsims, getByIccid, editEsim, getPackages, getByTripBalance |
| api.subscriptions | getPlans, getAll, createCheckout, cancel, getPortalUrl |
| api.orders | getCustomerOrders, getOrderDetails, updateConsent |
| api.payments | getPaymentQuote, createPayment, getPaymentMethods, deletePaymentMethod |
| api.loyalty | getCustomerLoyalty |
| api.promo | getPromoCodeList, deletePromoCode, applyPromoCode |
| api.user | getProfile, updateProfile, getPreferences, updatePreferences, getNotifications, updateNotifications |
| api.reviews | getReviews |
| api.rewards | validateRewards, redeemRewards |
| api.stock | checkStock |
API Reference
Every method accepts an optional trailing options?: { fetchOptions?: Record<string, unknown> } argument. fetchOptions is passed through to the underlying fetch call so consumers can attach things like Next.js cache/next.revalidate directives without the core knowing about them. Omitted from individual signatures below for brevity.
api.countries
search(query)→Promise<Country[]>— search countries by name.getAll(params?)→Promise<Country[]>— list countries;paramsare forwarded as query string (defaultlimit: 500).getBySlug(slug)→Promise<Country>— fetch a single country by its slug.getAllDestinations()→Promise<Destination[]>— list all destinations (regions + countries).getDestination(region)→Promise<RegionResponse>— fetch a destination by region name.getRegions()→Promise<any>— list all regions.getRegionalBundles()→Promise<{ count, next, previous, results: Country[] }>— paginated regional bundle entries.getSiteMap()→Promise<SiteMapUrls[]>— returns sitemap URLs for SEO routing.
api.packages
getByCountry(slug, options?: { lowToHigh? })→Promise<PackagesByCountry>— packages for a country slug; defaults to high-to-low price ordering.getTopUpPackages(iccid, options?: { lowToHigh? })→Promise<PackagesByCountry>— top-up packages available for an existing eSIM.iccidis a string (not a number — ICCIDs exceedNumber.MAX_SAFE_INTEGER).getPromoPackages(query?)→Promise<Package[]>— packages flagged for promotional surfaces.
api.esims
getCustomerEsims(params?: { showArchived? })→Promise<EsimInfo[]>— list the signed-in customer's eSIMs. Includes package + balance details.getByIccid(iccid)→Promise<EsimInfo>— fetch one eSIM by ICCID (string).editEsim(iccid, payload: EditEsim)→Promise<any>— update mutable eSIM fields (e.g.esim_name,auto_top_up,archived).getPackages(iccid)→Promise<EsimPackages[]>— list the package history attached to an eSIM.getByTripBalance(iccid)→Promise<EsimInfo>— public trip-balance lookup (no auth required).
api.subscriptions
getPlans()→Promise<SubscriptionPlan[]>— list available subscription plans.getAll()→Promise<SubscriptionDetail[]>— return the customer's active subscriptions.createCheckout(data: SubscriptionCheckoutRequest)→Promise<SubscriptionCheckoutResponse>— initiate a hosted, embedded, or custom subscription checkout. Returns a checkout URI and (for embedded) aclient_secret.cancel(subscriptionId)→Promise<void>— cancel a subscription by ID.getPortalUrl(subscriptionId, action: SubscriptionPortalAction, returnUrl?)→Promise<{ url: string }>— get a Stripe-style customer-portal URL for the requested action (e.g. update payment method, view invoices).
api.orders
getCustomerOrders(queryParams?)→Promise<OrderHistory[]>— list the customer's orders.queryParamsis a raw query string appended to the request.getOrderDetails(orderId, options?: { includeBase64QrCode?, showEsimDetails? })→Promise<OrderDetails>— fetch a single order; QR code and eSIM details are included by default.updateConsent(orderId)→Promise<any>— mark KYC consent on an order (PATCH ?kyc_consent=true).
api.payments
getPaymentQuote(data: PaymentQuoteRequest)→Promise<PaymentQuoteResponse>— price/discount quote for an intended purchase.createPayment(data: TransactionRequest)→Promise<TransactionResponse>— create a payment transaction for buy / top-up / subscribe flows.getPaymentMethods()→Promise<SavedPaymentMethod[]>— list the customer's saved payment methods.deletePaymentMethod(paymentMethodId)→Promise<void>— delete a saved payment method.
api.loyalty
getCustomerLoyalty()→Promise<CustomerLoyalty>— current loyalty balance, tier, and recent activity.
api.promo
getPromoCodeList(options?: { getList? })→Promise<PromoCodeCollection>— current applied promo (default) or full list (getList: true).applyPromoCode({ discount_code })→Promise<PromoCode | { detail: string }>— apply a promo code.deletePromoCode()→Promise<any>— clear the currently applied promo code.
api.user
getProfile()→Promise<Customer | undefined>— signed-in customer profile.updateProfile(data: ProfileUpdate)→Promise<APIError | ProfileUpdateResponse>— patch profile fields.getPreferences()→Promise<UserPreferences>— accept-language, accept-currency, etc.updatePreferences(data: UserPreferencesUpdate)→Promise<any>— patch preferences.getNotifications()→Promise<any>— notification subscription state.updateNotifications(data: { type, enabled }[])→Promise<any>— bulk-update notification subscriptions.
api.reviews
getReviews()→Promise<Reviews | undefined>— store reviews (filtered totype=store_review).
api.rewards
validateRewards(token)→Promise<ValidateRewards>— verify a reward token (e.g. from an email/onboarding link).redeemRewards(token, rewardType)→Promise<RedeemRewards>— redeem a validated token for the given reward type.
api.stock
checkStock(packageSlug, countrySlug, locale?)→Promise<StockCheckResponse>— check stock for a package + country, optionally pinning the response language viaaccept-language.
Utilities
| Function | What it does |
|----------|-------------|
| format_currency(locale, price, currency) | Format price with currency symbol using Intl |
| format_amount(locale, value, currency, fallback) | Safe wrapper around format_currency |
| format_bytes(bytes, unit) | Convert bytes to human-readable ("1.50 GB") |
| format_data_gb(dataGb) | Convert GB string to display ("500 MB", "Unlimited") |
| discountValue(price, discount) | Calculate price after discount |
| title_case(str) | Convert "global-data" to "Global Data" |
| from_timestamp(timestamp) | Format timestamp to locale string |
| day_count(days) | "1 Day" or "7 Days" |
Development
npm install # install dependencies
npm test # run tests (90 tests)
npm run build # build ESM + CJS to dist/
npm run typecheck # type check without emittingDesign Principles
- Zero runtime dependencies — uses native
fetchandIntl.NumberFormat - Platform-agnostic — no React, no Next.js, no framework code
- Backend boundary — if the backend sends it or expects it, it's in this package. UI concerns stay in each consumer.
- TypeScript strict mode — no
anytypes in the public API
License
MIT © eSIMplified — see LICENSE.
