@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
@@ -1,5 +1,4 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
3
  export const Timestamp = z.number().int().gte(0).brand("Timestamp");
4
-
5
4
  export type TimestampType = z.infer<typeof Timestamp>;
@@ -6,22 +6,15 @@ export const Timezone = z
6
6
  .refine(
7
7
  (value) => {
8
8
  try {
9
- // Create a dummy date and time format using the specified timezone
10
- const dummyDate = new Date();
9
+ const date = new Date();
11
10
  const formatter = new Intl.DateTimeFormat("en-US", { timeZone: value });
12
-
13
- // Format the dummy date
14
- formatter.format(dummyDate);
15
-
16
- // If the formatting succeeds without throwing an error, the timezone is valid
11
+ formatter.format(date);
17
12
  return true;
18
13
  } catch (_error) {
19
- // An error occurred, indicating an invalid timezone
20
14
  return false;
21
15
  }
22
16
  },
23
17
  { message: "timezone.invalid" },
24
18
  )
25
19
  .brand("Timezone");
26
-
27
20
  export type TimezoneType = z.infer<typeof Timezone>;
package/src/ts-utils.ts CHANGED
@@ -1,5 +1,3 @@
1
1
  export type Constructor<T> = new (...args: any[]) => T;
2
-
3
2
  export type Falsy<T> = T | null | undefined;
4
-
5
3
  export type Nullable<T> = T | null;
@@ -1,6 +1,7 @@
1
1
  import { Random } from "./random.service";
2
2
 
