@bgord/tools 0.12.25 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clock.vo.d.ts +4 -2
- package/dist/clock.vo.js +7 -1
- package/dist/hour.vo.d.ts +2 -0
- package/dist/hour.vo.js +11 -11
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/mean.service.js +1 -2
- package/dist/mime.vo.js +2 -4
- package/dist/min-max-scaler.service.js +5 -10
- package/dist/minute.vo.d.ts +1 -0
- package/dist/minute.vo.js +8 -10
- package/dist/money.vo.js +2 -4
- package/dist/outlier-detector.service.js +1 -2
- package/dist/percentage.service.js +1 -2
- package/dist/population-standard-deviation.service.js +1 -2
- package/dist/random.service.js +4 -8
- package/dist/rate-limiter.service.js +1 -4
- package/dist/relative-date.vo.js +1 -4
- package/dist/reordering.service.js +3 -6
- package/dist/revision.vo.js +2 -4
- package/dist/simple-linear-regression.service.js +6 -12
- package/dist/stepper.service.js +2 -4
- package/dist/stopwatch.service.js +1 -2
- package/dist/timezone.vo.js +2 -6
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/visually-unambiguous-characters-generator.service.js +1 -4
- package/dist/weekday.vo.d.ts +40 -0
- package/dist/weekday.vo.js +95 -0
- package/dist/z-score.service.js +1 -2
- package/package.json +6 -6
- package/readme.md +1 -2
- package/src/clock.vo.ts +9 -2
- package/src/hour.vo.ts +15 -13
- package/src/index.ts +1 -2
- package/src/mean.service.ts +1 -3
- package/src/mime.vo.ts +2 -9
- package/src/min-max-scaler.service.ts +5 -16
- package/src/minute.vo.ts +9 -15
- package/src/money.vo.ts +2 -6
- package/src/outlier-detector.service.ts +1 -3
- package/src/percentage.service.ts +1 -5
- package/src/population-standard-deviation.service.ts +1 -3
- package/src/random.service.ts +5 -19
- package/src/rate-limiter.service.ts +2 -11
- package/src/relative-date.vo.ts +1 -4
- package/src/reordering.service.ts +5 -13
- package/src/revision.vo.ts +2 -6
- package/src/simple-linear-regression.service.ts +6 -19
- package/src/stepper.service.ts +2 -8
- package/src/stopwatch.service.ts +1 -3
- package/src/timezone.vo.ts +2 -8
- package/src/visually-unambiguous-characters-generator.service.ts +1 -4
- package/src/weekday.vo.ts +113 -0
- package/src/z-score.service.ts +1 -3
- package/dist/build-version.vo.d.ts +0 -3
- package/dist/build-version.vo.js +0 -2
- package/dist/filter.vo.d.ts +0 -17
- package/dist/filter.vo.js +0 -22
- package/src/build-version.vo.ts +0 -5
- package/src/filter.vo.ts +0 -38
package/dist/z-score.service.js
CHANGED
|
@@ -7,9 +7,8 @@ export class ZScore {
|
|
|
7
7
|
standardDeviation;
|
|
8
8
|
constructor(values, rounding = new RoundToDecimal(2)) {
|
|
9
9
|
this.rounding = rounding;
|
|
10
|
-
if (values.length < 2)
|
|
10
|
+
if (values.length < 2)
|
|
11
11
|
throw new Error("At least two values are needed");
|
|
12
|
-
}
|
|
13
12
|
this.mean = Mean.calculate(values);
|
|
14
13
|
this.standardDeviation = PopulationStandardDeviation.calculate(values);
|
|
15
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bartosz Gordon",
|
|
@@ -21,25 +21,25 @@
|
|
|
21
21
|
"preinstall": "bunx only-allow bun"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@biomejs/biome": "2.2.
|
|
24
|
+
"@biomejs/biome": "2.2.4",
|
|
25
25
|
"@commitlint/cli": "19.8.1",
|
|
26
26
|
"@commitlint/config-conventional": "19.8.1",
|
|
27
|
-
"@types/bun": "1.2.
|
|
27
|
+
"@types/bun": "1.2.22",
|
|
28
28
|
"@types/mime-types": "3.0.1",
|
|
29
29
|
"cspell": "9.2.1",
|
|
30
30
|
"knip": "5.63.1",
|
|
31
|
-
"lefthook": "1.
|
|
31
|
+
"lefthook": "1.13.0",
|
|
32
32
|
"only-allow": "1.2.1",
|
|
33
33
|
"shellcheck": "4.1.0",
|
|
34
34
|
"typescript": "5.9.2",
|
|
35
|
-
"zod": "4.1.
|
|
35
|
+
"zod": "4.1.8"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"date-fns": "4.1.0",
|
|
39
39
|
"mime-types": "3.0.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"zod": "4.1.
|
|
42
|
+
"zod": "4.1.8"
|
|
43
43
|
},
|
|
44
44
|
"sideEffects": false
|
|
45
45
|
}
|
package/readme.md
CHANGED
|
@@ -26,7 +26,6 @@ Run the tests
|
|
|
26
26
|
src/
|
|
27
27
|
├── api-key.vo.ts
|
|
28
28
|
├── basename.vo.ts
|
|
29
|
-
├── build-version.vo.ts
|
|
30
29
|
├── clock.vo.ts
|
|
31
30
|
├── date-calculator.service.ts
|
|
32
31
|
├── date-formatter.service.ts
|
|
@@ -47,7 +46,6 @@ src/
|
|
|
47
46
|
├── filename-from-string.vo.ts
|
|
48
47
|
├── filename-suffix.vo.ts
|
|
49
48
|
├── filename.vo.ts
|
|
50
|
-
├── filter.vo.ts
|
|
51
49
|
├── hour.vo.ts
|
|
52
50
|
├── iban-mask.service.ts
|
|
53
51
|
├── iban.vo.ts
|
|
@@ -89,6 +87,7 @@ src/
|
|
|
89
87
|
├── visually-unambiguous-characters-generator.service.ts
|
|
90
88
|
├── week-iso-id.vo.ts
|
|
91
89
|
├── week.vo.ts
|
|
90
|
+
├── weekday.vo.ts
|
|
92
91
|
└── z-score.service.ts
|
|
93
92
|
```
|
|
94
93
|
|
package/src/clock.vo.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { Hour, HourFormatters } from "./hour.vo";
|
|
2
|
+
import { Minute } from "./minute.vo";
|
|
3
|
+
import type { TimestampType } from "./timestamp.vo";
|
|
3
4
|
|
|
4
5
|
export type ClockFormatter = (hour: Hour, minute: Minute) => string;
|
|
5
6
|
|
|
@@ -26,6 +27,12 @@ export class Clock {
|
|
|
26
27
|
this.formatter = (formatter as ClockFormatter) ?? ClockFormatters.TWENTY_FOUR_HOURS;
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
static fromUtcTimestamp(timestamp: TimestampType, formatter?: ClockFormatter) {
|
|
31
|
+
const hour = Hour.fromUtcTimestamp(timestamp);
|
|
32
|
+
const minute = Minute.fromUtcTimestamp(timestamp);
|
|
33
|
+
return new Clock(hour, minute, formatter);
|
|
34
|
+
}
|
|
35
|
+
|
|
29
36
|
get(formatter?: ClockFormatter) {
|
|
30
37
|
const format = formatter ?? this.formatter;
|
|
31
38
|
|
package/src/hour.vo.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { TimestampType } from "./timestamp.vo";
|
|
2
|
+
|
|
1
3
|
export type HourFormatter = (value: Hour["value"]) => string;
|
|
2
4
|
|
|
3
5
|
export enum HourFormatterEnum {
|
|
@@ -14,13 +16,13 @@ export const HourFormatters: Record<HourFormatterEnum, HourFormatter> = {
|
|
|
14
16
|
TWENTY_FOUR_HOURS_WO_PADDING: (value) => value.toString(),
|
|
15
17
|
|
|
16
18
|
AM_PM: (value) => {
|
|
17
|
-
|
|
18
|
-
return `${
|
|
19
|
+
const twelveHour = value % 12 || 12;
|
|
20
|
+
return `${twelveHour.toString()} ${value < 12 ? "a.m." : "p.m."}`;
|
|
19
21
|
},
|
|
20
22
|
|
|
21
|
-
TWELVE_HOURS: (value) => (value % 12).toString().padStart(2, "0"),
|
|
23
|
+
TWELVE_HOURS: (value) => (value % 12 || 12).toString().padStart(2, "0"),
|
|
22
24
|
|
|
23
|
-
TWELVE_HOURS_WO_PADDING: (value) => (value % 12).toString(),
|
|
25
|
+
TWELVE_HOURS_WO_PADDING: (value) => (value % 12 || 12).toString(),
|
|
24
26
|
} as const;
|
|
25
27
|
|
|
26
28
|
export class Hour {
|
|
@@ -33,15 +35,9 @@ export class Hour {
|
|
|
33
35
|
static readonly MAX = new Hour(23);
|
|
34
36
|
|
|
35
37
|
constructor(candidate: number, formatter?: HourFormatter) {
|
|
36
|
-
if (!Number.isInteger(candidate))
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (candidate < 0) {
|
|
40
|
-
throw new Error("Invalid hour");
|
|
41
|
-
}
|
|
42
|
-
if (candidate >= 24) {
|
|
43
|
-
throw new Error("Invalid hour");
|
|
44
|
-
}
|
|
38
|
+
if (!Number.isInteger(candidate)) throw new Error("Invalid hour");
|
|
39
|
+
if (candidate < 0) throw new Error("Invalid hour");
|
|
40
|
+
if (candidate >= 24) throw new Error("Invalid hour");
|
|
45
41
|
|
|
46
42
|
this.value = candidate;
|
|
47
43
|
this.formatter = (formatter as HourFormatter) ?? HourFormatters.TWENTY_FOUR_HOURS;
|
|
@@ -65,6 +61,12 @@ export class Hour {
|
|
|
65
61
|
return this.value < another.get().raw;
|
|
66
62
|
}
|
|
67
63
|
|
|
64
|
+
static fromUtcTimestamp(timestamp: TimestampType, formatter?: HourFormatter): Hour {
|
|
65
|
+
const hours = new Date(timestamp).getUTCHours();
|
|
66
|
+
|
|
67
|
+
return new Hour(hours, formatter);
|
|
68
|
+
}
|
|
69
|
+
|
|
68
70
|
static list(formatter?: HourFormatter) {
|
|
69
71
|
return Array.from({ length: 24 }).map((_, index) => new Hour(index, formatter));
|
|
70
72
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from "./api-key.vo";
|
|
2
2
|
export * from "./basename.vo";
|
|
3
|
-
export * from "./build-version.vo";
|
|
4
3
|
export * from "./clock.vo";
|
|
5
4
|
export * from "./date-calculator.service";
|
|
6
5
|
export * from "./date-formatter.service";
|
|
@@ -21,7 +20,6 @@ export * from "./file-path-relative-schema.vo";
|
|
|
21
20
|
export * from "./filename.vo";
|
|
22
21
|
export * from "./filename-from-string.vo";
|
|
23
22
|
export * from "./filename-suffix.vo";
|
|
24
|
-
export * from "./filter.vo";
|
|
25
23
|
export * from "./hour.vo";
|
|
26
24
|
export * from "./iban.vo";
|
|
27
25
|
export * from "./iban-mask.service";
|
|
@@ -63,4 +61,5 @@ export * from "./ts-utils";
|
|
|
63
61
|
export * from "./visually-unambiguous-characters-generator.service";
|
|
64
62
|
export * from "./week.vo";
|
|
65
63
|
export * from "./week-iso-id.vo";
|
|
64
|
+
export * from "./weekday.vo";
|
|
66
65
|
export * from "./z-score.service";
|
package/src/mean.service.ts
CHANGED
|
@@ -3,9 +3,7 @@ import { Sum } from "./sum.service";
|
|
|
3
3
|
|
|
4
4
|
export class Mean {
|
|
5
5
|
static calculate(values: number[], rounding: RoundingStrategy = new RoundToDecimal(2)): number {
|
|
6
|
-
if (values.length === 0)
|
|
7
|
-
throw new Error("Values should not be empty");
|
|
8
|
-
}
|
|
6
|
+
if (values.length === 0) throw new Error("Values should not be empty");
|
|
9
7
|
|
|
10
8
|
const mean = Sum.of(values) / values.length;
|
|
11
9
|
|
package/src/mime.vo.ts
CHANGED
|
@@ -2,9 +2,7 @@ import * as mime from "mime-types";
|
|
|
2
2
|
import { ExtensionSchema, type ExtensionType } from "./extension.vo";
|
|
3
3
|
|
|
4
4
|
export type MimeRawType = string;
|
|
5
|
-
|
|
6
5
|
type MimeTypeType = string;
|
|
7
|
-
|
|
8
6
|
type MimeSubtypeType = string;
|
|
9
7
|
|
|
10
8
|
export class Mime {
|
|
@@ -15,13 +13,8 @@ export class Mime {
|
|
|
15
13
|
constructor(value: MimeRawType) {
|
|
16
14
|
const [type, subtype] = value.split("/");
|
|
17
15
|
|
|
18
|
-
if (typeof type !== "string" || type.length === 0)
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (typeof subtype !== "string" || subtype.length === 0) {
|
|
23
|
-
throw new InvalidMimeError();
|
|
24
|
-
}
|
|
16
|
+
if (typeof type !== "string" || type.length === 0) throw new InvalidMimeError();
|
|
17
|
+
if (typeof subtype !== "string" || subtype.length === 0) throw new InvalidMimeError();
|
|
25
18
|
|
|
26
19
|
this.raw = value;
|
|
27
20
|
this.type = type;
|
|
@@ -26,13 +26,8 @@ export class MinMaxScaler {
|
|
|
26
26
|
const lower = config.bound?.lower ?? 0;
|
|
27
27
|
const upper = config.bound?.upper ?? 1;
|
|
28
28
|
|
|
29
|
-
if (config.max - config.min < 0)
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (upper - lower <= 0) {
|
|
34
|
-
throw new Error("Invalid MinMaxScaler bound config");
|
|
35
|
-
}
|
|
29
|
+
if (config.max - config.min < 0) throw new Error("Invalid MinMaxScaler min-max config");
|
|
30
|
+
if (upper - lower <= 0) throw new Error("Invalid MinMaxScaler bound config");
|
|
36
31
|
|
|
37
32
|
this.rounding = rounding;
|
|
38
33
|
|
|
@@ -45,9 +40,7 @@ export class MinMaxScaler {
|
|
|
45
40
|
scale(value: MinMaxScalerValueType) {
|
|
46
41
|
const { min, max, lower, upper } = this;
|
|
47
42
|
|
|
48
|
-
if (value < min || value > max)
|
|
49
|
-
throw new Error("Value out of min/max range");
|
|
50
|
-
}
|
|
43
|
+
if (value < min || value > max) throw new Error("Value out of min/max range");
|
|
51
44
|
|
|
52
45
|
if (min === max)
|
|
53
46
|
return {
|
|
@@ -70,9 +63,7 @@ export class MinMaxScaler {
|
|
|
70
63
|
descale(scaled: MinMaxScalerValueType) {
|
|
71
64
|
const { min, max, lower, upper } = this;
|
|
72
65
|
|
|
73
|
-
if (scaled < lower || scaled > upper)
|
|
74
|
-
throw new Error("Scaled value out of bounds");
|
|
75
|
-
}
|
|
66
|
+
if (scaled < lower || scaled > upper) throw new Error("Scaled value out of bounds");
|
|
76
67
|
|
|
77
68
|
const result = ((scaled - lower) / (upper - lower)) * (max - min) + min;
|
|
78
69
|
|
|
@@ -85,9 +76,7 @@ export class MinMaxScaler {
|
|
|
85
76
|
}
|
|
86
77
|
|
|
87
78
|
static getMinMax(values: MinMaxScalerValueType[]) {
|
|
88
|
-
if (values.length === 0)
|
|
89
|
-
throw new Error("An empty array supplied");
|
|
90
|
-
}
|
|
79
|
+
if (values.length === 0) throw new Error("An empty array supplied");
|
|
91
80
|
|
|
92
81
|
return { min: Math.min(...values), max: Math.max(...values) };
|
|
93
82
|
}
|
package/src/minute.vo.ts
CHANGED
|
@@ -6,26 +6,20 @@ export class Minute {
|
|
|
6
6
|
static readonly MAX = new Minute(59);
|
|
7
7
|
|
|
8
8
|
constructor(candidate: number) {
|
|
9
|
-
if (!Number.isInteger(candidate))
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (candidate < 0) {
|
|
14
|
-
throw new Error("Invalid minute");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (candidate >= 60) {
|
|
18
|
-
throw new Error("Invalid minute");
|
|
19
|
-
}
|
|
9
|
+
if (!Number.isInteger(candidate)) throw new Error("Invalid minute");
|
|
10
|
+
if (candidate < 0) throw new Error("Invalid minute");
|
|
11
|
+
if (candidate >= 60) throw new Error("Invalid minute");
|
|
20
12
|
|
|
21
13
|
this.value = candidate;
|
|
22
14
|
}
|
|
23
15
|
|
|
16
|
+
static fromUtcTimestamp(timestamp: number): Minute {
|
|
17
|
+
const minutes = new Date(timestamp).getUTCMinutes();
|
|
18
|
+
return new Minute(minutes);
|
|
19
|
+
}
|
|
20
|
+
|
|
24
21
|
get() {
|
|
25
|
-
return {
|
|
26
|
-
raw: this.value,
|
|
27
|
-
formatted: this.value.toString().padStart(2, "0"),
|
|
28
|
-
};
|
|
22
|
+
return { raw: this.value, formatted: this.value.toString().padStart(2, "0") };
|
|
29
23
|
}
|
|
30
24
|
|
|
31
25
|
equals(another: Minute): boolean {
|
package/src/money.vo.ts
CHANGED
|
@@ -55,17 +55,13 @@ export class Money {
|
|
|
55
55
|
subtract(money: Money) {
|
|
56
56
|
const result = this.rounding.round(this.amount - money.getAmount());
|
|
57
57
|
|
|
58
|
-
if (result < Money.ZERO)
|
|
59
|
-
throw new Error("Less than zero");
|
|
60
|
-
}
|
|
58
|
+
if (result < Money.ZERO) throw new Error("Less than zero");
|
|
61
59
|
|
|
62
60
|
return new Money(MoneyAmount.parse(result), this.rounding);
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
divide(factor: MoneyDivisionFactorType) {
|
|
66
|
-
if (factor === 0)
|
|
67
|
-
throw new Error("Cannot divide by zero");
|
|
68
|
-
}
|
|
64
|
+
if (factor === 0) throw new Error("Cannot divide by zero");
|
|
69
65
|
|
|
70
66
|
const result = this.rounding.round(this.amount / factor);
|
|
71
67
|
|
|
@@ -6,9 +6,7 @@ export class OutlierDetector {
|
|
|
6
6
|
private readonly threshold: number;
|
|
7
7
|
|
|
8
8
|
constructor(values: number[], threshold: number) {
|
|
9
|
-
if (values.length < 2)
|
|
10
|
-
throw new Error("At least two values are needed");
|
|
11
|
-
}
|
|
9
|
+
if (values.length < 2) throw new Error("At least two values are needed");
|
|
12
10
|
|
|
13
11
|
this.zScore = new ZScore(values);
|
|
14
12
|
this.threshold = Math.abs(threshold);
|
|
@@ -6,12 +6,8 @@ export class Percentage {
|
|
|
6
6
|
denominator: number,
|
|
7
7
|
rounding: RoundingStrategy = new RoundToNearest(),
|
|
8
8
|
): number {
|
|
9
|
-
if (denominator === 0)
|
|
10
|
-
throw new Error("Invalid denominator");
|
|
11
|
-
}
|
|
12
|
-
|
|
9
|
+
if (denominator === 0) throw new Error("Invalid denominator");
|
|
13
10
|
if (numerator === 0) return 0;
|
|
14
|
-
|
|
15
11
|
return rounding.round((numerator / denominator) * 100);
|
|
16
12
|
}
|
|
17
13
|
}
|
|
@@ -4,9 +4,7 @@ import { Sum } from "./sum.service";
|
|
|
4
4
|
|
|
5
5
|
export class PopulationStandardDeviation {
|
|
6
6
|
static calculate(values: number[], rounding: RoundingStrategy = new RoundToDecimal(2)): number {
|
|
7
|
-
if (values.length < 2)
|
|
8
|
-
throw new Error("At least two values are needed");
|
|
9
|
-
}
|
|
7
|
+
if (values.length < 2) throw new Error("At least two values are needed");
|
|
10
8
|
|
|
11
9
|
const mean = Mean.calculate(values);
|
|
12
10
|
const n = values.length;
|
package/src/random.service.ts
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
|
-
type RandomGenerateConfigType = {
|
|
2
|
-
min: number;
|
|
3
|
-
max: number;
|
|
4
|
-
};
|
|
1
|
+
type RandomGenerateConfigType = { min: number; max: number };
|
|
5
2
|
|
|
6
3
|
export class Random {
|
|
7
4
|
static generate(config?: RandomGenerateConfigType) {
|
|
8
5
|
const min = config?.min ?? 0;
|
|
9
6
|
const max = config?.max ?? 1;
|
|
10
7
|
|
|
11
|
-
if (!Number.isInteger(min))
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!Number.isInteger(max)) {
|
|
16
|
-
throw new Error("Maximum value is not an integer");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (min === max) {
|
|
20
|
-
throw new Error("Minimum and maximum values cannot be equal");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (min > max) {
|
|
24
|
-
throw new Error("Minimum value cannot be greater than maximum value");
|
|
25
|
-
}
|
|
8
|
+
if (!Number.isInteger(min)) throw new Error("Minimum value is not an integer");
|
|
9
|
+
if (!Number.isInteger(max)) throw new Error("Maximum value is not an integer");
|
|
10
|
+
if (min === max) throw new Error("Minimum and maximum values cannot be equal");
|
|
11
|
+
if (min > max) throw new Error("Minimum value cannot be greater than maximum value");
|
|
26
12
|
|
|
27
13
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
28
14
|
}
|
|
@@ -3,14 +3,8 @@ import { Timestamp, type TimestampType } from "./timestamp.vo";
|
|
|
3
3
|
import type { Falsy } from "./ts-utils";
|
|
4
4
|
|
|
5
5
|
type RateLimiterOptionsType = Pick<TimeResult, "ms">;
|
|
6
|
-
|
|
7
6
|
type RateLimiterResultSuccessType = { allowed: true };
|
|
8
|
-
|
|
9
|
-
type RateLimiterResultErrorType = {
|
|
10
|
-
allowed: false;
|
|
11
|
-
remainingMs: TimestampType;
|
|
12
|
-
};
|
|
13
|
-
|
|
7
|
+
type RateLimiterResultErrorType = { allowed: false; remainingMs: TimestampType };
|
|
14
8
|
type RateLimiterResultType = RateLimiterResultSuccessType | RateLimiterResultErrorType;
|
|
15
9
|
|
|
16
10
|
export class RateLimiter {
|
|
@@ -33,9 +27,6 @@ export class RateLimiter {
|
|
|
33
27
|
return { allowed: true };
|
|
34
28
|
}
|
|
35
29
|
|
|
36
|
-
return {
|
|
37
|
-
allowed: false,
|
|
38
|
-
remainingMs: Timestamp.parse(nextAllowedTimestampMs - currentTimestampMs),
|
|
39
|
-
};
|
|
30
|
+
return { allowed: false, remainingMs: Timestamp.parse(nextAllowedTimestampMs - currentTimestampMs) };
|
|
40
31
|
}
|
|
41
32
|
}
|
package/src/relative-date.vo.ts
CHANGED
|
@@ -16,9 +16,6 @@ export class RelativeDate {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
private static _format(timestampMs: TimestampType): RelativeDateType {
|
|
19
|
-
return {
|
|
20
|
-
raw: timestampMs,
|
|
21
|
-
relative: DateFormatters.relative(timestampMs),
|
|
22
|
-
};
|
|
19
|
+
return { raw: timestampMs, relative: DateFormatters.relative(timestampMs) };
|
|
23
20
|
}
|
|
24
21
|
}
|
|
@@ -63,10 +63,7 @@ export class ReorderingTransfer {
|
|
|
63
63
|
|
|
64
64
|
readonly to: ReorderingPosition;
|
|
65
65
|
|
|
66
|
-
constructor(config: {
|
|
67
|
-
id: ReorderingItem["id"];
|
|
68
|
-
to: ReorderingItemPositionValueType;
|
|
69
|
-
}) {
|
|
66
|
+
constructor(config: { id: ReorderingItem["id"]; to: ReorderingItemPositionValueType }) {
|
|
70
67
|
this.id = config.id;
|
|
71
68
|
this.to = new ReorderingPosition(config.to);
|
|
72
69
|
}
|
|
@@ -106,9 +103,8 @@ export class ReorderingCalculator {
|
|
|
106
103
|
|
|
107
104
|
delete(id: ReorderingItem["id"]) {
|
|
108
105
|
const item = this.dll.find((x) => x.data.eq(id));
|
|
109
|
-
if (!item)
|
|
110
|
-
|
|
111
|
-
}
|
|
106
|
+
if (!item) throw new Error("Cannot find Item");
|
|
107
|
+
|
|
112
108
|
this.dll.remove(item);
|
|
113
109
|
this.recalculate();
|
|
114
110
|
}
|
|
@@ -117,12 +113,8 @@ export class ReorderingCalculator {
|
|
|
117
113
|
const current = this.dll.find((node) => node.data.eq(transfer.id));
|
|
118
114
|
const target = this.dll.find((node) => node.data.position.eq(transfer.to));
|
|
119
115
|
|
|
120
|
-
if (!current)
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
if (!target) {
|
|
124
|
-
throw new Error("Cannot find target Item");
|
|
125
|
-
}
|
|
116
|
+
if (!current) throw new Error("Cannot find current Item");
|
|
117
|
+
if (!target) throw new Error("Cannot find target Item");
|
|
126
118
|
|
|
127
119
|
const direction = transfer.getDirection(current.data.position);
|
|
128
120
|
|
package/src/revision.vo.ts
CHANGED
|
@@ -31,16 +31,12 @@ export class Revision {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
static fromETag(etag: ETag | null): Revision {
|
|
34
|
-
if (!etag)
|
|
35
|
-
throw new InvalidRevisionError();
|
|
36
|
-
}
|
|
34
|
+
if (!etag) throw new InvalidRevisionError();
|
|
37
35
|
return new Revision(etag.revision);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
static fromWeakETag(weakEtag: WeakETag | null): Revision {
|
|
41
|
-
if (!weakEtag)
|
|
42
|
-
throw new InvalidRevisionError();
|
|
43
|
-
}
|
|
39
|
+
if (!weakEtag) throw new InvalidRevisionError();
|
|
44
40
|
return new Revision(weakEtag.revision);
|
|
45
41
|
}
|
|
46
42
|
}
|
|
@@ -20,9 +20,7 @@ export class SimpleLinearRegression {
|
|
|
20
20
|
static fromPairs(pairs: SLRPairType[], rounding?: RoundingStrategy) {
|
|
21
21
|
const n = pairs.length;
|
|
22
22
|
|
|
23
|
-
if (n < 2)
|
|
24
|
-
throw new Error("At least two pairs needed");
|
|
25
|
-
}
|
|
23
|
+
if (n < 2) throw new Error("At least two pairs needed");
|
|
26
24
|
|
|
27
25
|
const x = pairs.map((pair) => pair.x);
|
|
28
26
|
const y = pairs.map((pair) => pair.y);
|
|
@@ -30,30 +28,19 @@ export class SimpleLinearRegression {
|
|
|
30
28
|
const xy = pairs.map((pair) => pair.x * pair.y);
|
|
31
29
|
|
|
32
30
|
const sX = Sum.of(x);
|
|
33
|
-
if (sX >= Number.MAX_SAFE_INTEGER)
|
|
34
|
-
throw new Error("Sum of x values is too big");
|
|
35
|
-
}
|
|
31
|
+
if (sX >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x values is too big");
|
|
36
32
|
|
|
37
33
|
const sY = Sum.of(y);
|
|
38
|
-
if (sY >= Number.MAX_SAFE_INTEGER)
|
|
39
|
-
throw new Error("Sum of y values is too big");
|
|
40
|
-
}
|
|
34
|
+
if (sY >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of y values is too big");
|
|
41
35
|
|
|
42
36
|
const sSX = Sum.of(xx);
|
|
43
|
-
if (sSX >= Number.MAX_SAFE_INTEGER)
|
|
44
|
-
throw new Error("Sum of x squared values is too big");
|
|
45
|
-
}
|
|
37
|
+
if (sSX >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x squared values is too big");
|
|
46
38
|
|
|
47
39
|
const sXY = Sum.of(xy);
|
|
48
|
-
if (sXY >= Number.MAX_SAFE_INTEGER)
|
|
49
|
-
throw new Error("Sum of x times y values is too big");
|
|
50
|
-
}
|
|
40
|
+
if (sXY >= Number.MAX_SAFE_INTEGER) throw new Error("Sum of x times y values is too big");
|
|
51
41
|
|
|
52
42
|
const bDenominator = sSX - sX ** 2 / n;
|
|
53
|
-
|
|
54
|
-
if (bDenominator === 0) {
|
|
55
|
-
throw new Error("Unable to create the model");
|
|
56
|
-
}
|
|
43
|
+
if (bDenominator === 0) throw new Error("Unable to create the model");
|
|
57
44
|
|
|
58
45
|
const b = (sXY - (sX * sY) / n) / bDenominator;
|
|
59
46
|
const a = (sY - b * sX) / n;
|
package/src/stepper.service.ts
CHANGED
|
@@ -10,14 +10,8 @@ export class Stepper {
|
|
|
10
10
|
private readonly total: StepType;
|
|
11
11
|
|
|
12
12
|
constructor(config: StepperConfigType) {
|
|
13
|
-
if (!Number.isInteger(config.total))
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (config.total <= Stepper.DEFAULT_CURRENT) {
|
|
18
|
-
throw new Error("Total value should be greater than one");
|
|
19
|
-
}
|
|
20
|
-
|
|
13
|
+
if (!Number.isInteger(config.total)) throw new Error("Total value is not an integer");
|
|
14
|
+
if (config.total <= Stepper.DEFAULT_CURRENT) throw new Error("Total value should be greater than one");
|
|
21
15
|
this.total = config.total;
|
|
22
16
|
}
|
|
23
17
|
|
package/src/stopwatch.service.ts
CHANGED
|
@@ -16,9 +16,7 @@ export class Stopwatch {
|
|
|
16
16
|
constructor(private readonly startMs: TimestampType) {}
|
|
17
17
|
|
|
18
18
|
stop(): StopwatchResultType {
|
|
19
|
-
if (this.state === StopwatchState.stopped)
|
|
20
|
-
throw new Error("Stopwatch is already stopped");
|
|
21
|
-
}
|
|
19
|
+
if (this.state === StopwatchState.stopped) throw new Error("Stopwatch is already stopped");
|
|
22
20
|
|
|
23
21
|
this.state = StopwatchState.stopped;
|
|
24
22
|
this.stopMs = Timestamp.parse(Date.now());
|
package/src/timezone.vo.ts
CHANGED
|
@@ -6,17 +6,11 @@ export const Timezone = z
|
|
|
6
6
|
.refine(
|
|
7
7
|
(value) => {
|
|
8
8
|
try {
|
|
9
|
-
|
|
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
|
},
|
|
@@ -31,10 +31,7 @@ export class VisuallyUnambiguousCharactersGenerator {
|
|
|
31
31
|
.map(
|
|
32
32
|
() =>
|
|
33
33
|
VisuallyUnambiguousCharactersGenerator.chars[
|
|
34
|
-
Random.generate({
|
|
35
|
-
min: 0,
|
|
36
|
-
max: VisuallyUnambiguousCharactersGenerator.chars.length - 1,
|
|
37
|
-
})
|
|
34
|
+
Random.generate({ min: 0, max: VisuallyUnambiguousCharactersGenerator.chars.length - 1 })
|
|
38
35
|
],
|
|
39
36
|
)
|
|
40
37
|
.join("");
|