@bgord/tools 0.14.2 → 0.15.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.
Files changed (101) hide show
  1. package/dist/age.vo.d.ts +10 -6
  2. package/dist/age.vo.js +23 -17
  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 +3 -3
  63. package/readme.md +4 -2
  64. package/src/age.vo.ts +23 -19
  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
@@ -1,26 +1,24 @@
1
1
  import { Timestamp, type TimestampType } from "./timestamp.vo";
2
- import type { Falsy } from "./ts-utils";
3
2
 
4
3
  enum StopwatchState {
5
4
  started = "started",
6
5
  stopped = "stopped",
7
6
  }
8
7
 
8
+ export const StopwatchStateError = "stopwatch.already.stopped" as const;
9
+
9
10
  export type StopwatchResultType = { durationMs: TimestampType };
10
11
 
11
12
  export class Stopwatch {
12
13
  private state: StopwatchState = StopwatchState.started;
13
14
 
14
- private stopMs: Falsy<TimestampType>;
15
-
16
15
  constructor(private readonly startMs: TimestampType) {}
17
16
 
18
17
  stop(): StopwatchResultType {
19
- if (this.state === StopwatchState.stopped) throw new Error("Stopwatch is already stopped");
18
+ if (this.state === StopwatchState.stopped) throw new Error(StopwatchStateError);
20
19
 
21
20
  this.state = StopwatchState.stopped;
22
- this.stopMs = Timestamp.parse(Date.now());
23
21
 
24
- return { durationMs: Timestamp.parse(this.stopMs - this.startMs) };
22
+ return { durationMs: Timestamp.parse(Date.now() - this.startMs) };
25
23
  }
26
24
  }
