@bgord/tools 0.14.3 → 0.15.1

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.
Files changed (101) hide show
  1. package/dist/age.vo.d.ts +10 -6
  2. package/dist/age.vo.js +22 -14
  3. package/dist/api-key.vo.d.ts +3 -0
  4. package/dist/api-key.vo.js +7 -1
  5. package/dist/clock-format.service.d.ts +9 -0
  6. package/dist/clock-format.service.js +10 -0
  7. package/dist/clock.vo.d.ts +7 -14
  8. package/dist/clock.vo.js +25 -34
  9. package/dist/height.vo.d.ts +7 -7
  10. package/dist/height.vo.js +6 -6
  11. package/dist/hour-format.service.d.ts +10 -0
  12. package/dist/hour-format.service.js +19 -0
  13. package/dist/hour.vo.d.ts +8 -17
  14. package/dist/hour.vo.js +22 -39
  15. package/dist/iban-mask.service.js +6 -3
  16. package/dist/iban.vo.d.ts +6 -4
  17. package/dist/iban.vo.js +7 -5
  18. package/dist/image.vo.d.ts +8 -2
  19. package/dist/image.vo.js +14 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +2 -2
  22. package/dist/language.vo.d.ts +4 -1
  23. package/dist/language.vo.js +5 -3
  24. package/dist/mean.service.d.ts +4 -2
  25. package/dist/mean.service.js +9 -5
  26. package/dist/min-max-scaler.service.d.ts +22 -14
  27. package/dist/min-max-scaler.service.js +16 -15
  28. package/dist/minute.vo.d.ts +5 -6
  29. package/dist/minute.vo.js +14 -14
  30. package/dist/money.vo.d.ts +13 -2
  31. package/dist/money.vo.js +18 -13
  32. package/dist/outlier-detector.service.d.ts +2 -1
  33. package/dist/outlier-detector.service.js +5 -3
  34. package/dist/percentage.service.d.ts +3 -2
  35. package/dist/percentage.service.js +3 -2
  36. package/dist/population-standard-deviation.service.d.ts +3 -2
  37. package/dist/population-standard-deviation.service.js +5 -4
  38. package/dist/random.service.d.ts +6 -0
  39. package/dist/random.service.js +12 -6
  40. package/dist/rounding.adapter.d.ts +16 -0
  41. package/dist/{rounding.service.js → rounding.adapter.js} +8 -7
  42. package/dist/rounding.port.d.ts +3 -0
  43. package/dist/rounding.port.js +1 -0
  44. package/dist/simple-linear-regression.service.d.ts +11 -4
  45. package/dist/simple-linear-regression.service.js +39 -30
  46. package/dist/size.vo.js +1 -1
  47. package/dist/stopwatch.service.d.ts +1 -1
  48. package/dist/stopwatch.service.js +3 -4
  49. package/dist/sum.service.d.ts +2 -1
  50. package/dist/sum.service.js +11 -0
  51. package/dist/time.service.js +1 -1
  52. package/dist/timestamp.vo.d.ts +3 -0
  53. package/dist/timestamp.vo.js +7 -1
  54. package/dist/timezone.vo.d.ts +3 -0
  55. package/dist/timezone.vo.js +4 -3
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/dist/visually-unambiguous-characters-generator.service.js +0 -1
  58. package/dist/weight.vo.d.ts +4 -4
  59. package/dist/weight.vo.js +1 -1
  60. package/dist/z-score.service.d.ts +3 -2
  61. package/dist/z-score.service.js +3 -2
  62. package/package.json +2 -2
  63. package/readme.md +4 -2
  64. package/src/age.vo.ts +24 -14
  65. package/src/api-key.vo.ts +9 -1
  66. package/src/clock-format.service.ts +15 -0
  67. package/src/clock.vo.ts +24 -43
  68. package/src/height.vo.ts +12 -11
  69. package/src/hour-format.service.ts +21 -0
  70. package/src/hour.vo.ts +24 -47
  71. package/src/iban-mask.service.ts +8 -3
  72. package/src/iban.vo.ts +10 -8
  73. package/src/image.vo.ts +19 -4
  74. package/src/index.ts +2 -2
  75. package/src/language.vo.ts +7 -3
  76. package/src/mean.service.ts +13 -5
  77. package/src/min-max-scaler.service.ts +39 -24
  78. package/src/minute.vo.ts +18 -15
  79. package/src/money.vo.ts +26 -23
  80. package/src/outlier-detector.service.ts +6 -4
  81. package/src/percentage.service.ts +6 -7
  82. package/src/population-standard-deviation.service.ts +8 -5
  83. package/src/random.service.ts +16 -8
  84. package/src/relative-date.vo.ts +0 -1
  85. package/src/rounding.adapter.ts +33 -0
  86. package/src/rounding.port.ts +3 -0
  87. package/src/simple-linear-regression.service.ts +41 -31
  88. package/src/size.vo.ts +1 -1
  89. package/src/stopwatch.service.ts +4 -6
  90. package/src/sum.service.ts +15 -1
  91. package/src/time.service.ts +1 -1
  92. package/src/timestamp.vo.ts +9 -1
  93. package/src/timezone.vo.ts +15 -15
  94. package/src/visually-unambiguous-characters-generator.service.ts +0 -1
  95. package/src/weight.vo.ts +5 -4
  96. package/src/z-score.service.ts +6 -3
  97. package/dist/dates-of-the-week.vo.d.ts +0 -9
  98. package/dist/dates-of-the-week.vo.js +0 -10
  99. package/dist/rounding.service.d.ts +0 -17
  100. package/src/dates-of-the-week.vo.ts +0 -9
  101. package/src/rounding.service.ts +0 -31
