@bgord/tools 0.12.26 → 0.13.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 (106) hide show
  1. package/dist/clock.vo.d.ts +4 -2
  2. package/dist/clock.vo.js +7 -1
  3. package/dist/directory-path-absolute.vo.d.ts +1 -1
  4. package/dist/directory-path-absolute.vo.js +1 -1
  5. package/dist/file-path-absolute-schema.vo.d.ts +1 -1
  6. package/dist/hour.vo.d.ts +2 -0
  7. package/dist/hour.vo.js +11 -11
  8. package/dist/index.d.ts +7 -3
  9. package/dist/index.js +7 -3
  10. package/dist/mean.service.js +1 -2
  11. package/dist/mime.vo.js +2 -4
  12. package/dist/min-max-scaler.service.js +5 -10
  13. package/dist/minute.vo.d.ts +2 -0
  14. package/dist/minute.vo.js +8 -10
  15. package/dist/money.vo.js +3 -7
  16. package/dist/month-iso-id.vo.d.ts +3 -0
  17. package/dist/month-iso-id.vo.js +15 -0
  18. package/dist/month.vo.d.ts +9 -0
  19. package/dist/month.vo.js +22 -0
  20. package/dist/outlier-detector.service.js +1 -2
  21. package/dist/package-version.vo.js +0 -5
  22. package/dist/pagination.service.js +1 -8
  23. package/dist/percentage.service.js +1 -2
  24. package/dist/population-standard-deviation.service.js +1 -2
  25. package/dist/quarter-iso-id.vo.d.ts +3 -0
  26. package/dist/quarter-iso-id.vo.js +10 -0
  27. package/dist/quarter.vo.d.ts +9 -0
  28. package/dist/quarter.vo.js +24 -0
  29. package/dist/random.service.js +4 -8
  30. package/dist/reordering.service.js +3 -6
  31. package/dist/revision.vo.js +2 -4
  32. package/dist/simple-linear-regression.service.js +6 -12
  33. package/dist/stepper.service.js +2 -4
  34. package/dist/stopwatch.service.js +2 -3
  35. package/dist/timezone.vo.js +2 -6
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/dist/visually-unambiguous-characters-generator.service.js +2 -4
  38. package/dist/weekday.vo.d.ts +37 -0
  39. package/dist/weekday.vo.js +86 -0
  40. package/dist/year-iso-id.vo.d.ts +3 -0
  41. package/dist/year-iso-id.vo.js +8 -0
  42. package/dist/year.vo.d.ts +11 -0
  43. package/dist/year.vo.js +32 -0
  44. package/dist/z-score.service.js +1 -2
  45. package/package.json +3 -3
  46. package/readme.md +7 -3
  47. package/src/api-key.vo.ts +0 -1
  48. package/src/basename.vo.ts +0 -1
  49. package/src/clock.vo.ts +9 -2
  50. package/src/date-calculator.service.ts +1 -4
  51. package/src/date-formatter.service.ts +0 -1
  52. package/src/directory-path-absolute.vo.ts +1 -1
  53. package/src/dll.service.ts +0 -5
  54. package/src/email-mask.service.ts +0 -1
  55. package/src/etags.vo.ts +0 -1
  56. package/src/extension.vo.ts +0 -1
  57. package/src/feature-flag.vo.ts +1 -1
  58. package/src/filename-from-string.vo.ts +0 -1
  59. package/src/filename-suffix.vo.ts +0 -1
  60. package/src/hour.vo.ts +15 -13
  61. package/src/image.vo.ts +0 -2
  62. package/src/index.ts +7 -3
  63. package/src/language.vo.ts +0 -1
  64. package/src/mean.service.ts +1 -3
  65. package/src/mime.vo.ts +2 -9
  66. package/src/min-max-scaler.service.ts +6 -21
  67. package/src/minute.vo.ts +11 -15
  68. package/src/money.vo.ts +3 -9
  69. package/src/month-iso-id.vo.ts +25 -0
  70. package/src/month.vo.ts +26 -0
  71. package/src/object-key.vo.ts +0 -1
  72. package/src/outlier-detector.service.ts +1 -3
  73. package/src/package-version.vo.ts +0 -12
  74. package/src/pagination.service.ts +4 -29
  75. package/src/percentage.service.ts +1 -5
  76. package/src/population-standard-deviation.service.ts +1 -3
  77. package/src/quarter-iso-id.vo.ts +18 -0
  78. package/src/quarter.vo.ts +28 -0
  79. package/src/random.service.ts +5 -19
  80. package/src/rate-limiter.service.ts +0 -3
  81. package/src/reordering.service.ts +6 -19
  82. package/src/revision.vo.ts +2 -8
  83. package/src/simple-linear-regression.service.ts +6 -21
  84. package/src/size.vo.ts +0 -1
  85. package/src/stepper.service.ts +2 -9
  86. package/src/stopwatch.service.ts +2 -4
  87. package/src/streak-calculator.service.ts +1 -6
  88. package/src/time-zone-offset-value.vo.ts +0 -1
  89. package/src/timestamp.vo.ts +0 -1
  90. package/src/timezone.vo.ts +2 -9
  91. package/src/ts-utils.ts +0 -2
  92. package/src/visually-unambiguous-characters-generator.service.ts +2 -4
  93. package/src/week-iso-id.vo.ts +0 -1
  94. package/src/weekday.vo.ts +101 -0
  95. package/src/year-iso-id.vo.ts +13 -0
  96. package/src/year.vo.ts +36 -0
  97. package/src/z-score.service.ts +1 -3
  98. package/dist/build-version.vo.d.ts +0 -3
  99. package/dist/build-version.vo.js +0 -2
  100. package/dist/filter.vo.d.ts +0 -17
  101. package/dist/filter.vo.js +0 -22
  102. package/dist/leap-year-checker.service.d.ts +0 -4
  103. package/dist/leap-year-checker.service.js +0 -9
  104. package/src/build-version.vo.ts +0 -5
  105. package/src/filter.vo.ts +0 -38
  106. package/src/leap-year-checker.service.ts +0 -11
