-
Notifications
You must be signed in to change notification settings - Fork 196
Description
Recently I've started using dinero.js@alpha for currency-related operations, and I've noticed one important thing between dinero.js@v1 and @alpha, in alpha we can't like... query the currency so actual serialization of currency would only require stored code instad complete JSON with details of currency - in real-world scenarios currencies defined in ISO standard are unlikely to be changed in near time and I think library should expose utilities to search currency.
I'm aware it's a alpha version which should probably not be used by me, however I think this feature is missing because on back-end we do not always have access to imports and some multi-currency systems handles more currencies than one have tested or thought about
Sadly, I'm not much able to contribute in near time, however I'm able to provide the "wrapper" that I've build for my usecase that helped me a lot with alpha version and maybe some of this will be useful for earlier mentioned utilities. (ignore type aliases, I have weird need to represent things in natural langauge)
import Dinero from "dinero.js";
import * as DineroCurrencies from "@dinero.js/currencies";
import {Tagged} from "type-fest";
type CurrencyDictionary = {
[key in keyof typeof DineroCurrencies & string]: Currency;
};
export const currencies: CurrencyDictionary = DineroCurrencies
/**
* This is a type alias for Dinero.
*/
export var Money = Dinero;
/**
* This is a type alias for Dinero.Currency<number>.
*/
export type Currency = Dinero.Currency<number>;
export type CurrencyCode = Tagged<keyof typeof DineroCurrencies, "currency_code">;
export function isCurrencyCode(value: unknown): value is CurrencyCode {
if (typeof value !== "string") return false;
return value in currencies;
}
export function assertCurrencyCode(value: unknown): asserts value is CurrencyCode {
if (!isCurrencyCode(value)) {
throw new TypeError(`Expected ISO-4217 Currency Code, but received ${typeof value} ${value} instead.`);
}
}
/**
* Returns a Dinero.Currency object for the given currency code.
*
* @param currency The ISO-4217 Currency Code.
*/
export function getCurrencyByCode(currency: CurrencyCode): Currency {
return currencies[currency as keyof typeof currencies];
}
/**
* Function will validate if provided value is a valid Dinero.Currency object.
* This is validation which allows definition of custom currency objects once
* they are compatible with Dinero.Currency<number> type.
* @param value
*/
export function isCurrency(value: unknown): value is Currency {
if (!(value instanceof Object)) return false;
if (!("code" in value)) return false;
if (!("base" in value)) return false;
if (!("exponent" in value)) return false;
if (typeof value.code !== "string") return false;
if (typeof value.base !== "number") return false;
if (typeof value.exponent !== "number") return false;
if (!isCurrencyCode(value.code)) return false;
return true;
}
/**
* Function will validate if provided value is a valid Dinero.Currency object.
* @param value
*/
export function assertCurrency(value: unknown): asserts value is Currency {
if (!isCurrency(value)) {
throw new TypeError(`Expected Dinero.Currency<number> object, but received ${typeof value} (${JSON.stringify(value)}) instead.`);
}
}
/**
* Function will define currency object, this is useful for defining custom currency objects
* @param currency
*/
export function defineCurrency(currency: Currency): Currency {
assertCurrency(currency);
return currency;
}