@temboplus/frontend-core
v1.1.1
Published
A JavaScript/TypeScript package providing common utilities and logic shared across front-end TemboPlus projects.
Readme
@temboplus/frontend-core
Shared TypeScript package for TemboPlus products. Provides canonical domain entities (Amount, Bank, Country, Currency, MobileMoneyProvider, PhoneNumber) with their registries and factories, plus a focused set of pure, framework-agnostic utilities.
Quick Start
bun add @temboplus/frontend-core
# or
npm install @temboplus/frontend-coreimport { Amount, Country, Currency, formatDateTime } from "@temboplus/frontend-core";
const country = Country.fromCode("TZ");
const currency = Currency.fromCode("USD");
const amount = Amount.from(100, "USD");
formatDateTime(new Date(), "Africa/Nairobi"); // "25 MAY 2026, 02:30 PM"Dependencies
Runtime dependencies (all bundled into the published artifact):
| Package | Why |
| --- | --- |
| date-fns | Date math and formatting primitives. |
| @date-fns/tz | IANA timezone support layered on date-fns. |
| libphonenumber-js | International phone-number parsing/validation. |
| zod | Runtime schema validation for the bundled JSON datasets. |
| tslib | Shared TypeScript helpers (pairs with importHelpers: true). |
Consumed By
@temboplus/frontend-react-core— React hooks and components that wrap these utilities (useTimezone,useFormatDate, …).- Downstream TemboPlus apps and packages — add here as they adopt the library.
Architecture At A Glance
domain/ value objects, types, schemas, and entity helpers
factories/ construction, parsing, validation, and JSON re-resolution
registries/ cached lookup and query APIs over supported datasets
repositories/ internal raw JSON dataset readers
coverage/ supported countries, channels, providers, banks, and limits
utilities/ pure, feature-bound helpers
└── timezone/ IANA picker options, formatters, boundary + plain-date helpers
└── text/ name validation, slug, initials, capitalizationTwo big categories:
- Domain entities — TemboPlus-curated lists with typed models, accessed via static factories or registries.
- Utilities — pure functions, organised into named feature folders. Add new utility areas as feature folders (no
misc/or grab-bag homes).
Domain Entities
Most consumers start with static delegations on the domain objects:
import { Amount, Bank, BankHelpers, Country, Currency } from "@temboplus/frontend-core";
const country = Country.fromCode("TZ");
const currency = Currency.fromCode("USD");
const amount = Amount.from(100, "USD");
const bank = Bank.fromBIC("CORUTZTZ", "TZ");
const canUseBic = BankHelpers.validateSwiftCode("CORUTZTZ", "TZ");Use factories when you need lower-level construction or aggregate behavior, and registries when you need cached lookup, listing, search, or provider detection.
Main Exports
Amount— parses, formats, compares, serializes monetary values.Bank— resolves supported banks by BIC/SWIFT code.Country— resolves ISO-2 and ISO-3 country records.Currency— resolves ISO 4217 currency records.MobileMoneyProvider— resolves supported mobile-money providers.PhoneNumber— parses and formats international phone numbers.TemboCoverage— answers coverage questions for channels, countries, providers, banks, and limits.*Helpers— entity-scoped type guards, validators, parsers, and formatters.
Typed Codes
import type {
BankSwiftCode,
CountryCode,
CurrencyCode,
ISO2CountryCode,
ISO3CountryCode,
} from "@temboplus/frontend-core";
function quote(amount: number, currency: CurrencyCode, country: CountryCode) {
return { amount, currency, country };
}
quote(100, "TZS", "TZ");
quote(100, "USD", "USA");Coverage Example
import { TemboCoverage, TransactionDirection } from "@temboplus/frontend-core";
const payoutCountries = TemboCoverage.getSupportedCountryCodes({
direction: TransactionDirection.PAYOUT,
});
const tzBanks = TemboCoverage.getPayoutBanks("TZ");Utilities
Timezone
Helpers for working with IANA timezones, EAT-anchored TemboPlus dates, and timezone-aware formatting. All pure, all environment-agnostic.
import {
DEFAULT_TIMEZONE,
EAT_TIMEZONE,
TIMEZONE_OPTIONS,
formatDate,
formatDateTime,
formatUtcIsoDateTime,
isEatTimezone,
isValidTimezone,
shiftPlainDate,
padEatRange,
localDateInZone,
startOfDayInTimezone,
endOfDayInTimezone,
parseInTimezone,
} from "@temboplus/frontend-core";
// Imperative formatters (React hook counterparts live in frontend-react-core)
formatDateTime(new Date(), "Africa/Nairobi"); // "25 MAY 2026, 02:30 PM"
formatUtcIsoDateTime(new Date("2026-05-25T11:30:45.987Z")); // "2026-05-25T11:30:45Z"
// Plain-date math (no JS-runtime timezone bleed)
shiftPlainDate("2026-05-15", 1); // "2026-05-16"
padEatRange({ startDate: "2026-05-15", endDate: "2026-05-16" });
// → { startDate: "2026-05-14", endDate: "2026-05-17" }
// Picker boundaries — UTC instant of the wall-clock day in the chosen zone
startOfDayInTimezone(pickerDate, "Africa/Nairobi");Picker data:
TIMEZONE_OPTIONS— frozen list grouped intooperating(TemboPlus markets),anchors(UTC, London, NY, Paris),others(everything else fromIntl.supportedValuesOf).isValidTimezone(value)— narrowing type guard against the same set.EAT_TIMEZONE/DEFAULT_TIMEZONE— canonical East Africa Time id and the fallback used when a caller doesn't supply a zone.
Text
Name validation and lightweight text helpers.
import { TextUtils } from "@temboplus/frontend-core";
TextUtils.validateName("Mary O'Connor"); // true
TextUtils.validateBusinessName("Acme & Sons Ltd"); // true
TextUtils.abbreviateName("Mary O'Connor"); // "Mary O."
TextUtils.getInitialsFrom("Mary O'Connor"); // "MO"Documentation
Development
This repo uses mise for tool versioning, Bun for install/test/scripts, and Biome for lint+format. Bun is pinned in .tool-versions; Node is not required for development (Bun handles install, test, build). The release workflow uses a current LTS Node only for npm publish.
mise install # one-time: install pinned bun + node
bun install # install deps from bun.lock
bun run dev # rollup build in watch modeScripts
| Script | What it does |
| --- | --- |
| bun run dev | Rollup build in watch mode. |
| bun run build | Rollup build to dist/ (CJS + ESM + .d.ts). |
| bun test | Run the test suite via bun:test. |
| bun run lint | Biome lint + format check over src/. |
| bun run format | Biome auto-fix (lint + format) over src/. |
| bun run typecheck | tsc --noEmit. |
| bun run release | Reminds you releases are tag-driven (see below). |
Tests live alongside their sources under src/**/__tests__/*.test.ts. Path aliases (@domain/*, @utilities/*, @registries/*, …) are declared in tsconfig.json and honored natively by bun test and Rollup.
Release
Releases are tag-driven via .github/workflows/release.yml:
- Update
CHANGELOG.md— move the## [Unreleased]items into a new## [X.Y.Z] - YYYY-MM-DDsection. - Bump
versioninpackage.jsonto match. - Commit, then tag and push:
git tag vX.Y.Z git push origin main --tags - The release workflow runs the full pipeline (typecheck, test, build), extracts the matching CHANGELOG section as the GitHub Release body, and publishes to npm under
@temboplus(public access).
Pre-release tags (e.g. v1.0.3-beta.2) are detected automatically and marked as pre-releases on GitHub.
License
MIT © TemboPlus
