@bgord/tools 1.1.17 → 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/age.vo.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type AgeYearsType } from "./age-years.vo";
1
2
  import { Timestamp } from "./timestamp.vo";
2
3
  export declare const AgeError: {
3
4
  readonly FutureBirthdate: "age.future.birthdate";
@@ -8,6 +9,7 @@ export declare class Age {
8
9
  static readonly MAX: number;
9
10
  private constructor();
10
11
  static fromValue(candidate: number): Age;
12
+ static fromValueSafe(candidate: AgeYearsType): Age;
11
13
  static fromBirthdateTimestamp(params: {
12
14
  birthdate: Timestamp;
13
15
  now: Timestamp;
package/dist/age.vo.js CHANGED
@@ -12,6 +12,9 @@ export class Age {
12
12
  static fromValue(candidate) {
13
13
  return new Age(AgeYears.parse(candidate));
14
14
  }
15
+ static fromValueSafe(candidate) {
16
+ return new Age(candidate);
17
+ }
15
18
  static fromBirthdateTimestamp(params) {
16
19
  if (params.birthdate.isAfter(params.now))
17
20
  throw new Error(AgeError.FutureBirthdate);
@@ -0,0 +1,7 @@
1
+ import { z } from "zod/v4";
2
+ export declare const DistanceValueError: {
3
+ Type: string;
4
+ Invalid: string;
5
+ };
6
+ export declare const DistanceValue: z.core.$ZodBranded<z.ZodNumber, "DistanceValue">;
7
+ export type DistanceValueType = z.infer<typeof DistanceValue>;
@@ -0,0 +1,7 @@
1
+ import { z } from "zod/v4";
2
+ export const DistanceValueError = { Type: "distance.value.type", Invalid: "distance.value.invalid" };
3
+ export const DistanceValue = z
4
+ .number(DistanceValueError.Type)
5
+ .int(DistanceValueError.Type)
6
+ .min(0, DistanceValueError.Invalid)
7
+ .brand("DistanceValue");
@@ -0,0 +1,24 @@
1
+ import { type DistanceValueType } from "./distance-value.vo";
2
+ import type { RoundingPort } from "./rounding.port";
3
+ export declare const DistanceError: {
4
+ readonly SubtractResultLessThanZero: "distance.subtract.result.less.than.zero";
5
+ };
6
+ export declare class Distance {
7
+ private readonly value;
8
+ private static readonly ZERO;
9
+ private constructor();
10
+ static fromMeters(candidate: number): Distance;
11
+ static fromMetersSafe(candidate: DistanceValueType): Distance;
12
+ static fromKilometers(candidate: number, rounding?: RoundingPort): Distance;
13
+ static fromMiles(candidate: number, rounding?: RoundingPort): Distance;
14
+ get(): DistanceValueType;
15
+ add(distance: Distance): Distance;
16
+ subtract(money: Distance): Distance;
17
+ equals(another: Distance): boolean;
18
+ isLongerThan(another: Distance): boolean;
19
+ isShorterThan(another: Distance): boolean;
20
+ isZero(): boolean;
21
+ format(): string;
22
+ toString(): string;
23
+ toJSON(): number;
24
+ }
@@ -0,0 +1,57 @@
1
+ import { DistanceValue } from "./distance-value.vo";
2
+ import { RoundToNearest } from "./rounding.adapter";
3
+ export const DistanceError = {
4
+ SubtractResultLessThanZero: "distance.subtract.result.less.than.zero",
5
+ };
6
+ export class Distance {
7
+ value;
8
+ static ZERO = DistanceValue.parse(0);
9
+ constructor(value) {
10
+ this.value = value;
11
+ }
12
+ static fromMeters(candidate) {
13
+ return new Distance(DistanceValue.parse(candidate));
14
+ }
15
+ static fromMetersSafe(candidate) {
16
+ return new Distance(candidate);
17
+ }
18
+ static fromKilometers(candidate, rounding = new RoundToNearest()) {
19
+ return new Distance(DistanceValue.parse(rounding.round(candidate * 1000)));
20
+ }
21
+ static fromMiles(candidate, rounding = new RoundToNearest()) {
22
+ return new Distance(DistanceValue.parse(rounding.round(candidate * 1_609.344)));
23
+ }
24
+ get() {
25
+ return this.value;
26
+ }
27
+ add(distance) {
28
+ return new Distance(DistanceValue.parse(this.value + distance.get()));
29
+ }
30
+ subtract(money) {
31
+ const result = this.value - money.get();
32
+ if (result < Distance.ZERO)
33
+ throw new Error(DistanceError.SubtractResultLessThanZero);
34
+ return new Distance(DistanceValue.parse(result));
35
+ }
36
+ equals(another) {
37
+ return this.value === another.get();
38
+ }
39
+ isLongerThan(another) {
40
+ return this.value > another.get();
41
+ }
42
+ isShorterThan(another) {
43
+ return this.value < another.get();
44
+ }
45
+ isZero() {
46
+ return this.value === Distance.ZERO;
47
+ }
48
+ format() {
49
+ return this.value.toString();
50
+ }
51
+ toString() {
52
+ return this.format();
53
+ }
54
+ toJSON() {
55
+ return this.value;
56
+ }
57
+ }
@@ -4,3 +4,4 @@ export declare const HeightMillimetersError: {
4
4
  readonly Invalid: "height.millimeters.invalid";
5
5
  };
6
6
  export declare const HeightMillimeters: z.core.$ZodBranded<z.ZodNumber, "HeightMillimeters">;
7
+ export type HeightMillimetersType = z.infer<typeof HeightMillimeters>;
@@ -1,10 +1,13 @@
1
+ import { type HeightMillimetersType } from "./height-milimiters.vo";
1
2
  import type { RoundingPort } from "./rounding.port";
2
3
  export declare class Height {
3
4
  private readonly millimeters;
5
+ private static readonly ZERO;
4
6
  private static readonly MILLIMETERS_PER_CENTIMETER;
5
7
  private constructor();
6
- static fromCentimeters(centimeters: number, rounding?: RoundingPort): Height;
7
8
  static fromMillimeters(millimeters: number): Height;
9
+ static fromMillimetersSafe(millimeters: HeightMillimetersType): Height;
10
+ static fromCentimeters(centimeters: number, rounding?: RoundingPort): Height;
8
11
  static zero(): Height;
9
12
  get(): number;
10
13
  toMillimeters(): number;
package/dist/height.vo.js CHANGED
@@ -2,19 +2,23 @@ import { HeightMillimeters } from "./height-milimiters.vo";
2
2
  import { RoundToDecimal, RoundToNearest } from "./rounding.adapter";
3
3
  export class Height {
4
4
  millimeters;
5
+ static ZERO = HeightMillimeters.parse(0);
5
6
  static MILLIMETERS_PER_CENTIMETER = 10;
6
7
  constructor(millimeters) {
7
8
  this.millimeters = millimeters;
8
9
  }
9
- static fromCentimeters(centimeters, rounding = new RoundToNearest()) {
10
- const millimeters = rounding.round(centimeters * Height.MILLIMETERS_PER_CENTIMETER);
10
+ static fromMillimeters(millimeters) {
11
11
  return new Height(HeightMillimeters.parse(millimeters));
12
12
  }
13
- static fromMillimeters(millimeters) {
13
+ static fromMillimetersSafe(millimeters) {
14
+ return new Height(millimeters);
15
+ }
16
+ static fromCentimeters(centimeters, rounding = new RoundToNearest()) {
17
+ const millimeters = rounding.round(centimeters * Height.MILLIMETERS_PER_CENTIMETER);
14
18
  return new Height(HeightMillimeters.parse(millimeters));
15
19
  }
16
20
  static zero() {
17
- return new Height(0);
21
+ return Height.fromMillimetersSafe(Height.ZERO);
18
22
  }
19
23
  get() {
20
24
  return this.millimeters;
package/dist/hour.vo.d.ts CHANGED
@@ -4,11 +4,13 @@ import { Timestamp } from "./timestamp.vo";
4
4
  import type { TimestampValueType } from "./timestamp-value.vo";
5
5
  export declare class Hour {
6
6
  private readonly value;
7
- static readonly ZERO: Hour;
8
- static readonly MAX: Hour;
9
- constructor(candidate: number);
7
+ private constructor();
8
+ static fromValue(candidate: number): Hour;
9
+ static fromValueSafe(candidate: HourSchemaType): Hour;
10
10
  static fromTimestamp(timestamp: Timestamp): Hour;
11
11
  static fromTimestampValue(timestamp: TimestampValueType): Hour;
12
+ static zero(): Hour;
13
+ static max(): Hour;
12
14
  get(): HourSchemaType;
13
15
  format(formatter: HourFormatter): string;
14
16
  equals(another: Hour): boolean;
package/dist/hour.vo.js CHANGED
@@ -3,17 +3,27 @@ import { HourSchema } from "./hour-schema.vo";
3
3
  import { Timestamp } from "./timestamp.vo";
4
4
  export class Hour {
5
5
  value;
6
- static ZERO = new Hour(0);
7
- static MAX = new Hour(23);
8
- constructor(candidate) {
9
- this.value = HourSchema.parse(candidate);
6
+ constructor(value) {
7
+ this.value = value;
8
+ }
9
+ static fromValue(candidate) {
10
+ return new Hour(HourSchema.parse(candidate));
11
+ }
12
+ static fromValueSafe(candidate) {
13
+ return new Hour(candidate);
10
14
  }
11
15
  static fromTimestamp(timestamp) {
12
- return new Hour(new Date(timestamp.ms).getUTCHours());
16
+ return new Hour(HourSchema.parse(new Date(timestamp.ms).getUTCHours()));
13
17
  }
14
18
  static fromTimestampValue(timestamp) {
15
19
  return Hour.fromTimestamp(Timestamp.fromValue(timestamp));
16
20
  }
21
+ static zero() {
22
+ return Hour.fromValue(0);
23
+ }
24
+ static max() {
25
+ return Hour.fromValue(23);
26
+ }
17
27
  get() {
18
28
  return this.value;
19
29
  }
@@ -30,7 +40,7 @@ export class Hour {
30
40
  return this.value < another.value;
31
41
  }
32
42
  static list() {
33
- return Array.from({ length: 24 }, (_, index) => new Hour(index));
43
+ return Array.from({ length: 24 }, (_, index) => Hour.fromValue(index));
34
44
  }
35
45
  toString() {
36
46
  return HourFormatters.TWENTY_FOUR_HOURS(this.value);
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export * from "./day.vo";
11
11
  export * from "./day-iso-id.vo";
12
12
  export * from "./directory-path-absolute.vo";
13
13
  export * from "./directory-path-relative.vo";
14
+ export * from "./distance.vo";
15
+ export * from "./distance-value.vo";
14
16
  export * from "./division-factor.vo";
15
17
  export * from "./dll.service";
16
18
  export * from "./duration.service";
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ export * from "./day.vo";
11
11
  export * from "./day-iso-id.vo";
12
12
  export * from "./directory-path-absolute.vo";
13
13
  export * from "./directory-path-relative.vo";
14
+ export * from "./distance.vo";
15
+ export * from "./distance-value.vo";
14
16
  export * from "./division-factor.vo";
15
17
  export * from "./dll.service";
16
18
  export * from "./duration.service";
@@ -3,11 +3,13 @@ import { Timestamp } from "./timestamp.vo";
3
3
  import type { TimestampValueType } from "./timestamp-value.vo";
4
4
  export declare class Minute {
5
5
  private readonly value;
6
- static readonly ZERO: Minute;
7
- static readonly MAX: Minute;
8
- constructor(candidate: number);
6
+ private constructor();
7
+ static fromValue(candidate: number): Minute;
8
+ static fromValueSafe(candidate: MinuteSchemaType): Minute;
9
9
  static fromTimestamp(timestamp: Timestamp): Minute;
10
10
  static fromTimestampValue(timestamp: TimestampValueType): Minute;
11
+ static zero(): Minute;
12
+ static max(): Minute;
11
13
  get(): MinuteSchemaType;
12
14
  equals(another: Minute): boolean;
13
15
  isAfter(another: Minute): boolean;
package/dist/minute.vo.js CHANGED
@@ -2,17 +2,27 @@ import { MinuteSchema } from "./minute-schema.vo";
2
2
  import { Timestamp } from "./timestamp.vo";
3
3
  export class Minute {
4
4
  value;
5
- static ZERO = new Minute(0);
6
- static MAX = new Minute(59);
7
- constructor(candidate) {
8
- this.value = MinuteSchema.parse(candidate);
5
+ constructor(value) {
6
+ this.value = value;
7
+ }
8
+ static fromValue(candidate) {
9
+ return new Minute(MinuteSchema.parse(candidate));
10
+ }
11
+ static fromValueSafe(candidate) {
12
+ return new Minute(candidate);
9
13
  }
10
14
  static fromTimestamp(timestamp) {
11
- return new Minute(new Date(timestamp.ms).getUTCMinutes());
15
+ return new Minute(MinuteSchema.parse(new Date(timestamp.ms).getUTCMinutes()));
12
16
  }
13
17
  static fromTimestampValue(timestamp) {
14
18
  return Minute.fromTimestamp(Timestamp.fromValue(timestamp));
15
19
  }
20
+ static zero() {
21
+ return Minute.fromValue(0);
22
+ }
23
+ static max() {
24
+ return Minute.fromValue(59);
25
+ }
16
26
  get() {
17
27
  return this.value;
18
28
  }
@@ -26,7 +36,7 @@ export class Minute {
26
36
  return this.value < another.value;
27
37
  }
28
38
  static list() {
29
- return Array.from({ length: 60 }, (_, index) => new Minute(index));
39
+ return Array.from({ length: 60 }, (_, index) => Minute.fromValue(index));
30
40
  }
31
41
  toString() {
32
42
  return this.value.toString().padStart(2, "0");
@@ -6,11 +6,13 @@ export declare const MoneyError: {
6
6
  readonly SubtractResultLessThanZero: "money.subtract.result.less.than.zero";
7
7
  };
8
8
  export declare class Money {
9
- private static readonly ZERO;
10
- private static readonly DEFAULT_ROUNDING;
11
9
  private readonly amount;
12
10
  private readonly rounding;
13
- constructor(value?: number, rounding?: RoundingPort);
11
+ private static readonly ZERO;
12
+ private constructor();
13
+ static fromAmount(candidate: number, rounding?: RoundingPort): Money;
14
+ static fromAmountSafe(candidate: MoneyAmountType, rounding?: RoundingPort): Money;
15
+ static zero(): Money;
14
16
  getAmount(): MoneyAmountType;
15
17
  add(money: Money): Money;
16
18
  multiply(factor: MultiplicationFactorType): Money;
package/dist/money.vo.js CHANGED
@@ -2,34 +2,39 @@ import { MoneyAmount } from "./money-amount.vo";
2
2
  import { RoundDown, RoundToNearest } from "./rounding.adapter";
3
3
  export const MoneyError = { SubtractResultLessThanZero: "money.subtract.result.less.than.zero" };
4
4
  export class Money {
5
- static ZERO = 0;
6
- static DEFAULT_ROUNDING = new RoundToNearest();
7
5
  amount;
8
6
  rounding;
9
- constructor(value = Money.ZERO, rounding) {
10
- this.amount = MoneyAmount.parse(value);
11
- this.rounding = rounding ?? Money.DEFAULT_ROUNDING;
7
+ static ZERO = MoneyAmount.parse(0);
8
+ constructor(amount, rounding = new RoundToNearest()) {
9
+ this.amount = amount;
10
+ this.rounding = rounding;
11
+ }
12
+ static fromAmount(candidate, rounding) {
13
+ return new Money(MoneyAmount.parse(candidate), rounding);
14
+ }
15
+ static fromAmountSafe(candidate, rounding) {
16
+ return new Money(candidate, rounding);
17
+ }
18
+ static zero() {
19
+ return Money.fromAmount(0);
12
20
  }
13
21
  getAmount() {
14
22
  return this.amount;
15
23
  }
16
24
  add(money) {
17
- const result = this.amount + money.getAmount();
18
- return new Money(MoneyAmount.parse(result), this.rounding);
25
+ return new Money(MoneyAmount.parse(this.amount + money.getAmount()), this.rounding);
19
26
  }
20
27
  multiply(factor) {
21
- const result = this.rounding.round(this.amount * factor);
22
- return new Money(MoneyAmount.parse(result), this.rounding);
28
+ return new Money(MoneyAmount.parse(this.rounding.round(this.amount * factor)), this.rounding);
23
29
  }
24
30
  subtract(money) {
25
31
  const result = this.amount - money.getAmount();
26
32
  if (result < Money.ZERO)
27
33
  throw new Error(MoneyError.SubtractResultLessThanZero);
28
- return new Money(MoneyAmount.parse(result), this.rounding);
34
+ return new Money(MoneyAmount.parse(this.rounding.round(result)), this.rounding);
29
35
  }
30
36
  divide(factor) {
31
- const result = this.rounding.round(this.amount / factor);
32
- return new Money(MoneyAmount.parse(result), this.rounding);
37
+ return new Money(MoneyAmount.parse(this.rounding.round(this.amount / factor)), this.rounding);
33
38
  }
34
39
  equals(another) {
35
40
  return this.amount === another.getAmount();
@@ -1,9 +1,11 @@
1
+ import { type PackageVersionSchemaType } from "./package-version-schema.vo";
1
2
  export declare class PackageVersion {
2
3
  private readonly major;
3
4
  private readonly minor;
4
5
  private readonly patch;
5
6
  constructor(major: number, minor: number, patch: number);
6
- static fromStringWithV(candidate: string): PackageVersion;
7
+ static fromVersionString(candidate: string): PackageVersion;
8
+ static fromVersionStringSafe(candidate: PackageVersionSchemaType): PackageVersion;
7
9
  static fromString(candidate: string): PackageVersion;
8
10
  isGreaterThanOrEqual(another: PackageVersion): boolean;
9
11
  toString(): string;
@@ -8,10 +8,13 @@ export class PackageVersion {
8
8
  this.minor = minor;
9
9
  this.patch = patch;
10
10
  }
11
- static fromStringWithV(candidate) {
11
+ static fromVersionString(candidate) {
12
12
  const version = PackageVersionSchema.parse(candidate);
13
13
  return new PackageVersion(version.major, version.minor, version.patch);
14
14
  }
15
+ static fromVersionStringSafe(candidate) {
16
+ return new PackageVersion(candidate.major, candidate.minor, candidate.patch);
17
+ }
15
18
  static fromString(candidate) {
16
19
  const version = PackageVersionSchema.parse(`v${candidate}`);
17
20
  return new PackageVersion(version.major, version.minor, version.patch);
package/dist/size.vo.d.ts CHANGED
@@ -17,7 +17,7 @@ export declare class Size {
17
17
  private static readonly GB_MULTIPLIER;
18
18
  private static readonly CONVERT_ROUND;
19
19
  private static readonly FORMAT_ROUND;
20
- constructor(config: SizeConfigType);
20
+ private constructor();
21
21
  static fromBytes(value: SizeConfigType["value"]): Size;
22
22
  static fromKb(value: SizeConfigType["value"]): Size;
23
23
  static fromMB(value: SizeConfigType["value"]): Size;
@@ -1 +1 @@
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-affix.vo.ts","../src/filename-from-string.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/slug.service.ts","../src/stopwatch.service.ts","../src/sum.service.ts","../src/thousands-separator.service.ts","../src/time-zone-offset-value.vo.ts","../src/timestamp-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-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
+ {"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/distance-value.vo.ts","../src/distance.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-affix.vo.ts","../src/filename-from-string.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/slug.service.ts","../src/stopwatch.service.ts","../src/sum.service.ts","../src/thousands-separator.service.ts","../src/time-zone-offset-value.vo.ts","../src/timestamp-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-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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgord/tools",
3
- "version": "1.1.17",
3
+ "version": "1.1.18",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Bartosz Gordon",
package/readme.md CHANGED
@@ -37,6 +37,8 @@ src/
37
37
  ├── day.vo.ts
38
38
  ├── directory-path-absolute.vo.ts
39
39
  ├── directory-path-relative.vo.ts
40
+ ├── distance-value.vo.ts
41
+ ├── distance.vo.ts
40
42
  ├── division-factor.vo.ts
41
43
  ├── dll.service.ts
42
44
  ├── duration-ms.vo.ts
package/src/age.vo.ts CHANGED
@@ -14,6 +14,10 @@ export class Age {
14
14
  return new Age(AgeYears.parse(candidate));
15
15
  }
16
16
 
17
+ static fromValueSafe(candidate: AgeYearsType): Age {
18
+ return new Age(candidate);
19
+ }
20
+
17
21
  static fromBirthdateTimestamp(params: { birthdate: Timestamp; now: Timestamp }): Age {
18
22
  if (params.birthdate.isAfter(params.now)) throw new Error(AgeError.FutureBirthdate);
19
23
  return Age.fromValue(differenceInYears(params.now.ms, params.birthdate.ms));
@@ -0,0 +1,11 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const DistanceValueError = { Type: "distance.value.type", Invalid: "distance.value.invalid" };
4
+
5
+ export const DistanceValue = z
6
+ .number(DistanceValueError.Type)
7
+ .int(DistanceValueError.Type)
8
+ .min(0, DistanceValueError.Invalid)
9
+ .brand("DistanceValue");
10
+
11
+ export type DistanceValueType = z.infer<typeof DistanceValue>;
@@ -0,0 +1,72 @@
1
+ import { DistanceValue, type DistanceValueType } from "./distance-value.vo";
2
+ import { RoundToNearest } from "./rounding.adapter";
3
+ import type { RoundingPort } from "./rounding.port";
4
+
5
+ export const DistanceError = {
6
+ SubtractResultLessThanZero: "distance.subtract.result.less.than.zero",
7
+ } as const;
8
+
9
+ export class Distance {
10
+ private static readonly ZERO = DistanceValue.parse(0);
11
+
12
+ private constructor(private readonly value: DistanceValueType) {}
13
+
14
+ static fromMeters(candidate: number): Distance {
15
+ return new Distance(DistanceValue.parse(candidate));
16
+ }
17
+
18
+ static fromMetersSafe(candidate: DistanceValueType): Distance {
19
+ return new Distance(candidate);
20
+ }
21
+
22
+ static fromKilometers(candidate: number, rounding: RoundingPort = new RoundToNearest()): Distance {
23
+ return new Distance(DistanceValue.parse(rounding.round(candidate * 1000)));
24
+ }
25
+
26
+ static fromMiles(candidate: number, rounding: RoundingPort = new RoundToNearest()): Distance {
27
+ return new Distance(DistanceValue.parse(rounding.round(candidate * 1_609.344)));
28
+ }
29
+
30
+ get(): DistanceValueType {
31
+ return this.value;
32
+ }
33
+
34
+ add(distance: Distance): Distance {
35
+ return new Distance(DistanceValue.parse(this.value + distance.get()));
36
+ }
37
+
38
+ subtract(money: Distance): Distance {
39
+ const result = this.value - money.get();
40
+
41
+ if (result < Distance.ZERO) throw new Error(DistanceError.SubtractResultLessThanZero);
42
+ return new Distance(DistanceValue.parse(result));
43
+ }
44
+
45
+ equals(another: Distance): boolean {
46
+ return this.value === another.get();
47
+ }
48
+
49
+ isLongerThan(another: Distance): boolean {
50
+ return this.value > another.get();
51
+ }
52
+
53
+ isShorterThan(another: Distance): boolean {
54
+ return this.value < another.get();
55
+ }
56
+
57
+ isZero(): boolean {
58
+ return this.value === Distance.ZERO;
59
+ }
60
+
61
+ format(): string {
62
+ return this.value.toString();
63
+ }
64
+
65
+ toString(): string {
66
+ return this.format();
67
+ }
68
+
69
+ toJSON(): number {
70
+ return this.value;
71
+ }
72
+ }
@@ -10,3 +10,5 @@ export const HeightMillimeters = z
10
10
  .int(HeightMillimetersError.Type)
11
11
  .min(0, HeightMillimetersError.Invalid)
12
12
  .brand("HeightMillimeters");
13
+
14
+ export type HeightMillimetersType = z.infer<typeof HeightMillimeters>;
package/src/height.vo.ts CHANGED
@@ -1,24 +1,30 @@
1
- import { HeightMillimeters } from "./height-milimiters.vo";
1
+ import { HeightMillimeters, type HeightMillimetersType } from "./height-milimiters.vo";
2
2
  import { RoundToDecimal, RoundToNearest } from "./rounding.adapter";
3
3
  import type { RoundingPort } from "./rounding.port";
4
4
 
5
5
  export class Height {
6
- private static readonly MILLIMETERS_PER_CENTIMETER = 10;
6
+ private static readonly ZERO = HeightMillimeters.parse(0);
7
7
 
8
- private constructor(private readonly millimeters: number) {}
8
+ private static readonly MILLIMETERS_PER_CENTIMETER = 10;
9
9
 
10
- static fromCentimeters(centimeters: number, rounding: RoundingPort = new RoundToNearest()): Height {
11
- const millimeters = rounding.round(centimeters * Height.MILLIMETERS_PER_CENTIMETER);
10
+ private constructor(private readonly millimeters: HeightMillimetersType) {}
12
11
 
12
+ static fromMillimeters(millimeters: number): Height {
13
13
  return new Height(HeightMillimeters.parse(millimeters));
14
14
  }
15
15
 
16
- static fromMillimeters(millimeters: number): Height {
16
+ static fromMillimetersSafe(millimeters: HeightMillimetersType): Height {
17
+ return new Height(millimeters);
18
+ }
19
+
20
+ static fromCentimeters(centimeters: number, rounding: RoundingPort = new RoundToNearest()): Height {
21
+ const millimeters = rounding.round(centimeters * Height.MILLIMETERS_PER_CENTIMETER);
22
+
17
23
  return new Height(HeightMillimeters.parse(millimeters));
18
24
  }
19
25
 
20
26
  static zero(): Height {
21
- return new Height(0);
27
+ return Height.fromMillimetersSafe(Height.ZERO);
22
28
  }
23
29
 
24
30
  get(): number {
package/src/hour.vo.ts CHANGED
@@ -4,23 +4,32 @@ import { Timestamp } from "./timestamp.vo";
4
4
  import type { TimestampValueType } from "./timestamp-value.vo";
5
5
 
6
6
  export class Hour {
7
- private readonly value: HourSchemaType;
7
+ private constructor(private readonly value: HourSchemaType) {}
8
8
 
9
- static readonly ZERO = new Hour(0);
10
- static readonly MAX = new Hour(23);
9
+ static fromValue(candidate: number): Hour {
10
+ return new Hour(HourSchema.parse(candidate));
11
+ }
11
12
 
12
- constructor(candidate: number) {
13
- this.value = HourSchema.parse(candidate);
13
+ static fromValueSafe(candidate: HourSchemaType) {
14
+ return new Hour(candidate);
14
15
  }
15
16
 
16
17
  static fromTimestamp(timestamp: Timestamp): Hour {
17
- return new Hour(new Date(timestamp.ms).getUTCHours());
18
+ return new Hour(HourSchema.parse(new Date(timestamp.ms).getUTCHours()));
18
19
  }
19
20
 
20
21
  static fromTimestampValue(timestamp: TimestampValueType): Hour {
21
22
  return Hour.fromTimestamp(Timestamp.fromValue(timestamp));
22
23
  }
23
24
 
25
+ static zero(): Hour {
26
+ return Hour.fromValue(0);
27
+ }
28
+
29
+ static max(): Hour {
30
+ return Hour.fromValue(23);
31
+ }
32
+
24
33
  get(): HourSchemaType {
25
34
  return this.value;
26
35
  }
@@ -42,7 +51,7 @@ export class Hour {
42
51
  }
43
52
 
44
53
  static list(): readonly Hour[] {
45
- return Array.from({ length: 24 }, (_, index) => new Hour(index));
54
+ return Array.from({ length: 24 }, (_, index) => Hour.fromValue(index));
46
55
  }
47
56
 
48
57
  toString(): string {
package/src/index.ts CHANGED
@@ -11,6 +11,8 @@ export * from "./day.vo";
11
11
  export * from "./day-iso-id.vo";
12
12
  export * from "./directory-path-absolute.vo";
13
13
  export * from "./directory-path-relative.vo";
14
+ export * from "./distance.vo";
15
+ export * from "./distance-value.vo";
14
16
  export * from "./division-factor.vo";
15
17
  export * from "./dll.service";
16
18
  export * from "./duration.service";
package/src/minute.vo.ts CHANGED
@@ -3,23 +3,32 @@ import { Timestamp } from "./timestamp.vo";
3
3
  import type { TimestampValueType } from "./timestamp-value.vo";
4
4
 
5
5
  export class Minute {
6
- private readonly value: MinuteSchemaType;
6
+ private constructor(private readonly value: MinuteSchemaType) {}
7
7
 
8
- static readonly ZERO = new Minute(0);
9
- static readonly MAX = new Minute(59);
8
+ static fromValue(candidate: number): Minute {
9
+ return new Minute(MinuteSchema.parse(candidate));
10
+ }
10
11
 
11
- constructor(candidate: number) {
12
- this.value = MinuteSchema.parse(candidate);
12
+ static fromValueSafe(candidate: MinuteSchemaType) {
13
+ return new Minute(candidate);
13
14
  }
14
15
 
15
16
  static fromTimestamp(timestamp: Timestamp): Minute {
16
- return new Minute(new Date(timestamp.ms).getUTCMinutes());
17
+ return new Minute(MinuteSchema.parse(new Date(timestamp.ms).getUTCMinutes()));
17
18
  }
18
19
 
19
20
  static fromTimestampValue(timestamp: TimestampValueType): Minute {
20
21
  return Minute.fromTimestamp(Timestamp.fromValue(timestamp));
21
22
  }
22
23
 
24
+ static zero(): Minute {
25
+ return Minute.fromValue(0);
26
+ }
27
+
28
+ static max(): Minute {
29
+ return Minute.fromValue(59);
30
+ }
31
+
23
32
  get(): MinuteSchemaType {
24
33
  return this.value;
25
34
  }
@@ -37,7 +46,7 @@ export class Minute {
37
46
  }
38
47
 
39
48
  static list(): readonly Minute[] {
40
- return Array.from({ length: 60 }, (_, index) => new Minute(index));
49
+ return Array.from({ length: 60 }, (_, index) => Minute.fromValue(index));
41
50
  }
42
51
 
43
52
  toString(): string {
package/src/money.vo.ts CHANGED
@@ -7,15 +7,23 @@ import type { RoundingPort } from "./rounding.port";
7
7
  export const MoneyError = { SubtractResultLessThanZero: "money.subtract.result.less.than.zero" } as const;
8
8
 
9
9
  export class Money {
10
- private static readonly ZERO = 0;
11
- private static readonly DEFAULT_ROUNDING: RoundingPort = new RoundToNearest();
10
+ private static readonly ZERO = MoneyAmount.parse(0);
12
11
 
13
- private readonly amount: MoneyAmountType;
14
- private readonly rounding: RoundingPort;
12
+ private constructor(
13
+ private readonly amount: MoneyAmountType,
14
+ private readonly rounding: RoundingPort = new RoundToNearest(),
15
+ ) {}
15
16
 
16
- constructor(value: number = Money.ZERO, rounding?: RoundingPort) {
17
- this.amount = MoneyAmount.parse(value);
18
- this.rounding = rounding ?? Money.DEFAULT_ROUNDING;
17
+ static fromAmount(candidate: number, rounding?: RoundingPort): Money {
18
+ return new Money(MoneyAmount.parse(candidate), rounding);
19
+ }
20
+
21
+ static fromAmountSafe(candidate: MoneyAmountType, rounding?: RoundingPort): Money {
22
+ return new Money(candidate, rounding);
23
+ }
24
+
25
+ static zero(): Money {
26
+ return Money.fromAmount(0);
19
27
  }
20
28
 
21
29
  getAmount(): MoneyAmountType {
@@ -23,28 +31,22 @@ export class Money {
23
31
  }
24
32
 
25
33
  add(money: Money): Money {
26
- const result = this.amount + money.getAmount();
27
-
28
- return new Money(MoneyAmount.parse(result), this.rounding);
34
+ return new Money(MoneyAmount.parse(this.amount + money.getAmount()), this.rounding);
29
35
  }
30
36
 
31
37
  multiply(factor: MultiplicationFactorType): Money {
32
- const result = this.rounding.round(this.amount * factor);
33
-
34
- return new Money(MoneyAmount.parse(result), this.rounding);
38
+ return new Money(MoneyAmount.parse(this.rounding.round(this.amount * factor)), this.rounding);
35
39
  }
36
40
 
37
41
  subtract(money: Money): Money {
38
42
  const result = this.amount - money.getAmount();
39
43
 
40
44
  if (result < Money.ZERO) throw new Error(MoneyError.SubtractResultLessThanZero);
41
- return new Money(MoneyAmount.parse(result), this.rounding);
45
+ return new Money(MoneyAmount.parse(this.rounding.round(result)), this.rounding);
42
46
  }
43
47
 
44
48
  divide(factor: DivisionFactorType): Money {
45
- const result = this.rounding.round(this.amount / factor);
46
-
47
- return new Money(MoneyAmount.parse(result), this.rounding);
49
+ return new Money(MoneyAmount.parse(this.rounding.round(this.amount / factor)), this.rounding);
48
50
  }
49
51
 
50
52
  equals(another: Money): boolean {
@@ -1,4 +1,4 @@
1
- import { PackageVersionSchema } from "./package-version-schema.vo";
1
+ import { PackageVersionSchema, type PackageVersionSchemaType } from "./package-version-schema.vo";
2
2
 
3
3
  export class PackageVersion {
4
4
  constructor(
@@ -7,12 +7,16 @@ export class PackageVersion {
7
7
  private readonly patch: number,
8
8
  ) {}
9
9
 
10
- static fromStringWithV(candidate: string): PackageVersion {
10
+ static fromVersionString(candidate: string): PackageVersion {
11
11
  const version = PackageVersionSchema.parse(candidate);
12
12
 
13
13
  return new PackageVersion(version.major, version.minor, version.patch);
14
14
  }
15
15
 
16
+ static fromVersionStringSafe(candidate: PackageVersionSchemaType): PackageVersion {
17
+ return new PackageVersion(candidate.major, candidate.minor, candidate.patch);
18
+ }
19
+
16
20
  static fromString(candidate: string): PackageVersion {
17
21
  const version = PackageVersionSchema.parse(`v${candidate}`);
18
22
 
package/src/size.vo.ts CHANGED
@@ -21,7 +21,7 @@ export class Size {
21
21
  private static readonly CONVERT_ROUND = new RoundUp();
22
22
  private static readonly FORMAT_ROUND = new RoundToDecimal(2);
23
23
 
24
- constructor(config: SizeConfigType) {
24
+ private constructor(config: SizeConfigType) {
25
25
  this.unit = config.unit;
26
26
  this.bytes = this.calculateBytes(config.value, config.unit);
27
27
  }