nhb-toolbox 4.28.7 → 4.28.10

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 CHANGED
@@ -6,6 +6,14 @@ All notable changes to the package will be documented here.
6
6
 
7
7
  ---
8
8
 
9
+ ## [4.28.10] - 2025-12-03
10
+
11
+ - **Added** *new* `addOrOverrideCode` method and **modified** *existing* + **introduced** *new types* for `HttpStatus` class.
12
+
13
+ ## [4.28.8] - 2025-12-03
14
+
15
+ - **Fixed** a *tree-shaking issue* affecting `Chronos` and other *date/time utilities* by removing a *pre-compiled* `RegExp` instance from **date/constants**.
16
+
9
17
  ## [4.28.7] - 2025-12-02
10
18
 
11
19
  - **Updated** *invalid links* in *tsdoc* of the *hash utilities*.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MS_MAP = exports.TIME_UNIT_REGEX = exports.TIME_UNIT_VARIANTS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.DATE_PART_RANGES = exports.SORTED_TIME_FORMATS = exports.TIME_FORMATS = exports.MILLISECOND_FORMATS = exports.ZONE_FORMATS = exports.SECOND_FORMATS = exports.MINUTE_FORMATS = exports.HOUR_FORMATS = exports.DAY_FORMATS = exports.DATE_FORMATS = exports.MONTH_FORMATS = exports.YEAR_FORMATS = exports.MONTHS = exports.DAYS = exports.INTERNALS = void 0;
3
+ exports.MS_MAP = exports.TIME_UNIT_VARIANTS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.DATE_PART_RANGES = exports.SORTED_TIME_FORMATS = exports.TIME_FORMATS = exports.MILLISECOND_FORMATS = exports.ZONE_FORMATS = exports.SECOND_FORMATS = exports.MINUTE_FORMATS = exports.HOUR_FORMATS = exports.DAY_FORMATS = exports.DATE_FORMATS = exports.MONTH_FORMATS = exports.YEAR_FORMATS = exports.MONTHS = exports.DAYS = exports.INTERNALS = void 0;
4
4
  exports.INTERNALS = Symbol('Internals');