3
3
  export class VisuallyUnambiguousCharactersGenerator {
4
+ // prettier-ignore
4
5
  static chars = [
5
6
  "a",
6
7
  "b",
@@ -31,10 +32,7 @@ export class VisuallyUnambiguousCharactersGenerator {
31
32
  .map(
32
33
  () =>
33
34
  VisuallyUnambiguousCharactersGenerator.chars[
34
- Random.generate({
35
- min: 0,
36
- max: VisuallyUnambiguousCharactersGenerator.chars.length - 1,
37
- })
35
+ Random.generate({ min: 0, max: VisuallyUnambiguousCharactersGenerator.chars.length - 1 })
38
36
  ],
39
37
  )
40
38
  .join("");
@@ -20,5 +20,4 @@ export const WeekIsoId = z
20
20
  },
21
21
  { message: "week-iso-id.invalid" },
22
22
  );
23
-
24
23
  export type WeekIsoIdType = z.infer<typeof WeekIsoId>;
@@ -0,0 +1,101 @@
1
+ import type { TimestampType } from "./timestamp.vo";
2
+
3
+ export type WeekdayFormatter = (value: Weekday["value"]) => string;
4
+
5
+ export enum WeekdayFormatterEnum {
6
+ FULL = "FULL", // "Sunday"
7
+ SHORT = "SHORT", // "Sun"
8
+ ISO_NUMBER = "ISO_NUMBER", // Monday=1 ... Sunday=7
9
+ ZERO_BASED_NUMBER = "ZERO_BASED_NUMBER", // Sunday=0 ... Saturday=6 (JS)
10
+ }
11
+
12
+ const FULL_NAMES: readonly string[] = [
13
+ "Sunday",
14
+ "Monday",
15
+ "Tuesday",
16
+ "Wednesday",
17
+ "Thursday",
18
+ "Friday",
19
+ "Saturday",
20
+ ] as const;
21
+
22
+ const SHORT_NAMES: readonly string[] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] as const;
23
+
24
+ export const WeekdayFormatters: Record<WeekdayFormatterEnum, WeekdayFormatter> = {
25
+ FULL: (value) => FULL_NAMES[value],
26
+ SHORT: (value) => SHORT_NAMES[value],
27
+ ISO_NUMBER: (value) => (value === 0 ? 7 : value).toString(), // ISO-8601: Mon=1..Sun=7
28
+ ZERO_BASED_NUMBER: (value) => value.toString(), // JS getUTCDay(): Sun=0..Sat=6
29
+ } as const;
30
+
31
+ export class Weekday {
32
+ private readonly value: number;
33
+
34
+ private readonly formatter: WeekdayFormatter;
35
+
36
+ static readonly SUNDAY = new Weekday(0);
37
+ static readonly MONDAY = new Weekday(1);
38
+ static readonly TUESDAY = new Weekday(2);
39
+ static readonly WEDNESDAY = new Weekday(3);
40
+ static readonly THURSDAY = new Weekday(4);
41
+ static readonly FRIDAY = new Weekday(5);
42
+ static readonly SATURDAY = new Weekday(6);
43
+
44
+ constructor(candidate: number, formatter?: WeekdayFormatter) {
45
+ if (!Number.isInteger(candidate)) throw new Error("Invalid weekday");
46
+ if (candidate < 0) throw new Error("Invalid weekday");
47
+ if (candidate > 6) throw new Error("Invalid weekday");
48
+
49
+ this.value = candidate;
50
+ this.formatter = (formatter as WeekdayFormatter) ?? WeekdayFormatters.FULL;
51
+ }
52
+
53
+ static fromUtcTimestamp(timestamp: TimestampType, formatter?: WeekdayFormatter): Weekday {
54
+ const day = new Date(timestamp).getUTCDay(); // 0..6
55
+ return new Weekday(day, formatter);
56
+ }
57
+
58
+ get(formatter?: WeekdayFormatter) {
59
+ const format = formatter ?? this.formatter;
60
+ return { raw: this.value, formatted: format(this.value) };
61
+ }
62
+
63
+ equals(another: Weekday): boolean {
64
+ return this.value === another.get().raw;
65
+ }
66
+
67
+ toIsoNumber(): number {
68
+ return this.value === 0 ? 7 : this.value;
69
+ }
70
+
71
+ isMonday(): boolean {
72
+ return this.value === 1;
73
+ }
74
+ isTuesday(): boolean {
75
+ return this.value === 2;
76
+ }
77
+ isWednesday(): boolean {
78
+ return this.value === 3;
79
+ }
80
+ isThursday(): boolean {
81
+ return this.value === 4;
82
+ }
83
+ isFriday(): boolean {
84
+ return this.value === 5;
85
+ }
86
+ isSaturday(): boolean {
87
+ return this.value === 6;
88
+ }
89
+ isSunday(): boolean {
90
+ return this.value === 0;
91
+ }
92
+
93
+ static list(formatter?: WeekdayFormatter): Weekday[] {
94
+ return Array.from({ length: 7 }).map((_, index) => new Weekday(index, formatter));
95
+ }
96
+
97
+ static listMondayFirst(formatter?: WeekdayFormatter): Weekday[] {
98
+ const days = Weekday.list(formatter);
99
+ return [...days.slice(1), days[0]];
100
+ }
101
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const YearIsoId = z
4
+ .string()
5
+ .regex(/^\d{4}$/)
6
+ .refine(
7
+ (value) => {
8
+ const year = Number(value);
9
+ return value.length === 4 && Number.isInteger(year);
10
+ },
11
+ { message: "year-iso-id.invalid" },
12
+ );
13
+ export type YearIsoIdType = z.infer<typeof YearIsoId>;
package/src/year.vo.ts ADDED
@@ -0,0 +1,36 @@
1
+ import { endOfYear, getYear, startOfYear } from "date-fns";
2
+ import { DateRange } from "./date-range.vo";
3
+ import { Timestamp, type TimestampType } from "./timestamp.vo";
4
+ import { YearIsoId, type YearIsoIdType } from "./year-iso-id.vo";
5
+
6
+ export class Year extends DateRange {
7
+ toIsoId(): YearIsoIdType {
8
+ return String(getYear(this.getStart())) as YearIsoIdType;
9
+ }
10
+
11
+ isLeapYear(): boolean {
12
+ const year = getYear(this.getStart());
13
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
14
+ }
15
+
16
+ static fromTimestamp(timestamp: TimestampType): Year {
17
+ const start = Timestamp.parse(startOfYear(timestamp).getTime());
18
+ const end = Timestamp.parse(endOfYear(timestamp).getTime());
19
+ return new Year(start, end);
20
+ }
21
+
22
+ static fromNow(now: TimestampType): Year {
23
+ return Year.fromTimestamp(now);
24
+ }
25
+
26
+ static fromNumber(value: number): Year {
27
+ if (!Number.isInteger(value)) throw new Error("year.invalid_integer");
28
+ if (value < 0 || value > 9999) throw new Error("year.out_of_range");
29
+ const reference = Timestamp.parse(Date.UTC(value, 0, 1, 0, 0, 0, 0));
30
+ return Year.fromTimestamp(reference);
31
+ }
32
+
33
+ static fromIsoId(isoId: YearIsoIdType): Year {
34
+ return Year.fromNumber(Number(YearIsoId.parse(isoId)));
35
+ }
36
+ }
@@ -10,9 +10,7 @@ export class ZScore {
10
10
  values: number[],
11
11
  private readonly rounding: RoundingStrategy = new RoundToDecimal(2),
12
12
  ) {
13
- if (values.length < 2) {
14
- throw new Error("At least two values are needed");
15
- }
13
+ if (values.length < 2) throw new Error("At least two values are needed");
16
14
 
17
15
  this.mean = Mean.calculate(values);
18
16
  this.standardDeviation = PopulationStandardDeviation.calculate(values);
@@ -1,3 +0,0 @@
1
- import { z } from "zod/v4";
2
- export declare const BuildVersion: z.core.$ZodBranded<z.ZodString, "BuildVersion">;
3
- export type BuildVersionType = z.infer<typeof BuildVersion>;
@@ -1,2 +0,0 @@
1
- import { z } from "zod/v4";
2
- export const BuildVersion = z.string().min(1).max(8).brand("BuildVersion");
@@ -1,17 +0,0 @@
1
- import type { z } from "zod/v4";
2
- export type DefaultFilterSchemaType = z.ZodRawShape;
3
- export type FilterValuesType = Record<string, unknown>;
4
- export type FilterSchemaType<T extends DefaultFilterSchemaType> = z.ZodObject<T>;
5
- export type FilterParseConfigType<T extends DefaultFilterSchemaType> = {
6
- schema: FilterSchemaType<T>;
7
- values: FilterValuesType;
8
- };
9
- export declare class Filter<T extends DefaultFilterSchemaType> {
10
- private readonly schema;
11
- constructor(schema: FilterSchemaType<T>);
12
- parse(values: FilterValuesType): z.core.$InferObjectOutput<T, {}> | undefined;
13
- default(): z.core.$InferObjectOutput<T, {}> | undefined;
14
- static parse<T extends DefaultFilterSchemaType>(config: FilterParseConfigType<T>): z.core.$InferObjectOutput<T, {}> | undefined;
15
- static default<T extends DefaultFilterSchemaType>(config: Omit<FilterParseConfigType<T>, "values">): z.core.$InferObjectOutput<T, {}> | undefined;
16
- private static _parse;
17
- }
package/dist/filter.vo.js DELETED
@@ -1,22 +0,0 @@
1
- export class Filter {
2
- schema;
3
- constructor(schema) {
4
- this.schema = schema;
5
- }
6
- parse(values) {
7
- return Filter._parse({ schema: this.schema, values });
8
- }
9
- default() {
10
- return this.parse({});
11
- }
12
- static parse(config) {
13
- return Filter._parse(config);
14
- }
15
- static default(config) {
16
- return Filter._parse({ schema: config.schema, values: {} });
17
- }
18
- static _parse(config) {
19
- const result = config.schema.safeParse(config.values);
20
- return result.success ? result.data : undefined;
21
- }
22
- }
@@ -1,4 +0,0 @@
1
- export declare class LeapYearChecker {
2
- static isLeapYear(year: number): boolean;
3
- static isCurrentYearLeapYear(): boolean;
4
- }
@@ -1,9 +0,0 @@
1
- export class LeapYearChecker {
2
- static isLeapYear(year) {
3
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
4
- }
5
- static isCurrentYearLeapYear() {
6
- const year = new Date().getFullYear();
7
- return LeapYearChecker.isLeapYear(year);
8
- }
9
- }
@@ -1,5 +0,0 @@
1
- import { z } from "zod/v4";
2
-
3
- export const BuildVersion = z.string().min(1).max(8).brand("BuildVersion");
4
-
5
- export type BuildVersionType = z.infer<typeof BuildVersion>;
package/src/filter.vo.ts DELETED
@@ -1,38 +0,0 @@
1
- import type { z } from "zod/v4";
2
-
3
- export type DefaultFilterSchemaType = z.ZodRawShape;
4
-
5
- export type FilterValuesType = Record<string, unknown>;
6
-
7
- export type FilterSchemaType<T extends DefaultFilterSchemaType> = z.ZodObject<T>;
8
-
9
- export type FilterParseConfigType<T extends DefaultFilterSchemaType> = {
10
- schema: FilterSchemaType<T>;
11
- values: FilterValuesType;
12
- };
13
-
14
- export class Filter<T extends DefaultFilterSchemaType> {
15
- constructor(private readonly schema: FilterSchemaType<T>) {}
16
-
17
- parse(values: FilterValuesType) {
18
- return Filter._parse({ schema: this.schema, values });
19
- }
20
-
21
- default() {
22
- return this.parse({});
23
- }
24
-
25
- static parse<T extends DefaultFilterSchemaType>(config: FilterParseConfigType<T>) {
26
- return Filter._parse(config);
27
- }
28
-
29
- static default<T extends DefaultFilterSchemaType>(config: Omit<FilterParseConfigType<T>, "values">) {
30
- return Filter._parse({ schema: config.schema, values: {} });
31
- }
32
-
33
- private static _parse<T extends DefaultFilterSchemaType>(config: FilterParseConfigType<T>) {
34
- const result = config.schema.safeParse(config.values);
35
-
36
- return result.success ? result.data : undefined;
37
- }
38
- }
@@ -1,11 +0,0 @@
1
- export class LeapYearChecker {
2
- static isLeapYear(year: number): boolean {
3
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
4
- }
5
-
6
- static isCurrentYearLeapYear(): boolean {
7
- const year = new Date().getFullYear();
8
-
9
- return LeapYearChecker.isLeapYear(year);
10
- }
11
- }