@bgord/tools 0.17.2 → 1.0.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 (257) hide show
  1. package/dist/age-years.vo.d.ts +11 -0
  2. package/dist/age-years.vo.js +9 -0
  3. package/dist/age.vo.d.ts +11 -16
  4. package/dist/age.vo.js +20 -31
  5. package/dist/api-key.vo.d.ts +3 -1
  6. package/dist/api-key.vo.js +10 -5
  7. package/dist/basename.vo.d.ts +9 -9
  8. package/dist/basename.vo.js +22 -22
  9. package/dist/clock.vo.d.ts +10 -4
  10. package/dist/clock.vo.js +12 -14
  11. package/dist/date-calculator.service.d.ts +2 -1
  12. package/dist/date-formatter.service.d.ts +3 -4
  13. package/dist/date-range.vo.d.ts +7 -1
  14. package/dist/date-range.vo.js +5 -2
  15. package/dist/day-iso-id.vo.d.ts +5 -2
  16. package/dist/day-iso-id.vo.js +11 -7
  17. package/dist/day.vo.d.ts +4 -3
  18. package/dist/day.vo.js +18 -16
  19. package/dist/directory-path-absolute.vo.d.ts +10 -6
  20. package/dist/directory-path-absolute.vo.js +19 -17
  21. package/dist/directory-path-relative.vo.d.ts +10 -7
  22. package/dist/directory-path-relative.vo.js +18 -17
  23. package/dist/division-factor.vo.d.ts +7 -0
  24. package/dist/division-factor.vo.js +9 -0
  25. package/dist/duration-ms.vo.d.ts +6 -0
  26. package/dist/duration-ms.vo.js +3 -0
  27. package/dist/duration.service.d.ts +2 -14
  28. package/dist/duration.service.js +16 -35
  29. package/dist/email-mask.service.d.ts +1 -6
  30. package/dist/email-mask.service.js +6 -8
  31. package/dist/etags.vo.d.ts +4 -3
  32. package/dist/etags.vo.js +3 -3
  33. package/dist/extension.vo.d.ts +6 -4
  34. package/dist/extension.vo.js +15 -10
  35. package/dist/feature-flag-value.vo.d.ts +10 -0
  36. package/dist/feature-flag-value.vo.js +8 -0
  37. package/dist/feature-flag.vo.d.ts +1 -7
  38. package/dist/feature-flag.vo.js +1 -7
  39. package/dist/file-path-absolute-schema.vo.d.ts +10 -7
  40. package/dist/file-path-absolute-schema.vo.js +17 -17
  41. package/dist/file-path-relative-schema.vo.d.ts +10 -7
  42. package/dist/file-path-relative-schema.vo.js +14 -12
  43. package/dist/file-path.vo.d.ts +4 -4
  44. package/dist/file-path.vo.js +8 -8
  45. package/dist/filename-from-string.vo.d.ts +4 -2
  46. package/dist/filename-from-string.vo.js +10 -8
  47. package/dist/filename-suffix.vo.d.ts +7 -3
  48. package/dist/filename-suffix.vo.js +13 -7
  49. package/dist/filename.vo.d.ts +2 -0
  50. package/dist/filename.vo.js +8 -2
  51. package/dist/height-milimiters.vo.d.ts +6 -0
  52. package/dist/height-milimiters.vo.js +10 -0
  53. package/dist/height.vo.d.ts +3 -20
  54. package/dist/height.vo.js +11 -62
  55. package/dist/hour-format.service.js +1 -1
  56. package/dist/hour-schema.vo.d.ts +7 -0
  57. package/dist/hour-schema.vo.js +8 -0
  58. package/dist/hour.vo.d.ts +4 -3
  59. package/dist/hour.vo.js +8 -8
  60. package/dist/iban-mask.service.d.ts +1 -3
  61. package/dist/iban-mask.service.js +2 -2
  62. package/dist/iban-schema.vo.d.ts +7 -0
  63. package/dist/iban-schema.vo.js +10 -0
  64. package/dist/iban.vo.d.ts +4 -10
  65. package/dist/iban.vo.js +6 -13
  66. package/dist/image.vo.d.ts +6 -4
  67. package/dist/image.vo.js +13 -12
  68. package/dist/index.d.ts +24 -2
  69. package/dist/index.js +24 -2
  70. package/dist/language.vo.d.ts +2 -1
  71. package/dist/language.vo.js +6 -4
  72. package/dist/linear-regression.service.d.ts +27 -0
  73. package/dist/{simple-linear-regression.service.js → linear-regression.service.js} +17 -15
  74. package/dist/mean.service.d.ts +3 -1
  75. package/dist/mean.service.js +3 -4
  76. package/dist/mime-types.vo.d.ts +1 -2
  77. package/dist/mime-value.vo.d.ts +9 -0
  78. package/dist/mime-value.vo.js +9 -0
  79. package/dist/mime.vo.d.ts +11 -17
  80. package/dist/mime.vo.js +10 -27
  81. package/dist/min-max-scaler.service.d.ts +7 -5
  82. package/dist/min-max-scaler.service.js +12 -10
  83. package/dist/minute-schema.vo.d.ts +7 -0
  84. package/dist/minute-schema.vo.js +8 -0
  85. package/dist/minute.vo.d.ts +4 -3
  86. package/dist/minute.vo.js +8 -8
  87. package/dist/money-amount.vo.d.ts +7 -0
  88. package/dist/money-amount.vo.js +7 -0
  89. package/dist/money.vo.d.ts +9 -18
  90. package/dist/money.vo.js +14 -27
  91. package/dist/month-iso-id.vo.d.ts +4 -2
  92. package/dist/month-iso-id.vo.js +13 -7
  93. package/dist/month.vo.d.ts +4 -3
  94. package/dist/month.vo.js +21 -21
  95. package/dist/multiplication-factor.vo.d.ts +7 -0
  96. package/dist/multiplication-factor.vo.js +9 -0
  97. package/dist/object-key.vo.d.ts +9 -6
  98. package/dist/object-key.vo.js +20 -19
  99. package/dist/outlier-detector.service.d.ts +3 -1
  100. package/dist/outlier-detector.service.js +2 -2
  101. package/dist/package-version-schema.vo.d.ts +11 -0
  102. package/dist/package-version-schema.vo.js +15 -0
  103. package/dist/package-version.vo.d.ts +11 -20
  104. package/dist/package-version.vo.js +11 -20
  105. package/dist/pagination-page.vo.d.ts +6 -0
  106. package/dist/pagination-page.vo.js +7 -0
  107. package/dist/pagination-skip.vo.d.ts +7 -0
  108. package/dist/pagination-skip.vo.js +9 -0
  109. package/dist/pagination-take.vo.d.ts +7 -0
  110. package/dist/pagination-take.vo.js +9 -0
  111. package/dist/pagination.service.d.ts +3 -8
  112. package/dist/pagination.service.js +5 -12
  113. package/dist/percentage.service.d.ts +3 -1
  114. package/dist/percentage.service.js +2 -2
  115. package/dist/population-standard-deviation.service.d.ts +3 -1
  116. package/dist/population-standard-deviation.service.js +5 -4
  117. package/dist/quarter-iso-id.vo.d.ts +3 -2
  118. package/dist/quarter-iso-id.vo.js +7 -9
  119. package/dist/quarter.vo.d.ts +2 -1
  120. package/dist/quarter.vo.js +10 -7
  121. package/dist/random.service.d.ts +3 -4
  122. package/dist/random.service.js +5 -11
  123. package/dist/rate-limiter.service.d.ts +2 -2
  124. package/dist/rate-limiter.service.js +8 -8
  125. package/dist/reordering-item-position-value.vo.d.ts +6 -0
  126. package/dist/reordering-item-position-value.vo.js +6 -0
  127. package/dist/reordering.service.d.ts +7 -23
  128. package/dist/reordering.service.js +15 -24
  129. package/dist/revision-value.vo.d.ts +7 -0
  130. package/dist/revision-value.vo.js +6 -0
  131. package/dist/revision.vo.d.ts +6 -13
  132. package/dist/revision.vo.js +10 -22
  133. package/dist/rounding.adapter.d.ts +7 -2
  134. package/dist/rounding.adapter.js +13 -5
  135. package/dist/size-bytes.vo.d.ts +6 -0
  136. package/dist/size-bytes.vo.js +7 -0
  137. package/dist/size.vo.d.ts +15 -15
  138. package/dist/size.vo.js +41 -51
  139. package/dist/stopwatch.service.d.ts +3 -1
  140. package/dist/stopwatch.service.js +2 -2
  141. package/dist/sum.service.js +8 -8
  142. package/dist/thousands-separator.service.js +4 -1
  143. package/dist/time.service.d.ts +8 -0
  144. package/dist/time.service.js +13 -0
  145. package/dist/timestamp.vo.d.ts +1 -1
  146. package/dist/timestamp.vo.js +4 -5
  147. package/dist/timezone.vo.d.ts +4 -1
  148. package/dist/timezone.vo.js +12 -6
  149. package/dist/tsconfig.tsbuildinfo +1 -1
  150. package/dist/week-iso-id.vo.d.ts +4 -2
  151. package/dist/week-iso-id.vo.js +15 -9
  152. package/dist/week.vo.d.ts +4 -3
  153. package/dist/week.vo.js +21 -22
  154. package/dist/weekday.vo.d.ts +1 -1
  155. package/dist/weekday.vo.js +6 -8
  156. package/dist/weight-grams.vo.d.ts +7 -0
  157. package/dist/weight-grams.vo.js +7 -0
  158. package/dist/weight.vo.d.ts +12 -35
  159. package/dist/weight.vo.js +23 -72
  160. package/dist/year-iso-id.vo.d.ts +3 -2
  161. package/dist/year-iso-id.vo.js +6 -4
  162. package/dist/year.vo.d.ts +5 -6
  163. package/dist/year.vo.js +21 -26
  164. package/dist/z-score.service.d.ts +3 -1
  165. package/dist/z-score.service.js +2 -2
  166. package/package.json +4 -4
  167. package/readme.md +21 -2
  168. package/src/age-years.vo.ts +14 -0
  169. package/src/age.vo.ts +22 -35
  170. package/src/api-key.vo.ts +11 -5
  171. package/src/basename.vo.ts +24 -22
  172. package/src/clock.vo.ts +16 -17
  173. package/src/date-calculator.service.ts +2 -1
  174. package/src/date-formatter.service.ts +4 -5
  175. package/src/date-range.vo.ts +6 -2
  176. package/src/day-iso-id.vo.ts +12 -8
  177. package/src/day.vo.ts +27 -24
  178. package/src/directory-path-absolute.vo.ts +23 -18
  179. package/src/directory-path-relative.vo.ts +21 -18
  180. package/src/division-factor.vo.ts +13 -0
  181. package/src/duration-ms.vo.ts +7 -0
  182. package/src/duration.service.ts +16 -40
  183. package/src/email-mask.service.ts +7 -15
  184. package/src/etags.vo.ts +4 -5
  185. package/src/extension.vo.ts +17 -10
  186. package/src/feature-flag-value.vo.ts +12 -0
  187. package/src/feature-flag.vo.ts +1 -9
  188. package/src/file-path-absolute-schema.vo.ts +18 -17
  189. package/src/file-path-relative-schema.vo.ts +15 -12
  190. package/src/file-path.vo.ts +8 -8
  191. package/src/filename-from-string.vo.ts +12 -9
  192. package/src/filename-suffix.vo.ts +14 -7
  193. package/src/filename.vo.ts +11 -2
  194. package/src/height-milimiters.vo.ts +12 -0
  195. package/src/height.vo.ts +12 -83
  196. package/src/hour-format.service.ts +2 -1
  197. package/src/hour-schema.vo.ts +12 -0
  198. package/src/hour.vo.ts +12 -12
  199. package/src/iban-mask.service.ts +3 -5
  200. package/src/iban-schema.vo.ts +15 -0
  201. package/src/iban.vo.ts +9 -22
  202. package/src/image.vo.ts +14 -12
  203. package/src/index.ts +24 -2
  204. package/src/language.vo.ts +7 -4
  205. package/src/linear-regression.service.ts +71 -0
  206. package/src/mean.service.ts +3 -5
  207. package/src/mime-types.vo.ts +1 -3
  208. package/src/mime-value.vo.ts +12 -0
  209. package/src/mime.vo.ts +12 -33
  210. package/src/min-max-scaler.service.ts +13 -11
  211. package/src/minute-schema.vo.ts +12 -0
  212. package/src/minute.vo.ts +12 -12
  213. package/src/money-amount.vo.ts +11 -0
  214. package/src/money.vo.ts +20 -38
  215. package/src/month-iso-id.vo.ts +14 -7
  216. package/src/month.vo.ts +25 -24
  217. package/src/multiplication-factor.vo.ts +13 -0
  218. package/src/object-key.vo.ts +25 -21
  219. package/src/outlier-detector.service.ts +2 -2
  220. package/src/package-version-schema.vo.ts +21 -0
  221. package/src/package-version.vo.ts +17 -33
  222. package/src/pagination-page.vo.ts +11 -0
  223. package/src/pagination-skip.vo.ts +13 -0
  224. package/src/pagination-take.vo.ts +13 -0
  225. package/src/pagination.service.ts +5 -22
  226. package/src/percentage.service.ts +2 -2
  227. package/src/population-standard-deviation.service.ts +5 -4
  228. package/src/quarter-iso-id.vo.ts +7 -10
  229. package/src/quarter.vo.ts +14 -9
  230. package/src/random.service.ts +6 -9
  231. package/src/rate-limiter.service.ts +9 -8
  232. package/src/reordering-item-position-value.vo.ts +10 -0
  233. package/src/reordering.service.ts +19 -28
  234. package/src/revision-value.vo.ts +10 -0
  235. package/src/revision.vo.ts +10 -25
  236. package/src/rounding.adapter.ts +16 -3
  237. package/src/size-bytes.vo.ts +11 -0
  238. package/src/size.vo.ts +43 -54
  239. package/src/stopwatch.service.ts +3 -3
  240. package/src/sum.service.ts +8 -8
  241. package/src/thousands-separator.service.ts +4 -1
  242. package/src/time.service.ts +15 -0
  243. package/src/timestamp.vo.ts +4 -5
  244. package/src/timezone.vo.ts +12 -6
  245. package/src/week-iso-id.vo.ts +16 -12
  246. package/src/week.vo.ts +26 -28
  247. package/src/weekday.vo.ts +6 -9
  248. package/src/weight-grams.vo.ts +11 -0
  249. package/src/weight.vo.ts +28 -85
  250. package/src/year-iso-id.vo.ts +7 -4
  251. package/src/year.vo.ts +27 -33
  252. package/src/z-score.service.ts +2 -2
  253. package/dist/simple-linear-regression.service.d.ts +0 -25
  254. package/dist/streak-calculator.service.d.ts +0 -13
  255. package/dist/streak-calculator.service.js +0 -22
  256. package/src/simple-linear-regression.service.ts +0 -69
  257. package/src/streak-calculator.service.ts +0 -32