package/dist/age.vo.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { z } from "zod/v4";
2
2
  import type { TimestampType } from "./timestamp.vo";
3
3
  export declare const AgeValueError: {
4
- error: string;
4
+ readonly error: "invalid.age";
5
5
  };
6
+ export declare const InvalidBirthdateInFutureError: "invalid.birthdate_in_future";
7
+ export declare const InvalidBirthdateError: "invalid.birthdate";
6
8
  export declare class Age {
7
9
  private readonly value;
8
10
  static readonly MIN = 1;
@@ -11,12 +13,12 @@ export declare class Age {
11
13
  private constructor();
12
14
  get(): number;
13
15
  compare(other: Age): -1 | 0 | 1;
14
- equals(another: Age): boolean;
15
- isOlderThan(another: Age): boolean;
16
- isYoungerThan(another: Age): boolean;
17
- isAdult(minAge: Age): boolean;
16
+ equals(other: Age): boolean;
17
+ isOlderThan(other: Age): boolean;
18
+ isYoungerThan(other: Age): boolean;
19
+ isAdult(minimumAge: Age): boolean;
18
20
  static fromValue(candidate: number): Age;
19
- static fromBirthdateTimestamp(params: {
21
+ static fromBirthdateEpochMs(params: {
20
22
  birthdate: TimestampType;
21
23
  now: TimestampType;
22
24
  }): Age;
@@ -24,4 +26,6 @@ export declare class Age {
24
26
  birthdate: string;
25
27
  now: TimestampType;
26
28
  }): Age;
29
+ toJSON(): number;
30
+ toString(): string;
27
31
  }
package/dist/age.vo.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { differenceInYears } from "date-fns";
2
2
  import { z } from "zod/v4";
3
3
  export const AgeValueError = { error: "invalid.age" };
4
+ export const InvalidBirthdateInFutureError = "invalid.birthdate_in_future";
5
+ export const InvalidBirthdateError = "invalid.birthdate";
4
6
  export class Age {
5
7
  value;
6
8
  static MIN = 1;
@@ -20,30 +22,36 @@ export class Age {
20
22
  compare(other) {
21
23
  return this.value === other.value ? 0 : this.value < other.value ? -1 : 1;
22
24
  }
23
- equals(another) {
24
- return this.compare(another) === 0;
25
+ equals(other) {
26
+ return this.value === other.value;
25
27
  }
26
- isOlderThan(another) {
27
- return this.compare(another) === 1;
28
+ isOlderThan(other) {
29
+ return this.value > other.value;
28
30
  }
29
- isYoungerThan(another) {
30
- return this.compare(another) === -1;
31
+ isYoungerThan(other) {
32
+ return this.value < other.value;
31
33
  }
32
- isAdult(minAge) {
33
- return this.equals(minAge) || this.isOlderThan(minAge);
34
+ isAdult(minimumAge) {
35
+ return this.value >= minimumAge.value;
34
36
  }
35
37
  static fromValue(candidate) {
36
38
  return new Age(Age.AgeValue.parse(candidate));
37
39
  }
38
- static fromBirthdateTimestamp(params) {
40
+ static fromBirthdateEpochMs(params) {
39
41
  if (params.birthdate > params.now)
40
- throw new Error("invalid.birthdate_in_future");
42
+ throw new Error(InvalidBirthdateInFutureError);
41
43
  return Age.fromValue(differenceInYears(params.now, params.birthdate));
42
44
  }
43
45
  static fromBirthdate(params) {
44
- const birthdate = new Date(params.birthdate).getTime();
45
- if (birthdate > params.now)
46
- throw new Error("invalid.birthdate_in_future");
47
- return Age.fromValue(differenceInYears(params.now, birthdate));
46
+ const birthdateMs = new Date(params.birthdate).getTime();
47
+ if (birthdateMs > params.now)
48
+ throw new Error(InvalidBirthdateInFutureError);
49
+ return Age.fromValue(differenceInYears(params.now, birthdateMs));
50
+ }
51
+ toJSON() {
52
+ return this.get();
53
+ }
54
+ toString() {
55
+ return String(this.value);
48
56
  }
49
57
  }
@@ -1,3 +1,6 @@
1
1
  import { z } from "zod/v4";
2
+ export declare const ApiKeyError: {
3
+ error: string;
4
+ };
2
5
  export declare const ApiKey: z.core.$ZodBranded<z.ZodString, "ApiKey">;
3
6
  export type ApiKeyType = z.infer<typeof ApiKey>;
@@ -1,2 +1,8 @@
1
1
  import { z } from "zod/v4";
2
- export const ApiKey = z.string().trim().length(64).brand("ApiKey");
2
+ export const ApiKeyError = { error: "invalid.api.key" };
3
+ export const ApiKey = z
4
+ .string(ApiKeyError)
5
+ .trim()
6
+ .length(64, ApiKeyError)
7
+ .regex(/^[0-9a-zA-Z]{64}$/i, ApiKeyError)
8
+ .brand("ApiKey");
@@ -0,0 +1,9 @@
1
+ import type { Hour } from "./hour.vo";
2
+ import type { Minute } from "./minute.vo";
3
+ export type ClockFormatter = (hour: Hour, minute: Minute) => string;
4
+ declare enum ClockFormatterEnum {
5
+ TWENTY_FOUR_HOURS = "TWENTY_FOUR_HOURS",
6
+ TWELVE_HOURS = "TWELVE_HOURS"
7
+ }
8
+ export declare const ClockFormatters: Record<ClockFormatterEnum, ClockFormatter>;
9
+ export {};
@@ -0,0 +1,10 @@
1
+ import { HourFormatters } from "./hour-format.service";
2
+ var ClockFormatterEnum;
3
+ (function (ClockFormatterEnum) {
4
+ ClockFormatterEnum["TWENTY_FOUR_HOURS"] = "TWENTY_FOUR_HOURS";
5
+ ClockFormatterEnum["TWELVE_HOURS"] = "TWELVE_HOURS";
6
+ })(ClockFormatterEnum || (ClockFormatterEnum = {}));
7
+ export const ClockFormatters = {
8
+ TWENTY_FOUR_HOURS: (hour, minute) => `${hour.toString()}:${minute.toString()}`,
9
+ TWELVE_HOURS: (hour, minute) => `${hour.format(HourFormatters.TWELVE_HOURS)}:${minute.toString()}`,
10
+ };
@@ -1,27 +1,20 @@
1
+ import { type ClockFormatter } from "./clock-format.service";
1
2
  import { Hour } from "./hour.vo";
2
3
  import { Minute } from "./minute.vo";
3
4
  import type { TimestampType } from "./timestamp.vo";
4
- export type ClockFormatter = (hour: Hour, minute: Minute) => string;
5
- declare enum ClockFormatterEnum {
6
- TWENTY_FOUR_HOURS = "TWENTY_FOUR_HOURS",
7
- TWELVE_HOURS = "TWELVE_HOURS"
8
- }
9
- export declare const ClockFormatters: Record<ClockFormatterEnum, ClockFormatter>;
10
5
  export declare class Clock {
11
6
  private readonly hour;
12
7
  private readonly minute;
13
8
  private readonly formatter;
14
9
  constructor(hour: Hour, minute: Minute, formatter?: ClockFormatter);
15
- static fromUtcTimestamp(timestamp: TimestampType, formatter?: ClockFormatter): Clock;
16
- get(formatter?: ClockFormatter): {
17
- raw: {
18
- hour: number;
19
- minute: number;
20
- };
21
- formatted: string;
10
+ static fromEpochMs(timestamp: TimestampType, formatter?: ClockFormatter): Clock;
11
+ get(): {
12
+ hour: number;
13
+ minute: number;
22
14
  };
15
+ format(formatter?: ClockFormatter): string;
16
+ toString(): string;
23
17
  equals(another: Clock): boolean;
24
18
  isAfter(another: Clock): boolean;
25
19
  isBefore(another: Clock): boolean;
26
20
  }
27
- export {};
package/dist/clock.vo.js CHANGED
@@ -1,14 +1,6 @@
1
- import { Hour, HourFormatters } from "./hour.vo";
1
+ import { ClockFormatters } from "./clock-format.service";
2
+ import { Hour } from "./hour.vo";
2
3
  import { Minute } from "./minute.vo";
3
- var ClockFormatterEnum;
4
- (function (ClockFormatterEnum) {
5
- ClockFormatterEnum["TWENTY_FOUR_HOURS"] = "TWENTY_FOUR_HOURS";
6
- ClockFormatterEnum["TWELVE_HOURS"] = "TWELVE_HOURS";
7
- })(ClockFormatterEnum || (ClockFormatterEnum = {}));
8
- export const ClockFormatters = {
9
- TWENTY_FOUR_HOURS: (hour, minute) => `${hour.get().formatted}:${minute.get().formatted}`,
10
- TWELVE_HOURS: (hour, minute) => `${hour.get(HourFormatters.TWELVE_HOURS).formatted}:${minute.get().formatted}`,
11
- };
12
4
  export class Clock {
13
5
  hour;
14
6
  minute;
@@ -18,37 +10,36 @@ export class Clock {
18
10
  this.minute = minute;
19
11
  this.formatter = formatter ?? ClockFormatters.TWENTY_FOUR_HOURS;
20
12
  }
21
- static fromUtcTimestamp(timestamp, formatter) {
22
- const hour = Hour.fromUtcTimestamp(timestamp);
23
- const minute = Minute.fromUtcTimestamp(timestamp);
13
+ static fromEpochMs(timestamp, formatter) {
14
+ const hour = Hour.fromEpochMs(timestamp);
15
+ const minute = Minute.fromEpochMs(timestamp);
24
16
  return new Clock(hour, minute, formatter);
25
17
  }
26
- get(formatter) {
27
- const format = formatter ?? this.formatter;
28
- return {
29
- raw: { hour: this.hour.get().raw, minute: this.minute.get().raw },
30
- formatted: format(this.hour, this.minute),
31
- };
18
+ get() {
19
+ return { hour: this.hour.get(), minute: this.minute.get() };
20
+ }
21
+ format(formatter) {
22
+ const chosen = formatter ?? this.formatter;
23
+ return chosen(this.hour, this.minute);
24
+ }
25
+ toString() {
26
+ return this.format();
32
27
  }
33
28
  equals(another) {
34
- return (this.hour.get().raw === another.get().raw.hour && this.minute.get().raw === another.get().raw.minute);
29
+ return this.hour.get() === another.hour.get() && this.minute.get() === another.minute.get();
35
30
  }
36
31
  isAfter(another) {
37
- if (this.hour.get().raw > another.hour.get().raw) {
38
- return true;
39
- }
40
- if (this.hour.get().raw === another.hour.get().raw && this.minute.get().raw > another.minute.get().raw) {
41
- return true;
42
- }
43
- return false;
32
+ const thisHour = this.hour.get();
33
+ const otherHour = another.hour.get();
34
+ if (thisHour !== otherHour)
35
+ return thisHour > otherHour;
36
+ return this.minute.get() > another.minute.get();
44
37
  }
45
38
  isBefore(another) {
46
- if (this.hour.get().raw < another.hour.get().raw) {
47
- return true;
48
- }
49
- if (this.hour.get().raw === another.hour.get().raw && this.minute.get().raw < another.minute.get().raw) {
50
- return true;
51
- }
52
- return false;
39
+ const thisHour = this.hour.get();
40
+ const otherHour = another.hour.get();
41
+ if (thisHour !== otherHour)
42
+ return thisHour < otherHour;
43
+ return this.minute.get() < another.minute.get();
53
44
  }
54
45
  }
@@ -1,4 +1,4 @@
1
- import { type RoundingStrategy } from "./rounding.service";
1
+ import type { RoundingPort } from "./rounding.port";
2
2
  export declare enum HeightUnit {
3
3
  cm = "cm",
4
4
  ft_in = "ft_in"
@@ -9,17 +9,17 @@ export declare class Height {
9
9
  private static readonly MILLIMETERS_PER_INCH;
10
10
  private static readonly INCHES_PER_FOOT;
11
11
  private constructor();
12
- static fromCentimeters(centimeters: number, rounding?: RoundingStrategy): Height;
13
- static fromFeetInches(feet: number, inches?: number, rounding?: RoundingStrategy): Height;
14
- static fromMillimeters(millimeters: number, rounding?: RoundingStrategy): Height;
12
+ static fromCentimeters(centimeters: number, rounding?: RoundingPort): Height;
13
+ static fromFeetInches(feet: number, inches?: number, rounding?: RoundingPort): Height;
14
+ static fromMillimeters(millimeters: number, rounding?: RoundingPort): Height;
15
15
  static zero(): Height;
16
16
  toMillimeters(): number;
17
- toCentimeters(rounding?: RoundingStrategy): number;
18
- toFeetInches(rounding?: RoundingStrategy): {
17
+ toCentimeters(rounding?: RoundingPort): number;
18
+ toFeetInches(rounding?: RoundingPort): {
19
19
  feet: number;
20
20
  inches: number;
21
21
  };
22
- format(unit: HeightUnit, roundingStrategy?: RoundingStrategy): string;
22
+ format(unit: HeightUnit, rounding?: RoundingPort): string;
23
23
  equals(other: Height): boolean;
24
24
  compare(other: Height): -1 | 0 | 1;
25
25
  greaterThan(other: Height): boolean;
package/dist/height.vo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod/v4";
2
- import { RoundToDecimal, RoundToNearest } from "./rounding.service";
2
+ import { RoundToDecimal, RoundToNearest } from "./rounding.adapter";
3
3
  const FiniteNumericValue = z.number().refine(Number.isFinite, { message: "Expected a finite number" });
4
4
  const NonNegativeNumericValue = FiniteNumericValue.min(0, { message: "Must be greater than or equal to 0" });
5
5
  const NonNegativeIntegerMillimeters = FiniteNumericValue.int().min(0, {
@@ -61,15 +61,15 @@ export class Height {
61
61
  const inches = integerInches % Height.INCHES_PER_FOOT;
62
62
  return { feet, inches };
63
63
  }
64
- format(unit, roundingStrategy) {
64
+ format(unit, rounding) {
65
65
  return {
66
66
  [HeightUnit.cm]: () => {
67
- const rounding = roundingStrategy ?? new RoundToDecimal(1);
68
- return `${this.toCentimeters(rounding)} cm`;
67
+ const chosen = rounding ?? new RoundToDecimal(1);
68
+ return `${this.toCentimeters(chosen)} cm`;
69
69
  },
70
70
  [HeightUnit.ft_in]: () => {
71
- const rounding = roundingStrategy ?? new RoundToNearest();
72
- const { feet, inches } = this.toFeetInches(rounding);
71
+ const chosen = rounding ?? new RoundToNearest();
72
+ const { feet, inches } = this.toFeetInches(chosen);
73
73
  return `${feet}′${inches}″`;
74
74
  },
75
75
  }[unit]();
@@ -0,0 +1,10 @@
1
+ export type HourFormatter = (value: number) => string;
2
+ declare enum HourFormatterEnum {
3
+ TWENTY_FOUR_HOURS = "TWENTY_FOUR_HOURS",
4
+ TWENTY_FOUR_HOURS_WO_PADDING = "TWENTY_FOUR_HOURS_WO_PADDING",
5
+ AM_PM = "AM_PM",
6
+ TWELVE_HOURS = "TWELVE_HOURS",
7
+ TWELVE_HOURS_WO_PADDING = "TWELVE_HOURS_WO_PADDING"
8
+ }
9
+ export declare const HourFormatters: Record<HourFormatterEnum, HourFormatter>;
10
+ export {};
@@ -0,0 +1,19 @@
1
+ var HourFormatterEnum;
2
+ (function (HourFormatterEnum) {
3
+ HourFormatterEnum["TWENTY_FOUR_HOURS"] = "TWENTY_FOUR_HOURS";
4
+ HourFormatterEnum["TWENTY_FOUR_HOURS_WO_PADDING"] = "TWENTY_FOUR_HOURS_WO_PADDING";
5
+ HourFormatterEnum["AM_PM"] = "AM_PM";
6
+ HourFormatterEnum["TWELVE_HOURS"] = "TWELVE_HOURS";
7
+ HourFormatterEnum["TWELVE_HOURS_WO_PADDING"] = "TWELVE_HOURS_WO_PADDING";
8
+ })(HourFormatterEnum || (HourFormatterEnum = {}));
9
+ export const HourFormatters = {
10
+ TWENTY_FOUR_HOURS: (value) => value.toString().padStart(2, "0"),
11
+ TWENTY_FOUR_HOURS_WO_PADDING: (value) => value.toString(),
12
+ AM_PM: (value) => {
13
+ const twelveHourValue = value % 12 || 12;
14
+ const suffix = value < 12 ? "a.m." : "p.m.";
15
+ return `${twelveHourValue} ${suffix}`;
16
+ },
17
+ TWELVE_HOURS: (value) => (value % 12 || 12).toString().padStart(2, "0"),
18
+ TWELVE_HOURS_WO_PADDING: (value) => (value % 12 || 12).toString(),
19
+ };
package/dist/hour.vo.d.ts CHANGED
@@ -1,26 +1,17 @@
1
+ import { type HourFormatter } from "./hour-format.service";
1
2
  import type { TimestampType } from "./timestamp.vo";
2
- export type HourFormatter = (value: Hour["value"]) => string;
3
- export declare enum HourFormatterEnum {
4
- TWENTY_FOUR_HOURS = "TWENTY_FOUR_HOURS",
5
- TWENTY_FOUR_HOURS_WO_PADDING = "TWENTY_FOUR_HOURS_WO_PADDING",
6
- AM_PM = "AM_PM",
7
- TWELVE_HOURS = "TWELVE_HOURS",
8
- TWELVE_HOURS_WO_PADDING = "TWELVE_HOURS_WO_PADDING"
9
- }
10
- export declare const HourFormatters: Record<HourFormatterEnum, HourFormatter>;
3
+ export declare const HourValueError: "invalid.hour";
11
4
  export declare class Hour {
12
5
  private readonly value;
13
- private readonly formatter;
14
6
  static readonly ZERO: Hour;
15
7
  static readonly MAX: Hour;
16
- constructor(candidate: number, formatter?: HourFormatter);
17
- get(formatter?: HourFormatter): {
18
- raw: number;
19
- formatted: string;
20
- };
8
+ constructor(candidate: number);
9
+ static fromEpochMs(timestamp: TimestampType): Hour;
10
+ get(): number;
11
+ toString(): string;
12
+ format(formatter: HourFormatter): string;
21
13
  equals(another: Hour): boolean;
22
14
  isAfter(another: Hour): boolean;
23
15
  isBefore(another: Hour): boolean;
24
- static fromUtcTimestamp(timestamp: TimestampType, formatter?: HourFormatter): Hour;
25
- static list(formatter?: HourFormatter): Hour[];
16
+ static list(): readonly Hour[];
26
17
  }
package/dist/hour.vo.js CHANGED
@@ -1,54 +1,37 @@
1
- export var HourFormatterEnum;
2
- (function (HourFormatterEnum) {
3
- HourFormatterEnum["TWENTY_FOUR_HOURS"] = "TWENTY_FOUR_HOURS";
4
- HourFormatterEnum["TWENTY_FOUR_HOURS_WO_PADDING"] = "TWENTY_FOUR_HOURS_WO_PADDING";
5
- HourFormatterEnum["AM_PM"] = "AM_PM";
6
- HourFormatterEnum["TWELVE_HOURS"] = "TWELVE_HOURS";
7
- HourFormatterEnum["TWELVE_HOURS_WO_PADDING"] = "TWELVE_HOURS_WO_PADDING";
8
- })(HourFormatterEnum || (HourFormatterEnum = {}));
9
- export const HourFormatters = {
10
- TWENTY_FOUR_HOURS: (value) => value.toString().padStart(2, "0"),
11
- TWENTY_FOUR_HOURS_WO_PADDING: (value) => value.toString(),
12
- AM_PM: (value) => {
13
- const twelveHour = value % 12 || 12;
14
- return `${twelveHour.toString()} ${value < 12 ? "a.m." : "p.m."}`;
15
- },
16
- TWELVE_HOURS: (value) => (value % 12 || 12).toString().padStart(2, "0"),
17
- TWELVE_HOURS_WO_PADDING: (value) => (value % 12 || 12).toString(),
18
- };
1
+ import { HourFormatters } from "./hour-format.service";
2
+ export const HourValueError = "invalid.hour";
19
3
  export class Hour {
20
4
  value;
21
- formatter;
22
5
  static ZERO = new Hour(0);
23
6
  static MAX = new Hour(23);
24
- constructor(candidate, formatter) {
25
- if (!Number.isInteger(candidate))
26
- throw new Error("Invalid hour");
27
- if (candidate < 0)
28
- throw new Error("Invalid hour");
29
- if (candidate >= 24)
30
- throw new Error("Invalid hour");
7
+ constructor(candidate) {
8
+ if (!Number.isInteger(candidate) || candidate < 0 || candidate >= 24) {
9
+ throw new Error(HourValueError);
10
+ }
31
11
  this.value = candidate;
32
- this.formatter = formatter ?? HourFormatters.TWENTY_FOUR_HOURS;
33
12
  }
34
- get(formatter) {
35
- const format = formatter ?? this.formatter;
36
- return { raw: this.value, formatted: format(this.value) };
13
+ static fromEpochMs(timestamp) {
14
+ return new Hour(new Date(timestamp).getUTCHours());
15
+ }
16
+ get() {
17
+ return this.value;
18
+ }
19
+ toString() {
20
+ return HourFormatters.TWENTY_FOUR_HOURS(this.value);
21
+ }
22
+ format(formatter) {
23
+ return formatter(this.value);
37
24
  }
38
25
  equals(another) {
39
- return this.value === another.get().raw;
26
+ return this.value === another.value;
40
27
  }
41
28
  isAfter(another) {
42
- return this.value > another.get().raw;
29
+ return this.value > another.value;
43
30
  }
44
31
  isBefore(another) {
45
- return this.value < another.get().raw;
46
- }
47
- static fromUtcTimestamp(timestamp, formatter) {
48
- const hours = new Date(timestamp).getUTCHours();
49
- return new Hour(hours, formatter);
32
+ return this.value < another.value;
50
33
  }
51
- static list(formatter) {
52
- return Array.from({ length: 24 }).map((_, index) => new Hour(index, formatter));
34
+ static list() {
35
+ return Array.from({ length: 24 }, (_, index) => new Hour(index));
53
36
  }
54
37
  }
@@ -1,9 +1,12 @@
1
1
  export class IbanMask {
2
2
  static censor(iban) {
3
3
  const value = iban.format();
4
- const start = value.slice(0, 4);
5
- const middle = value.slice(5, -5).replace(/\d/g, "*");
4
+ const FIRST_SPACE_INDEX = 4;
5
+ const LAST_SPACE_START_INDEX = value.length - 5;
6
+ const start = value.slice(0, FIRST_SPACE_INDEX);
7
+ const middle = value.slice(FIRST_SPACE_INDEX + 1, LAST_SPACE_START_INDEX);
6
8
  const end = value.slice(-4);
7
- return `${start} ${middle} ${end}`;
9
+ const maskedMiddle = middle.replace(/[A-Z0-9]/g, "*");
10
+ return `${start} ${maskedMiddle} ${end}`;
8
11
  }
9
12
  }
package/dist/iban.vo.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { z } from "zod/v4";
2
- declare const IBANValueSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
3
- type IBANValueType = z.infer<typeof IBANValueSchema>;
4
- type IBANCountryCode = string;
2
+ export declare const IBANError: {
3
+ readonly error: "invalid.iban.format";
4
+ };
5
+ export declare const IBANValue: z.core.$ZodBranded<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, "IBAN">;
6
+ export type IBANValueType = z.infer<typeof IBANValue>;
7
+ export type IBANCountryCode = string;
5
8
  export declare class IBAN {
6
9
  private readonly value;
7
10
  constructor(value: string);
@@ -10,4 +13,3 @@ export declare class IBAN {
10
13
  get countryCode(): IBANCountryCode;
11
14
  equals(other: IBAN): boolean;
12
15
  }
13
- export {};
package/dist/iban.vo.js CHANGED
@@ -1,16 +1,18 @@
1
1
  import { z } from "zod/v4";
2
- // Basic IBAN format regex (2-letter country code + 2 digits + 11–30 alphanumerics)
2
+ export const IBANError = { error: "invalid.iban.format" };
3
+ // 2-letter country code + 2 digits + 11–30 alphanumerics (overall 15–34 chars)
3
4
  const IBAN_REGEX = /^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/;
4
- const IBANValueSchema = z
5
- .string()
5
+ export const IBANValue = z
6
+ .string(IBANError)
6
7
  .trim()
7
8
  .toUpperCase()
8
9
  .transform((val) => val.replace(/\s+/g, ""))
9
- .refine((iban) => IBAN_REGEX.test(iban), { message: "invalid.iban.format" });
10
+ .refine((iban) => IBAN_REGEX.test(iban), IBANError)
11
+ .brand("IBAN");
10
12
  export class IBAN {
11
13
  value;
12
14
  constructor(value) {
13
- this.value = IBANValueSchema.parse(value);
15
+ this.value = IBANValue.parse(value);
14
16
  }
15
17
  toString() {
16
18
  return this.value;
@@ -1,5 +1,11 @@
1
1
  import { z } from "zod/v4";
2
+ export declare const ImageWidthError: {
3
+ readonly error: "invalid.image.width";
4
+ };
5
+ export declare const ImageHeightError: {
6
+ readonly error: "invalid.image.height";
7
+ };
2
8
  export declare const ImageWidth: z.core.$ZodBranded<z.ZodNumber, "image-width">;
3
- export type WidthType = z.infer<typeof ImageWidth>;
9
+ export type ImageWidthType = z.infer<typeof ImageWidth>;
4
10
  export declare const ImageHeight: z.core.$ZodBranded<z.ZodNumber, "image-height">;
5
- export type HeightType = z.infer<typeof ImageHeight>;
11
+ export type ImageHeightType = z.infer<typeof ImageHeight>;
package/dist/image.vo.js CHANGED
@@ -1,3 +1,15 @@
1
1
  import { z } from "zod/v4";
2
- export const ImageWidth = z.number().int().positive().max(10000).brand("image-width");
3
- export const ImageHeight = z.number().int().positive().max(10000).brand("image-height");
2
+ export const ImageWidthError = { error: "invalid.image.width" };
3
+ export const ImageHeightError = { error: "invalid.image.height" };
4
+ export const ImageWidth = z
5
+ .number(ImageWidthError)
6
+ .int(ImageWidthError)
7
+ .positive(ImageWidthError)
8
+ .max(10_000, ImageWidthError)
9
+ .brand("image-width");
10
+ export const ImageHeight = z
11
+ .number(ImageHeightError)
12
+ .int(ImageHeightError)
13
+ .positive(ImageHeightError)
14
+ .max(10_000, ImageHeightError)
15
+ .brand("image-height");
package/dist/index.d.ts CHANGED
@@ -5,7 +5,6 @@ export * from "./clock.vo";
5
5
  export * from "./date-calculator.service";
6
6
  export * from "./date-formatter.service";
7
7
  export * from "./date-range.vo";
8
- export * from "./dates-of-the-week.vo";
9
8
  export * from "./day.vo";
10
9
  export * from "./day-iso-id.vo";
11
10
  export * from "./directory-path-absolute.vo";
@@ -50,7 +49,8 @@ export * from "./rate-limiter.service";
50
49
  export * from "./relative-date.vo";
51
50
  export * from "./reordering.service";
52
51
  export * from "./revision.vo";
53
- export * from "./rounding.service";
52
+ export * from "./rounding.adapter";
53
+ export * from "./rounding.port";
54
54
  export * from "./simple-linear-regression.service";
55
55
  export * from "./size.vo";
56
56
  export * from "./stepper.service";
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@ export * from "./clock.vo";
5
5
  export * from "./date-calculator.service";
6
6
  export * from "./date-formatter.service";
7
7
  export * from "./date-range.vo";
8
- export * from "./dates-of-the-week.vo";
9
8
  export * from "./day.vo";
10
9
  export * from "./day-iso-id.vo";
11
10
  export * from "./directory-path-absolute.vo";
@@ -50,7 +49,8 @@ export * from "./rate-limiter.service";
50
49
  export * from "./relative-date.vo";
51
50
  export * from "./reordering.service";
52
51
  export * from "./revision.vo";
53
- export * from "./rounding.service";
52
+ export * from "./rounding.adapter";
53
+ export * from "./rounding.port";
54
54
  export * from "./simple-linear-regression.service";
55
55
  export * from "./size.vo";
56
56
  export * from "./stepper.service";
@@ -1,3 +1,6 @@
1
1
  import { z } from "zod/v4";
2
- export declare const Language: z.ZodString;
2
+ export declare const LanguageError: {
3
+ readonly error: "invalid.language";
4
+ };
5
+ export declare const Language: z.core.$ZodBranded<z.ZodString, "Language">;
3
6
  export type LanguageType = z.infer<typeof Language>;
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod/v4";
2
+ export const LanguageError = { error: "invalid.language" };
2
3
  export const Language = z
3
- .string()
4
- .length(2)
5
- .regex(/^[a-z]{2}$/, { message: "invalid_language" });
4
+ .string(LanguageError)
5
+ .length(2, LanguageError)
6
+ .regex(/^[a-z]{2}$/, LanguageError)
7
+ .brand("Language");
@@ -1,4 +1,6 @@
1
- import { type RoundingStrategy } from "./rounding.service";
1
+ import type { RoundingPort } from "./rounding.port";
2
+ export declare const MeanEmptyValuesError: "mean.values.empty";
2
3
  export declare class Mean {
3
- static calculate(values: number[], rounding?: RoundingStrategy): number;
4
+ private static readonly DEFAULT_ROUNDING;
5
+ static calculate(values: number[], rounding?: RoundingPort): number;
4
6
  }
@@ -1,10 +1,14 @@
1
- import { RoundToDecimal } from "./rounding.service";
1
+ import { RoundToDecimal } from "./rounding.adapter";
2
2
  import { Sum } from "./sum.service";
3
+ export const MeanEmptyValuesError = "mean.values.empty";
3
4
  export class Mean {
4
- static calculate(values, rounding = new RoundToDecimal(2)) {
5
+ static DEFAULT_ROUNDING = new RoundToDecimal(2);
6
+ static calculate(values, rounding) {
5
7
  if (values.length === 0)
6
- throw new Error("Values should not be empty");
7
- const mean = Sum.of(values) / values.length;
8
- return rounding.round(mean);
8
+ throw new Error(MeanEmptyValuesError);
9
+ const sum = Sum.of(values);
10
+ const mean = sum / values.length;
11
+ const chosen = rounding ?? Mean.DEFAULT_ROUNDING;
12
+ return chosen.round(mean);
9
13
  }
10
14
  }