@bgord/tools 1.2.19 → 1.2.21
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/duration.service.d.ts +3 -0
- package/dist/duration.service.js +7 -0
- package/package.json +2 -3
- package/src/age-years.vo.ts +0 -16
- package/src/age.vo.ts +0 -60
- package/src/api-key.vo.ts +0 -16
- package/src/basename.vo.ts +0 -33
- package/src/clock-format.service.ts +0 -15
- package/src/clock.vo.ts +0 -55
- package/src/date-calculator.service.ts +0 -18
- package/src/date-formatter.service.ts +0 -21
- package/src/date-range.vo.ts +0 -36
- package/src/day-iso-id.vo.ts +0 -21
- package/src/day.vo.ts +0 -59
- package/src/directory-path-absolute.vo.ts +0 -36
- package/src/directory-path-relative.vo.ts +0 -34
- package/src/distance-value.vo.ts +0 -13
- package/src/distance.vo.ts +0 -76
- package/src/division-factor.vo.ts +0 -12
- package/src/dll.service.ts +0 -177
- package/src/duration-ms.vo.ts +0 -9
- package/src/duration.service.ts +0 -89
- package/src/email-mask.service.ts +0 -17
- package/src/email.vo.ts +0 -9
- package/src/etags.vo.ts +0 -47
- package/src/extension.vo.ts +0 -27
- package/src/feature-flag-value.vo.ts +0 -12
- package/src/feature-flag.vo.ts +0 -11
- package/src/file-path-absolute-schema.vo.ts +0 -34
- package/src/file-path-relative-schema.vo.ts +0 -34
- package/src/file-path.vo.ts +0 -100
- package/src/filename-affix.vo.ts +0 -27
- package/src/filename-from-string.vo.ts +0 -27
- package/src/filename.vo.ts +0 -92
- package/src/height-milimiters.vo.ts +0 -16
- package/src/height.vo.ts +0 -79
- package/src/hour-format.service.ts +0 -22
- package/src/hour-schema.vo.ts +0 -14
- package/src/hour.vo.ts +0 -64
- package/src/iban-mask.service.ts +0 -18
- package/src/iban-schema.vo.ts +0 -17
- package/src/iban.vo.ts +0 -28
- package/src/image.vo.ts +0 -28
- package/src/index.ts +0 -105
- package/src/integer-non-negative.vo.ts +0 -16
- package/src/integer-positive.vo.ts +0 -13
- package/src/integer.vo.ts +0 -9
- package/src/language.vo.ts +0 -13
- package/src/linear-regression.service.ts +0 -73
- package/src/mean.service.ts +0 -18
- package/src/mime-types.vo.ts +0 -7
- package/src/mime-value.vo.ts +0 -14
- package/src/mime.vo.ts +0 -50
- package/src/min-max-scaler.service.ts +0 -96
- package/src/minute-schema.vo.ts +0 -14
- package/src/minute.vo.ts +0 -59
- package/src/money-amount.vo.ts +0 -13
- package/src/money.vo.ts +0 -83
- package/src/month-iso-id.vo.ts +0 -24
- package/src/month.vo.ts +0 -53
- package/src/multiplication-factor.vo.ts +0 -15
- package/src/noop.service.ts +0 -3
- package/src/notification-template.vo.ts +0 -10
- package/src/object-key.vo.ts +0 -36
- package/src/outlier-detector.service.ts +0 -21
- package/src/package-version-schema.vo.ts +0 -23
- package/src/package-version.vo.ts +0 -66
- package/src/pagination-page.vo.ts +0 -11
- package/src/pagination-skip.vo.ts +0 -10
- package/src/pagination-take.vo.ts +0 -10
- package/src/pagination.service.ts +0 -73
- package/src/percentage.service.ts +0 -15
- package/src/population-standard-deviation.service.ts +0 -23
- package/src/quarter-iso-id.vo.ts +0 -15
- package/src/quarter.vo.ts +0 -41
- package/src/random.service.ts +0 -19
- package/src/rate-limiter.service.ts +0 -30
- package/src/relative-date.vo.ts +0 -21
- package/src/reordering-item-position-value.vo.ts +0 -10
- package/src/reordering.service.ts +0 -163
- package/src/revision-value.vo.ts +0 -10
- package/src/revision.vo.ts +0 -44
- package/src/rounding-decimal.strategy.ts +0 -25
- package/src/rounding-down.strategy.ts +0 -7
- package/src/rounding-to-nearest.strategy.ts +0 -7
- package/src/rounding-up.strategy.ts +0 -7
- package/src/rounding.strategy.ts +0 -3
- package/src/size-bytes.vo.ts +0 -13
- package/src/size.vo.ts +0 -113
- package/src/slug.service.ts +0 -18
- package/src/sum.service.ts +0 -19
- package/src/thousands-separator.service.ts +0 -10
- package/src/time-zone-offset-value.vo.ts +0 -21
- package/src/timestamp-value.vo.ts +0 -13
- package/src/timestamp.vo.ts +0 -66
- package/src/timezone.vo.ts +0 -26
- package/src/ts-utils.ts +0 -3
- package/src/url-with-slash.vo.ts +0 -12
- package/src/url-without-slash.vo.ts +0 -12
- package/src/visually-unambiguous-characters-generator.service.ts +0 -39
- package/src/week-iso-id.vo.ts +0 -28
- package/src/week.vo.ts +0 -57
- package/src/weekday.vo.ts +0 -119
- package/src/weight-grams.vo.ts +0 -13
- package/src/weight.vo.ts +0 -91
- package/src/year-iso-id.vo.ts +0 -15
- package/src/year.vo.ts +0 -63
- package/src/z-score.service.ts +0 -25
package/src/mime.vo.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import * as mime from "mime-types";
|
|
2
|
-
import { Extension, type ExtensionType } from "./extension.vo";
|
|
3
|
-
import { MimeValue } from "./mime-value.vo";
|
|
4
|
-
|
|
5
|
-
export const MimeError = { NotAccepted: "mime.not.accepted" };
|
|
6
|
-
|
|
7
|
-
export class Mime {
|
|
8
|
-
private constructor(
|
|
9
|
-
readonly type: string,
|
|
10
|
-
readonly subtype: string,
|
|
11
|
-
) {}
|
|
12
|
-
|
|
13
|
-
static fromString(candidate: string): Mime {
|
|
14
|
-
const { type, subtype } = MimeValue.parse(candidate.split(";")[0].trim());
|
|
15
|
-
|
|
16
|
-
return new Mime(type, subtype);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static fromExtension(extension: ExtensionType): Mime {
|
|
20
|
-
return Mime.fromString(String(mime.contentType(extension)));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
isSatisfiedBy(another: Mime): boolean {
|
|
24
|
-
if (!(this.type === another.type || this.type === "*")) return false;
|
|
25
|
-
return this.subtype === another.subtype || this.subtype === "*";
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
toExtension(): ExtensionType {
|
|
29
|
-
return Extension.parse(mime.extension(this.toString()));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
toString(): string {
|
|
33
|
-
return `${this.type}/${this.subtype}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
toJSON(): { type: string; subtype: string } {
|
|
37
|
-
return { type: this.type, subtype: this.subtype };
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const MIMES = {
|
|
42
|
-
csv: Mime.fromString("text/csv"),
|
|
43
|
-
text: Mime.fromString("text/plain"),
|
|
44
|
-
markdown: Mime.fromString("text/markdown"),
|
|
45
|
-
pdf: Mime.fromString("application/pdf"),
|
|
46
|
-
png: Mime.fromString("image/png"),
|
|
47
|
-
jpeg: Mime.fromString("image/jpeg"),
|
|
48
|
-
webp: Mime.fromString("image/webp"),
|
|
49
|
-
zip: Mime.fromString("application/zip"),
|
|
50
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { RoundingStrategy } from "./rounding.strategy";
|
|
2
|
-
import { RoundingDecimalStrategy } from "./rounding-decimal.strategy";
|
|
3
|
-
|
|
4
|
-
type MinMaxScalerValueType = number;
|
|
5
|
-
|
|
6
|
-
type MinMaxScalerConfigType = {
|
|
7
|
-
min: MinMaxScalerValueType;
|
|
8
|
-
max: MinMaxScalerValueType;
|
|
9
|
-
bound?: { lower: MinMaxScalerValueType; upper: MinMaxScalerValueType };
|
|
10
|
-
rounding?: RoundingStrategy;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type ScaleResult = {
|
|
14
|
-
original: MinMaxScalerValueType;
|
|
15
|
-
scaled: MinMaxScalerValueType;
|
|
16
|
-
isMin: boolean;
|
|
17
|
-
isMax: boolean;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type DescaleResult = {
|
|
21
|
-
original: MinMaxScalerValueType;
|
|
22
|
-
scaled: MinMaxScalerValueType;
|
|
23
|
-
isLowerBound: boolean;
|
|
24
|
-
isUpperBound: boolean;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const MinMaxScalerError = {
|
|
28
|
-
InvalidMinMax: "min.max.scaler.invalid.min.max",
|
|
29
|
-
InvalidBound: "min.max.scaler.invalid.bound",
|
|
30
|
-
ValueOutOfRange: "min.max.scaler.value.out.of.range",
|
|
31
|
-
ScaledOutOfBounds: "min.max.scaler.scaled.out.of.bounds",
|
|
32
|
-
EmptyArray: "min.max.scaler.empty.array",
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export class MinMaxScaler {
|
|
36
|
-
private static readonly DEFAULT_ROUNDING: RoundingStrategy = new RoundingDecimalStrategy(2);
|
|
37
|
-
|
|
38
|
-
private readonly min: MinMaxScalerValueType;
|
|
39
|
-
private readonly max: MinMaxScalerValueType;
|
|
40
|
-
private readonly lower: MinMaxScalerValueType;
|
|
41
|
-
private readonly upper: MinMaxScalerValueType;
|
|
42
|
-
private readonly rounding: RoundingStrategy;
|
|
43
|
-
|
|
44
|
-
constructor(config: MinMaxScalerConfigType) {
|
|
45
|
-
const lower = config.bound?.lower ?? 0;
|
|
46
|
-
const upper = config.bound?.upper ?? 1;
|
|
47
|
-
|
|
48
|
-
if (config.max - config.min < 0) throw new Error(MinMaxScalerError.InvalidMinMax);
|
|
49
|
-
if (upper - lower <= 0) throw new Error(MinMaxScalerError.InvalidBound);
|
|
50
|
-
|
|
51
|
-
this.rounding = config.rounding ?? MinMaxScaler.DEFAULT_ROUNDING;
|
|
52
|
-
this.min = config.min;
|
|
53
|
-
this.max = config.max;
|
|
54
|
-
this.lower = lower;
|
|
55
|
-
this.upper = upper;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
scale(value: MinMaxScalerValueType): ScaleResult {
|
|
59
|
-
const { min, max, lower, upper } = this;
|
|
60
|
-
|
|
61
|
-
if (value < min || value > max) throw new Error(MinMaxScalerError.ValueOutOfRange);
|
|
62
|
-
|
|
63
|
-
if (min === max) {
|
|
64
|
-
return { original: value, scaled: (lower + upper) / 2, isMin: true, isMax: true };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const result = ((value - min) / (max - min)) * (upper - lower) + lower;
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
original: value,
|
|
71
|
-
scaled: this.rounding.round(result),
|
|
72
|
-
isMin: value === min,
|
|
73
|
-
isMax: value === max,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
descale(scaled: MinMaxScalerValueType): DescaleResult {
|
|
78
|
-
const { min, max, lower, upper } = this;
|
|
79
|
-
|
|
80
|
-
if (scaled < lower || scaled > upper) throw new Error(MinMaxScalerError.ScaledOutOfBounds);
|
|
81
|
-
|
|
82
|
-
const result = ((scaled - lower) / (upper - lower)) * (max - min) + min;
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
original: this.rounding.round(result),
|
|
86
|
-
scaled,
|
|
87
|
-
isLowerBound: scaled === lower,
|
|
88
|
-
isUpperBound: scaled === upper,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
static getMinMax(values: MinMaxScalerValueType[]): { min: number; max: number } {
|
|
93
|
-
if (values.length === 0) throw new Error(MinMaxScalerError.EmptyArray);
|
|
94
|
-
return { min: Math.min(...values), max: Math.max(...values) };
|
|
95
|
-
}
|
|
96
|
-
}
|
package/src/minute-schema.vo.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const MinuteSchemaError = { Type: "minute.schema.error", Invalid: "minute.schema.invalid" };
|
|
4
|
-
|
|
5
|
-
// Stryker disable all
|
|
6
|
-
export const MinuteSchema = z
|
|
7
|
-
// Stryker restore all
|
|
8
|
-
.number(MinuteSchemaError.Type)
|
|
9
|
-
.int(MinuteSchemaError.Type)
|
|
10
|
-
.gte(0, MinuteSchemaError.Invalid)
|
|
11
|
-
.lte(59, MinuteSchemaError.Invalid)
|
|
12
|
-
.brand("MinuteSchema");
|
|
13
|
-
|
|
14
|
-
export type MinuteSchemaType = z.infer<typeof MinuteSchema>;
|
package/src/minute.vo.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { MinuteSchema, type MinuteSchemaType } from "./minute-schema.vo";
|
|
2
|
-
import { Timestamp } from "./timestamp.vo";
|
|
3
|
-
import type { TimestampValueType } from "./timestamp-value.vo";
|
|
4
|
-
|
|
5
|
-
export class Minute {
|
|
6
|
-
private constructor(private readonly value: MinuteSchemaType) {}
|
|
7
|
-
|
|
8
|
-
static fromValue(candidate: number): Minute {
|
|
9
|
-
return new Minute(MinuteSchema.parse(candidate));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
static fromValueSafe(candidate: MinuteSchemaType) {
|
|
13
|
-
return new Minute(candidate);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static fromTimestamp(timestamp: Timestamp): Minute {
|
|
17
|
-
return new Minute(MinuteSchema.parse(new Date(timestamp.ms).getUTCMinutes()));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static fromTimestampValue(timestamp: TimestampValueType): Minute {
|
|
21
|
-
return Minute.fromTimestamp(Timestamp.fromValue(timestamp));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static zero(): Minute {
|
|
25
|
-
return Minute.fromValue(0);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
static max(): Minute {
|
|
29
|
-
return Minute.fromValue(59);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get(): MinuteSchemaType {
|
|
33
|
-
return this.value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
equals(another: Minute): boolean {
|
|
37
|
-
return this.value === another.value;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
isBefore(another: Minute): boolean {
|
|
41
|
-
return this.value < another.value;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
isAfter(another: Minute): boolean {
|
|
45
|
-
return this.value > another.value;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
static list(): readonly Minute[] {
|
|
49
|
-
return Array.from({ length: 60 }, (_, index) => Minute.fromValue(index));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
toString(): string {
|
|
53
|
-
return this.value.toString().padStart(2, "0");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
toJSON(): number {
|
|
57
|
-
return this.value;
|
|
58
|
-
}
|
|
59
|
-
}
|
package/src/money-amount.vo.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const MoneyAmountError = { Type: "money.amount.type", Invalid: "money.amount.invalid" };
|
|
4
|
-
|
|
5
|
-
// Stryker disable all
|
|
6
|
-
export const MoneyAmount = z
|
|
7
|
-
// Stryker restore all
|
|
8
|
-
.number(MoneyAmountError.Type)
|
|
9
|
-
.int(MoneyAmountError.Type)
|
|
10
|
-
.min(0, MoneyAmountError.Invalid)
|
|
11
|
-
.brand("MoneyAmount");
|
|
12
|
-
|
|
13
|
-
export type MoneyAmountType = z.infer<typeof MoneyAmount>;
|
package/src/money.vo.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import type { DivisionFactorType } from "./division-factor.vo";
|
|
2
|
-
import { MoneyAmount, type MoneyAmountType } from "./money-amount.vo";
|
|
3
|
-
import type { MultiplicationFactorType } from "./multiplication-factor.vo";
|
|
4
|
-
import type { RoundingStrategy } from "./rounding.strategy";
|
|
5
|
-
import { RoundingDownStrategy } from "./rounding-down.strategy";
|
|
6
|
-
import { RoundingToNearestStrategy } from "./rounding-to-nearest.strategy";
|
|
7
|
-
|
|
8
|
-
export const MoneyError = { SubtractResultLessThanZero: "money.subtract.result.less.than.zero" };
|
|
9
|
-
|
|
10
|
-
export class Money {
|
|
11
|
-
private static readonly ZERO = MoneyAmount.parse(0);
|
|
12
|
-
|
|
13
|
-
private constructor(
|
|
14
|
-
private readonly amount: MoneyAmountType,
|
|
15
|
-
private readonly rounding: RoundingStrategy = new RoundingToNearestStrategy(),
|
|
16
|
-
) {}
|
|
17
|
-
|
|
18
|
-
static fromAmount(candidate: number, rounding?: RoundingStrategy): Money {
|
|
19
|
-
return new Money(MoneyAmount.parse(candidate), rounding);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static fromAmountSafe(candidate: MoneyAmountType, rounding?: RoundingStrategy): Money {
|
|
23
|
-
return new Money(candidate, rounding);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
static zero(): Money {
|
|
27
|
-
return Money.fromAmount(0);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getAmount(): MoneyAmountType {
|
|
31
|
-
return this.amount;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
add(money: Money): Money {
|
|
35
|
-
return new Money(MoneyAmount.parse(this.amount + money.getAmount()), this.rounding);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
multiply(factor: MultiplicationFactorType): Money {
|
|
39
|
-
return new Money(MoneyAmount.parse(this.rounding.round(this.amount * factor)), this.rounding);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
subtract(money: Money): Money {
|
|
43
|
-
const result = this.amount - money.getAmount();
|
|
44
|
-
|
|
45
|
-
if (result < Money.ZERO) throw new Error(MoneyError.SubtractResultLessThanZero);
|
|
46
|
-
return new Money(MoneyAmount.parse(this.rounding.round(result)), this.rounding);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
divide(factor: DivisionFactorType): Money {
|
|
50
|
-
return new Money(MoneyAmount.parse(this.rounding.round(this.amount / factor)), this.rounding);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
equals(another: Money): boolean {
|
|
54
|
-
return this.amount === another.getAmount();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
isGreaterThan(another: Money): boolean {
|
|
58
|
-
return this.amount > another.getAmount();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
isLessThan(another: Money): boolean {
|
|
62
|
-
return this.amount < another.getAmount();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
isZero(): boolean {
|
|
66
|
-
return this.amount === Money.ZERO;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
format(): string {
|
|
70
|
-
const whole = new RoundingDownStrategy().round(this.amount / 100);
|
|
71
|
-
const fraction = this.amount % 100;
|
|
72
|
-
|
|
73
|
-
return `${whole}.${fraction.toString().padStart(2, "0")}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
toString(): string {
|
|
77
|
-
return this.format();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
toJSON(): number {
|
|
81
|
-
return this.amount;
|
|
82
|
-
}
|
|
83
|
-
}
|
package/src/month-iso-id.vo.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const MonthIsoIdError = {
|
|
4
|
-
Type: "month.iso.id.type",
|
|
5
|
-
BadChars: "month.iso.id.bad.chars",
|
|
6
|
-
Invalid: "month.iso.id.invalid",
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
// Four digits, hyphen, two digits
|
|
10
|
-
const MONTH_ISO_ID_CHARS_WHITELIST = /^\d{4}-\d{2}$/;
|
|
11
|
-
|
|
12
|
-
// Stryker disable all
|
|
13
|
-
export const MonthIsoId = z
|
|
14
|
-
// Stryker restore all
|
|
15
|
-
.string(MonthIsoIdError.Type)
|
|
16
|
-
.regex(MONTH_ISO_ID_CHARS_WHITELIST, MonthIsoIdError.BadChars)
|
|
17
|
-
.refine((value) => {
|
|
18
|
-
const month = value.split("-").map(Number)[1];
|
|
19
|
-
|
|
20
|
-
return month >= 1 && month <= 12;
|
|
21
|
-
}, MonthIsoIdError.Invalid)
|
|
22
|
-
.brand("MonthIsoId");
|
|
23
|
-
|
|
24
|
-
export type MonthIsoIdType = z.infer<typeof MonthIsoId>;
|
package/src/month.vo.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { endOfMonth, format, getMonth, setMonth, startOfMonth } from "date-fns";
|
|
2
|
-
import { DateRange } from "./date-range.vo";
|
|
3
|
-
import { Integer, type IntegerType } from "./integer.vo";
|
|
4
|
-
import { MonthIsoId, type MonthIsoIdType } from "./month-iso-id.vo";
|
|
5
|
-
import { Timestamp } from "./timestamp.vo";
|
|
6
|
-
import type { TimestampValueType } from "./timestamp-value.vo";
|
|
7
|
-
|
|
8
|
-
export class Month extends DateRange {
|
|
9
|
-
static fromTimestamp(timestamp: Timestamp): Month {
|
|
10
|
-
const start = Timestamp.fromNumber(startOfMonth(timestamp.ms).getTime());
|
|
11
|
-
const end = Timestamp.fromNumber(endOfMonth(timestamp.ms).getTime());
|
|
12
|
-
|
|
13
|
-
return new Month(start, end);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static fromTimestampValue(timestamp: TimestampValueType): Month {
|
|
17
|
-
return Month.fromTimestamp(Timestamp.fromValue(timestamp));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static fromNow(now: Timestamp): Month {
|
|
21
|
-
return Month.fromTimestamp(now);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static fromIsoId(iso: MonthIsoIdType): Month {
|
|
25
|
-
const [year, month] = MonthIsoId.parse(iso).split("-").map(Number);
|
|
26
|
-
|
|
27
|
-
const reference = setMonth(Date.UTC(year), month - 1).getTime();
|
|
28
|
-
|
|
29
|
-
return Month.fromTimestamp(Timestamp.fromNumber(reference));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
toIsoId(): MonthIsoIdType {
|
|
33
|
-
return MonthIsoId.parse(format(this.getStart().ms, "yyyy-MM"));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
previous(): Month {
|
|
37
|
-
return this.shift(Integer.parse(-1));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
next(): Month {
|
|
41
|
-
return this.shift(Integer.parse(1));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
shift(count: IntegerType): Month {
|
|
45
|
-
const shifted = setMonth(this.getStart().ms, getMonth(this.getStart().ms) + count).getTime();
|
|
46
|
-
|
|
47
|
-
return Month.fromTimestamp(Timestamp.fromNumber(shifted));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
toString(): string {
|
|
51
|
-
return this.toIsoId();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const MultiplicationFactorError = {
|
|
4
|
-
Type: "multiplication.factor.type",
|
|
5
|
-
Invalid: "multiplication.factor.invalid",
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
// Stryker disable all
|
|
9
|
-
export const MultiplicationFactor = z
|
|
10
|
-
// Stryker restore all
|
|
11
|
-
.number(MultiplicationFactorError.Type)
|
|
12
|
-
.min(0, MultiplicationFactorError.Invalid)
|
|
13
|
-
.brand("MultiplicationFactor");
|
|
14
|
-
|
|
15
|
-
export type MultiplicationFactorType = z.infer<typeof MultiplicationFactor>;
|
package/src/noop.service.ts
DELETED
package/src/object-key.vo.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const ObjectKeyError = {
|
|
4
|
-
Type: "object.key.type",
|
|
5
|
-
LeadingSlash: "object.key.leading.slash",
|
|
6
|
-
Empty: "object.key.empty",
|
|
7
|
-
TooLong: "object.key.too.long",
|
|
8
|
-
BadChars: "object.key.bad.chars",
|
|
9
|
-
DotSegments: "object.key.dot.segments",
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// Lowercase letters, digits, dots, underscores, and hyphens
|
|
13
|
-
const OBJECT_KEY_SEGMENT_CHARS_WHITELIST = /^[a-z0-9._-]+$/;
|
|
14
|
-
|
|
15
|
-
const DOT_SEGMENTS = [".", ".."];
|
|
16
|
-
|
|
17
|
-
// Stryker disable all
|
|
18
|
-
export const ObjectKey = z
|
|
19
|
-
// Stryker restore all
|
|
20
|
-
.string(ObjectKeyError.Type)
|
|
21
|
-
.min(1, ObjectKeyError.Empty)
|
|
22
|
-
.max(256, ObjectKeyError.TooLong)
|
|
23
|
-
.refine((value) => !value.startsWith("/"), ObjectKeyError.LeadingSlash)
|
|
24
|
-
// Allow only known characters for users/avatars/1234567890/avatar.png segments
|
|
25
|
-
.refine(
|
|
26
|
-
(value) => value.split("/").every((segment) => OBJECT_KEY_SEGMENT_CHARS_WHITELIST.test(segment)),
|
|
27
|
-
ObjectKeyError.BadChars,
|
|
28
|
-
)
|
|
29
|
-
// Reject object keys like users/./avatar.png or users/../avatar.png
|
|
30
|
-
.refine(
|
|
31
|
-
(value) => value.split("/").every((segment) => !DOT_SEGMENTS.includes(segment)),
|
|
32
|
-
ObjectKeyError.DotSegments,
|
|
33
|
-
)
|
|
34
|
-
.brand("ObjectKey");
|
|
35
|
-
|
|
36
|
-
export type ObjectKeyType = z.infer<typeof ObjectKey>;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ZScore } from "./z-score.service";
|
|
2
|
-
|
|
3
|
-
export const OutlierDetectorError = { NotEnoughValues: "outlier.detector.not.enough.values" };
|
|
4
|
-
|
|
5
|
-
export class OutlierDetector {
|
|
6
|
-
private readonly zScore: ZScore;
|
|
7
|
-
private readonly threshold: number;
|
|
8
|
-
|
|
9
|
-
constructor(values: number[], threshold: number) {
|
|
10
|
-
if (values.length < 2) throw new Error(OutlierDetectorError.NotEnoughValues);
|
|
11
|
-
|
|
12
|
-
this.zScore = new ZScore(values);
|
|
13
|
-
this.threshold = Math.abs(threshold);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
isInlier(value: number): boolean {
|
|
17
|
-
const score = this.zScore.calculate(value);
|
|
18
|
-
|
|
19
|
-
return Math.abs(score) <= this.threshold;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const PackageVersionSchemaError = {
|
|
4
|
-
Type: "package.version.schema.error",
|
|
5
|
-
BadChars: "package.version.schema.bad.chars",
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
// v, 1-4 digits, dot, 1-4 digits, dot, 1-4 digits - () for capturing groups
|
|
9
|
-
const PACKAGE_VERSIONS_CHARS_WHITELIST = /^v([0-9]{1,4})\.([0-9]{1,4})\.([0-9]{1,4})$/;
|
|
10
|
-
|
|
11
|
-
// Stryker disable all
|
|
12
|
-
export const PackageVersionSchema = z
|
|
13
|
-
// Stryker restore all
|
|
14
|
-
.string(PackageVersionSchemaError.Type)
|
|
15
|
-
.regex(PACKAGE_VERSIONS_CHARS_WHITELIST, PackageVersionSchemaError.BadChars)
|
|
16
|
-
.transform((value) => {
|
|
17
|
-
const match = PACKAGE_VERSIONS_CHARS_WHITELIST.exec(value)!;
|
|
18
|
-
|
|
19
|
-
return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) };
|
|
20
|
-
})
|
|
21
|
-
.brand("PackageVersionSchema");
|
|
22
|
-
|
|
23
|
-
export type PackageVersionSchemaType = z.infer<typeof PackageVersionSchema>;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { PackageVersionSchema, type PackageVersionSchemaType } from "./package-version-schema.vo";
|
|
2
|
-
|
|
3
|
-
export class PackageVersion {
|
|
4
|
-
constructor(
|
|
5
|
-
private readonly major: number,
|
|
6
|
-
private readonly minor: number,
|
|
7
|
-
private readonly patch: number,
|
|
8
|
-
) {}
|
|
9
|
-
|
|
10
|
-
static fromVersionString(candidate: string): PackageVersion {
|
|
11
|
-
const version = PackageVersionSchema.parse(candidate);
|
|
12
|
-
|
|
13
|
-
return new PackageVersion(version.major, version.minor, version.patch);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static fromVersionStringSafe(candidate: PackageVersionSchemaType): PackageVersion {
|
|
17
|
-
return new PackageVersion(candidate.major, candidate.minor, candidate.patch);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static fromString(candidate: string): PackageVersion {
|
|
21
|
-
const version = PackageVersionSchema.parse(`v${candidate}`);
|
|
22
|
-
|
|
23
|
-
return new PackageVersion(version.major, version.minor, version.patch);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private compareTo(another: PackageVersion): -1 | 0 | 1 {
|
|
27
|
-
if (this.major > another.major) return 1;
|
|
28
|
-
if (this.major < another.major) return -1;
|
|
29
|
-
|
|
30
|
-
if (this.minor > another.minor) return 1;
|
|
31
|
-
if (this.minor < another.minor) return -1;
|
|
32
|
-
|
|
33
|
-
if (this.patch > another.patch) return 1;
|
|
34
|
-
if (this.patch < another.patch) return -1;
|
|
35
|
-
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
equals(another: PackageVersion): boolean {
|
|
40
|
-
return this.compareTo(another) === 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
isGreaterThan(another: PackageVersion): boolean {
|
|
44
|
-
return this.compareTo(another) === 1;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
isGreaterThanOrEqual(another: PackageVersion): boolean {
|
|
48
|
-
return this.compareTo(another) !== -1;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
isSmallerThan(another: PackageVersion): boolean {
|
|
52
|
-
return this.compareTo(another) === -1;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
isSmallerThanOrEqual(another: PackageVersion): boolean {
|
|
56
|
-
return this.compareTo(another) !== 1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
toString(): string {
|
|
60
|
-
return `${this.major}.${this.minor}.${this.patch}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
toJSON(): { major: number; minor: number; patch: number } {
|
|
64
|
-
return { major: this.major, minor: this.minor, patch: this.patch };
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const PaginationPageError = { Type: "pagination.page.type" };
|
|
4
|
-
|
|
5
|
-
export const Page = z.coerce
|
|
6
|
-
.number(PaginationPageError.Type)
|
|
7
|
-
.int(PaginationPageError.Type)
|
|
8
|
-
.transform((value) => (value <= 0 ? 1 : value))
|
|
9
|
-
.default(1);
|
|
10
|
-
|
|
11
|
-
export type PageType = z.infer<typeof Page>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const PaginationSkipError = { Type: "pagination.skip.type", Invalid: "pagination.skip.invalid" };
|
|
4
|
-
|
|
5
|
-
export const Skip = z
|
|
6
|
-
.number(PaginationSkipError.Type)
|
|
7
|
-
.int(PaginationSkipError.Type)
|
|
8
|
-
.gte(0, PaginationSkipError.Invalid);
|
|
9
|
-
|
|
10
|
-
export type SkipType = z.infer<typeof Skip>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { z } from "zod/v4";
|
|
2
|
-
|
|
3
|
-
export const PaginationTakeError = { Type: "pagination.take.type", Invalid: "pagination.take.invalid" };
|
|
4
|
-
|
|
5
|
-
export const Take = z
|
|
6
|
-
.number(PaginationTakeError.Type)
|
|
7
|
-
.int(PaginationTakeError.Type)
|
|
8
|
-
.gte(1, PaginationTakeError.Invalid);
|
|
9
|
-
|
|
10
|
-
export type TakeType = z.infer<typeof Take>;
|