@@ -1,31 +1,22 @@
1
1
  import { z } from "zod/v4";
2
2
  import { DoublyLinkedList, Node } from "./dll.service";
3
- export const ReorderingPositionError = { error: "reordering.position.invalid" };
4
- export const ReorderingCannotFindItemError = { error: "reordering.item.not_found" };
5
- export const ReorderingCannotFindCurrentError = { error: "reordering.current_item.not_found" };
6
- export const ReorderingCannotFindTargetError = { error: "reordering.target_item.not_found" };
7
- export const ReorderingCorrelationIdError = { error: "reordering.correlation_id.invalid" };
8
- export const ReorderingItemIdError = { error: "reordering.item_id.invalid" };
9
- export const ReorderingItemPositionValue = z
10
- .number(ReorderingPositionError)
11
- .int(ReorderingPositionError)
12
- .min(0, ReorderingPositionError);
13
- export const ReorderingCorrelationId = z
14
- .string(ReorderingCorrelationIdError)
15
- .min(1, ReorderingCorrelationIdError);
16
- export const ReorderingItemId = z.string(ReorderingItemIdError);
3
+ import { ReorderingItemPositionValue, } from "./reordering-item-position-value.vo";
4
+ export const ReorderingError = {
5
+ CannotFindItem: "reordering.cannot.find.item",
6
+ CannotFindCurrent: "reordering.cannot.find.current",
7
+ CannotFindTarget: "reordering.cannot.find.target",
8
+ };
9
+ const ReorderingIdError = { Type: "reordering.id.type" };
10
+ export const ReorderingId = z.string(ReorderingIdError.Type).min(1, ReorderingIdError.Type);
17
11
  export const Reordering = z.object({
18
- correlationId: ReorderingCorrelationId,
19
- id: ReorderingItemId,
12
+ correlationId: ReorderingId,
13
+ id: ReorderingId,
20
14
  position: ReorderingItemPositionValue,
21
15
  });