@@ -1,5 +1,19 @@
1
1
  export class Sum {
2
- static of(values: number[]): number {
2
+ static of(values: readonly number[]): number {
3
3
  return values.reduce((sum, x) => sum + x, 0);
4
4
  }
5
+
6
+ static precise(values: readonly number[]): number {
7
+ let runningTotal = 0;
8
+ let roundingCompensation = 0;
9
+
10
+ for (const currentValue of values) {
11
+ const correctedAddend = currentValue - roundingCompensation;
12
+ const tentativeTotal = runningTotal + correctedAddend;
13
+ roundingCompensation = tentativeTotal - runningTotal - correctedAddend;
14
+ runningTotal = tentativeTotal;
15
+ }
16
+
17
+ return runningTotal;
18
+ }
5
19
  }
@@ -1,4 +1,4 @@
1
- import { RoundToDecimal } from "./rounding.service";
1
+ import { RoundToDecimal } from "./rounding.adapter";
2
2
  import type { TimestampType } from "./timestamp.vo";
3
3
 
4
4
  const rounding = new RoundToDecimal(2);
@@ -1,4 +1,12 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
- export const Timestamp = z.number().int().gte(0).brand("Timestamp");
3
+ export const TimestampError = { error: "invalid.timestamp" } as const;
4
+
5
+ export const Timestamp = z
6
+ .number(TimestampError)
7
+ .int(TimestampError)
8
+ .gte(0, TimestampError)
9
+ .lte(Number.MAX_SAFE_INTEGER, TimestampError)
10
+ .brand("Timestamp");
11
+
4
12
  export type TimestampType = z.infer<typeof Timestamp>;
@@ -1,20 +1,20 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
+ export const TimezoneError = { error: "timezone.invalid" } as const;
4
+
3
5
  export const Timezone = z
4
- .string()
5
- .min(1)
6
- .refine(
7
- (value) => {
8
- try {
9
- const date = new Date();
10
- const formatter = new Intl.DateTimeFormat("en-US", { timeZone: value });
11
- formatter.format(date);
12
- return true;
13
- } catch (_error) {
14
- return false;
15
- }
16
- },
17
- { message: "timezone.invalid" },
18
- )
6
+ .string(TimezoneError)
7
+ .min(1, TimezoneError)
8
+ .refine((value) => {
9
+ try {
10
+ const date = new Date();
11
+ const formatter = new Intl.DateTimeFormat("en-US", { timeZone: value });
12
+ formatter.format(date);
13
+ return true;
14
+ } catch (_error) {
15
+ return false;
16
+ }
17
+ }, TimezoneError)
19
18
  .brand("Timezone");
19
+
20
20
  export type TimezoneType = z.infer<typeof Timezone>;
@@ -1,7 +1,6 @@
1
1
  import { Random } from "./random.service";
2
2
 
3
3
  export class VisuallyUnambiguousCharactersGenerator {
4
- // prettier-ignore
5
4
  static chars = [
6
5
  "a",
7
6
  "b",
package/src/weight.vo.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod/v4";
2
- import { type RoundingStrategy, RoundToDecimal } from "./rounding.service";
2
+ import { RoundToDecimal } from "./rounding.adapter";
3
+ import type { RoundingPort } from "./rounding.port";
3
4
 
4
5
  const FiniteNumericValue = z.number().refine(Number.isFinite, { message: "Expected a finite number" });
5
6
  const NonNegativeNumericValue = FiniteNumericValue.min(0, { message: "Must be greater than or equal to 0" });
@@ -49,17 +50,17 @@ export class Weight {
49
50
  return this.grams;
50
51
  }
51
52
 
52
- toKilograms(rounding?: RoundingStrategy): number {
53
+ toKilograms(rounding?: RoundingPort): number {
53
54
  const kilograms = this.grams / Weight.GRAMS_PER_KILOGRAM;
54
55
  return rounding ? rounding.round(kilograms) : kilograms;
55
56
  }
56
57
 
57
- toPounds(rounding?: RoundingStrategy): number {
58
+ toPounds(rounding?: RoundingPort): number {
58
59
  const pounds = (this.grams / Weight.GRAMS_PER_KILOGRAM) * Weight.POUNDS_PER_KILOGRAM;
59
60
  return rounding ? rounding.round(pounds) : pounds;
60
61
  }
61
62
 
62
- format(unit: WeightUnit, rounding: RoundingStrategy = new RoundToDecimal(2)): string {
63
+ format(unit: WeightUnit, rounding: RoundingPort = new RoundToDecimal(2)): string {
63
64
  const value = { [WeightUnit.kg]: this.toKilograms(rounding), [WeightUnit.lb]: this.toPounds(rounding) }[
64
65
  unit
65
66
  ];
@@ -1,6 +1,9 @@
1
1
  import { Mean } from "./mean.service";
2
2
  import { PopulationStandardDeviation } from "./population-standard-deviation.service";
3
- import { type RoundingStrategy, RoundToDecimal } from "./rounding.service";
3
+ import { RoundToDecimal } from "./rounding.adapter";
4
+ import type { RoundingPort } from "./rounding.port";
5
+
6
+ export const ZScoreMinValuesError = "zscore.min.values" as const;
4
7
 
5
8
  export class ZScore {
6
9
  private readonly mean: number;
@@ -8,9 +11,9 @@ export class ZScore {
8
11
 
9
12
  constructor(
10
13
  values: number[],
11
- private readonly rounding: RoundingStrategy = new RoundToDecimal(2),
14
+ private readonly rounding: RoundingPort = new RoundToDecimal(2),
12
15
  ) {
13
- if (values.length < 2) throw new Error("At least two values are needed");
16
+ if (values.length < 2) throw new Error(ZScoreMinValuesError);
14
17
 
15
18
  this.mean = Mean.calculate(values);
16
19
  this.standardDeviation = PopulationStandardDeviation.calculate(values);
@@ -1,9 +0,0 @@
1
- export declare enum DayOfTheWeekEnum {
2
- Monday = 1,
3
- Tuesday = 2,
4
- Wednesday = 3,
5
- Thursday = 4,
6
- Friday = 5,
7
- Saturday = 6,
8
- Sunday = 0
9
- }
@@ -1,10 +0,0 @@
1
- export var DayOfTheWeekEnum;
2
- (function (DayOfTheWeekEnum) {
3
- DayOfTheWeekEnum[DayOfTheWeekEnum["Monday"] = 1] = "Monday";
4
- DayOfTheWeekEnum[DayOfTheWeekEnum["Tuesday"] = 2] = "Tuesday";
5
- DayOfTheWeekEnum[DayOfTheWeekEnum["Wednesday"] = 3] = "Wednesday";
6
- DayOfTheWeekEnum[DayOfTheWeekEnum["Thursday"] = 4] = "Thursday";
7
- DayOfTheWeekEnum[DayOfTheWeekEnum["Friday"] = 5] = "Friday";
8
- DayOfTheWeekEnum[DayOfTheWeekEnum["Saturday"] = 6] = "Saturday";
9
- DayOfTheWeekEnum[DayOfTheWeekEnum["Sunday"] = 0] = "Sunday";
10
- })(DayOfTheWeekEnum || (DayOfTheWeekEnum = {}));
@@ -1,17 +0,0 @@
1
- export declare abstract class RoundingStrategy {
2
- abstract round(value: number): number;
3
- }
4
- export declare class RoundToNearest extends RoundingStrategy {
5
- round(value: number): number;
6
- }
7
- export declare class RoundUp extends RoundingStrategy {
8
- round(value: number): number;
9
- }
10
- export declare class RoundDown extends RoundingStrategy {
11
- round(value: number): number;
12
- }
13
- export declare class RoundToDecimal extends RoundingStrategy {
14
- private readonly decimals;
15
- constructor(decimals: number);
16
- round(value: number): number;
17
- }
@@ -1,9 +0,0 @@
1
- export enum DayOfTheWeekEnum {
2
- Monday = 1,
3
- Tuesday = 2,
4
- Wednesday = 3,
5
- Thursday = 4,
6
- Friday = 5,
7
- Saturday = 6,
8
- Sunday = 0,
9
- }
@@ -1,31 +0,0 @@
1
- export abstract class RoundingStrategy {
2
- abstract round(value: number): number;
3
- }
4
-
5
- export class RoundToNearest extends RoundingStrategy {
6
- round(value: number): number {
7
- return Math.round(value);
8
- }
9
- }
10
-
11
- export class RoundUp extends RoundingStrategy {
12
- round(value: number): number {
13
- return Math.ceil(value);
14
- }
15
- }
16
-
17
- export class RoundDown extends RoundingStrategy {
18
- round(value: number): number {
19
- return Math.floor(value);
20
- }
21
- }
22
-
23
- export class RoundToDecimal extends RoundingStrategy {
24
- constructor(private readonly decimals: number) {
25
- super();
26
- }
27
-
28
- round(value: number): number {
29
- return Number.parseFloat(value.toFixed(this.decimals));
30
- }
31
- }