@nexim/localizer
Version:
Lightweight i18n utilities to handle translations, number formatting, date/time localization using native browser APIs.
168 lines (166 loc) • 5.95 kB
JavaScript
/* @nexim/localizer v1.1.1 */
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/main.ts
var main_exports = {};
__export(main_exports, {
Localizer: () => Localizer
});
module.exports = __toCommonJS(main_exports);
var import_logger = require("@alwatr/logger");
var import_package_tracer = require("@alwatr/package-tracer");
var import_unicode_digits = require("@alwatr/unicode-digits");
__dev_mode__: import_package_tracer.packageTracer.add("@nexim/localizer", "1.1.1");
var _Localizer = class _Localizer {
/**
* Creates a new instance of the Localizer class.
*
* @param options__ - Configuration options for localization
*/
constructor(options__) {
this.options__ = options__;
this.logger_ = (0, import_logger.createLogger)("@nexim/localizer");
this.numberFormatter_ = new Intl.NumberFormat(this.options__.locale.code);
this.unicodeDigits_ = new import_unicode_digits.UnicodeDigits(this.options__.locale.language);
}
/**
* Retrieves a localized message by key from the resource dictionary.
*
* @param key - The key to lookup in the resource dictionary
* @returns The localized message string
*
* @remarks
* - Returns "\{key\}" if the key is not found in the dictionary
* - Returns an empty string if the key is null or undefined
*
* @example
* ```typescript
* const localizer = new Localizer({...});
* console.log(localizer.message('hello_world')); // "Hello world!"
* console.log(localizer.message('missing_key')); // "{missing_key}"
* ```
*/
message(key) {
if (!key) return "";
const msg = this.options__.resource?.[key];
if (msg === void 0) {
this.logger_.accident("message", "l10n_key_not_found", "Key not defined in the localization resource", {
key,
locale: this.options__.locale
});
return `{${key}}`;
}
return msg;
}
/**
* Formats a number according to the current locale settings.
*
* @param number - The number to format
* @param decimal - Number of decimal places (default: 2)
* @returns Formatted number string using locale-specific formatting
*
* @example
* ```typescript
* const localizer = new Localizer({...});
* console.log(localizer.number(1234.567)); // "1,234.57"
* console.log(localizer.number(1234.567, 1)); // "1,234.6"
* ```
*/
number(number, decimal = 2) {
if (number == null) return "";
decimal = Math.pow(10, decimal);
number = Math.round(number * decimal) / decimal;
return this.numberFormatter_.format(number);
}
/**
* Replaces all numeric digits in a string with their locale-specific Unicode equivalents.
*
* @param str - The input string containing numbers to replace
* @returns String with numbers converted to locale-specific digits
*
* @example
* ```typescript
* const localizer = new Localizer({locale: {code: 'fa-IR', language: 'fa'}, ...});
* console.log(localizer.replaceNumber('123')); // '۱۲۳'
* ```
*/
replaceNumber(str) {
return this.unicodeDigits_.translate(str);
}
/**
* Formats a date according to the current locale settings.
*
* @param date - Date to format (as Date object or timestamp)
* @param options - Intl.DateTimeFormatOptions for customizing the output
* @returns Localized date string
*
* @example
* ```typescript
* const localizer = new Localizer({...});
* console.log(localizer.time(new Date())); // "4/21/2025"
* ```
*/
time(date, options) {
if (typeof date === "number") date = new Date(date);
return date.toLocaleDateString(this.options__.locale.code, options);
}
/**
* Creates a relative time string comparing two dates.
*
* @param date - The date to compare (as Date object or timestamp)
* @param from - Reference date for comparison (defaults to current time)
* @param options - Formatting options for relative time
* @returns Localized relative time string
*
* @example
* ```typescript
* const localizer = new Localizer({...});
* const date = new Date(Date.now() - 3600000); // 1 hour ago
* console.log(localizer.relativeTime(date)); // "1 hour ago"
* ```
*/
relativeTime(date, from = Date.now(), options = { numeric: "auto", style: "narrow" }) {
const rtf = new Intl.RelativeTimeFormat(this.options__.locale.code, options);
if (typeof date !== "number") date = date.getTime();
if (typeof from !== "number") from = from.getTime();
const diffSec = (from - date) / 1e3;
for (const unit of _Localizer.timeUnits_) {
const interval = Math.floor(Math.abs(diffSec / unit.seconds));
if (interval >= 1) {
return rtf.format(diffSec > 0 ? interval : -interval, unit.label);
}
}
return rtf.format(0, "second");
}
};
/**
* Time units used for relative time calculations.
* @internal
*/
_Localizer.timeUnits_ = [
{ label: "year", seconds: 31536e3 },
{ label: "month", seconds: 2592e3 },
{ label: "week", seconds: 604800 },
{ label: "day", seconds: 86400 },
{ label: "hour", seconds: 3600 },
{ label: "minute", seconds: 60 },
{ label: "second", seconds: 1 }
];
var Localizer = _Localizer;
//# sourceMappingURL=main.cjs.map