nhb-toolbox 4.24.2 → 4.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/date/Chronos.js +28 -1
- package/dist/cjs/index.js +12 -5
- package/dist/cjs/pluralizer/Pluralizer.js +2 -2
- package/dist/cjs/string/convert.js +1 -1
- package/dist/dts/colors/Color.d.ts +1 -1
- package/dist/dts/colors/types.d.ts +4 -6
- package/dist/dts/date/Chronos.d.ts +11 -5
- package/dist/dts/date/types.d.ts +17 -0
- package/dist/dts/index.d.ts +1 -0
- package/dist/esm/date/Chronos.js +28 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/pluralizer/Pluralizer.js +2 -2
- package/dist/esm/string/convert.js +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,15 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [4.25.0] - 2025-11-03
|
|
10
|
+
|
|
11
|
+
- **Added** new `Chronos` method `durationString(...)` and **Fixed** issues with internal *duration normalization logic*.
|
|
12
|
+
- **Fixed** all *pluralization logic* in `pluralize(...)` method of `Pluralizer` and `formatUnitWithPlural` utility: *Only `1` is considered singular, every other number is plural*.
|
|
13
|
+
|
|
14
|
+
## [4.24.4] - 2025-10-31
|
|
15
|
+
|
|
16
|
+
- **Exported** color *checkers/guards* from *main path*. **Reverted** color types (optimized spacing).
|
|
17
|
+
|
|
9
18
|
## [4.24.2] - 2025-10-31
|
|
10
19
|
|
|
11
20
|
- **Fixed** *return type* when no `'colorType'` option is passed in `generateRandomColor`. **Improved** color related *types*.
|
package/dist/cjs/date/Chronos.js
CHANGED
|
@@ -205,7 +205,7 @@ class Chronos {
|
|
|
205
205
|
}
|
|
206
206
|
#normalizeDuration(result, absolute, isFuture) {
|
|
207
207
|
const entries = Object.entries(result);
|
|
208
|
-
const updated = {};
|
|
208
|
+
const updated = { ...result };
|
|
209
209
|
if (!absolute && !isFuture) {
|
|
210
210
|
for (const [key, value] of entries) {
|
|
211
211
|
if (value !== 0) {
|
|
@@ -776,6 +776,33 @@ class Chronos {
|
|
|
776
776
|
};
|
|
777
777
|
return this.#normalizeDuration(result, absolute, isFuture);
|
|
778
778
|
}
|
|
779
|
+
durationString(options) {
|
|
780
|
+
const { toTime, absolute = true, maxUnits = 7, separator = ', ', style = 'full', showZero = false, } = options ?? {};
|
|
781
|
+
const duration = this.duration(toTime, absolute);
|
|
782
|
+
const units = {
|
|
783
|
+
years: 'y',
|
|
784
|
+
months: 'mo',
|
|
785
|
+
days: 'd',
|
|
786
|
+
hours: 'h',
|
|
787
|
+
minutes: 'm',
|
|
788
|
+
seconds: 's',
|
|
789
|
+
milliseconds: 'ms',
|
|
790
|
+
};
|
|
791
|
+
const _formatUnit = (unit, value) => {
|
|
792
|
+
if (style === 'short') {
|
|
793
|
+
return `${value}${units[unit]}`;
|
|
794
|
+
}
|
|
795
|
+
const $unit = Math.abs(value) === 1 ? unit.slice(0, -1) : unit;
|
|
796
|
+
return `${value} ${$unit}`;
|
|
797
|
+
};
|
|
798
|
+
const parts = Object.entries(duration)
|
|
799
|
+
.filter(([_, value]) => showZero || Math.abs(value) > 0)
|
|
800
|
+
.slice(0, maxUnits)
|
|
801
|
+
.map(([unit, value]) => _formatUnit(unit, value));
|
|
802
|
+
return (parts.length ? parts.join(separator)
|
|
803
|
+
: style === 'short' ? '0s'
|
|
804
|
+
: '0 seconds');
|
|
805
|
+
}
|
|
779
806
|
day(index) {
|
|
780
807
|
return constants_1.DAYS[index ?? this.weekDay];
|
|
781
808
|
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.convertToDecimal = exports.calculateLCM = exports.calculateLCD = exports.calculateHCF = exports.calculateGCD = exports.calculateFactorial = exports.calculateAverage = exports.verbalizer = exports.Verbalizer = exports.pluralizer = exports.Pluralizer = exports.VolumeConverter = exports.TimeConverter = exports.TemperatureConverter = exports.MassConverter = exports.LengthConverter = exports.DataConverter = exports.converter = exports.Converter = exports.AreaConverter = exports.wordCount = exports.parseNumbersFromText = exports.levenshteinDistance = exports.getLevenshteinDistance = exports.extractNumbersFromString = exports.extractNumbers = exports.countWordsInString = exports.countWords = exports.slugifyString = exports.reverseString = exports.replaceAllInString = exports.normalizeString = exports.maskString = exports.formatWithPlural = exports.formatUnitWithPlural = exports.formatNumberWithPluralUnit = exports.extractURLs = exports.extractEmails = exports.convertStringCase = exports.isSnakeCase = exports.isPascalCase = exports.isPalindrome = exports.isKebabCase = exports.isEmojiOnly = exports.isCamelCase = exports.generateAnagrams = exports.truncateString = exports.trimString = exports.generateRandomID = exports.capitalizeString = void 0;
|
|
4
4
|
exports.convertRomanToNumeric = exports.convertRomanToInteger = exports.convertRomanToArabic = exports.convertNumberToWordsOrdinal = exports.convertNumberToWords = exports.cardinalWordsToOrdinal = exports.arabicToRoman = exports.isPerfectSquare = exports.isPartOfFibonacciSeries = exports.isPartOfFibonacci = exports.isOddNumber = exports.isOdd = exports.isNumberInvalid = exports.isMultiple = exports.isInvalidNumber = exports.isFibonacci = exports.isEvenNumber = exports.isEven = exports.areNumbersInvalid = exports.areInvalidNumbers = exports.getNthFibonacci = exports.getMemoizedFibonacciSeries = exports.getMemoizedFibonacci = exports.getFibonacciSeriesMemo = exports.getFibonacciSeries = exports.getFibonacciNumbers = exports.getFibonacci = exports.generateFibonacci = exports.fibonacciGenerator = exports.calculatePercentage = exports.UnitConverter = exports.Unit = exports.Currency = exports.sumOfNumbers = exports.sumNumbers = exports.sumDigits = exports.roundToDecimal = exports.roundNumber = exports.reverseNumber = exports.getSumOfNumbers = exports.getRandomNumber = exports.getRandomInt = exports.getFactors = exports.getFactorial = exports.getDivisors = exports.getAverageOfNumbers = exports.getAverage = exports.factorsOf = exports.factorial = exports.convertToFixed = void 0;
|
|
5
5
|
exports.convertHslToHex = exports.convertHslaToRgba = exports.convertHslaToHex8 = exports.convertHexToRgb = exports.convertHexToHsl = exports.convertHex8ToRgba = exports.convertHex8ToHsla = exports.convertColorCode = exports.getRandomHSL = exports.getRandomColor = exports.generateRandomHSLColor = exports.generateRandomHSL = exports.generateRandomColorInHexRGB = exports.generateRandomColor = exports.getColorForInitial = exports.getNumbersInRange = exports.roundToNearestInterval = exports.roundToNearest = exports.roundNumberToNearestInterval = exports.numberToOrdinal = exports.normalizeNumber = exports.getRandomFloat = exports.getRandomDecimal = exports.getOrdinalNumber = exports.getOrdinal = exports.formatCurrency = exports.convertToOrdinal = exports.convertNumberToOrdinal = exports.convertNumberToCurrency = exports.clampNumber = exports.cardinalToOrdinal = exports.isPrimeNumber = exports.isPrime = exports.getPrimeNumbers = exports.findPrimeNumbers = exports.wordToNumber = exports.wordsToNumber = exports.toRomanNumeral = exports.toRoman = exports.romanToNumeric = exports.romanToInteger = exports.romanToArabic = exports.numericToRoman = exports.numberToWordsOrdinal = exports.numberToWords = exports.numberToRoman = exports.integerToRoman = exports.convertWordToNumber = exports.convertWordsToNumber = exports.convertToRomanNumerals = void 0;
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.httpStatus = exports.HttpStatus = exports.isValidSet = exports.isValidObject = exports.isValidMap = void 0;
|
|
6
|
+
exports.getTotalMinutes = exports.getTimeStringFromUTC = exports.getTimeFromMinutes = exports.getMinutesFromUTC = exports.getHourMinutesFromMinutes = exports.getCurrentTime = exports.getCurrentDateTime = exports.formatUTCOffset = exports.extractTotalMinutesFromTime = exports.extractTimeStringFromUTC = exports.extractTimeFromUTC = exports.extractMinutesFromUTC = exports.extractHourMinute = exports.convertMinutesToUTCOffset = exports.convertMinutesToTime = exports.convertMinutesToHourMinutes = exports.chronusts = exports.chronusjs = exports.chronus = exports.chronosts = exports.chronosjs = exports.chronos = exports.INTERNALS = exports.Chronus = exports.Chronos = exports.isValidUTCOffSet = exports.isValidUTC = exports.isValidTimeString = exports.isValidTime = exports.isLeapYear = exports.isDateLike = exports.greet = exports.getGreeting = exports.generateGreeting = exports.extractSolidColorValues = exports.extractAlphaColorValues = exports.Colour = exports.Color = exports.isRGBA = exports.isRGB = exports.isHSLA = exports.isHSL = exports.isHex8 = exports.isHex6 = exports.convertRgbToRgba = exports.convertRgbToHsl = exports.convertRgbToHex = exports.convertRgbaToHsla = exports.convertRgbaToHex8 = exports.convertHslToRgb = void 0;
|
|
7
|
+
exports.isOriginFileObj = exports.isFileUpload = exports.isFileOrBlob = exports.isFileList = exports.isFileArray = exports.isCustomFileArray = exports.isCustomFile = exports.serializeForm = exports.parseFormData = exports.createFormData = exports.createControlledFormData = exports.convertIntoFormData = exports.naturalSortForString = exports.naturalSort = exports.compareSorter = exports.compareNaturally = exports.splitArrayByProperty = exports.splitArray = exports.rotateArray = exports.removeDuplicatesFromArray = exports.removeDuplicates = exports.moveArrayElement = exports.groupArrayByProperty = exports.getMissingElements = exports.getDuplicatesFromArray = exports.getDuplicates = exports.findMissingElements = exports.extractMissingElements = exports.extractDuplicatesFromArray = exports.extractDuplicates = exports.createOptionsArray = exports.sortAnArray = exports.Finder = exports.totalDeltaByField = exports.sumFieldDifference = exports.sumByField = exports.groupAndSumByField = exports.groupAndAvgByField = exports.groupAndAverageByField = exports.avgByField = exports.averageByField = exports.shuffleArray = exports.isValidEmptyArray = exports.isInvalidOrEmptyArray = exports.getLastArrayElement = exports.flattenArray = exports.filterArrayOfObjects = exports.minutesToUTCOffset = exports.getTotalMinutesFromUTC = exports.getTotalMinutesFromTime = void 0;
|
|
8
|
+
exports.saveToSessionStorage = exports.saveToLocalStorage = exports.removeFromSessionStorage = exports.removeFromLocalStorage = exports.getFromSessionStorage = exports.getFromLocalStorage = exports.toggleFullScreen = exports.smoothScrollTo = exports.copyToClipboard = exports.updateQueryParam = exports.queryStringToObject = exports.parseQueryStringLiteral = exports.parseQueryString = exports.literalQueryStringToObject = exports.getQueryStringAsObject = exports.getQueryParams = exports.generateQueryParams = exports.formatQueryParams = exports.createQueryParams = exports.removeObjectFields = exports.removeFields = exports.remapObjectFields = exports.remapFields = exports.pickObjectFieldsByCondition = exports.pickObjectFields = exports.pickFieldsByCondition = exports.pickFields = exports.omitObjectFields = exports.omitFields = exports.deleteObjectFields = exports.deleteFields = exports.convertObjectValues = exports.sanitizeData = exports.parseStringifiedObjectValues = exports.parseObjectValues = exports.parseJsonToObject = exports.mergeObjects = exports.mergeAndFlattenObjects = exports.flattenObjectKeyValue = exports.flattenObjectDotNotation = exports.extractUpdatedFields = exports.extractUpdatedAndNewFields = exports.extractNewFields = exports.extractObjectKeysDeep = exports.extractObjectKeys = exports.extractKeysDeep = exports.extractKeys = exports.countObjectFields = exports.cloneObject = exports.isValidFormData = void 0;
|
|
9
|
+
exports.isPromise = exports.isObjectWithKeys = exports.isObjectEmpty = exports.isObject = exports.isNotEmptyObject = exports.isMethodDescriptor = exports.isMethod = exports.isMap = exports.isJSONObject = exports.isJSON = exports.isFunction = exports.isError = exports.isEmptyObjectGuard = exports.isEmptyObject = exports.isDate = exports.isArrayWithLength = exports.isArrayOfType = exports.isArray = exports.doesReturnPromise = exports.isUndefined = exports.isTruthy = exports.isSymbol = exports.isString = exports.isPrimitive = exports.isPositiveInteger = exports.isNumber = exports.isNull = exports.isNormalPrimitive = exports.isNonEmptyString = exports.isInteger = exports.isFalsy = exports.isBoolean = exports.isBigInt = exports.Paginator = exports.throttleAction = exports.parsePrimitivesDeep = exports.parseJsonDeep = exports.parseJSON = exports.joinArrayElements = exports.isDeepEqual = exports.getStaticMethodsCount = exports.getStaticMethodNames = exports.getInstanceMethodsCount = exports.getInstanceMethodNames = exports.getClassDetails = exports.deepParsePrimitives = exports.debounceAction = exports.countStaticMethods = exports.countInstanceMethods = exports.convertArrayToString = void 0;
|
|
10
|
+
exports.isValidURL = exports.isValidEmail = exports.isUUID = exports.isURL = exports.isPhoneNumber = exports.isNumericString = exports.isNodeEnvironment = exports.isNodeENV = exports.isNode = exports.isIPAddress = exports.isExpectedNodeENV = exports.isEnvironment = exports.isEmailArray = exports.isEmail = exports.isDateString = exports.isBrowser = exports.isBase64 = exports.httpStatus = exports.HttpStatus = exports.isValidSet = exports.isValidObject = exports.isValidMap = exports.isValidJSON = exports.isValidArray = exports.isSet = exports.isReturningPromise = exports.isRegularExpression = exports.isRegExp = void 0;
|
|
11
11
|
var basics_1 = require("./string/basics");
|
|
12
12
|
Object.defineProperty(exports, "capitalizeString", { enumerable: true, get: function () { return basics_1.capitalizeString; } });
|
|
13
13
|
Object.defineProperty(exports, "generateRandomID", { enumerable: true, get: function () { return basics_1.generateRandomID; } });
|
|
@@ -186,6 +186,13 @@ Object.defineProperty(exports, "convertRgbaToHsla", { enumerable: true, get: fun
|
|
|
186
186
|
Object.defineProperty(exports, "convertRgbToHex", { enumerable: true, get: function () { return convert_3.convertRgbToHex; } });
|
|
187
187
|
Object.defineProperty(exports, "convertRgbToHsl", { enumerable: true, get: function () { return convert_3.convertRgbToHsl; } });
|
|
188
188
|
Object.defineProperty(exports, "convertRgbToRgba", { enumerable: true, get: function () { return convert_3.convertRgbToRgba; } });
|
|
189
|
+
var helpers_1 = require("./colors/helpers");
|
|
190
|
+
Object.defineProperty(exports, "isHex6", { enumerable: true, get: function () { return helpers_1._isHex6; } });
|
|
191
|
+
Object.defineProperty(exports, "isHex8", { enumerable: true, get: function () { return helpers_1._isHex8; } });
|
|
192
|
+
Object.defineProperty(exports, "isHSL", { enumerable: true, get: function () { return helpers_1._isHSL; } });
|
|
193
|
+
Object.defineProperty(exports, "isHSLA", { enumerable: true, get: function () { return helpers_1._isHSLA; } });
|
|
194
|
+
Object.defineProperty(exports, "isRGB", { enumerable: true, get: function () { return helpers_1._isRGB; } });
|
|
195
|
+
Object.defineProperty(exports, "isRGBA", { enumerable: true, get: function () { return helpers_1._isRGBA; } });
|
|
189
196
|
var Color_1 = require("./colors/Color");
|
|
190
197
|
Object.defineProperty(exports, "Color", { enumerable: true, get: function () { return Color_1.Color; } });
|
|
191
198
|
Object.defineProperty(exports, "Colour", { enumerable: true, get: function () { return Color_1.Color; } });
|
|
@@ -100,8 +100,8 @@ class Pluralizer {
|
|
|
100
100
|
pluralize(word, options = {}) {
|
|
101
101
|
const count = (0, utilities_1.normalizeNumber)(options?.count);
|
|
102
102
|
if (typeof count === 'number') {
|
|
103
|
-
const pluralized = count
|
|
104
|
-
return options
|
|
103
|
+
const pluralized = count === 1 ? this.toSingular(word) : this.toPlural(word);
|
|
104
|
+
return options?.inclusive ? `${count} ${pluralized}` : pluralized;
|
|
105
105
|
}
|
|
106
106
|
return this.toPlural(word);
|
|
107
107
|
}
|
|
@@ -48,6 +48,6 @@ function extractURLs(str) {
|
|
|
48
48
|
}
|
|
49
49
|
function formatUnitWithPlural(count, unit, withNumber = true) {
|
|
50
50
|
const abs = Math.abs(count);
|
|
51
|
-
const pluralized = abs
|
|
51
|
+
const pluralized = abs === 1 ? unit : `${unit}s`;
|
|
52
52
|
return withNumber ? `${count} ${pluralized}` : pluralized;
|
|
53
53
|
}
|
|
@@ -100,7 +100,7 @@ export declare class Color {
|
|
|
100
100
|
*/
|
|
101
101
|
constructor(color: CSSColor);
|
|
102
102
|
/** - Iterates over the color representations (Hex, RGB, HSL). */
|
|
103
|
-
[Symbol.iterator](): Generator<Hex8 |
|
|
103
|
+
[Symbol.iterator](): Generator<Hex8 | HSL | Hex6 | RGB | RGBA | HSLA, void, unknown>;
|
|
104
104
|
/**
|
|
105
105
|
* @instance Applies or modifies the opacity of a color. Mutate the original instance.
|
|
106
106
|
* - For solid colors (Hex6/RGB/HSL): Adds an alpha channel with the specified opacity.
|
|
@@ -15,8 +15,6 @@ export type Hex = `#${string}`;
|
|
|
15
15
|
* * Format: `#3C6945`
|
|
16
16
|
*/
|
|
17
17
|
export type Hex6 = Branded<`#${string}`, 'Hex6'>;
|
|
18
|
-
/** Optional space */
|
|
19
|
-
export type $Space = '' | ' ';
|
|
20
18
|
/**
|
|
21
19
|
* * Represents an RGB color string.
|
|
22
20
|
* * Format: `rgb(R, G, B)`
|
|
@@ -25,7 +23,7 @@ export type $Space = '' | ' ';
|
|
|
25
23
|
* - G (Green): 0-255
|
|
26
24
|
* - B (Blue): 0-255
|
|
27
25
|
*/
|
|
28
|
-
export type RGB = `rgb(${number}
|
|
26
|
+
export type RGB = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${number},${number})`;
|
|
29
27
|
/**
|
|
30
28
|
* * Represents an HSL color string.
|
|
31
29
|
* * Format: `hsl(H, S%, L%)`
|
|
@@ -34,7 +32,7 @@ export type RGB = `rgb(${number},${$Space}${number},${$Space}${number})`;
|
|
|
34
32
|
* - S (Saturation): 0-100%
|
|
35
33
|
* - L (Lightness): 0-100%
|
|
36
34
|
*/
|
|
37
|
-
export type HSL = `hsl(${number}
|
|
35
|
+
export type HSL = `hsl(${number}, ${number}%, ${number}%)` | `hsl(${number},${number}%,${number}%)`;
|
|
38
36
|
/**
|
|
39
37
|
* * Represents a hexadecimal color code with optional alpha channel.
|
|
40
38
|
* * Format: `#3C6945FF`
|
|
@@ -44,12 +42,12 @@ export type Hex8 = Branded<`#${string}`, 'Hex8'>;
|
|
|
44
42
|
* * Represents an RGBA color string, now includes optional alpha (opacity).
|
|
45
43
|
* * Format: `rgba(R, G, B, A)`
|
|
46
44
|
*/
|
|
47
|
-
export type RGBA = `rgba(${number}
|
|
45
|
+
export type RGBA = `rgba(${number}, ${number}, ${number}, ${number})` | `rgba(${number},${number},${number},${number})`;
|
|
48
46
|
/**
|
|
49
47
|
* * Represents an HSLA color string with optional alpha channel.
|
|
50
48
|
* * Format: `hsla(H, S%, L%, A)`
|
|
51
49
|
*/
|
|
52
|
-
export type HSLA = `hsla(${number}
|
|
50
|
+
export type HSLA = `hsla(${number}, ${number}%, ${number}%, ${number})` | `hsla(${number},${number}%,${number}%,${number})`;
|
|
53
51
|
/** Represents an object with `hex` (`hex6`) and `rgb` color */
|
|
54
52
|
export type RandomHexRGB = {
|
|
55
53
|
/** Represents a hexadecimal color code. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Enumerate, LocaleCode, NumberRange } from '../number/types';
|
|
2
2
|
import type { TupleOf } from '../utils/types';
|
|
3
3
|
import { INTERNALS } from './constants';
|
|
4
|
-
import type { $UTCOffset, ChronosInput, ChronosInternals, ChronosMethods, ChronosObject, ChronosPlugin, ChronosWithOptions, DateRangeOptions, FormatOptions, Milliseconds, MonthName, Quarter, RangeWithDates, RelativeDateRange, RelativeRangeOptions, StrictFormat, TimeDuration, TimeParts, TimeUnit, WeekDay } from './types';
|
|
4
|
+
import type { $UTCOffset, ChronosInput, ChronosInternals, ChronosMethods, ChronosObject, ChronosPlugin, ChronosWithOptions, DateRangeOptions, DurationOptions, FormatOptions, Milliseconds, MonthName, Quarter, RangeWithDates, RelativeDateRange, RelativeRangeOptions, StrictFormat, TimeDuration, TimeParts, TimeUnit, WeekDay } from './types';
|
|
5
5
|
/**
|
|
6
6
|
* * Creates a new immutable `Chronos` instance.
|
|
7
7
|
*
|
|
@@ -36,7 +36,7 @@ export declare class Chronos {
|
|
|
36
36
|
* - **NOTE**: It is **HIGHLY** advised *not to rely* on this public property to access native JS `Date`. It's not reliable when timezone and/or UTC related operations are performed. If you really need to use native `Date`, use `toDate` method. This property is purely for developer convenience and sugar.
|
|
37
37
|
*/
|
|
38
38
|
native: Date;
|
|
39
|
-
/** Origin of the `Chronos` instance (Method that created `new Chronos`), useful
|
|
39
|
+
/** Origin of the `Chronos` instance (Method that created `new Chronos`), useful for tracking instance. */
|
|
40
40
|
origin: ChronosMethods | 'root';
|
|
41
41
|
/**
|
|
42
42
|
* * Creates a new immutable `Chronos` instance.
|
|
@@ -493,12 +493,18 @@ export declare class Chronos {
|
|
|
493
493
|
/** @instance Returns new `Chronos` instance in local time */
|
|
494
494
|
toLocal(): Chronos;
|
|
495
495
|
/**
|
|
496
|
-
* @instance Returns the full time duration breakdown between current input (start) and another time (to).
|
|
497
|
-
* @param toTime The time to compare with. Defaults to now
|
|
496
|
+
* @instance Returns the full time duration breakdown between current input (start) and another time (to) as object.
|
|
497
|
+
* @param toTime The time to compare with. Defaults to `now`.
|
|
498
498
|
* @param absolute If true, returns all values as positive numbers. Defaults to `true`.
|
|
499
499
|
* @returns An object of time units: years, months, days, hours, minutes, seconds, milliseconds.
|
|
500
500
|
*/
|
|
501
501
|
duration(toTime?: ChronosInput, absolute?: boolean): TimeDuration;
|
|
502
|
+
/**
|
|
503
|
+
* @instance Returns a human-readable formatted duration string between the current instance (start) and another time (to).
|
|
504
|
+
* @param options Options to format duration string, including the time to compare with.
|
|
505
|
+
* @returns A formatted duration string, e.g. `"2 hours, 5 minutes"` or `"2h 5m"`.
|
|
506
|
+
*/
|
|
507
|
+
durationString(options?: DurationOptions): string;
|
|
502
508
|
/**
|
|
503
509
|
* @instance Returns the name of the current day or optional day index.
|
|
504
510
|
* @param index Optional day index (`0–6`, where `0` is `Sunday`) to override current day.
|
|
@@ -570,7 +576,7 @@ export declare class Chronos {
|
|
|
570
576
|
/**
|
|
571
577
|
* @static Parses a date string with a given format (limited support only).
|
|
572
578
|
*
|
|
573
|
-
*
|
|
579
|
+
* **Supported format tokens**:
|
|
574
580
|
* - `YYYY`: Full year (e.g., 2023)
|
|
575
581
|
* - `YY`: Two-digit year (e.g., 23 for 2023, 99 for 1999)
|
|
576
582
|
* - `MM`: Month (01-12)
|
package/dist/dts/date/types.d.ts
CHANGED
|
@@ -122,6 +122,23 @@ export interface TimeDuration {
|
|
|
122
122
|
/** Number of milliseconds remaining after full seconds are counted. */
|
|
123
123
|
milliseconds: number;
|
|
124
124
|
}
|
|
125
|
+
/** Key of {@link TimeDuration} */
|
|
126
|
+
export type DurationKey = keyof TimeDuration;
|
|
127
|
+
/** Options for formatting duration string */
|
|
128
|
+
export interface DurationOptions {
|
|
129
|
+
/** The time to compare with. Defaults to `now`. */
|
|
130
|
+
toTime?: ChronosInput;
|
|
131
|
+
/** If true, returns all values as positive numbers. Defaults to `true`. */
|
|
132
|
+
absolute?: boolean;
|
|
133
|
+
/** Maximum number of units to display, e.g. 2 → "1 hour, 20 minutes" */
|
|
134
|
+
maxUnits?: NumberRange<1, 7>;
|
|
135
|
+
/** Separator between units (default: `", "`) */
|
|
136
|
+
separator?: string;
|
|
137
|
+
/** Display mode: `"full"` (default) → "2 hours", `"short"` → "2h" */
|
|
138
|
+
style?: 'full' | 'short';
|
|
139
|
+
/** Whether to include zero values (default: `false`) */
|
|
140
|
+
showZero?: boolean;
|
|
141
|
+
}
|
|
125
142
|
/** Interface for accessing internal private properties in extended `Chronos` class */
|
|
126
143
|
export interface ChronosInternals {
|
|
127
144
|
/**
|
package/dist/dts/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export { getNumbersInRange } from './number/range';
|
|
|
35
35
|
export { getColorForInitial } from './colors/initials';
|
|
36
36
|
export { generateRandomColor, generateRandomColorInHexRGB, generateRandomHSLColor as generateRandomHSL, generateRandomHSLColor, generateRandomColor as getRandomColor, generateRandomHSLColor as getRandomHSL, } from './colors/random';
|
|
37
37
|
export { convertColorCode, convertHex8ToHsla, convertHex8ToRgba, convertHexToHsl, convertHexToRgb, convertHslaToHex8, convertHslaToRgba, convertHslToHex, convertHslToRgb, convertRgbaToHex8, convertRgbaToHsla, convertRgbToHex, convertRgbToHsl, convertRgbToRgba, } from './colors/convert';
|
|
38
|
+
export { _isHex6 as isHex6, _isHex8 as isHex8, _isHSL as isHSL, _isHSLA as isHSLA, _isRGB as isRGB, _isRGBA as isRGBA, } from './colors/helpers';
|
|
38
39
|
export { Color, Color as Colour } from './colors/Color';
|
|
39
40
|
export { extractAlphaColorValues, extractSolidColorValues } from './colors/utils';
|
|
40
41
|
export { getGreeting as generateGreeting, getGreeting, getGreeting as greet, } from './date/greet';
|
package/dist/esm/date/Chronos.js
CHANGED
|
@@ -202,7 +202,7 @@ export class Chronos {
|
|
|
202
202
|
}
|
|
203
203
|
#normalizeDuration(result, absolute, isFuture) {
|
|
204
204
|
const entries = Object.entries(result);
|
|
205
|
-
const updated = {};
|
|
205
|
+
const updated = { ...result };
|
|
206
206
|
if (!absolute && !isFuture) {
|
|
207
207
|
for (const [key, value] of entries) {
|
|
208
208
|
if (value !== 0) {
|
|
@@ -773,6 +773,33 @@ export class Chronos {
|
|
|
773
773
|
};
|
|
774
774
|
return this.#normalizeDuration(result, absolute, isFuture);
|
|
775
775
|
}
|
|
776
|
+
durationString(options) {
|
|
777
|
+
const { toTime, absolute = true, maxUnits = 7, separator = ', ', style = 'full', showZero = false, } = options ?? {};
|
|
778
|
+
const duration = this.duration(toTime, absolute);
|
|
779
|
+
const units = {
|
|
780
|
+
years: 'y',
|
|
781
|
+
months: 'mo',
|
|
782
|
+
days: 'd',
|
|
783
|
+
hours: 'h',
|
|
784
|
+
minutes: 'm',
|
|
785
|
+
seconds: 's',
|
|
786
|
+
milliseconds: 'ms',
|
|
787
|
+
};
|
|
788
|
+
const _formatUnit = (unit, value) => {
|
|
789
|
+
if (style === 'short') {
|
|
790
|
+
return `${value}${units[unit]}`;
|
|
791
|
+
}
|
|
792
|
+
const $unit = Math.abs(value) === 1 ? unit.slice(0, -1) : unit;
|
|
793
|
+
return `${value} ${$unit}`;
|
|
794
|
+
};
|
|
795
|
+
const parts = Object.entries(duration)
|
|
796
|
+
.filter(([_, value]) => showZero || Math.abs(value) > 0)
|
|
797
|
+
.slice(0, maxUnits)
|
|
798
|
+
.map(([unit, value]) => _formatUnit(unit, value));
|
|
799
|
+
return (parts.length ? parts.join(separator)
|
|
800
|
+
: style === 'short' ? '0s'
|
|
801
|
+
: '0 seconds');
|
|
802
|
+
}
|
|
776
803
|
day(index) {
|
|
777
804
|
return DAYS[index ?? this.weekDay];
|
|
778
805
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export { getNumbersInRange } from './number/range.js';
|
|
|
20
20
|
export { getColorForInitial } from './colors/initials.js';
|
|
21
21
|
export { generateRandomColor, generateRandomColorInHexRGB, generateRandomHSLColor as generateRandomHSL, generateRandomHSLColor, generateRandomColor as getRandomColor, generateRandomHSLColor as getRandomHSL, } from './colors/random.js';
|
|
22
22
|
export { convertColorCode, convertHex8ToHsla, convertHex8ToRgba, convertHexToHsl, convertHexToRgb, convertHslaToHex8, convertHslaToRgba, convertHslToHex, convertHslToRgb, convertRgbaToHex8, convertRgbaToHsla, convertRgbToHex, convertRgbToHsl, convertRgbToRgba, } from './colors/convert.js';
|
|
23
|
+
export { _isHex6 as isHex6, _isHex8 as isHex8, _isHSL as isHSL, _isHSLA as isHSLA, _isRGB as isRGB, _isRGBA as isRGBA, } from './colors/helpers.js';
|
|
23
24
|
export { Color, Color as Colour } from './colors/Color.js';
|
|
24
25
|
export { extractAlphaColorValues, extractSolidColorValues } from './colors/utils.js';
|
|
25
26
|
export { getGreeting as generateGreeting, getGreeting, getGreeting as greet, } from './date/greet.js';
|
|
@@ -97,8 +97,8 @@ export class Pluralizer {
|
|
|
97
97
|
pluralize(word, options = {}) {
|
|
98
98
|
const count = normalizeNumber(options?.count);
|
|
99
99
|
if (typeof count === 'number') {
|
|
100
|
-
const pluralized = count
|
|
101
|
-
return options
|
|
100
|
+
const pluralized = count === 1 ? this.toSingular(word) : this.toPlural(word);
|
|
101
|
+
return options?.inclusive ? `${count} ${pluralized}` : pluralized;
|
|
102
102
|
}
|
|
103
103
|
return this.toPlural(word);
|
|
104
104
|
}
|
|
@@ -37,6 +37,6 @@ export function extractURLs(str) {
|
|
|
37
37
|
}
|
|
38
38
|
export function formatUnitWithPlural(count, unit, withNumber = true) {
|
|
39
39
|
const abs = Math.abs(count);
|
|
40
|
-
const pluralized = abs
|
|
40
|
+
const pluralized = abs === 1 ? unit : `${unit}s`;
|
|
41
41
|
return withNumber ? `${count} ${pluralized}` : pluralized;
|
|
42
42
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nhb-toolbox",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.25.0",
|
|
4
4
|
"description": "A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
},
|
|
40
40
|
"license": "Apache-2.0",
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@eslint/js": "^9.
|
|
42
|
+
"@eslint/js": "^9.39.0",
|
|
43
43
|
"@types/jest": "^30.0.0",
|
|
44
44
|
"@types/node": "^24.9.2",
|
|
45
45
|
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
46
46
|
"@typescript-eslint/parser": "^8.46.2",
|
|
47
|
-
"eslint": "^9.
|
|
47
|
+
"eslint": "^9.39.0",
|
|
48
48
|
"eslint-config-prettier": "^10.1.8",
|
|
49
49
|
"eslint-plugin-prettier": "^5.5.4",
|
|
50
|
-
"globals": "^16.
|
|
50
|
+
"globals": "^16.5.0",
|
|
51
51
|
"husky": "^9.1.7",
|
|
52
52
|
"jest": "^30.2.0",
|
|
53
53
|
"lint-staged": "^16.2.6",
|