package/src/mime.vo.ts CHANGED
@@ -2,9 +2,7 @@ import * as mime from "mime-types";
2
2
  import { ExtensionSchema, type ExtensionType } from "./extension.vo";
3
3
 
4
4
  export type MimeRawType = string;
5
-
6
5
  type MimeTypeType = string;
7
-
8
6
  type MimeSubtypeType = string;
9
7
 
10
8
  export class Mime {
@@ -15,13 +13,8 @@ export class Mime {
15
13
  constructor(value: MimeRawType) {
16
14
  const [type, subtype] = value.split("/");
17
15
 
18
- if (typeof type !== "string" || type.length === 0) {
19
- throw new InvalidMimeError();
20
- }
21
-
22
- if (typeof subtype !== "string" || subtype.length === 0) {
23
- throw new InvalidMimeError();
24
- }
16
+ if (typeof type !== "string" || type.length === 0) throw new InvalidMimeError();
17
+ if (typeof subtype !== "string" || subtype.length === 0) throw new InvalidMimeError();
25
18
 
26
19
  this.raw = value;
27
20
  this.type = type;
@@ -1,14 +1,10 @@
1
1
  import { type RoundingStrategy, RoundToDecimal } from "./rounding.service";
2
2
 
3
3
  type MinMaxScalerValueType = number;
4
-
5
4
  type MinMaxScalerConfigType = {
6
5
  min: MinMaxScalerValueType;
7
6
  max: MinMaxScalerValueType;
8
- bound?: {
9
- lower: MinMaxScalerValueType;
10
- upper: MinMaxScalerValueType;
11
- };
7
+ bound?: { lower: MinMaxScalerValueType; upper: MinMaxScalerValueType };
12
8
  rounding?: RoundingStrategy;
13
9
  };
14
10
 
@@ -26,13 +22,8 @@ export class MinMaxScaler {
26
22
  const lower = config.bound?.lower ?? 0;
27
23
  const upper = config.bound?.upper ?? 1;
28
24
 
29
- if (config.max - config.min < 0) {
30
- throw new Error("Invalid MinMaxScaler min-max config");
31
- }
32
-
33
- if (upper - lower <= 0) {
34
- throw new Error("Invalid MinMaxScaler bound config");
35
- }
25
+ if (config.max - config.min < 0) throw new Error("Invalid MinMaxScaler min-max config");
26
+ if (upper - lower <= 0) throw new Error("Invalid MinMaxScaler bound config");
36
27
 
37
28
  this.rounding = rounding;
38
29
 
@@ -45,9 +36,7 @@ export class MinMaxScaler {
45
36
  scale(value: MinMaxScalerValueType) {
46
37
  const { min, max, lower, upper } = this;
47
38
 
48
- if (value < min || value > max) {
49
- throw new Error("Value out of min/max range");
50
- }
39
+ if (value < min || value > max) throw new Error("Value out of min/max range");
51
40
 
52
41
  if (min === max)
53
42
  return {
@@ -70,9 +59,7 @@ export class MinMaxScaler {
70
59
  descale(scaled: MinMaxScalerValueType) {
71
60
  const { min, max, lower, upper } = this;
72
61
 
73
- if (scaled < lower || scaled > upper) {
74
- throw new Error("Scaled value out of bounds");
75
- }
62
+ if (scaled < lower || scaled > upper) throw new Error("Scaled value out of bounds");
76
63
 
77
64
  const result = ((scaled - lower) / (upper - lower)) * (max - min) + min;
78
65
 
@@ -85,9 +72,7 @@ export class MinMaxScaler {
85
72
  }
86
73
 
87
74
  static getMinMax(values: MinMaxScalerValueType[]) {
88
- if (values.length === 0) {
89
- throw new Error("An empty array supplied");
90
- }
75
+ if (values.length === 0) throw new Error("An empty array supplied");
91
76
 
92
77
  return { min: Math.min(...values), max: Math.max(...values) };
93
78
  }
package/src/minute.vo.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { TimestampType } from "./timestamp.vo";
2
+
1
3
  export class Minute {
2
4
  private readonly value: number;
3
5
 
@@ -6,26 +8,20 @@ export class Minute {
6
8
  static readonly MAX = new Minute(59);
7
9
 
8
10
  constructor(candidate: number) {
9
- if (!Number.isInteger(candidate)) {
10
- throw new Error("Invalid minute");
11
- }
12
-
13
- if (candidate < 0) {
14
- throw new Error("Invalid minute");
15
- }
16
-
17
- if (candidate >= 60) {
18
- throw new Error("Invalid minute");
19
- }
11
+ if (!Number.isInteger(candidate)) throw new Error("Invalid minute");
12
+ if (candidate < 0) throw new Error("Invalid minute");
13
+ if (candidate >= 60) throw new Error("Invalid minute");
20
14
 
21
15
  this.value = candidate;
22
16
  }
23
17
 
18
+ static fromUtcTimestamp(timestamp: TimestampType): Minute {
19
+ const minutes = new Date(timestamp).getUTCMinutes();
20
+ return new Minute(minutes);
21
+ }
22
+
24
23
  get() {
25
- return {
26
- raw: this.value,
27
- formatted: this.value.toString().padStart(2, "0"),
28
- };
24
+ return { raw: this.value, formatted: this.value.toString().padStart(2, "0") };
29
25
  }
30
26
 
31
27
  equals(another: Minute): boolean {
package/src/money.vo.ts CHANGED
@@ -3,8 +3,8 @@ import { type RoundingStrategy, RoundToNearest } from "./rounding.service";
3
3
 
4
4
  export const MoneyAmount = z
5
5
  .number()
6
- .int({ message: "money.amount.invalid " })
7
- .min(0, { message: "money.amount.invalid " })
6
+ .int({ message: "money.amount.invalid" })
7
+ .min(0, { message: "money.amount.invalid" })
8
8
  .brand("MoneyAmount");
9
9
 
10
10
  export type MoneyAmountType = z.infer<typeof MoneyAmount>;
@@ -55,18 +55,12 @@ export class Money {
55
55
  subtract(money: Money) {
56
56
  const result = this.rounding.round(this.amount - money.getAmount());
57
57
 
58
- if (result < Money.ZERO) {
59
- throw new Error("Less than zero");
60
- }
58
+ if (result < Money.ZERO) throw new Error("Less than zero");
61
59
 
62
60
  return new Money(MoneyAmount.parse(result), this.rounding);
63
61
  }
64
62
 
65
63
  divide(factor: MoneyDivisionFactorType) {
66
- if (factor === 0) {
67
- throw new Error("Cannot divide by zero");
68
- }
69
-
70
64
  const result = this.rounding.round(this.amount / factor);
71
65
 
72
66
  return new Money(MoneyAmount.parse(result), this.rounding);
@@ -0,0 +1,25 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const MonthIsoId = z
4
+ .string()
5
+ .regex(/^\d{4}-\d{2}$/)
6
+ .refine(
7
+ (value) => {
8
+ const [y, m] = value.split("-");
9
+
10
+ const year = Number(y);
11
+ const month = Number(m);
12
+
13
+ return (
14
+ y.length === 4 &&
15
+ m.length === 2 &&
16
+ Number.isInteger(year) &&
17
+ Number.isInteger(month) &&
18
+ month >= 1 &&
19
+ month <= 12
20
+ );
21
+ },
22
+ { message: "month-iso-id.invalid" },
23
+ );
24
+
25
+ export type MonthIsoIdType = z.infer<typeof MonthIsoId>;
@@ -0,0 +1,26 @@
1
+ import { endOfMonth, startOfMonth } from "date-fns";
2
+ import { DateRange } from "./date-range.vo";
3
+ import { MonthIsoId, type MonthIsoIdType } from "./month-iso-id.vo";
4
+ import { Timestamp, type TimestampType } from "./timestamp.vo";
5
+
6
+ export class Month extends DateRange {
7
+ toIsoId(): MonthIsoIdType {
8
+ return new Date(this.getStart()).toISOString().slice(0, 7) as MonthIsoIdType;
9
+ }
10
+
11
+ static fromTimestamp(timestamp: TimestampType): Month {
12
+ const start = Timestamp.parse(startOfMonth(timestamp).getTime());
13
+ const end = Timestamp.parse(endOfMonth(timestamp).getTime());
14
+ return new Month(start, end);
15
+ }
16
+
17
+ static fromNow(now: TimestampType): Month {
18
+ return Month.fromTimestamp(now);
19
+ }
20
+
21
+ static fromIsoId(iso: MonthIsoIdType): Month {
22
+ const [year, month] = MonthIsoId.parse(iso).split("-").map(Number);
23
+ const reference = new Date(Date.UTC(year, month - 1, 1));
24
+ return Month.fromTimestamp(Timestamp.parse(reference.getTime()));
25
+ }
26
+ }
@@ -13,5 +13,4 @@ export const ObjectKey = z
13
13
  "obj_key_bad_segments",
14
14
  )
15
15
  .brand("object_key");
16
-
17
16
  export type ObjectKeyType = z.infer<typeof ObjectKey>;
@@ -6,9 +6,7 @@ export class OutlierDetector {
6
6
  private readonly threshold: number;
7
7
 
8
8
  constructor(values: number[], threshold: number) {
9
- if (values.length < 2) {
10
- throw new Error("At least two values are needed");
11
- }
9
+ if (values.length < 2) throw new Error("At least two values are needed");
12
10
 
13
11
  this.zScore = new ZScore(values);
14
12
  this.threshold = Math.abs(threshold);
@@ -1,9 +1,7 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
3
  type MajorType = number;
4
-
5
4
  type MinorType = number;
6
-
7
5
  type PatchType = number;
8
6
 
9
7
  export const PackageVersionValue = z
@@ -30,16 +28,6 @@ export const PackageVersionValue = z
30
28
  return false;
31
29
  }
32
30
 
33
- if (
34
- !(
35
- Number.isInteger(Number(major)) &&
36
- Number.isInteger(Number(minor)) &&
37
- Number.isInteger(Number(patch))
38
- )
39
- ) {
40
- return false;
41
- }
42
-
43
31
  return true;
44
32
  } catch (_error) {
45
33
  return false;
@@ -1,11 +1,9 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
3
  const Take = z.number().int().gte(0);
4
-
5
4
  type TakeType = z.infer<typeof Take>;
6
5
 
7
6
  const Skip = z.number().int().gte(0);
8
-
9
7
  type SkipType = z.infer<typeof Skip>;
10
8
 
11
9
  const Page = z.coerce
@@ -13,30 +11,14 @@ const Page = z.coerce
13
11
  .int()
14
12
  .transform((value) => (value <= 0 ? 1 : value))
15
13
  .default(1);
16
-
17
14
  export type PageType = z.infer<typeof Page>;
18
15
 
19
- export type PaginationType = {
20
- values: { take: TakeType; skip: SkipType };
21
- page: PageType;
22
- };
23
-
16
+ export type PaginationType = { values: { take: TakeType; skip: SkipType }; page: PageType };
24
17
  export type PaginationValuesType = Record<string, unknown>;
25
-
26
18
  export type TotalType = number;
27
-
28
19
  export type ExhaustedType = boolean;
29
-
30
- export type PaginationExhaustedConfig = {
31
- total: TotalType;
32
- pagination: PaginationType;
33
- };
34
-
35
- export type PaginationPrepareConfigType<T> = {
36
- total: TotalType;
37
- pagination: PaginationType;
38
- result: T[];
39
- };
20
+ export type PaginationExhaustedConfig = { total: TotalType; pagination: PaginationType };
21
+ export type PaginationPrepareConfigType<T> = { total: TotalType; pagination: PaginationType; result: T[] };
40
22
 
41
23
  export class Pagination {
42
24
  static parse(values: PaginationValuesType, _take: TakeType): PaginationType {
@@ -59,14 +41,7 @@ export class Pagination {
59
41
 
60
42
  return {
61
43
  result: config.result,
62
- meta: {
63
- exhausted,
64
- currentPage,
65
- previousPage,
66
- nextPage,
67
- lastPage,
68
- total: config.total,
69
- },
44
+ meta: { exhausted, currentPage, previousPage, nextPage, lastPage, total: config.total },
70
45
  };
71
46
  }
72
47
 
@@ -6,12 +6,8 @@ export class Percentage {
6
6
  denominator: number,
7
7
  rounding: RoundingStrategy = new RoundToNearest(),
8
8
  ): number {
9
- if (denominator === 0) {
10
- throw new Error("Invalid denominator");
11
- }
12
-
9
+ if (denominator === 0) throw new Error("Invalid denominator");
13
10
  if (numerator === 0) return 0;
14
-
15
11
  return rounding.round((numerator / denominator) * 100);
16
12
  }
17
13
  }
@@ -4,9 +4,7 @@ import { Sum } from "./sum.service";
4
4
 
5
5
  export class PopulationStandardDeviation {
6
6
  static calculate(values: number[], rounding: RoundingStrategy = new RoundToDecimal(2)): number {
7
- if (values.length < 2) {
8
- throw new Error("At least two values are needed");
9
- }
7
+ if (values.length < 2) throw new Error("At least two values are needed");
10
8
 
11
9
  const mean = Mean.calculate(values);
12
10
  const n = values.length;
@@ -0,0 +1,18 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const QuarterIsoId = z
4
+ .string()
5
+ .regex(/^\d{4}-Q[1-4]$/)
6
+ .refine(
7
+ (value) => {
8
+ const [y, q] = value.split("-Q");
9
+ const year = Number(y);
10
+ const quarter = Number(q);
11
+
12
+ return (
13
+ y.length === 4 && Number.isInteger(year) && Number.isInteger(quarter) && quarter >= 1 && quarter <= 4
14
+ );
15
+ },
16
+ { message: "quarter-iso-id.invalid" },
17
+ );
18
+ export type QuarterIsoIdType = z.infer<typeof QuarterIsoId>;
@@ -0,0 +1,28 @@
1
+ import { endOfQuarter, getQuarter, getYear, setQuarter, startOfQuarter } from "date-fns";
2
+ import { DateRange } from "./date-range.vo";
3
+ import { QuarterIsoId, type QuarterIsoIdType } from "./quarter-iso-id.vo";
4
+ import { Timestamp, type TimestampType } from "./timestamp.vo";
5
+
6
+ export class Quarter extends DateRange {
7
+ toIsoId(): QuarterIsoIdType {
8
+ const year = getYear(this.getStart());
9
+ const quarter = getQuarter(this.getStart());
10
+ return `${year}-Q${quarter}` as QuarterIsoIdType;
11
+ }
12
+
13
+ static fromTimestamp(timestamp: TimestampType): Quarter {
14
+ const start = Timestamp.parse(startOfQuarter(timestamp).getTime());
15
+ const end = Timestamp.parse(endOfQuarter(timestamp).getTime());
16
+ return new Quarter(start, end);
17
+ }
18
+
19
+ static fromNow(now: TimestampType): Quarter {
20
+ return Quarter.fromTimestamp(now);
21
+ }
22
+
23
+ static fromIsoId(isoId: QuarterIsoIdType): Quarter {
24
+ const [year, quarter] = QuarterIsoId.parse(isoId).split("-Q").map(Number);
25
+ const reference = setQuarter(new Date(Date.UTC(year, 0, 1)), quarter);
26
+ return Quarter.fromTimestamp(Timestamp.parse(reference.getTime()));
27
+ }
28
+ }
@@ -1,28 +1,14 @@
1
- type RandomGenerateConfigType = {
2
- min: number;
3
- max: number;
4
- };
1
+ type RandomGenerateConfigType = { min: number; max: number };
5
2
 
6
3
  export class Random {
7
4
  static generate(config?: RandomGenerateConfigType) {
8
5
  const min = config?.min ?? 0;
9
6
  const max = config?.max ?? 1;
10
7
 
11
- if (!Number.isInteger(min)) {
12
- throw new Error("Minimum value is not an integer");
13
- }
14
-
15
- if (!Number.isInteger(max)) {
16
- throw new Error("Maximum value is not an integer");
17
- }
18
-
19
- if (min === max) {
20
- throw new Error("Minimum and maximum values cannot be equal");
21
- }
22
-
23
- if (min > max) {
24
- throw new Error("Minimum value cannot be greater than maximum value");
25
- }
8
+ if (!Number.isInteger(min)) throw new Error("Minimum value is not an integer");
9
+ if (!Number.isInteger(max)) throw new Error("Maximum value is not an integer");
10
+ if (min === max) throw new Error("Minimum and maximum values cannot be equal");
11
+ if (min > max) throw new Error("Minimum value cannot be greater than maximum value");
26
12
 
27
13
  return Math.floor(Math.random() * (max - min + 1)) + min;
28
14
  }
@@ -3,11 +3,8 @@ import { Timestamp, type TimestampType } from "./timestamp.vo";
3
3
  import type { Falsy } from "./ts-utils";
4
4
 
5
5
  type RateLimiterOptionsType = Pick<TimeResult, "ms">;
6
-
7
6
  type RateLimiterResultSuccessType = { allowed: true };
8
-
9
7
  type RateLimiterResultErrorType = { allowed: false; remainingMs: TimestampType };
10
-
11
8
  type RateLimiterResultType = RateLimiterResultSuccessType | RateLimiterResultErrorType;
12
9
 
13
10
  export class RateLimiter {
@@ -2,15 +2,12 @@ import { z } from "zod/v4";
2
2
  import { DoublyLinkedList, Node } from "./dll.service";
3
3
 
4
4
  export const ReorderingItemPositionValue = z.number().int().min(0);
5
-
6
5
  export type ReorderingItemPositionValueType = z.infer<typeof ReorderingItemPositionValue>;
7
6
 
8
7
  export const ReorderingCorrelationId = z.string().min(1);
9
-
10
8
  export type ReorderingCorrelationIdType = z.infer<typeof ReorderingCorrelationId>;
11
9
 
12
10
  export const ReorderingItemId = z.uuid();
13
-
14
11
  export type ReorderingItemIdType = z.infer<typeof ReorderingItemId>;
15
12
 
16
13
  export const Reordering = z.object({
@@ -21,9 +18,7 @@ export const Reordering = z.object({
21
18
 
22
19
  export type ReorderingType = z.infer<typeof Reordering>;
23
20
 
24
- export type WithReorderingPositionValue<T> = T & {
25
- position: ReorderingItemPositionValueType;
26
- };
21
+ export type WithReorderingPositionValue<T> = T & { position: ReorderingItemPositionValueType };
27
22
 
28
23
  export class ReorderingPosition {
29
24
  readonly value: ReorderingItemPositionValueType;
@@ -63,10 +58,7 @@ export class ReorderingTransfer {
63
58
 
64
59
  readonly to: ReorderingPosition;
65
60
 
66
- constructor(config: {
67
- id: ReorderingItem["id"];
68
- to: ReorderingItemPositionValueType;
69
- }) {
61
+ constructor(config: { id: ReorderingItem["id"]; to: ReorderingItemPositionValueType }) {
70
62
  this.id = config.id;
71
63
  this.to = new ReorderingPosition(config.to);
72
64
  }
@@ -106,9 +98,8 @@ export class ReorderingCalculator {
106
98
 
107
99
  delete(id: ReorderingItem["id"]) {
108
100
  const item = this.dll.find((x) => x.data.eq(id));
109
- if (!item) {
110
- throw new Error("Cannot find Item");
111
- }
101
+ if (!item) throw new Error("Cannot find Item");
102
+
112
103
  this.dll.remove(item);
113
104
  this.recalculate();
114
105
  }
@@ -117,12 +108,8 @@ export class ReorderingCalculator {
117
108
  const current = this.dll.find((node) => node.data.eq(transfer.id));
118
109
  const target = this.dll.find((node) => node.data.position.eq(transfer.to));
119
110
 
120
- if (!current) {
121
- throw new Error("Cannot find current Item");
122
- }
123
- if (!target) {
124
- throw new Error("Cannot find target Item");
125
- }
111
+ if (!current) throw new Error("Cannot find current Item");
112
+ if (!target) throw new Error("Cannot find target Item");
126
113
 
127
114
  const direction = transfer.getDirection(current.data.position);
128
115
 
@@ -2,12 +2,10 @@ import { z } from "zod/v4";
2
2
  import type { ETag, WeakETag } from "./etags.vo";
3
3
 
4
4
  export const RevisionValue = z.number().int().min(0);
5
-
6
5
  export type RevisionValueType = z.infer<typeof RevisionValue>;
7
6
 
8
7
  export class Revision {
9
8
  readonly value: RevisionValueType;
10
-
11
9
  static initial: RevisionValueType = 0;
12
10
 
13
11
  constructor(value: unknown) {
@@ -31,16 +29,12 @@ export class Revision {
31
29
  }
32
30
 
33
31
  static fromETag(etag: ETag | null): Revision {
34
- if (!etag) {
35
- throw new InvalidRevisionError();
36
- }
32
+ if (!etag) throw new InvalidRevisionError();
37
33
  return new Revision(etag.revision);
38
34
  }
39
35
 
40
36
  static fromWeakETag(weakEtag: WeakETag | null): Revision {
41
- if (!weakEtag) {
42
- throw new InvalidRevisionError();
43
- }
37
+ if (!weakEtag) throw new InvalidRevisionError();
44
38
  return new Revision(weakEtag.revision);
45
39
  }
46
40
  }
@@ -2,9 +2,7 @@ import { type RoundingStrategy, RoundToNearest } from "./rounding.service";
2
2
  import { Sum } from "./sum.service";
3
3
 
4
4
  export type SLRPairType = { x: number; y: number };
5
-
6
5
  export type SLRParamsType = { a: number; b: number };
7
-
8
6
  export type SLRPredictionType = number;
9
7
 
10
8
  export class SimpleLinearRegression {
@@ -20,9 +18,7 @@ export class SimpleLinearRegression {
20
18
  static fromPairs(pairs: SLRPairType[], rounding?: RoundingStrategy) {
21
19
  const n = pairs.length;
22
20
 
23
- if (n < 2) {
24
- throw new Error("At least two pairs needed");
25
- }
21
+ if (n < 2) throw new Error("At least two pairs needed");
26
22
 
27
23
  const x = pairs.map((pair) => pair.x);
28
24
  const y = pairs.map((pair) => pair.y);
@@ -30,30 +26,19 @@ export class SimpleLinearRegression {
30
26
  const xy = pairs.map((pair) => pair.x * pair.y);
31
27
 
32
28
  const sX = Sum.of(x);
33
- if (sX >= Number.MAX_SAFE_INTEGER) {
34
- throw new Error("Sum of x values is too big");
35
- }
29
+ if (sX >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x values is too big");
36
30
 
37
31
  const sY = Sum.of(y);
38
- if (sY >= Number.MAX_SAFE_INTEGER) {
39
- throw new Error("Sum of y values is too big");
40
- }
32
+ if (sY >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of y values is too big");
41
33
 
42
34
  const sSX = Sum.of(xx);
43
- if (sSX >= Number.MAX_SAFE_INTEGER) {
44
- throw new Error("Sum of x squared values is too big");
45
- }
35
+ if (sSX >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x squared values is too big");
46
36
 
47
37
  const sXY = Sum.of(xy);
48
- if (sXY >= Number.MAX_SAFE_INTEGER) {
49
- throw new Error("Sum of x times y values is too big");
50
- }
38
+ if (sXY >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x times y values is too big");
51
39
 
52
40
  const bDenominator = sSX - sX ** 2 / n;
53
-
54
- if (bDenominator === 0) {
55
- throw new Error("Unable to create the model");
56
- }
41
+ if (bDenominator === 0) throw new Error("Unable to create the model");
57
42
 
58
43
  const b = (sXY - (sX * sY) / n) / bDenominator;
59
44
  const a = (sY - b * sX) / n;
package/src/size.vo.ts CHANGED
@@ -9,7 +9,6 @@ export enum SizeUnit {
9
9
  }
10
10
 
11
11
  export const SizeValue = z.number().positive().brand("SizeValue");
12
-
13
12
  type SizeValueType = z.infer<typeof SizeValue>;
14
13
 
15
14
  type SizeConfigType = { unit: SizeUnit; value: number };
@@ -1,5 +1,4 @@
1
1
  type StepType = number;
2
-
3
2
  type StepperConfigType = { total: StepType };
4
3
 
5
4
  export class Stepper {
@@ -10,14 +9,8 @@ export class Stepper {
10
9
  private readonly total: StepType;
11
10
 
12
11
  constructor(config: StepperConfigType) {
13
- if (!Number.isInteger(config.total)) {
14
- throw new Error("Total value is not an integer");
15
- }
16
-
17
- if (config.total <= Stepper.DEFAULT_CURRENT) {
18
- throw new Error("Total value should be greater than one");
19
- }
20
-
12
+ if (!Number.isInteger(config.total)) throw new Error("Total value is not an integer");
13
+ if (config.total <= Stepper.DEFAULT_CURRENT) throw new Error("Total value should be greater than one");
21
14
  this.total = config.total;
22
15
  }
23
16
 
@@ -3,7 +3,7 @@ import type { Falsy } from "./ts-utils";
3
3
 
4
4
  enum StopwatchState {
5
5
  started = "started",
6
- stopped = "finished",
6
+ stopped = "stopped",
7
7
  }
8
8
 
9
9
  export type StopwatchResultType = { durationMs: TimestampType };
@@ -16,9 +16,7 @@ export class Stopwatch {
16
16
  constructor(private readonly startMs: TimestampType) {}
17
17
 
18
18
  stop(): StopwatchResultType {
19
- if (this.state === StopwatchState.stopped) {
20
- throw new Error("Stopwatch is already stopped");
21
- }
19
+ if (this.state === StopwatchState.stopped) throw new Error("Stopwatch is already stopped");
22
20
 
23
21
  this.state = StopwatchState.stopped;
24
22
  this.stopMs = Timestamp.parse(Date.now());
@@ -1,12 +1,7 @@
1
1
  import { format, isAfter, isEqual, subDays } from "date-fns";
2
2
 
3
3
  type DateType = string;
4
-
5
- export type StreakType = {
6
- cutoff: DateType;
7
- dates: DateType[];
8
- streak: number;
9
- };
4
+ export type StreakType = { cutoff: DateType; dates: DateType[]; streak: number };
10
5
 
11
6
  export class StreakCalculator {
12
7
  private readonly cutoff: DateType;
@@ -7,5 +7,4 @@ export const TimeZoneOffsetValue = z
7
7
  .transform((value) => Number(value))
8
8
  .transform((value) => (Number.isNaN(value) ? 0 : value))
9
9
  .brand("TimeZoneOffsetValue");
10
-
11
10
  export type TimeZoneOffsetValueType = z.infer<typeof TimeZoneOffsetValue>;