5
5
  exports.DAYS = /* @__PURE__ */ Object.freeze([
6
6
  'Sunday',
@@ -106,11 +106,6 @@ exports.TIME_UNIT_VARIANTS = /* @__PURE__ */ Object.freeze({
106
106
  second: ['s', 'sec', 'secs', 'second', 'seconds'],
107
107
  millisecond: ['ms', 'msec', 'msecs', 'millisecond', 'milliseconds'],
108
108
  });
109
- const TIME_UNIT_REGEX_STR = /* @__PURE__ */ Object.freeze(Object.values(exports.TIME_UNIT_VARIANTS)
110
- .flat()
111
- .sort((a, b) => b.length - a.length)
112
- .join('|'));
113
- exports.TIME_UNIT_REGEX = /* @__PURE__ */ Object.freeze(new RegExp(`^(?<value>-?\\d*\\.?\\d+) *(?<unit>${TIME_UNIT_REGEX_STR})?$`, 'i'));
114
109
  exports.MS_MAP = /* @__PURE__ */ Object.freeze((() => {
115
110
  const s = 1000;
116
111
  const m = s * 60;
@@ -10,7 +10,6 @@ exports.isTimeWithUnit = isTimeWithUnit;
10
10
  const primitives_1 = require("../guards/primitives");
11
11
  const specials_1 = require("../guards/specials");
12
12
  const utilities_1 = require("../number/utilities");
13
- const constants_1 = require("./constants");
14
13
  const timezone_1 = require("./timezone");
15
14
  function isValidTime(value) {
16
15
  if (!(0, primitives_1.isNonEmptyString)(value))
@@ -67,5 +66,6 @@ function isDateLike(value) {
67
66
  return false;
68
67
  }
69
68
  function isTimeWithUnit(value) {
70
- return (0, primitives_1.isNonEmptyString)(value) && constants_1.TIME_UNIT_REGEX.test(value);
69
+ return ((0, primitives_1.isNonEmptyString)(value) &&
70
+ /^-?\d*\.?\d+ *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mo|years?|yrs?|y)?$/i.test(value));
71
71
  }
@@ -21,7 +21,7 @@ function _parse(str, sec = false) {
21
21
  if (!(0, primitives_1.isNonEmptyString)(str) || str.length > 100) {
22
22
  throw new RangeError(`Value must be a string with length between 1 and 99!`);
23
23
  }
24
- const match = constants_1.TIME_UNIT_REGEX.exec(str);
24
+ const match = /^(?<value>-?\d*\.?\d+) *(?<unit>milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mo|years?|yrs?|y)?$/i.exec(str);
25
25
  if (!match?.groups)
26
26
  return NaN;
27
27
  const unit = (match.groups.unit ?? 'ms').toLowerCase();
@@ -47,12 +47,20 @@ class HttpStatus {
47
47
  }
48
48
  return added;
49
49
  }
50
+ addOrOverrideCode(...entries) {
51
+ for (const entry of entries) {
52
+ this.#storeEntry(entry);
53
+ HttpStatus.Groups[entry.category].push(entry.code);
54
+ }
55
+ return this;
56
+ }
50
57
  list(category) {
58
+ const entries = [...this.#codesByNumber.values()];
51
59
  if (!category) {
52
- return [...this.#codesByNumber.values()];
60
+ return entries;
53
61
  }
54
62
  else {
55
- return [...this.#codesByNumber.values()].filter((entry) => entry.category === category);
63
+ return entries.filter((entry) => entry.category === category);
56
64
  }
57
65
  }
58
66
  #storeEntry(entry) {
@@ -40,7 +40,5 @@ export declare const TIME_UNIT_VARIANTS: Readonly<{
40
40
  readonly second: readonly ["s", "sec", "secs", "second", "seconds"];
41
41
  readonly millisecond: readonly ["ms", "msec", "msecs", "millisecond", "milliseconds"];
42
42
  }>;
43
- /** `RegExp` for time unit variants */
44
- export declare const TIME_UNIT_REGEX: Readonly<RegExp>;
45
43
  /** Map to different time units to milliseconds */
46
44
  export declare const MS_MAP: Readonly<Record<"year" | "y" | "yr" | "yrs" | "years" | "month" | "mo" | "months" | "week" | "w" | "weeks" | "day" | "d" | "days" | "hour" | "h" | "hr" | "hrs" | "hours" | "minute" | "m" | "min" | "mins" | "minutes" | "second" | "s" | "sec" | "secs" | "seconds" | "millisecond" | "ms" | "msec" | "msecs" | "milliseconds", number>>;
@@ -486,8 +486,12 @@ export type ChronosWithOptions = Partial<{
486
486
  /** Milliseconds of the second, from 0 to 999. */
487
487
  millisecond: Milliseconds;
488
488
  }>;
489
+ /** Mapped type to {@link TIME_UNIT_VARIANTS} */
490
+ export type $TimeUnitVarMap = typeof TIME_UNIT_VARIANTS;
491
+ /** Key of {@link TIME_UNIT_VARIANTS} */
492
+ export type $TimeUnitKey = keyof typeof TIME_UNIT_VARIANTS;
489
493
  /** Variants of different time units in lowercase */
490
- export type $TimeUnitVar = (typeof TIME_UNIT_VARIANTS)[keyof typeof TIME_UNIT_VARIANTS][number];
494
+ export type $TimeUnitVar<U extends $TimeUnitKey = $TimeUnitKey> = $TimeUnitVarMap[U][number];
491
495
  /** Variants of different time units in lowercase, uppercase and capitalized */
492
496
  export type $UnitAnyCase = Capitalize<$TimeUnitVar> | Uppercase<$TimeUnitVar> | $TimeUnitVar;
493
497
  /** Number (time value) with variants of different time units */
@@ -1,4 +1,4 @@
1
- import type { HttpStatusName, StatusCategory, StatusCode, StatusEntry } from './types';
1
+ import type { HttpStatusCode, HttpStatusName, StatusCategory, StatusCode, StatusEntry, StatusName } from './types';
2
2
  /**
3
3
  * * Utility class for retrieving and managing HTTP status codes with rich MDN-based metadata.
4
4
  *
@@ -37,10 +37,16 @@ export declare class HttpStatus {
37
37
  #private;
38
38
  /**
39
39
  * * Static category groups for quick reference.
40
- * * Populated at runtime from the provided data.
40
+ * @remarks Populated at runtime from default and the provided data.
41
41
  */
42
42
  static Groups: Record<StatusCategory, StatusCode[]>;
43
43
  constructor();
44
+ /**
45
+ * * Get status entry by standard numeric HTTP code.
46
+ * @param code Standard HTTP status code.
47
+ * @returns Matching standard status entry.
48
+ */
49
+ getByCode(code: HttpStatusCode): StatusEntry;
44
50
  /**
45
51
  * * Get status entry by numeric HTTP code.
46
52
  * @param code HTTP status code.
@@ -48,11 +54,17 @@ export declare class HttpStatus {
48
54
  */
49
55
  getByCode(code: StatusCode): StatusEntry | undefined;
50
56
  /**
51
- * * Get status entry by name (either SOME_NAME or "Some Name").
52
- * @param name Status name.
57
+ * * Get status entry by standard name (either as `SOME_NAME` or `Some Name`).
58
+ * @param name Standard status name either as `SOME_NAME` or `Some Name`.
59
+ * @returns Matching standard status entry.
60
+ */
61
+ getByName(name: HttpStatusName): StatusEntry;
62
+ /**
63
+ * * Get status entry by name (either as `SOME_NAME` or `Some Name`).
64
+ * @param name Status name either as `SOME_NAME` or `Some Name`.
53
65
  * @returns Matching status entry or `undefined` if not found.
54
66
  */
55
- getByName(name: HttpStatusName): StatusEntry | undefined;
67
+ getByName(name: StatusName): StatusEntry | undefined;
56
68
  /**
57
69
  * * Override the short message of an existing code.
58
70
  * @param code HTTP status code.
@@ -64,6 +76,7 @@ export declare class HttpStatus {
64
76
  * * Add one or more new HTTP status code entries.
65
77
  *
66
78
  * @remarks
79
+ * - New entries are compared **by their `code` value** to determine uniqueness.
67
80
  * - If a code already exists, it will be skipped and not overwritten.
68
81
  * - Returns `true` if at least one code was successfully added.
69
82
  * - Returns `false` if all provided codes already exist.
@@ -72,6 +85,15 @@ export declare class HttpStatus {
72
85
  * @returns `true` if at least one code was added, otherwise `false`.
73
86
  */
74
87
  addCode(...entries: StatusEntry[]): boolean;
88
+ /**
89
+ * * Add/override one or more HTTP status code entries.
90
+ *
91
+ * @remarks New entries use their `code` value as the comparison key and will overwrite existing ones.
92
+ *
93
+ * @param entries One or more status entries to add/override.
94
+ * @returns The modified instance with the newly added/updated entries.
95
+ */
96
+ addOrOverrideCode(...entries: StatusEntry[]): HttpStatus;
75
97
  /**
76
98
  * * List all codes, optionally filtered by category.
77
99
  * @param category Optional category filter.
@@ -1,4 +1,4 @@
1
- /** Data for HTTP Status Codes */
1
+ /** HTTP status data from {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status MDN} */
2
2
  export declare const HTTP_STATUS_DATA: readonly [{
3
3
  readonly category: "informational";
4
4
  readonly link: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/100";
@@ -504,7 +504,7 @@ export declare const HTTP_STATUS_DATA: readonly [{
504
504
  readonly message: "Network Authentication Required";
505
505
  readonly description: "Indicates that the client needs to authenticate to gain network access.";
506
506
  }];
507
- /** List of HTTP Status Names with Corresponding Codes */
507
+ /** List of {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status HTTP Status Names with Corresponding Codes} */
508
508
  export declare const HTTP_STATUS_CODES: Readonly<{
509
509
  /**
510
510
  * * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/100 Continue}
@@ -1,28 +1,44 @@
1
1
  import type { LooseLiteral } from '../utils/types';
2
2
  import type { HTTP_STATUS_DATA } from './constants';
3
- /** HTTP Status Code, e.g. `404`, `500` etc. */
4
- export type StatusCode = LooseLiteral<(typeof HTTP_STATUS_DATA)[number]['code']>;
5
- /** Name for the Status Code in Uppercase snake case, e.g. `"NOT_FOUND"`, `"INTERNAL_SERVER_ERROR"` */
6
- export type StatusName = LooseLiteral<(typeof HTTP_STATUS_DATA)[number]['name']>;
7
- /** Name for the Status Code in Human readable form, e.g. `"Not Found"`, `"Internal Server Error"` */
8
- export type StatusNameReadable = LooseLiteral<(typeof HTTP_STATUS_DATA)[number]['readableName']>;
9
- /** Name for the Status Code in both Human readable and Uppercase snake case */
10
- export type HttpStatusName = StatusName | StatusNameReadable;
3
+ /** Mapped type of HTTP status entries */
4
+ export type $HttpStatusMap = (typeof HTTP_STATUS_DATA)[number];
5
+ /** HTTP status name variants: `name` or `readableName` */
6
+ export type $StatusNameVar = 'name' | 'readableName';
11
7
  /** * Categories of HTTP status codes: `"informational"`, `"success"`, `"redirection"`, `"clientError`" or `"serverError"` */
12
- export type StatusCategory = (typeof HTTP_STATUS_DATA)[number]['category'];
8
+ export type StatusCategory = $HttpStatusMap['category'];
9
+ /** - Extracts standard HTTP status codes by the given `Category` name. Defaults to all {@link StatusCategory categories}. */
10
+ export type HttpStatusCode<Category extends StatusCategory = StatusCategory> = $HttpStatusMap extends infer Target ? Target extends $HttpStatusMap ? Target['category'] extends Category ? Target['code'] : never : never : never;
11
+ /** Standard HTTP Status Code, e.g. `404`, `500` etc. + any number */
12
+ export type StatusCode = LooseLiteral<HttpStatusCode>;
13
+ /**
14
+ * - Extracts standard HTTP status names filtered by {@link $StatusNameVar variant} and {@link StatusCategory category}.
15
+ * - Defaults to all `variants` and `categories`.
16
+ *
17
+ * @remarks
18
+ * - `Name` selects either the `name` (CONSTANT_CASE) or `readableName` (Title Case).
19
+ * - `Category` restricts results to the chosen HTTP status {@link StatusCategory category}.
20
+ * - Produces a union of all matching literal status name values.
21
+ */
22
+ export type HttpStatusName<Name extends $StatusNameVar = $StatusNameVar, Category extends StatusCategory = StatusCategory> = $HttpStatusMap extends infer Target ? Target extends $HttpStatusMap ? Target['category'] extends Category ? Target[Name] : never : never : never;
23
+ /** Standard HTTP status name in `CONSTANT_CASE`, e.g. `"INTERNAL_SERVER_ERROR"` + any string */
24
+ export type StatusName = LooseLiteral<HttpStatusName>;
25
+ /** HTTP status name (`CONSTANT_CASE`) in {@link StatusEntry} interface */
26
+ export type EntryStatusName = LooseLiteral<HttpStatusName<'name'>>;
27
+ /** HTTP status name (`Title Case`) in {@link StatusEntry} interface */
28
+ export type EntryReadableName = LooseLiteral<HttpStatusName<'readableName'>>;
13
29
  /** * Shape of an HTTP status entry. */
14
30
  export interface StatusEntry {
15
31
  /** HTTP Status Code, e.g. `404`, `500` etc. */
16
32
  code: StatusCode;
17
- /** Name for the Status Code in Uppercase snake case, e.g. `"NOT_FOUND"`, `"INTERNAL_SERVER_ERROR"` */
18
- name: StatusName;
19
- /** Name for the Status Code in Human readable form, e.g. `"Not Found"`, `"Internal Server Error"` */
20
- readableName: StatusNameReadable;
33
+ /** HTTP status name in `CONSTANT_CASE`, e.g. `"NOT_FOUND"`, `"INTERNAL_SERVER_ERROR"` */
34
+ name: EntryStatusName;
35
+ /** HTTP status name in `Title Case` form, e.g. `"Not Found"`, `"Internal Server Error"` */
36
+ readableName: EntryReadableName;
21
37
  /** Link to full `MDN` Docs if available */
22
38
  link?: string;
23
39
  /** Short message, Can override using `httpStatus.setMessage` method */
24
40
  message: string;
25
- /** A brief description if available */
41
+ /** A brief description of the status code */
26
42
  description: string;
27
43
  /** The type of HTTP Status: `"informational"`, `"success"`, `"redirection"`, `"clientError`" or `"serverError"` */
28
44
  category: StatusCategory;
@@ -103,11 +103,6 @@ export const TIME_UNIT_VARIANTS = /* @__PURE__ */ Object.freeze({
103
103
  second: ['s', 'sec', 'secs', 'second', 'seconds'],
104
104
  millisecond: ['ms', 'msec', 'msecs', 'millisecond', 'milliseconds'],
105
105
  });
106
- const TIME_UNIT_REGEX_STR = /* @__PURE__ */ Object.freeze(Object.values(TIME_UNIT_VARIANTS)
107
- .flat()
108
- .sort((a, b) => b.length - a.length)
109
- .join('|'));
110
- export const TIME_UNIT_REGEX = /* @__PURE__ */ Object.freeze(new RegExp(`^(?<value>-?\\d*\\.?\\d+) *(?<unit>${TIME_UNIT_REGEX_STR})?$`, 'i'));
111
106
  export const MS_MAP = /* @__PURE__ */ Object.freeze((() => {
112
107
  const s = 1000;
113
108
  const m = s * 60;
@@ -1,7 +1,6 @@
1
1
  import { isNonEmptyString, isString } from '../guards/primitives.js';
2
2
  import { isNumericString } from '../guards/specials.js';
3
3
  import { normalizeNumber } from '../number/utilities.js';
4
- import { TIME_UNIT_REGEX } from './constants.js';
5
4
  import { IANA_TZ_IDS } from './timezone.js';
6
5
  export function isValidTime(value) {
7
6
  if (!isNonEmptyString(value))
@@ -58,5 +57,6 @@ export function isDateLike(value) {
58
57
  return false;
59
58
  }
60
59
  export function isTimeWithUnit(value) {
61
- return isNonEmptyString(value) && TIME_UNIT_REGEX.test(value);
60
+ return (isNonEmptyString(value) &&
61
+ /^-?\d*\.?\d+ *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mo|years?|yrs?|y)?$/i.test(value));
62
62
  }
@@ -1,6 +1,6 @@
1
1
  import { isNonEmptyString, isNumber } from '../guards/primitives.js';
2
2
  import { isNumericString } from '../guards/specials.js';
3
- import { MS_MAP, TIME_UNIT_REGEX } from './constants.js';
3
+ import { MS_MAP } from './constants.js';
4
4
  import { isTimeWithUnit } from './guards.js';
5
5
  export function parseMSec(value, sec = false) {
6
6
  if (isNumericString(value)) {
@@ -18,7 +18,7 @@ function _parse(str, sec = false) {
18
18
  if (!isNonEmptyString(str) || str.length > 100) {
19
19
  throw new RangeError(`Value must be a string with length between 1 and 99!`);
20
20
  }
21
- const match = TIME_UNIT_REGEX.exec(str);
21
+ const match = /^(?<value>-?\d*\.?\d+) *(?<unit>milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mo|years?|yrs?|y)?$/i.exec(str);
22
22
  if (!match?.groups)
23
23
  return NaN;
24
24
  const unit = (match.groups.unit ?? 'ms').toLowerCase();
@@ -44,12 +44,20 @@ export class HttpStatus {
44
44
  }
45
45
  return added;
46
46
  }
47
+ addOrOverrideCode(...entries) {
48
+ for (const entry of entries) {
49
+ this.#storeEntry(entry);
50
+ HttpStatus.Groups[entry.category].push(entry.code);
51
+ }
52
+ return this;
53
+ }
47
54
  list(category) {
55
+ const entries = [...this.#codesByNumber.values()];
48
56
  if (!category) {
49
- return [...this.#codesByNumber.values()];
57
+ return entries;
50
58
  }
51
59
  else {
52
- return [...this.#codesByNumber.values()].filter((entry) => entry.category === category);
60
+ return entries.filter((entry) => entry.category === category);
53
61
  }
54
62
  }
55
63
  #storeEntry(entry) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "4.28.7",
3
+ "version": "4.28.10",
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",