@bgord/tools 0.17.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/age-years.vo.d.ts +11 -0
- package/dist/age-years.vo.js +9 -0
- package/dist/age.vo.d.ts +11 -16
- package/dist/age.vo.js +20 -31
- package/dist/api-key.vo.d.ts +3 -1
- package/dist/api-key.vo.js +10 -5
- package/dist/basename.vo.d.ts +9 -9
- package/dist/basename.vo.js +22 -22
- package/dist/clock.vo.d.ts +10 -4
- package/dist/clock.vo.js +12 -14
- package/dist/date-calculator.service.d.ts +2 -1
- package/dist/date-formatter.service.d.ts +3 -4
- package/dist/date-range.vo.d.ts +7 -1
- package/dist/date-range.vo.js +5 -2
- package/dist/day-iso-id.vo.d.ts +5 -2
- package/dist/day-iso-id.vo.js +11 -7
- package/dist/day.vo.d.ts +4 -3
- package/dist/day.vo.js +18 -16
- package/dist/directory-path-absolute.vo.d.ts +10 -6
- package/dist/directory-path-absolute.vo.js +19 -17
- package/dist/directory-path-relative.vo.d.ts +10 -7
- package/dist/directory-path-relative.vo.js +18 -17
- package/dist/division-factor.vo.d.ts +7 -0
- package/dist/division-factor.vo.js +9 -0
- package/dist/duration-ms.vo.d.ts +6 -0
- package/dist/duration-ms.vo.js +3 -0
- package/dist/duration.service.d.ts +2 -14
- package/dist/duration.service.js +16 -35
- package/dist/email-mask.service.d.ts +1 -6
- package/dist/email-mask.service.js +6 -8
- package/dist/etags.vo.d.ts +4 -3
- package/dist/etags.vo.js +3 -3
- package/dist/extension.vo.d.ts +6 -4
- package/dist/extension.vo.js +15 -10
- package/dist/feature-flag-value.vo.d.ts +10 -0
- package/dist/feature-flag-value.vo.js +8 -0
- package/dist/feature-flag.vo.d.ts +1 -7
- package/dist/feature-flag.vo.js +1 -7
- package/dist/file-path-absolute-schema.vo.d.ts +10 -7
- package/dist/file-path-absolute-schema.vo.js +17 -17
- package/dist/file-path-relative-schema.vo.d.ts +10 -7
- package/dist/file-path-relative-schema.vo.js +14 -12
- package/dist/file-path.vo.d.ts +4 -4
- package/dist/file-path.vo.js +8 -8
- package/dist/filename-from-string.vo.d.ts +4 -2
- package/dist/filename-from-string.vo.js +10 -8
- package/dist/filename-suffix.vo.d.ts +7 -3
- package/dist/filename-suffix.vo.js +13 -7
- package/dist/filename.vo.d.ts +2 -0
- package/dist/filename.vo.js +8 -2
- package/dist/height-milimiters.vo.d.ts +6 -0
- package/dist/height-milimiters.vo.js +10 -0
- package/dist/height.vo.d.ts +3 -20
- package/dist/height.vo.js +11 -62
- package/dist/hour-format.service.js +1 -1
- package/dist/hour-schema.vo.d.ts +7 -0
- package/dist/hour-schema.vo.js +8 -0
- package/dist/hour.vo.d.ts +4 -3
- package/dist/hour.vo.js +8 -8
- package/dist/iban-mask.service.d.ts +1 -3
- package/dist/iban-mask.service.js +2 -2
- package/dist/iban-schema.vo.d.ts +7 -0
- package/dist/iban-schema.vo.js +10 -0
- package/dist/iban.vo.d.ts +4 -10
- package/dist/iban.vo.js +6 -13
- package/dist/image.vo.d.ts +6 -4
- package/dist/image.vo.js +13 -12
- package/dist/index.d.ts +24 -2
- package/dist/index.js +24 -2
- package/dist/language.vo.d.ts +2 -1
- package/dist/language.vo.js +6 -4
- package/dist/linear-regression.service.d.ts +27 -0
- package/dist/{simple-linear-regression.service.js → linear-regression.service.js} +17 -15
- package/dist/mean.service.d.ts +3 -1
- package/dist/mean.service.js +3 -4
- package/dist/mime-types.vo.d.ts +1 -2
- package/dist/mime-value.vo.d.ts +9 -0
- package/dist/mime-value.vo.js +9 -0
- package/dist/mime.vo.d.ts +11 -17
- package/dist/mime.vo.js +10 -27
- package/dist/min-max-scaler.service.d.ts +7 -5
- package/dist/min-max-scaler.service.js +12 -10
- package/dist/minute-schema.vo.d.ts +7 -0
- package/dist/minute-schema.vo.js +8 -0
- package/dist/minute.vo.d.ts +4 -3
- package/dist/minute.vo.js +8 -8
- package/dist/money-amount.vo.d.ts +7 -0
- package/dist/money-amount.vo.js +7 -0
- package/dist/money.vo.d.ts +9 -18
- package/dist/money.vo.js +14 -27
- package/dist/month-iso-id.vo.d.ts +4 -2
- package/dist/month-iso-id.vo.js +13 -7
- package/dist/month.vo.d.ts +4 -3
- package/dist/month.vo.js +21 -21
- package/dist/multiplication-factor.vo.d.ts +7 -0
- package/dist/multiplication-factor.vo.js +9 -0
- package/dist/object-key.vo.d.ts +9 -6
- package/dist/object-key.vo.js +20 -19
- package/dist/outlier-detector.service.d.ts +3 -1
- package/dist/outlier-detector.service.js +2 -2
- package/dist/package-version-schema.vo.d.ts +11 -0
- package/dist/package-version-schema.vo.js +15 -0
- package/dist/package-version.vo.d.ts +11 -20
- package/dist/package-version.vo.js +11 -20
- package/dist/pagination-page.vo.d.ts +6 -0
- package/dist/pagination-page.vo.js +7 -0
- package/dist/pagination-skip.vo.d.ts +7 -0
- package/dist/pagination-skip.vo.js +9 -0
- package/dist/pagination-take.vo.d.ts +7 -0
- package/dist/pagination-take.vo.js +9 -0
- package/dist/pagination.service.d.ts +3 -8
- package/dist/pagination.service.js +5 -12
- package/dist/percentage.service.d.ts +3 -1
- package/dist/percentage.service.js +2 -2
- package/dist/population-standard-deviation.service.d.ts +3 -1
- package/dist/population-standard-deviation.service.js +5 -4
- package/dist/quarter-iso-id.vo.d.ts +3 -2
- package/dist/quarter-iso-id.vo.js +7 -9
- package/dist/quarter.vo.d.ts +2 -1
- package/dist/quarter.vo.js +10 -7
- package/dist/random.service.d.ts +3 -4
- package/dist/random.service.js +5 -11
- package/dist/rate-limiter.service.d.ts +2 -2
- package/dist/rate-limiter.service.js +8 -8
- package/dist/reordering-item-position-value.vo.d.ts +6 -0
- package/dist/reordering-item-position-value.vo.js +6 -0
- package/dist/reordering.service.d.ts +7 -23
- package/dist/reordering.service.js +15 -24
- package/dist/revision-value.vo.d.ts +7 -0
- package/dist/revision-value.vo.js +6 -0
- package/dist/revision.vo.d.ts +6 -13
- package/dist/revision.vo.js +10 -22
- package/dist/rounding.adapter.d.ts +7 -2
- package/dist/rounding.adapter.js +13 -5
- package/dist/size-bytes.vo.d.ts +6 -0
- package/dist/size-bytes.vo.js +7 -0
- package/dist/size.vo.d.ts +15 -15
- package/dist/size.vo.js +41 -51
- package/dist/stopwatch.service.d.ts +3 -1
- package/dist/stopwatch.service.js +2 -2
- package/dist/sum.service.js +8 -8
- package/dist/thousands-separator.service.js +4 -1
- package/dist/time.service.d.ts +8 -0
- package/dist/time.service.js +13 -0
- package/dist/timestamp.vo.d.ts +1 -1
- package/dist/timestamp.vo.js +4 -5
- package/dist/timezone.vo.d.ts +4 -1
- package/dist/timezone.vo.js +12 -6
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/week-iso-id.vo.d.ts +4 -2
- package/dist/week-iso-id.vo.js +15 -9
- package/dist/week.vo.d.ts +4 -3
- package/dist/week.vo.js +21 -22
- package/dist/weekday.vo.d.ts +1 -1
- package/dist/weekday.vo.js +6 -8
- package/dist/weight-grams.vo.d.ts +7 -0
- package/dist/weight-grams.vo.js +7 -0
- package/dist/weight.vo.d.ts +12 -35
- package/dist/weight.vo.js +23 -72
- package/dist/year-iso-id.vo.d.ts +3 -2
- package/dist/year-iso-id.vo.js +6 -4
- package/dist/year.vo.d.ts +5 -6
- package/dist/year.vo.js +21 -26
- package/dist/z-score.service.d.ts +3 -1
- package/dist/z-score.service.js +2 -2
- package/package.json +4 -4
- package/readme.md +21 -2
- package/src/age-years.vo.ts +14 -0
- package/src/age.vo.ts +22 -35
- package/src/api-key.vo.ts +11 -5
- package/src/basename.vo.ts +24 -22
- package/src/clock.vo.ts +16 -17
- package/src/date-calculator.service.ts +2 -1
- package/src/date-formatter.service.ts +4 -5
- package/src/date-range.vo.ts +6 -2
- package/src/day-iso-id.vo.ts +12 -8
- package/src/day.vo.ts +27 -24
- package/src/directory-path-absolute.vo.ts +23 -18
- package/src/directory-path-relative.vo.ts +21 -18
- package/src/division-factor.vo.ts +13 -0
- package/src/duration-ms.vo.ts +7 -0
- package/src/duration.service.ts +16 -40
- package/src/email-mask.service.ts +7 -15
- package/src/etags.vo.ts +4 -5
- package/src/extension.vo.ts +17 -10
- package/src/feature-flag-value.vo.ts +12 -0
- package/src/feature-flag.vo.ts +1 -9
- package/src/file-path-absolute-schema.vo.ts +18 -17
- package/src/file-path-relative-schema.vo.ts +15 -12
- package/src/file-path.vo.ts +8 -8
- package/src/filename-from-string.vo.ts +12 -9
- package/src/filename-suffix.vo.ts +14 -7
- package/src/filename.vo.ts +11 -2
- package/src/height-milimiters.vo.ts +12 -0
- package/src/height.vo.ts +12 -83
- package/src/hour-format.service.ts +2 -1
- package/src/hour-schema.vo.ts +12 -0
- package/src/hour.vo.ts +12 -12
- package/src/iban-mask.service.ts +3 -5
- package/src/iban-schema.vo.ts +15 -0
- package/src/iban.vo.ts +9 -22
- package/src/image.vo.ts +14 -12
- package/src/index.ts +24 -2
- package/src/language.vo.ts +7 -4
- package/src/linear-regression.service.ts +71 -0
- package/src/mean.service.ts +3 -5
- package/src/mime-types.vo.ts +1 -3
- package/src/mime-value.vo.ts +12 -0
- package/src/mime.vo.ts +12 -33
- package/src/min-max-scaler.service.ts +13 -11
- package/src/minute-schema.vo.ts +12 -0
- package/src/minute.vo.ts +12 -12
- package/src/money-amount.vo.ts +11 -0
- package/src/money.vo.ts +20 -38
- package/src/month-iso-id.vo.ts +14 -7
- package/src/month.vo.ts +25 -24
- package/src/multiplication-factor.vo.ts +13 -0
- package/src/object-key.vo.ts +25 -21
- package/src/outlier-detector.service.ts +2 -2
- package/src/package-version-schema.vo.ts +21 -0
- package/src/package-version.vo.ts +17 -33
- package/src/pagination-page.vo.ts +11 -0
- package/src/pagination-skip.vo.ts +13 -0
- package/src/pagination-take.vo.ts +13 -0
- package/src/pagination.service.ts +5 -22
- package/src/percentage.service.ts +2 -2
- package/src/population-standard-deviation.service.ts +5 -4
- package/src/quarter-iso-id.vo.ts +7 -10
- package/src/quarter.vo.ts +14 -9
- package/src/random.service.ts +6 -9
- package/src/rate-limiter.service.ts +9 -8
- package/src/reordering-item-position-value.vo.ts +10 -0
- package/src/reordering.service.ts +19 -28
- package/src/revision-value.vo.ts +10 -0
- package/src/revision.vo.ts +10 -25
- package/src/rounding.adapter.ts +16 -3
- package/src/size-bytes.vo.ts +11 -0
- package/src/size.vo.ts +43 -54
- package/src/stopwatch.service.ts +3 -3
- package/src/sum.service.ts +8 -8
- package/src/thousands-separator.service.ts +4 -1
- package/src/time.service.ts +15 -0
- package/src/timestamp.vo.ts +4 -5
- package/src/timezone.vo.ts +12 -6
- package/src/week-iso-id.vo.ts +16 -12
- package/src/week.vo.ts +26 -28
- package/src/weekday.vo.ts +6 -9
- package/src/weight-grams.vo.ts +11 -0
- package/src/weight.vo.ts +28 -85
- package/src/year-iso-id.vo.ts +7 -4
- package/src/year.vo.ts +27 -33
- package/src/z-score.service.ts +2 -2
- package/dist/simple-linear-regression.service.d.ts +0 -25
- package/dist/streak-calculator.service.d.ts +0 -13
- package/dist/streak-calculator.service.js +0 -22
- package/src/simple-linear-regression.service.ts +0 -69
- package/src/streak-calculator.service.ts +0 -32
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { RoundToNearest } from "./rounding.adapter";
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
export const LinearRegressionError = {
|
|
3
|
+
MinPairs: "linear.regression.min.pairs",
|
|
4
|
+
SumXTooBig: "linear.regression.sum.x.too.big",
|
|
5
|
+
SumYTooBig: "linear.regression.sum.y.too.big",
|
|
6
|
+
SumXSquaredTooBig: "linear.regression.sum.x.squared.too.big",
|
|
7
|
+
SumXTimesYTooBig: "linear.regression.sum.x.times.y.too.big",
|
|
8
|
+
ModelCreation: "linear.regression.model.creation",
|
|
9
|
+
};
|
|
10
|
+
export class LinearRegression {
|
|
9
11
|
static DEFAULT_ROUNDING = new RoundToNearest();
|
|
10
12
|
params;
|
|
11
13
|
rounding;
|
|
12
14
|
constructor(params, rounding) {
|
|
13
15
|
this.params = params;
|
|
14
|
-
this.rounding = rounding ??
|
|
16
|
+
this.rounding = rounding ?? LinearRegression.DEFAULT_ROUNDING;
|
|
15
17
|
}
|
|
16
18
|
static fromPairs(pairs, rounding) {
|
|
17
19
|
const count = pairs.length;
|
|
18
20
|
if (count < 2)
|
|
19
|
-
throw new Error(
|
|
21
|
+
throw new Error(LinearRegressionError.MinPairs);
|
|
20
22
|
let sumX = 0;
|
|
21
23
|
let sumY = 0;
|
|
22
24
|
let sumXX = 0;
|
|
@@ -29,19 +31,19 @@ export class SimpleLinearRegression {
|
|
|
29
31
|
sumXY += pair.x * pair.y;
|
|
30
32
|
}
|
|
31
33
|
if (Math.abs(sumX) >= Number.MAX_SAFE_INTEGER)
|
|
32
|
-
throw new Error(
|
|
34
|
+
throw new Error(LinearRegressionError.SumXTooBig);
|
|
33
35
|
if (Math.abs(sumY) >= Number.MAX_SAFE_INTEGER)
|
|
34
|
-
throw new Error(
|
|
36
|
+
throw new Error(LinearRegressionError.SumYTooBig);
|
|
35
37
|
if (Math.abs(sumXY) >= Number.MAX_SAFE_INTEGER)
|
|
36
|
-
throw new Error(
|
|
38
|
+
throw new Error(LinearRegressionError.SumXTimesYTooBig);
|
|
37
39
|
if (Math.abs(sumXX) >= Number.MAX_SAFE_INTEGER)
|
|
38
|
-
throw new Error(
|
|
40
|
+
throw new Error(LinearRegressionError.SumXSquaredTooBig);
|
|
39
41
|
const bDenominator = sumXX - sumX ** 2 / count;
|
|
40
42
|
if (bDenominator === 0)
|
|
41
|
-
throw new Error(
|
|
43
|
+
throw new Error(LinearRegressionError.ModelCreation);
|
|
42
44
|
const b = (sumXY - (sumX * sumY) / count) / bDenominator;
|
|
43
45
|
const a = (sumY - b * sumX) / count;
|
|
44
|
-
return new
|
|
46
|
+
return new LinearRegression({ a, b }, rounding);
|
|
45
47
|
}
|
|
46
48
|
predict(x, rounding) {
|
|
47
49
|
const chosen = rounding ?? this.rounding;
|
package/dist/mean.service.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { RoundingPort } from "./rounding.port";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const MeanError: {
|
|
3
|
+
readonly NotEnoughValues: "mean.not.enough.values";
|
|
4
|
+
};
|
|
3
5
|
export declare class Mean {
|
|
4
6
|
private static readonly DEFAULT_ROUNDING;
|
|
5
7
|
static calculate(values: number[], rounding?: RoundingPort): number;
|
package/dist/mean.service.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { RoundToDecimal } from "./rounding.adapter";
|
|
2
2
|
import { Sum } from "./sum.service";
|
|
3
|
-
export const
|
|
3
|
+
export const MeanError = { NotEnoughValues: "mean.not.enough.values" };
|
|
4
4
|
export class Mean {
|
|
5
5
|
static DEFAULT_ROUNDING = new RoundToDecimal(2);
|
|
6
6
|
static calculate(values, rounding) {
|
|
7
7
|
if (values.length === 0)
|
|
8
|
-
throw new Error(
|
|
8
|
+
throw new Error(MeanError.NotEnoughValues);
|
|
9
9
|
const sum = Sum.of(values);
|
|
10
10
|
const mean = sum / values.length;
|
|
11
|
-
|
|
12
|
-
return chosen.round(mean);
|
|
11
|
+
return (rounding ?? Mean.DEFAULT_ROUNDING).round(mean);
|
|
13
12
|
}
|
|
14
13
|
}
|
package/dist/mime-types.vo.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const MIME_TYPES: Record<string, MimeRawType[]>;
|
|
1
|
+
export declare const MIME_TYPES: Record<string, string[]>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export declare const MimeValueError: {
|
|
3
|
+
Type: string;
|
|
4
|
+
Invalid: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const MimeValue: z.core.$ZodBranded<z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
7
|
+
type: string;
|
|
8
|
+
subtype: string;
|
|
9
|
+
}, string>>, "MimeValue">;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export const MimeValueError = { Type: "mime.value.type", Invalid: "mime.value.invalid" };
|
|
3
|
+
// One to twenty four lowercase letters, asterisk or hyphen, forward slash, one to twenty four lowercase letters, asterisk or hyphen
|
|
4
|
+
const MIME_VALUE_CHARS_WHITELIST = /^[a-z*-]{1,24}\/[a-z*-]{1,24}$/;
|
|
5
|
+
export const MimeValue = z
|
|
6
|
+
.string(MimeValueError.Type)
|
|
7
|
+
.regex(MIME_VALUE_CHARS_WHITELIST, MimeValueError.Invalid)
|
|
8
|
+
.transform((value) => ({ type: value.split("/")[0], subtype: value.split("/")[1] }))
|
|
9
|
+
.brand("MimeValue");
|
package/dist/mime.vo.d.ts
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import { type ExtensionType } from "./extension.vo";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare const InvalidMimeErrorMessage: "invalid.mime";
|
|
6
|
-
export declare const NotAcceptedMimeErrorMessage: "mime.not.accepted";
|
|
2
|
+
export declare const MimeError: {
|
|
3
|
+
readonly NotAccepted: "mime.not.accepted";
|
|
4
|
+
};
|
|
7
5
|
export declare class Mime {
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
10
|
-
|
|
11
|
-
constructor(value: MimeRawType);
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly subtype: string;
|
|
8
|
+
constructor(candidate: string);
|
|
12
9
|
static fromExtension(extension: ExtensionType): Mime;
|
|
13
10
|
isSatisfiedBy(another: Mime): boolean;
|
|
14
11
|
toExtension(): ExtensionType;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
mime: MimeRawType;
|
|
21
|
-
constructor(mimeValue: MimeRawType);
|
|
12
|
+
toString(): string;
|
|
13
|
+
toJSON(): {
|
|
14
|
+
type: string;
|
|
15
|
+
subtype: string;
|
|
16
|
+
};
|
|
22
17
|
}
|
|
23
18
|
export declare const MIMES: {
|
|
24
19
|
csv: Mime;
|
|
@@ -26,4 +21,3 @@ export declare const MIMES: {
|
|
|
26
21
|
markdown: Mime;
|
|
27
22
|
pdf: Mime;
|
|
28
23
|
};
|
|
29
|
-
export {};
|
package/dist/mime.vo.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import * as mime from "mime-types";
|
|
2
2
|
import { Extension } from "./extension.vo";
|
|
3
|
-
|
|
4
|
-
export const
|
|
3
|
+
import { MimeValue } from "./mime-value.vo";
|
|
4
|
+
export const MimeError = { NotAccepted: "mime.not.accepted" };
|
|
5
5
|
export class Mime {
|
|
6
|
-
raw;
|
|
7
6
|
type;
|
|
8
7
|
subtype;
|
|
9
|
-
constructor(
|
|
10
|
-
const
|
|
11
|
-
if (typeof type !== "string" || type.length === 0)
|
|
12
|
-
throw new InvalidMimeError();
|
|
13
|
-
if (typeof subtype !== "string" || subtype.length === 0)
|
|
14
|
-
throw new InvalidMimeError();
|
|
15
|
-
this.raw = value;
|
|
8
|
+
constructor(candidate) {
|
|
9
|
+
const { type, subtype } = MimeValue.parse(candidate);
|
|
16
10
|
this.type = type;
|
|
17
11
|
this.subtype = subtype;
|
|
18
12
|
}
|
|
@@ -20,29 +14,18 @@ export class Mime {
|
|
|
20
14
|
return new Mime(String(mime.contentType(extension)));
|
|
21
15
|
}
|
|
22
16
|
isSatisfiedBy(another) {
|
|
23
|
-
if (this.
|
|
24
|
-
return true;
|
|
25
|
-
const typeMatches = this.type === another.type || this.type === "*";
|
|
26
|
-
if (!typeMatches)
|
|
17
|
+
if (!(this.type === another.type || this.type === "*"))
|
|
27
18
|
return false;
|
|
28
19
|
return this.subtype === another.subtype || this.subtype === "*";
|
|
29
20
|
}
|
|
30
21
|
toExtension() {
|
|
31
|
-
return Extension.parse(mime.extension(this.
|
|
22
|
+
return Extension.parse(mime.extension(this.toString()));
|
|
32
23
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
constructor() {
|
|
36
|
-
super(InvalidMimeErrorMessage);
|
|
37
|
-
Object.setPrototypeOf(this, InvalidMimeError.prototype);
|
|
24
|
+
toString() {
|
|
25
|
+
return `${this.type}/${this.subtype}`;
|
|
38
26
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
mime;
|
|
42
|
-
constructor(mimeValue) {
|
|
43
|
-
super(NotAcceptedMimeErrorMessage);
|
|
44
|
-
Object.setPrototypeOf(this, NotAcceptedMimeError.prototype);
|
|
45
|
-
this.mime = mimeValue;
|
|
27
|
+
toJSON() {
|
|
28
|
+
return { type: this.type, subtype: this.subtype };
|
|
46
29
|
}
|
|
47
30
|
}
|
|
48
31
|
export const MIMES = {
|
|
@@ -9,11 +9,6 @@ type MinMaxScalerConfigType = {
|
|
|
9
9
|
};
|
|
10
10
|
rounding?: RoundingPort;
|
|
11
11
|
};
|
|
12
|
-
export declare const MinMaxInvalidMinMaxError: "minmax.invalid.minmax";
|
|
13
|
-
export declare const MinMaxInvalidBoundError: "minmax.invalid.bound";
|
|
14
|
-
export declare const MinMaxValueOutOfRangeError: "minmax.value.out.of.range";
|
|
15
|
-
export declare const MinMaxScaledOutOfBoundsError: "minmax.scaled.out.of.bounds";
|
|
16
|
-
export declare const MinMaxEmptyArrayError: "minmax.empty.array";
|
|
17
12
|
type ScaleResult = {
|
|
18
13
|
original: MinMaxScalerValueType;
|
|
19
14
|
scaled: MinMaxScalerValueType;
|
|
@@ -26,6 +21,13 @@ type DescaleResult = {
|
|
|
26
21
|
isLowerBound: boolean;
|
|
27
22
|
isUpperBound: boolean;
|
|
28
23
|
};
|
|
24
|
+
export declare const MinMaxScalerError: {
|
|
25
|
+
readonly InvalidMinMax: "min.max.scaler.invalid.min.max";
|
|
26
|
+
readonly InvalidBound: "min.max.scaler.invalid.bound";
|
|
27
|
+
readonly ValueOutOfRange: "min.max.scaler.value.out.of.range";
|
|
28
|
+
readonly ScaledOutOfBounds: "min.max.scaler.scaled.out.of.bounds";
|
|
29
|
+
readonly EmptyArray: "min.max.scaler.empty.array";
|
|
30
|
+
};
|
|
29
31
|
export declare class MinMaxScaler {
|
|
30
32
|
private static readonly DEFAULT_ROUNDING;
|
|
31
33
|
private readonly min;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { RoundToDecimal } from "./rounding.adapter";
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
export const MinMaxScalerError = {
|
|
3
|
+
InvalidMinMax: "min.max.scaler.invalid.min.max",
|
|
4
|
+
InvalidBound: "min.max.scaler.invalid.bound",
|
|
5
|
+
ValueOutOfRange: "min.max.scaler.value.out.of.range",
|
|
6
|
+
ScaledOutOfBounds: "min.max.scaler.scaled.out.of.bounds",
|
|
7
|
+
EmptyArray: "min.max.scaler.empty.array",
|
|
8
|
+
};
|
|
7
9
|
export class MinMaxScaler {
|
|
8
10
|
static DEFAULT_ROUNDING = new RoundToDecimal(2);
|
|
9
11
|
min;
|
|
@@ -15,9 +17,9 @@ export class MinMaxScaler {
|
|
|
15
17
|
const lower = config.bound?.lower ?? 0;
|
|
16
18
|
const upper = config.bound?.upper ?? 1;
|
|
17
19
|
if (config.max - config.min < 0)
|
|
18
|
-
throw new Error(
|
|
20
|
+
throw new Error(MinMaxScalerError.InvalidMinMax);
|
|
19
21
|
if (upper - lower <= 0)
|
|
20
|
-
throw new Error(
|
|
22
|
+
throw new Error(MinMaxScalerError.InvalidBound);
|
|
21
23
|
this.rounding = config.rounding ?? MinMaxScaler.DEFAULT_ROUNDING;
|
|
22
24
|
this.min = config.min;
|
|
23
25
|
this.max = config.max;
|
|
@@ -27,7 +29,7 @@ export class MinMaxScaler {
|
|
|
27
29
|
scale(value) {
|
|
28
30
|
const { min, max, lower, upper } = this;
|
|
29
31
|
if (value < min || value > max)
|
|
30
|
-
throw new Error(
|
|
32
|
+
throw new Error(MinMaxScalerError.ValueOutOfRange);
|
|
31
33
|
if (min === max) {
|
|
32
34
|
return { original: value, scaled: (lower + upper) / 2, isMin: value === min, isMax: value === max };
|
|
33
35
|
}
|
|
@@ -42,7 +44,7 @@ export class MinMaxScaler {
|
|
|
42
44
|
descale(scaled) {
|
|
43
45
|
const { min, max, lower, upper } = this;
|
|
44
46
|
if (scaled < lower || scaled > upper)
|
|
45
|
-
throw new Error(
|
|
47
|
+
throw new Error(MinMaxScalerError.ScaledOutOfBounds);
|
|
46
48
|
const result = ((scaled - lower) / (upper - lower)) * (max - min) + min;
|
|
47
49
|
return {
|
|
48
50
|
original: this.rounding.round(result),
|
|
@@ -53,7 +55,7 @@ export class MinMaxScaler {
|
|
|
53
55
|
}
|
|
54
56
|
static getMinMax(values) {
|
|
55
57
|
if (values.length === 0)
|
|
56
|
-
throw new Error(
|
|
58
|
+
throw new Error(MinMaxScalerError.EmptyArray);
|
|
57
59
|
return { min: Math.min(...values), max: Math.max(...values) };
|
|
58
60
|
}
|
|
59
61
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export const MinuteSchemaError = { Type: "minute.schema.error", Invalid: "minute.schema.invalid" };
|
|
3
|
+
export const MinuteSchema = z
|
|
4
|
+
.number(MinuteSchemaError.Type)
|
|
5
|
+
.int(MinuteSchemaError.Type)
|
|
6
|
+
.gte(0, MinuteSchemaError.Invalid)
|
|
7
|
+
.lte(59, MinuteSchemaError.Invalid)
|
|
8
|
+
.brand("MinuteSchema");
|
package/dist/minute.vo.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { type MinuteSchemaType } from "./minute-schema.vo";
|
|
1
2
|
import type { TimestampType } from "./timestamp.vo";
|
|
2
|
-
export declare const MinuteValueError: "invalid.minute";
|
|
3
3
|
export declare class Minute {
|
|
4
4
|
private readonly value;
|
|
5
5
|
static readonly ZERO: Minute;
|
|
6
6
|
static readonly MAX: Minute;
|
|
7
7
|
constructor(candidate: number);
|
|
8
8
|
static fromEpochMs(timestamp: TimestampType): Minute;
|
|
9
|
-
get():
|
|
10
|
-
toString(): string;
|
|
9
|
+
get(): MinuteSchemaType;
|
|
11
10
|
equals(another: Minute): boolean;
|
|
12
11
|
isAfter(another: Minute): boolean;
|
|
13
12
|
isBefore(another: Minute): boolean;
|
|
14
13
|
static list(): readonly Minute[];
|
|
14
|
+
toString(): string;
|
|
15
|
+
toJSON(): number;
|
|
15
16
|
}
|
package/dist/minute.vo.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { MinuteSchema } from "./minute-schema.vo";
|
|
2
2
|
export class Minute {
|
|
3
3
|
value;
|
|
4
4
|
static ZERO = new Minute(0);
|
|
5
5
|
static MAX = new Minute(59);
|
|
6
6
|
constructor(candidate) {
|
|
7
|
-
|
|
8
|
-
throw new Error(MinuteValueError);
|
|
9
|
-
}
|
|
10
|
-
this.value = candidate;
|
|
7
|
+
this.value = MinuteSchema.parse(candidate);
|
|
11
8
|
}
|
|
12
9
|
static fromEpochMs(timestamp) {
|
|
13
10
|
return new Minute(new Date(timestamp).getUTCMinutes());
|
|
@@ -15,9 +12,6 @@ export class Minute {
|
|
|
15
12
|
get() {
|
|
16
13
|
return this.value;
|
|
17
14
|
}
|
|
18
|
-
toString() {
|
|
19
|
-
return this.value.toString().padStart(2, "0");
|
|
20
|
-
}
|
|
21
15
|
equals(another) {
|
|
22
16
|
return this.value === another.value;
|
|
23
17
|
}
|
|
@@ -30,4 +24,10 @@ export class Minute {
|
|
|
30
24
|
static list() {
|
|
31
25
|
return Array.from({ length: 60 }, (_, index) => new Minute(index));
|
|
32
26
|
}
|
|
27
|
+
toString() {
|
|
28
|
+
return this.value.toString().padStart(2, "0");
|
|
29
|
+
}
|
|
30
|
+
toJSON() {
|
|
31
|
+
return this.value;
|
|
32
|
+
}
|
|
33
33
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export const MoneyAmountError = { Type: "money.amount.type", Invalid: "money.amount.invalid" };
|
|
3
|
+
export const MoneyAmount = z
|
|
4
|
+
.number(MoneyAmountError.Type)
|
|
5
|
+
.int(MoneyAmountError.Type)
|
|
6
|
+
.min(0, MoneyAmountError.Invalid)
|
|
7
|
+
.brand("MoneyAmount");
|
package/dist/money.vo.d.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DivisionFactorType } from "./division-factor.vo";
|
|
2
|
+
import { type MoneyAmountType } from "./money-amount.vo";
|
|
3
|
+
import type { MultiplicationFactorType } from "./multiplication-factor.vo";
|
|
2
4
|
import type { RoundingPort } from "./rounding.port";
|
|
3
|
-
export declare const
|
|
4
|
-
readonly
|
|
5
|
+
export declare const MoneyError: {
|
|
6
|
+
readonly SubtractResultLessThanZero: "money.subtract.result.less.than.zero";
|
|
5
7
|
};
|
|
6
|
-
export declare const MoneyMultiplicationFactorInvalidError: {
|
|
7
|
-
readonly error: "money.multiplication-factor.invalid";
|
|
8
|
-
};
|
|
9
|
-
export declare const MoneyDivisionFactorInvalidError: {
|
|
10
|
-
readonly error: "money.division-factor.invalid";
|
|
11
|
-
};
|
|
12
|
-
export declare const MoneySubtractLessThanZeroError: "money.subtract.less.than.zero";
|
|
13
|
-
export declare const MoneyAmount: z.core.$ZodBranded<z.ZodNumber, "MoneyAmount">;
|
|
14
|
-
export type MoneyAmountType = z.infer<typeof MoneyAmount>;
|
|
15
|
-
export declare const MoneyMultiplicationFactor: z.core.$ZodBranded<z.ZodNumber, "MoneyMultiplicationFactor">;
|
|
16
|
-
export type MoneyMultiplicationFactorType = z.infer<typeof MoneyMultiplicationFactor>;
|
|
17
|
-
export declare const MoneyDivisionFactor: z.core.$ZodBranded<z.ZodNumber, "MoneyDivisionFactor">;
|
|
18
|
-
export type MoneyDivisionFactorType = z.infer<typeof MoneyDivisionFactor>;
|
|
19
8
|
export declare class Money {
|
|
20
9
|
private static readonly ZERO;
|
|
21
10
|
private static readonly DEFAULT_ROUNDING;
|
|
@@ -24,12 +13,14 @@ export declare class Money {
|
|
|
24
13
|
constructor(value?: number, rounding?: RoundingPort);
|
|
25
14
|
getAmount(): MoneyAmountType;
|
|
26
15
|
add(money: Money): Money;
|
|
27
|
-
multiply(factor:
|
|
16
|
+
multiply(factor: MultiplicationFactorType): Money;
|
|
28
17
|
subtract(money: Money): Money;
|
|
29
|
-
divide(factor:
|
|
18
|
+
divide(factor: DivisionFactorType): Money;
|
|
30
19
|
equals(another: Money): boolean;
|
|
31
20
|
isGreaterThan(another: Money): boolean;
|
|
32
21
|
isLessThan(another: Money): boolean;
|
|
33
22
|
isZero(): boolean;
|
|
34
23
|
format(): string;
|
|
24
|
+
toString(): string;
|
|
25
|
+
toJSON(): number;
|
|
35
26
|
}
|
package/dist/money.vo.js
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { RoundToNearest } from "./rounding.adapter";
|
|
3
|
-
export const
|
|
4
|
-
export const MoneyMultiplicationFactorInvalidError = {
|
|
5
|
-
error: "money.multiplication-factor.invalid",
|
|
6
|
-
};
|
|
7
|
-
export const MoneyDivisionFactorInvalidError = { error: "money.division-factor.invalid" };
|
|
8
|
-
export const MoneySubtractLessThanZeroError = "money.subtract.less.than.zero";
|
|
9
|
-
export const MoneyAmount = z
|
|
10
|
-
.number(MoneyAmountInvalidError)
|
|
11
|
-
.int(MoneyAmountInvalidError)
|
|
12
|
-
.min(0, MoneyAmountInvalidError)
|
|
13
|
-
.brand("MoneyAmount");
|
|
14
|
-
export const MoneyMultiplicationFactor = z
|
|
15
|
-
.number(MoneyMultiplicationFactorInvalidError)
|
|
16
|
-
.min(0, MoneyMultiplicationFactorInvalidError)
|
|
17
|
-
.brand("MoneyMultiplicationFactor");
|
|
18
|
-
export const MoneyDivisionFactor = z
|
|
19
|
-
.number(MoneyDivisionFactorInvalidError)
|
|
20
|
-
.gt(0, MoneyDivisionFactorInvalidError)
|
|
21
|
-
.brand("MoneyDivisionFactor");
|
|
1
|
+
import { MoneyAmount } from "./money-amount.vo";
|
|
2
|
+
import { RoundDown, RoundToNearest } from "./rounding.adapter";
|
|
3
|
+
export const MoneyError = { SubtractResultLessThanZero: "money.subtract.result.less.than.zero" };
|
|
22
4
|
export class Money {
|
|
23
5
|
static ZERO = 0;
|
|
24
6
|
static DEFAULT_ROUNDING = new RoundToNearest();
|
|
@@ -32,7 +14,7 @@ export class Money {
|
|
|
32
14
|
return this.amount;
|
|
33
15
|
}
|
|
34
16
|
add(money) {
|
|
35
|
-
const result = this.
|
|
17
|
+
const result = this.amount + money.getAmount();
|
|
36
18
|
return new Money(MoneyAmount.parse(result), this.rounding);
|
|
37
19
|
}
|
|
38
20
|
multiply(factor) {
|
|
@@ -40,9 +22,9 @@ export class Money {
|
|
|
40
22
|
return new Money(MoneyAmount.parse(result), this.rounding);
|
|
41
23
|
}
|
|
42
24
|
subtract(money) {
|
|
43
|
-
const result = this.
|
|
25
|
+
const result = this.amount - money.getAmount();
|
|
44
26
|
if (result < Money.ZERO)
|
|
45
|
-
throw new Error(
|
|
27
|
+
throw new Error(MoneyError.SubtractResultLessThanZero);
|
|
46
28
|
return new Money(MoneyAmount.parse(result), this.rounding);
|
|
47
29
|
}
|
|
48
30
|
divide(factor) {
|
|
@@ -62,9 +44,14 @@ export class Money {
|
|
|
62
44
|
return this.amount === Money.ZERO;
|
|
63
45
|
}
|
|
64
46
|
format() {
|
|
65
|
-
const whole =
|
|
47
|
+
const whole = new RoundDown().round(this.amount / 100);
|
|
66
48
|
const fraction = this.amount % 100;
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
return `${whole}.${fraction.toString().padStart(2, "0")}`;
|
|
50
|
+
}
|
|
51
|
+
toString() {
|
|
52
|
+
return this.format();
|
|
53
|
+
}
|
|
54
|
+
toJSON() {
|
|
55
|
+
return this.amount;
|
|
69
56
|
}
|
|
70
57
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
export declare const MonthIsoIdError: {
|
|
3
|
-
readonly
|
|
3
|
+
readonly Type: "month.iso.id.type";
|
|
4
|
+
readonly BadChars: "month.iso.id.bad.chars";
|
|
5
|
+
readonly Invalid: "month.iso.id.invalid";
|
|
4
6
|
};
|
|
5
|
-
export declare const MonthIsoId: z.ZodString
|
|
7
|
+
export declare const MonthIsoId: z.core.$ZodBranded<z.ZodString, "MonthIsoId">;
|
|
6
8
|
export type MonthIsoIdType = z.infer<typeof MonthIsoId>;
|
package/dist/month-iso-id.vo.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
|
-
export const MonthIsoIdError = {
|
|
2
|
+
export const MonthIsoIdError = {
|
|
3
|
+
Type: "month.iso.id.type",
|
|
4
|
+
BadChars: "month.iso.id.bad.chars",
|
|
5
|
+
Invalid: "month.iso.id.invalid",
|
|
6
|
+
};
|
|
7
|
+
// Four digits, hyphen, two digits
|
|
8
|
+
const MONTH_ISO_ID_CHARS_WHITELIST = /^\d{4}-\d{2}$/;
|
|
3
9
|
export const MonthIsoId = z
|
|
4
|
-
.string(MonthIsoIdError)
|
|
5
|
-
.regex(
|
|
10
|
+
.string(MonthIsoIdError.Type)
|
|
11
|
+
.regex(MONTH_ISO_ID_CHARS_WHITELIST, MonthIsoIdError.BadChars)
|
|
6
12
|
.refine((value) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
const month = value.split("-").map(Number)[1];
|
|
14
|
+
return month >= 1 && month <= 12;
|
|
15
|
+
}, MonthIsoIdError.Invalid)
|
|
16
|
+
.brand("MonthIsoId");
|
package/dist/month.vo.d.ts
CHANGED
|
@@ -2,11 +2,12 @@ import { DateRange } from "./date-range.vo";
|
|
|
2
2
|
import { type MonthIsoIdType } from "./month-iso-id.vo";
|
|
3
3
|
import { type TimestampType } from "./timestamp.vo";
|
|
4
4
|
export declare class Month extends DateRange {
|
|
5
|
+
static fromTimestamp(timestamp: TimestampType): Month;
|
|
6
|
+
static fromNow(now: TimestampType): Month;
|
|
7
|
+
static fromIsoId(iso: MonthIsoIdType): Month;
|
|
5
8
|
toIsoId(): MonthIsoIdType;
|
|
6
9
|
previous(): Month;
|
|
7
10
|
next(): Month;
|
|
8
11
|
shift(count: number): Month;
|
|
9
|
-
|
|
10
|
-
static fromNow(now: TimestampType): Month;
|
|
11
|
-
static fromIsoId(iso: MonthIsoIdType): Month;
|
|
12
|
+
toString(): string;
|
|
12
13
|
}
|
package/dist/month.vo.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
+
import { endOfMonth, format, getMonth, setMonth, startOfMonth } from "date-fns";
|
|
1
2
|
import { DateRange } from "./date-range.vo";
|
|
2
3
|
import { MonthIsoId } from "./month-iso-id.vo";
|
|
3
4
|
import { Timestamp } from "./timestamp.vo";
|
|
4
5
|
export class Month extends DateRange {
|
|
6
|
+
static fromTimestamp(timestamp) {
|
|
7
|
+
const start = Timestamp.parse(startOfMonth(timestamp).getTime());
|
|
8
|
+
const end = Timestamp.parse(endOfMonth(timestamp).getTime());
|
|
9
|
+
return new Month(start, end);
|
|
10
|
+
}
|
|
11
|
+
static fromNow(now) {
|
|
12
|
+
return Month.fromTimestamp(now);
|
|
13
|
+
}
|
|
14
|
+
static fromIsoId(iso) {
|
|
15
|
+
const [year, month] = MonthIsoId.parse(iso).split("-").map(Number);
|
|
16
|
+
const reference = setMonth(Date.UTC(year), month - 1).getTime();
|
|
17
|
+
return Month.fromTimestamp(Timestamp.parse(reference));
|
|
18
|
+
}
|
|
5
19
|
toIsoId() {
|
|
6
|
-
return
|
|
20
|
+
return MonthIsoId.parse(format(this.getStart(), "yyyy-MM"));
|
|
7
21
|
}
|
|
8
22
|
previous() {
|
|
9
|
-
return
|
|
23
|
+
return this.shift(-1);
|
|
10
24
|
}
|
|
11
25
|
next() {
|
|
12
|
-
return
|
|
26
|
+
return this.shift(1);
|
|
13
27
|
}
|
|
14
28
|
shift(count) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
return Month.fromTimestamp(Timestamp.parse(date.getTime()));
|
|
29
|
+
const shifted = setMonth(this.getStart(), getMonth(this.getStart()) + count).getTime();
|
|
30
|
+
return Month.fromTimestamp(Timestamp.parse(shifted));
|
|
18
31
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return Month.fromIsoId(isoMonth);
|
|
22
|
-
}
|
|
23
|
-
static fromNow(now) {
|
|
24
|
-
return Month.fromTimestamp(now);
|
|
25
|
-
}
|
|
26
|
-
static fromIsoId(iso) {
|
|
27
|
-
const validated = MonthIsoId.parse(iso);
|
|
28
|
-
const year = Number(validated.slice(0, 4));
|
|
29
|
-
const monthIndex = Number(validated.slice(5, 7)) - 1;
|
|
30
|
-
const startUtc = Date.UTC(year, monthIndex, 1);
|
|
31
|
-
const nextStartUtc = Date.UTC(year, monthIndex + 1, 1);
|
|
32
|
-
const endUtc = nextStartUtc - 1;
|
|
33
|
-
return new Month(Timestamp.parse(startUtc), Timestamp.parse(endUtc));
|
|
32
|
+
toString() {
|
|
33
|
+
return this.toIsoId();
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export declare const MultiplicationFactorError: {
|
|
3
|
+
readonly Type: "multiplication.factor.type";
|
|
4
|
+
readonly Invalid: "multiplication.factor.invalid";
|
|
5
|
+
};
|
|
6
|
+
export declare const MultiplicationFactor: z.core.$ZodBranded<z.ZodNumber, "MultiplicationFactor">;
|
|
7
|
+
export type MultiplicationFactorType = z.infer<typeof MultiplicationFactor>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
export const MultiplicationFactorError = {
|
|
3
|
+
Type: "multiplication.factor.type",
|
|
4
|
+
Invalid: "multiplication.factor.invalid",
|
|
5
|
+
};
|
|
6
|
+
export const MultiplicationFactor = z
|
|
7
|
+
.number(MultiplicationFactorError.Type)
|
|
8
|
+
.min(0, MultiplicationFactorError.Invalid)
|
|
9
|
+
.brand("MultiplicationFactor");
|