22
16
  export class ReorderingPosition {
23
17
  value;
24
18
  constructor(value) {
25
- const parsed = ReorderingItemPositionValue.safeParse(value);
26
- if (!parsed.success)
27
- throw new Error(ReorderingPositionError.error);
28
- this.value = value;
19
+ this.value = ReorderingItemPositionValue.parse(value);
29
20
  }
30
21
  eq(another) {
31
22
  return this.value === another.value;
@@ -88,17 +79,17 @@ export class ReorderingCalculator {
88
79
  delete(id) {
89
80
  const node = this.dll.find((x) => x.data.eq(id));
90
81
  if (!node)
91
- throw new Error(ReorderingCannotFindItemError.error);
82
+ throw new Error(ReorderingError.CannotFindItem);
92
83
  this.dll.remove(node);
93
84
  this.recalculate();
94
85
  }
95
86
  transfer(transfer) {
96
87
  const current = this.dll.find((node) => node.data.eq(transfer.id));
97
88
  if (!current)
98
- throw new Error(ReorderingCannotFindCurrentError.error);
89
+ throw new Error(ReorderingError.CannotFindCurrent);
99
90
  const target = this.dll.find((node) => node.data.position.eq(transfer.to));
100
91
  if (!target)
101
- throw new Error(ReorderingCannotFindTargetError.error);
92
+ throw new Error(ReorderingError.CannotFindTarget);
102
93
  const direction = transfer.getDirection(current.data.position);
103
94
  if (direction === ReorderingTransferDirection.noop)
104
95
  return this.read();
@@ -122,7 +113,7 @@ export class ReorderingCalculator {
122
113
  let index = 0;
123
114
  for (const node of this.dll) {
124
115
  const id = node.data.id;
125
- const position = new ReorderingPosition(index);
116
+ const position = new ReorderingPosition(ReorderingItemPositionValue.parse(index));
126
117
  node.data = new ReorderingItem(id, position);
127
118
  index += 1;
128
119
  }
@@ -0,0 +1,7 @@
1
+ import { z } from "zod/v4";
2
+ export declare const RevisionValueError: {
3
+ readonly Type: "revision.value.type";
4
+ readonly Invalid: "revision.value.invalid";
5
+ };
6
+ export declare const RevisionValue: z.ZodNumber;
7
+ export type RevisionValueType = z.infer<typeof RevisionValue>;
@@ -0,0 +1,6 @@
1
+ import { z } from "zod/v4";
2
+ export const RevisionValueError = { Type: "revision.value.type", Invalid: "revision.value.invalid" };
3
+ export const RevisionValue = z
4
+ .number(RevisionValueError.Type)
5
+ .int(RevisionValueError.Type)
6
+ .min(0, RevisionValueError.Invalid);
@@ -1,12 +1,9 @@
1
- import { z } from "zod/v4";
2
1
  import type { ETag, WeakETag } from "./etags.vo";
3
- export declare const RevisionValueError: {
4
- readonly error: "invalid.revision.value";
2
+ import { type RevisionValueType } from "./revision-value.vo";
3
+ export declare const RevisionError: {
4
+ readonly Missing: "revision.missing";
5
+ readonly Mismatch: "revision.mismatch";
5
6
  };
6
- export declare const RevisionValue: z.ZodNumber;
7
- export type RevisionValueType = z.infer<typeof RevisionValue>;
8
- export declare const RevisionInvalidErrorMessage: "revision.invalid";
9
- export declare const RevisionMismatchErrorMessage: "revision.mismatch";
10
7
  export declare class Revision {
11
8
  static readonly INITIAL: RevisionValueType;
12
9
  readonly value: RevisionValueType;
@@ -16,10 +13,6 @@ export declare class Revision {
16
13
  next(): Revision;
17
14
  static fromETag(etag: ETag | null): Revision;
18
15
  static fromWeakETag(weakEtag: WeakETag | null): Revision;
19
- }
20
- export declare class RevisionMismatchError extends Error {
21
- constructor();
22
- }
23
- export declare class InvalidRevisionError extends Error {
24
- constructor();
16
+ toString(): string;
17
+ toJSON(): number;
25
18
  }
@@ -1,47 +1,35 @@
1
- import { z } from "zod/v4";
2
- export const RevisionValueError = { error: "invalid.revision.value" };
3
- export const RevisionValue = z.number(RevisionValueError).int(RevisionValueError).min(0, RevisionValueError);
4
- export const RevisionInvalidErrorMessage = "revision.invalid";
5
- export const RevisionMismatchErrorMessage = "revision.mismatch";
1
+ import { RevisionValue } from "./revision-value.vo";
2
+ export const RevisionError = { Missing: "revision.missing", Mismatch: "revision.mismatch" };
6
3
  export class Revision {
7
4
  static INITIAL = RevisionValue.parse(0);
8
5
  value;
9
6
  constructor(value) {
10
- const result = RevisionValue.safeParse(value);
11
- if (!result.success)
12
- throw new InvalidRevisionError();
13
- this.value = result.data;
7
+ this.value = RevisionValue.parse(value);
14
8
  }
15
9
  equals(another) {
16
10
  return this.value === another;
17
11
  }
18
12
  validate(another) {
19
13
  if (!this.equals(another))
20
- throw new RevisionMismatchError();
14
+ throw new Error(RevisionError.Mismatch);
21
15
  }
22
16
  next() {
23
17
  return new Revision(this.value + 1);
24
18
  }
25
19
  static fromETag(etag) {
26
20
  if (!etag)
27
- throw new InvalidRevisionError();
21
+ throw new Error(RevisionError.Missing);
28
22
  return new Revision(etag.revision);
29
23
  }
30
24
  static fromWeakETag(weakEtag) {
31
25
  if (!weakEtag)
32
- throw new InvalidRevisionError();
26
+ throw new Error(RevisionError.Missing);
33
27
  return new Revision(weakEtag.revision);
34
28
  }
35
- }
36
- export class RevisionMismatchError extends Error {
37
- constructor() {
38
- super(RevisionMismatchErrorMessage);
39
- Object.setPrototypeOf(this, RevisionMismatchError.prototype);
29
+ toString() {
30
+ return this.value.toString();
40
31
  }
41
- }
42
- export class InvalidRevisionError extends Error {
43
- constructor() {
44
- super(RevisionInvalidErrorMessage);
45
- Object.setPrototypeOf(this, InvalidRevisionError.prototype);
32
+ toJSON() {
33
+ return this.value;
46
34
  }
47
35
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod/v4";
1
2
  import type { RoundingPort } from "./rounding.port";
2
3
  export declare class RoundToNearest implements RoundingPort {
3
4
  round(value: number): number;
@@ -8,9 +9,13 @@ export declare class RoundUp implements RoundingPort {
8
9
  export declare class RoundDown implements RoundingPort {
9
10
  round(value: number): number;
10
11
  }
11
- export declare const RoundingDecimalsError: "invalid.rounding.decimals";
12
+ export declare const RoundingDecimalError: {
13
+ readonly Type: "rounding.decimal.type";
14
+ readonly Invalid: "rounding.decimal.invalid";
15
+ };
16
+ export declare const RoundingDecimal: z.core.$ZodBranded<z.ZodNumber, "RoundingDecimal">;
12
17
  export declare class RoundToDecimal implements RoundingPort {
13
18
  private readonly decimals;
14
- constructor(decimals: number);
19
+ constructor(candidate: number);
15
20
  round(value: number): number;
16
21
  }
@@ -1,3 +1,4 @@
1
+ import { z } from "zod/v4";
1
2
  export class RoundToNearest {
2
3
  round(value) {
3
4
  return Math.round(value);
@@ -13,13 +14,20 @@ export class RoundDown {
13
14
  return Math.floor(value);
14
15
  }
15
16
  }
16
- export const RoundingDecimalsError = "invalid.rounding.decimals";
17
+ export const RoundingDecimalError = {
18
+ Type: "rounding.decimal.type",
19
+ Invalid: "rounding.decimal.invalid",
20
+ };
21
+ export const RoundingDecimal = z
22
+ .number(RoundingDecimalError.Type)
23
+ .int(RoundingDecimalError.Invalid)
24
+ .min(1, RoundingDecimalError.Invalid)
25
+ .max(100, RoundingDecimalError.Invalid)
26
+ .brand("RoundingDecimal");
17
27
  export class RoundToDecimal {
18
28
  decimals;
19
- constructor(decimals) {
20
- this.decimals = decimals;
21
- if (!Number.isInteger(decimals) || decimals < 0 || decimals > 100)
22
- throw new Error(RoundingDecimalsError);
29
+ constructor(candidate) {
30
+ this.decimals = RoundingDecimal.parse(candidate);
23
31
  }
24
32
  round(value) {
25
33
  return Number.parseFloat(value.toFixed(this.decimals));
@@ -0,0 +1,6 @@
1
+ import { z } from "zod/v4";
2
+ export declare const SizeBytesError: {
3
+ readonly Invalid: "size.bytes.invalid";
4
+ };
5
+ export declare const SizeBytes: z.core.$ZodBranded<z.ZodNumber, "SizeBytes">;
6
+ export type SizeBytesType = z.infer<typeof SizeBytes>;
@@ -0,0 +1,7 @@
1
+ import { z } from "zod/v4";
2
+ export const SizeBytesError = { Invalid: "size.bytes.invalid" };
3
+ export const SizeBytes = z
4
+ .number(SizeBytesError.Invalid)
5
+ .int(SizeBytesError.Invalid)
6
+ .gte(0, SizeBytesError.Invalid)
7
+ .brand("SizeBytes");
package/dist/size.vo.d.ts CHANGED
@@ -1,35 +1,35 @@
1
- import { z } from "zod/v4";
2
- export declare enum SizeUnit {
1
+ import { type SizeBytesType } from "./size-bytes.vo";
2
+ declare enum SizeUnitEnum {
3
3
  b = "b",
4
4
  kB = "kB",
5
5
  MB = "MB",
6
6
  GB = "GB"
7
7
  }
8
- export declare const SizeValue: z.core.$ZodBranded<z.ZodNumber, "SizeValue">;
9
- type SizeValueType = z.infer<typeof SizeValue>;
10
8
  type SizeConfigType = {
11
- unit: SizeUnit;
9
+ unit: SizeUnitEnum;
12
10
  value: number;
13
11
  };
14
12
  export declare class Size {
15
13
  private readonly unit;
16
- private readonly value;
17
14
  private readonly bytes;
18
15
  private static readonly KB_MULTIPLIER;
19
16
  private static readonly MB_MULTIPLIER;
20
17
  private static readonly GB_MULTIPLIER;
21
18
  private static readonly ROUNDER;
22
19
  constructor(config: SizeConfigType);
23
- static fromBytes(candidate: number): Size;
24
- static fromKb(candidate: number): Size;
25
- static fromMB(candidate: number): Size;
26
- static fromGB(candidate: number): Size;
27
- toString(): string;
28
- toBytes(): SizeValueType;
20
+ static fromBytes(value: SizeConfigType["value"]): Size;
21
+ static fromKb(value: SizeConfigType["value"]): Size;
22
+ static fromMB(value: SizeConfigType["value"]): Size;
23
+ static fromGB(value: SizeConfigType["value"]): Size;
24
+ toBytes(): SizeBytesType;
29
25
  isGreaterThan(another: Size): boolean;
30
- format(unit: SizeUnit): string;
31
- static toBytes(config: SizeConfigType): SizeValueType;
32
- static unit: typeof SizeUnit;
26
+ format(unit: SizeUnitEnum): string;
27
+ static toBytes(config: SizeConfigType): SizeBytesType;
28
+ static unit: typeof SizeUnitEnum;
33
29
  private calculateBytes;
30
+ toString(): string;
31
+ toJSON(): {
32
+ bytes: number;
33
+ };
34
34
  }
35
35
  export {};
package/dist/size.vo.js CHANGED
@@ -1,16 +1,14 @@
1
- import { z } from "zod/v4";
2
1
  import { RoundToDecimal } from "./rounding.adapter";
3
- export var SizeUnit;
4
- (function (SizeUnit) {
5
- SizeUnit["b"] = "b";
6
- SizeUnit["kB"] = "kB";
7
- SizeUnit["MB"] = "MB";
8
- SizeUnit["GB"] = "GB";
9
- })(SizeUnit || (SizeUnit = {}));
10
- export const SizeValue = z.number().positive().brand("SizeValue");
2
+ import { SizeBytes } from "./size-bytes.vo";
3
+ var SizeUnitEnum;
4
+ (function (SizeUnitEnum) {
5
+ SizeUnitEnum["b"] = "b";
6
+ SizeUnitEnum["kB"] = "kB";
7
+ SizeUnitEnum["MB"] = "MB";
8
+ SizeUnitEnum["GB"] = "GB";
9
+ })(SizeUnitEnum || (SizeUnitEnum = {}));
11
10
  export class Size {
12
11
  unit;
13
- value;
14
12
  bytes;
15
13
  static KB_MULTIPLIER = 1024;
16
14
  static MB_MULTIPLIER = 1024 * Size.KB_MULTIPLIER;
@@ -18,27 +16,19 @@ export class Size {
18
16
  static ROUNDER = new RoundToDecimal(2);
19
17
  constructor(config) {
20
18
  this.unit = config.unit;
21
- this.value = SizeValue.parse(config.value);
22
- this.bytes = this.calculateBytes();
19
+ this.bytes = this.calculateBytes(config.value, config.unit);
23
20
  }
24
- static fromBytes(candidate) {
25
- const value = SizeValue.parse(candidate);
26
- return new Size({ value, unit: SizeUnit.b });
21
+ static fromBytes(value) {
22
+ return new Size({ value, unit: SizeUnitEnum.b });
27
23
  }
28
- static fromKb(candidate) {
29
- const value = SizeValue.parse(candidate);
30
- return new Size({ value, unit: SizeUnit.kB });
24
+ static fromKb(value) {
25
+ return new Size({ value, unit: SizeUnitEnum.kB });
31
26
  }
32
- static fromMB(candidate) {
33
- const value = SizeValue.parse(candidate);
34
- return new Size({ value, unit: SizeUnit.MB });
27
+ static fromMB(value) {
28
+ return new Size({ value, unit: SizeUnitEnum.MB });
35
29
  }
36
- static fromGB(candidate) {
37
- const value = SizeValue.parse(candidate);
38
- return new Size({ value, unit: SizeUnit.GB });
39
- }
40
- toString() {
41
- return `${this.value} ${this.unit}`;
30
+ static fromGB(value) {
31
+ return new Size({ value, unit: SizeUnitEnum.GB });
42
32
  }
43
33
  toBytes() {
44
34
  return this.bytes;
@@ -48,36 +38,36 @@ export class Size {
48
38
  }
49
39
  format(unit) {
50
40
  switch (unit) {
51
- case SizeUnit.kB: {
52
- return `${Size.ROUNDER.round(this.bytes / Size.KB_MULTIPLIER)} ${SizeUnit.kB}`;
53
- }
54
- case SizeUnit.MB: {
55
- return `${Size.ROUNDER.round(this.bytes / Size.MB_MULTIPLIER)} ${SizeUnit.MB}`;
56
- }
57
- case SizeUnit.GB: {
58
- return `${Size.ROUNDER.round(this.bytes / Size.GB_MULTIPLIER)} ${SizeUnit.GB}`;
59
- }
60
- default: {
61
- // SizeUnit.b
62
- return `${this.bytes} ${SizeUnit.b}`;
63
- }
41
+ case SizeUnitEnum.kB:
42
+ return `${Size.ROUNDER.round(this.bytes / Size.KB_MULTIPLIER)} ${SizeUnitEnum.kB}`;
43
+ case SizeUnitEnum.MB:
44
+ return `${Size.ROUNDER.round(this.bytes / Size.MB_MULTIPLIER)} ${SizeUnitEnum.MB}`;
45
+ case SizeUnitEnum.GB:
46
+ return `${Size.ROUNDER.round(this.bytes / Size.GB_MULTIPLIER)} ${SizeUnitEnum.GB}`;
47
+ default:
48
+ return `${this.bytes} ${SizeUnitEnum.b}`;
64
49
  }
65
50
  }
66
51
  static toBytes(config) {
67
52
  return new Size(config).toBytes();
68
53
  }
69
- static unit = SizeUnit;
70
- calculateBytes() {
71
- switch (this.unit) {
72
- case SizeUnit.kB:
73
- return SizeValue.parse(this.value * Size.KB_MULTIPLIER);
74
- case SizeUnit.MB:
75
- return SizeValue.parse(this.value * Size.MB_MULTIPLIER);
76
- case SizeUnit.GB:
77
- return SizeValue.parse(this.value * Size.GB_MULTIPLIER);
54
+ static unit = SizeUnitEnum;
55
+ calculateBytes(value, unit) {
56
+ switch (unit) {
57
+ case SizeUnitEnum.kB:
58
+ return SizeBytes.parse(value * Size.KB_MULTIPLIER);
59
+ case SizeUnitEnum.MB:
60
+ return SizeBytes.parse(value * Size.MB_MULTIPLIER);
61
+ case SizeUnitEnum.GB:
62
+ return SizeBytes.parse(value * Size.GB_MULTIPLIER);
78
63
  default:
79
- // SizeUnit.b
80
- return this.value;
64
+ return SizeBytes.parse(value);
81
65
  }
82
66
  }
67
+ toString() {
68
+ return this.format(this.unit);
69
+ }
70
+ toJSON() {
71
+ return { bytes: this.bytes };
72
+ }
83
73
  }
@@ -1,6 +1,8 @@
1
1
  import { Duration } from "./duration.service";
2
2
  import { type TimestampType } from "./timestamp.vo";
3
- export declare const StopwatchStateError: "stopwatch.already.stopped";
3
+ export declare const StopwatchError: {
4
+ readonly AlreadyStopped: "stopwatch.already.stopped";
5
+ };
4
6
  export type StopwatchResultType = Duration;
5
7
  export declare class Stopwatch {
6
8
  private readonly startMs;
@@ -1,11 +1,11 @@
1
1
  import { Duration } from "./duration.service";
2
2
  import { Timestamp } from "./timestamp.vo";
3
+ export const StopwatchError = { AlreadyStopped: "stopwatch.already.stopped" };
3
4
  var StopwatchState;
4
5
  (function (StopwatchState) {
5
6
  StopwatchState["started"] = "started";
6
7
  StopwatchState["stopped"] = "stopped";
7
8
  })(StopwatchState || (StopwatchState = {}));
8
- export const StopwatchStateError = "stopwatch.already.stopped";
9
9
  export class Stopwatch {
10
10
  startMs;
11
11
  state = StopwatchState.started;
@@ -14,7 +14,7 @@ export class Stopwatch {
14
14
  }
15
15
  stop() {
16
16
  if (this.state === StopwatchState.stopped)
17
- throw new Error(StopwatchStateError);
17
+ throw new Error(StopwatchError.AlreadyStopped);
18
18
  this.state = StopwatchState.stopped;
19
19
  return Duration.Ms(Timestamp.parse(Date.now() - this.startMs));
20
20
  }
@@ -3,14 +3,14 @@ export class Sum {
3
3
  return values.reduce((sum, x) => sum + x, 0);
4
4
  }
5
5
  static precise(values) {
6
- let runningTotal = 0;
7
- let roundingCompensation = 0;
8
- for (const currentValue of values) {
9
- const correctedAddend = currentValue - roundingCompensation;
10
- const tentativeTotal = runningTotal + correctedAddend;
11
- roundingCompensation = tentativeTotal - runningTotal - correctedAddend;
12
- runningTotal = tentativeTotal;
6
+ let sum = 0;
7
+ let compensation = 0;
8
+ for (const value of values) {
9
+ const adjusted = value - compensation;
10
+ const temporary = sum + adjusted;
11
+ compensation = temporary - sum - adjusted;
12
+ sum = temporary;
13
13
  }
14
- return runningTotal;
14
+ return sum;
15
15
  }
16
16
  }
@@ -1,6 +1,9 @@
1
1
  export class ThousandsSeparator {
2
2
  static DEFAULT_SEPARATOR = " ";
3
3
  static format(value, separator = ThousandsSeparator.DEFAULT_SEPARATOR) {
4
- return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
4
+ // B - not a word boundary, prevents inserting at the very start
5
+ // (?=([0-9]{3})+(?![0-9])) - positive lookahead, find three digits
6
+ // (?![0-9]) - negative lookahead, the next character is not a digit
7
+ return value.toString().replace(/\B(?=([0-9]{3})+(?![0-9]))/g, separator);
5
8
  }
6
9
  }
@@ -0,0 +1,8 @@
1
+ import type { Duration } from "./duration.service";
2
+ import { type TimestampType } from "./timestamp.vo";
3
+ export declare const Time: {
4
+ Now(now: TimestampType): {
5
+ Add(duration: Duration): TimestampType;
6
+ Minus(duration: Duration): TimestampType;
7
+ };
8
+ };
@@ -0,0 +1,13 @@
1
+ import { Timestamp } from "./timestamp.vo";
2
+ export const Time = {
3
+ Now(now) {
4
+ return {
5
+ Add(duration) {
6
+ return Timestamp.parse(now + duration.ms);
7
+ },
8
+ Minus(duration) {
9
+ return Timestamp.parse(now - duration.ms);
10
+ },
11
+ };
12
+ },
13
+ };
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod/v4";
2
2
  export declare const TimestampError: {
3
- readonly error: "invalid.timestamp";
3
+ readonly Invalid: "timestamp.invalid";
4
4
  };
5
5
  export declare const Timestamp: z.core.$ZodBranded<z.ZodNumber, "Timestamp">;
6
6
  export type TimestampType = z.infer<typeof Timestamp>;
@@ -1,8 +1,7 @@
1
1
  import { z } from "zod/v4";
2
- export const TimestampError = { error: "invalid.timestamp" };
2
+ export const TimestampError = { Invalid: "timestamp.invalid" };
3
3
  export const Timestamp = z
4
- .number(TimestampError)
5
- .int(TimestampError)
6
- .gte(0, TimestampError)
7
- .lte(Number.MAX_SAFE_INTEGER, TimestampError)
4
+ .number(TimestampError.Invalid)
5
+ .int(TimestampError.Invalid)
6
+ .gte(0, TimestampError.Invalid)
8
7
  .brand("Timestamp");
@@ -1,6 +1,9 @@
1
1
  import { z } from "zod/v4";
2
2
  export declare const TimezoneError: {
3
- readonly error: "timezone.invalid";
3
+ readonly Type: "timezone.type";
4
+ readonly Empty: "timezone.empty";
5
+ readonly TooLong: "timezone.too.long";
6
+ readonly Invalid: "timezone.invalid";
4
7
  };
5
8
  export declare const Timezone: z.core.$ZodBranded<z.ZodString, "Timezone">;
6
9
  export type TimezoneType = z.infer<typeof Timezone>;
@@ -1,15 +1,21 @@
1
1
  import { z } from "zod/v4";
2
- export const TimezoneError = { error: "timezone.invalid" };
2
+ export const TimezoneError = {
3
+ Type: "timezone.type",
4
+ Empty: "timezone.empty",
5
+ TooLong: "timezone.too.long",
6
+ Invalid: "timezone.invalid",
7
+ };
3
8
  export const Timezone = z
4
- .string(TimezoneError)
5
- .min(1, TimezoneError)
9
+ .string(TimezoneError.Type)
10
+ .min(1, TimezoneError.Empty)
11
+ .max(128, TimezoneError.TooLong)
6
12
  .refine((value) => {
7
13
  try {
8
- new Intl.DateTimeFormat("en-US", { timeZone: value }).format(new Date());
14
+ new Intl.DateTimeFormat("en-US", { timeZone: value }).format(Date.now());
9
15
  return true;
10
16
  }
11
- catch (_error) {
17
+ catch {
12
18
  return false;
13
19
  }
14
- }, TimezoneError)
20
+ }, TimezoneError.Invalid)
15
21
  .brand("Timezone");
@@ -1 +1 @@
1
- {"root":["../src/age.vo.ts","../src/api-key.vo.ts","../src/basename.vo.ts","../src/clock-format.service.ts","../src/clock.vo.ts","../src/date-calculator.service.ts","../src/date-formatter.service.ts","../src/date-range.vo.ts","../src/day-iso-id.vo.ts","../src/day.vo.ts","../src/directory-path-absolute.vo.ts","../src/directory-path-relative.vo.ts","../src/dll.service.ts","../src/duration.service.ts","../src/email-mask.service.ts","../src/etags.vo.ts","../src/extension.vo.ts","../src/feature-flag.vo.ts","../src/file-path-absolute-schema.vo.ts","../src/file-path-relative-schema.vo.ts","../src/file-path.vo.ts","../src/filename-from-string.vo.ts","../src/filename-suffix.vo.ts","../src/filename.vo.ts","../src/height.vo.ts","../src/hour-format.service.ts","../src/hour.vo.ts","../src/iban-mask.service.ts","../src/iban.vo.ts","../src/image.vo.ts","../src/index.ts","../src/language.vo.ts","../src/mean.service.ts","../src/mime-types.vo.ts","../src/mime.vo.ts","../src/min-max-scaler.service.ts","../src/minute.vo.ts","../src/money.vo.ts","../src/month-iso-id.vo.ts","../src/month.vo.ts","../src/noop.service.ts","../src/notification-template.vo.ts","../src/object-key.vo.ts","../src/outlier-detector.service.ts","../src/package-version.vo.ts","../src/pagination.service.ts","../src/percentage.service.ts","../src/population-standard-deviation.service.ts","../src/quarter-iso-id.vo.ts","../src/quarter.vo.ts","../src/random.service.ts","../src/rate-limiter.service.ts","../src/relative-date.vo.ts","../src/reordering.service.ts","../src/revision.vo.ts","../src/rounding.adapter.ts","../src/rounding.port.ts","../src/simple-linear-regression.service.ts","../src/size.vo.ts","../src/stopwatch.service.ts","../src/streak-calculator.service.ts","../src/sum.service.ts","../src/thousands-separator.service.ts","../src/time-zone-offset-value.vo.ts","../src/timestamp.vo.ts","../src/timezone.vo.ts","../src/ts-utils.ts","../src/visually-unambiguous-characters-generator.service.ts","../src/week-iso-id.vo.ts","../src/week.vo.ts","../src/weekday.vo.ts","../src/weight.vo.ts","../src/year-iso-id.vo.ts","../src/year.vo.ts","../src/z-score.service.ts"],"version":"5.9.3"}
1
+ {"root":["../src/age-years.vo.ts","../src/age.vo.ts","../src/api-key.vo.ts","../src/basename.vo.ts","../src/clock-format.service.ts","../src/clock.vo.ts","../src/date-calculator.service.ts","../src/date-formatter.service.ts","../src/date-range.vo.ts","../src/day-iso-id.vo.ts","../src/day.vo.ts","../src/directory-path-absolute.vo.ts","../src/directory-path-relative.vo.ts","../src/division-factor.vo.ts","../src/dll.service.ts","../src/duration-ms.vo.ts","../src/duration.service.ts","../src/email-mask.service.ts","../src/etags.vo.ts","../src/extension.vo.ts","../src/feature-flag-value.vo.ts","../src/feature-flag.vo.ts","../src/file-path-absolute-schema.vo.ts","../src/file-path-relative-schema.vo.ts","../src/file-path.vo.ts","../src/filename-from-string.vo.ts","../src/filename-suffix.vo.ts","../src/filename.vo.ts","../src/height-milimiters.vo.ts","../src/height.vo.ts","../src/hour-format.service.ts","../src/hour-schema.vo.ts","../src/hour.vo.ts","../src/iban-mask.service.ts","../src/iban-schema.vo.ts","../src/iban.vo.ts","../src/image.vo.ts","../src/index.ts","../src/language.vo.ts","../src/linear-regression.service.ts","../src/mean.service.ts","../src/mime-types.vo.ts","../src/mime-value.vo.ts","../src/mime.vo.ts","../src/min-max-scaler.service.ts","../src/minute-schema.vo.ts","../src/minute.vo.ts","../src/money-amount.vo.ts","../src/money.vo.ts","../src/month-iso-id.vo.ts","../src/month.vo.ts","../src/multiplication-factor.vo.ts","../src/noop.service.ts","../src/notification-template.vo.ts","../src/object-key.vo.ts","../src/outlier-detector.service.ts","../src/package-version-schema.vo.ts","../src/package-version.vo.ts","../src/pagination-page.vo.ts","../src/pagination-skip.vo.ts","../src/pagination-take.vo.ts","../src/pagination.service.ts","../src/percentage.service.ts","../src/population-standard-deviation.service.ts","../src/quarter-iso-id.vo.ts","../src/quarter.vo.ts","../src/random.service.ts","../src/rate-limiter.service.ts","../src/relative-date.vo.ts","../src/reordering-item-position-value.vo.ts","../src/reordering.service.ts","../src/revision-value.vo.ts","../src/revision.vo.ts","../src/rounding.adapter.ts","../src/rounding.port.ts","../src/size-bytes.vo.ts","../src/size.vo.ts","../src/stopwatch.service.ts","../src/sum.service.ts","../src/thousands-separator.service.ts","../src/time-zone-offset-value.vo.ts","../src/time.service.ts","../src/timestamp.vo.ts","../src/timezone.vo.ts","../src/ts-utils.ts","../src/visually-unambiguous-characters-generator.service.ts","../src/week-iso-id.vo.ts","../src/week.vo.ts","../src/weekday.vo.ts","../src/weight-grams.vo.ts","../src/weight.vo.ts","../src/year-iso-id.vo.ts","../src/year.vo.ts","../src/z-score.service.ts"],"version":"5.9.3"}
@@ -1,6 +1,8 @@
1
1
  import { z } from "zod/v4";
2
2
  export declare const WeekIsoIdError: {
3
- readonly error: "week-iso-id.invalid";
3
+ readonly Type: "week.iso.id.type";
4
+ readonly BadChars: "week.iso.id.bad.chars";
5
+ readonly Invalid: "week.iso.id.invalid";
4
6
  };
5
- export declare const WeekIsoId: z.ZodString;
7
+ export declare const WeekIsoId: z.core.$ZodBranded<z.ZodString, "WeekIsoId">;
6
8
  export type WeekIsoIdType = z.infer<typeof WeekIsoId>;
@@ -1,15 +1,21 @@
1
1
  import { getISOWeeksInYear } from "date-fns";
2
2
  import { z } from "zod/v4";
3
- export const WeekIsoIdError = { error: "week-iso-id.invalid" };
3
+ export const WeekIsoIdError = {
4
+ Type: "week.iso.id.type",
5
+ BadChars: "week.iso.id.bad.chars",
6
+ Invalid: "week.iso.id.invalid",
7
+ };
8
+ // Four digits, hypen, W, followed by two digits
9
+ const WEEK_ISO_ID_CHARS_WHITELIST = /^[0-9]{4}-W[0-9]{2}$/;
4
10
  export const WeekIsoId = z
5
- .string(WeekIsoIdError)
6
- .regex(/^\d{4}-W\d{2}$/, WeekIsoIdError)
11
+ .string(WeekIsoIdError.Type)
12
+ .regex(WEEK_ISO_ID_CHARS_WHITELIST, WeekIsoIdError.BadChars)
7
13
  .refine((value) => {
8
- const [yearPart, weekPart] = value.split("-W");
9
- const year = Number(yearPart);
10
- const week = Number(weekPart);
11
- if (!(Number.isInteger(year) && Number.isInteger(week)) || week < 1)
14
+ const [year, week] = value.split("-W").map(Number);
15
+ // ISO-8601 rule: Jan 4 is always in week 01 of the ISO week-year.
16
+ const weeksInYear = getISOWeeksInYear(Date.UTC(year, 0, 4));
17
+ if (week < 1)
12
18
  return false;
13
- const weeksInYear = getISOWeeksInYear(new Date(Date.UTC(year, 0, 4)));
14
19
  return week <= weeksInYear;
15
- }, WeekIsoIdError);
20
+ }, WeekIsoIdError.Invalid)
21
+ .brand("WeekIsoId");