@bgord/bun 1.15.4 → 1.16.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/alert-channel-collecting.adapter.d.ts +8 -0
- package/dist/alert-channel-collecting.adapter.d.ts.map +1 -0
- package/dist/alert-channel-collecting.adapter.js +10 -0
- package/dist/alert-channel-collecting.adapter.js.map +1 -0
- package/dist/alert-channel-composite.adapter.d.ts +13 -0
- package/dist/alert-channel-composite.adapter.d.ts.map +1 -0
- package/dist/alert-channel-composite.adapter.js +22 -0
- package/dist/alert-channel-composite.adapter.js.map +1 -0
- package/dist/alert-channel-mailer.adapter.d.ts +18 -0
- package/dist/alert-channel-mailer.adapter.d.ts.map +1 -0
- package/dist/alert-channel-mailer.adapter.js +15 -0
- package/dist/alert-channel-mailer.adapter.js.map +1 -0
- package/dist/alert-channel-noop.adapter.d.ts +7 -0
- package/dist/alert-channel-noop.adapter.d.ts.map +1 -0
- package/dist/alert-channel-noop.adapter.js +7 -0
- package/dist/alert-channel-noop.adapter.js.map +1 -0
- package/dist/alert-channel-sms.adapter.d.ts +18 -0
- package/dist/alert-channel-sms.adapter.d.ts.map +1 -0
- package/dist/alert-channel-sms.adapter.js +15 -0
- package/dist/alert-channel-sms.adapter.js.map +1 -0
- package/dist/alert-channel-with-logger.adapter.d.ts +17 -0
- package/dist/alert-channel-with-logger.adapter.d.ts.map +1 -0
- package/dist/alert-channel-with-logger.adapter.js +33 -0
- package/dist/alert-channel-with-logger.adapter.js.map +1 -0
- package/dist/alert-channel-with-retry.adapter.d.ts +19 -0
- package/dist/alert-channel-with-retry.adapter.d.ts.map +1 -0
- package/dist/alert-channel-with-retry.adapter.js +16 -0
- package/dist/alert-channel-with-retry.adapter.js.map +1 -0
- package/dist/alert-channel-with-timeout.adapter.d.ts +19 -0
- package/dist/alert-channel-with-timeout.adapter.d.ts.map +1 -0
- package/dist/alert-channel-with-timeout.adapter.js +15 -0
- package/dist/alert-channel-with-timeout.adapter.js.map +1 -0
- package/dist/alert-channel.builder.d.ts +14 -0
- package/dist/alert-channel.builder.d.ts.map +1 -0
- package/dist/alert-channel.builder.js +28 -0
- package/dist/alert-channel.builder.js.map +1 -0
- package/dist/alert-channel.port.d.ts +6 -0
- package/dist/alert-channel.port.d.ts.map +1 -0
- package/dist/alert-channel.port.js +2 -0
- package/dist/alert-channel.port.js.map +1 -0
- package/dist/alert-message.vo.d.ts +10 -0
- package/dist/alert-message.vo.d.ts.map +1 -0
- package/dist/alert-message.vo.js +12 -0
- package/dist/alert-message.vo.js.map +1 -0
- package/dist/antivirus-clamav.adapter.js +1 -1
- package/dist/antivirus-clamav.adapter.js.map +1 -1
- package/dist/api-version-hono.middleware.d.ts +3 -2
- package/dist/api-version-hono.middleware.d.ts.map +1 -1
- package/dist/api-version-hono.middleware.js.map +1 -1
- package/dist/api-version.middleware.d.ts +4 -3
- package/dist/api-version.middleware.d.ts.map +1 -1
- package/dist/api-version.middleware.js +1 -1
- package/dist/api-version.middleware.js.map +1 -1
- package/dist/build-info.vo.d.ts +11 -0
- package/dist/build-info.vo.d.ts.map +1 -0
- package/dist/build-info.vo.js +11 -0
- package/dist/build-info.vo.js.map +1 -0
- package/dist/error-normalizer.service.js +1 -1
- package/dist/error-normalizer.service.js.map +1 -1
- package/dist/healthcheck-hono.handler.d.ts +3 -2
- package/dist/healthcheck-hono.handler.d.ts.map +1 -1
- package/dist/healthcheck-hono.handler.js.map +1 -1
- package/dist/healthcheck.handler.d.ts +3 -2
- package/dist/healthcheck.handler.d.ts.map +1 -1
- package/dist/healthcheck.handler.js +6 -6
- package/dist/healthcheck.handler.js.map +1 -1
- package/dist/image-alpha-sharp.adapter.js +76 -14
- package/dist/image-alpha-sharp.adapter.js.map +1 -1
- package/dist/image-blur-sharp.adapter.js +72 -10
- package/dist/image-blur-sharp.adapter.js.map +1 -1
- package/dist/image-compressor-sharp.adapter.js +73 -11
- package/dist/image-compressor-sharp.adapter.js.map +1 -1
- package/dist/image-exif-clear-sharp.adapter.js +70 -8
- package/dist/image-exif-clear-sharp.adapter.js.map +1 -1
- package/dist/image-formatter-sharp.adapter.js +75 -13
- package/dist/image-formatter-sharp.adapter.js.map +1 -1
- package/dist/image-grayscale-sharp.adapter.js +70 -8
- package/dist/image-grayscale-sharp.adapter.js.map +1 -1
- package/dist/image-info-sharp.adapter.js +73 -11
- package/dist/image-info-sharp.adapter.js.map +1 -1
- package/dist/image-processor-sharp.adapter.js +86 -24
- package/dist/image-processor-sharp.adapter.js.map +1 -1
- package/dist/image-resizer-sharp.adapter.js +81 -19
- package/dist/image-resizer-sharp.adapter.js.map +1 -1
- package/dist/index.d.ts +26 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/mailer-collecting.adapter.d.ts +8 -0
- package/dist/mailer-collecting.adapter.d.ts.map +1 -0
- package/dist/mailer-collecting.adapter.js +10 -0
- package/dist/mailer-collecting.adapter.js.map +1 -0
- package/dist/prerequisite-verifier-sms.adapter.d.ts +13 -0
- package/dist/prerequisite-verifier-sms.adapter.d.ts.map +1 -0
- package/dist/prerequisite-verifier-sms.adapter.js +20 -0
- package/dist/prerequisite-verifier-sms.adapter.js.map +1 -0
- package/dist/reactive-config-file-json.adapter.d.ts +15 -0
- package/dist/reactive-config-file-json.adapter.d.ts.map +1 -0
- package/dist/reactive-config-file-json.adapter.js +21 -0
- package/dist/reactive-config-file-json.adapter.js.map +1 -0
- package/dist/reactive-config-noop.adapter.d.ts +8 -0
- package/dist/reactive-config-noop.adapter.d.ts.map +1 -0
- package/dist/reactive-config-noop.adapter.js +18 -0
- package/dist/reactive-config-noop.adapter.js.map +1 -0
- package/dist/reactive-config-with-cache.adapter.d.ts +16 -0
- package/dist/reactive-config-with-cache.adapter.d.ts.map +1 -0
- package/dist/reactive-config-with-cache.adapter.js +15 -0
- package/dist/reactive-config-with-cache.adapter.js.map +1 -0
- package/dist/reactive-config-with-fallback.adapter.d.ts +9 -0
- package/dist/reactive-config-with-fallback.adapter.d.ts.map +1 -0
- package/dist/reactive-config-with-fallback.adapter.js +25 -0
- package/dist/reactive-config-with-fallback.adapter.js.map +1 -0
- package/dist/reactive-config.port.d.ts +9 -0
- package/dist/reactive-config.port.d.ts.map +1 -0
- package/dist/reactive-config.port.js +2 -0
- package/dist/reactive-config.port.js.map +1 -0
- package/dist/redactor-error-cause-depth-limit.strategy.d.ts.map +1 -1
- package/dist/redactor-error-cause-depth-limit.strategy.js +2 -2
- package/dist/redactor-error-cause-depth-limit.strategy.js.map +1 -1
- package/dist/redactor-error-stack-hide.strategy.d.ts.map +1 -1
- package/dist/redactor-error-stack-hide.strategy.js +2 -2
- package/dist/redactor-error-stack-hide.strategy.js.map +1 -1
- package/dist/redactor-metadata-compact-array.strategy.js +1 -1
- package/dist/redactor-metadata-compact-array.strategy.js.map +1 -1
- package/dist/redactor-metadata-compact-object.strategy.js +1 -1
- package/dist/redactor-metadata-compact-object.strategy.js.map +1 -1
- package/dist/setup-hono.service.d.ts +3 -2
- package/dist/setup-hono.service.d.ts.map +1 -1
- package/dist/setup-hono.service.js.map +1 -1
- package/dist/shield-recaptcha.strategy.js +1 -1
- package/dist/shield-recaptcha.strategy.js.map +1 -1
- package/dist/sms-collecting.adapter.d.ts +8 -0
- package/dist/sms-collecting.adapter.d.ts.map +1 -0
- package/dist/sms-collecting.adapter.js +10 -0
- package/dist/sms-collecting.adapter.js.map +1 -0
- package/dist/sms-noop.adapter.d.ts +7 -0
- package/dist/sms-noop.adapter.d.ts.map +1 -0
- package/dist/sms-noop.adapter.js +7 -0
- package/dist/sms-noop.adapter.js.map +1 -0
- package/dist/sms-with-logger.adapter.d.ts +17 -0
- package/dist/sms-with-logger.adapter.d.ts.map +1 -0
- package/dist/sms-with-logger.adapter.js +28 -0
- package/dist/sms-with-logger.adapter.js.map +1 -0
- package/dist/sms-with-retry.adapter.d.ts +19 -0
- package/dist/sms-with-retry.adapter.d.ts.map +1 -0
- package/dist/sms-with-retry.adapter.js +16 -0
- package/dist/sms-with-retry.adapter.js.map +1 -0
- package/dist/sms-with-timeout.adapter.d.ts +18 -0
- package/dist/sms-with-timeout.adapter.d.ts.map +1 -0
- package/dist/sms-with-timeout.adapter.js +15 -0
- package/dist/sms-with-timeout.adapter.js.map +1 -0
- package/dist/sms.builder.d.ts +14 -0
- package/dist/sms.builder.d.ts.map +1 -0
- package/dist/sms.builder.js +28 -0
- package/dist/sms.builder.js.map +1 -0
- package/dist/sms.port.d.ts +6 -0
- package/dist/sms.port.d.ts.map +1 -0
- package/dist/sms.port.js +2 -0
- package/dist/sms.port.js.map +1 -0
- package/package.json +12 -11
- package/readme.md +26 -4
- package/src/alert-channel-collecting.adapter.ts +14 -0
- package/src/alert-channel-composite.adapter.ts +24 -0
- package/src/alert-channel-mailer.adapter.ts +22 -0
- package/src/alert-channel-noop.adapter.ts +10 -0
- package/src/alert-channel-sms.adapter.ts +22 -0
- package/src/alert-channel-with-logger.adapter.ts +46 -0
- package/src/alert-channel-with-retry.adapter.ts +22 -0
- package/src/alert-channel-with-timeout.adapter.ts +25 -0
- package/src/alert-channel.builder.ts +48 -0
- package/src/alert-channel.port.ts +7 -0
- package/src/alert-message.vo.ts +10 -0
- package/src/antivirus-clamav.adapter.ts +1 -1
- package/src/api-version-hono.middleware.ts +3 -2
- package/src/api-version.middleware.ts +5 -4
- package/src/build-info.vo.ts +14 -0
- package/src/error-normalizer.service.ts +1 -1
- package/src/healthcheck-hono.handler.ts +3 -2
- package/src/healthcheck.handler.ts +9 -8
- package/src/index.ts +26 -4
- package/src/mailer-collecting.adapter.ts +14 -0
- package/src/prerequisite-verifier-sms.adapter.ts +26 -0
- package/src/reactive-config-file-json.adapter.ts +26 -0
- package/src/reactive-config-noop.adapter.ts +19 -0
- package/src/reactive-config-with-cache.adapter.ts +19 -0
- package/src/reactive-config-with-fallback.adapter.ts +24 -0
- package/src/reactive-config.port.ts +9 -0
- package/src/redactor-error-cause-depth-limit.strategy.ts +2 -3
- package/src/redactor-error-stack-hide.strategy.ts +2 -3
- package/src/redactor-metadata-compact-array.strategy.ts +1 -1
- package/src/redactor-metadata-compact-object.strategy.ts +1 -1
- package/src/setup-hono.service.ts +3 -2
- package/src/shield-recaptcha.strategy.ts +1 -1
- package/src/sms-collecting.adapter.ts +14 -0
- package/src/sms-noop.adapter.ts +10 -0
- package/src/sms-with-logger.adapter.ts +37 -0
- package/src/sms-with-retry.adapter.ts +22 -0
- package/src/sms-with-timeout.adapter.ts +21 -0
- package/src/sms.builder.ts +39 -0
- package/src/sms.port.ts +6 -0
- package/dist/build-info-repository-file.strategy.d.ts +0 -14
- package/dist/build-info-repository-file.strategy.d.ts.map +0 -1
- package/dist/build-info-repository-file.strategy.js +0 -18
- package/dist/build-info-repository-file.strategy.js.map +0 -1
- package/dist/build-info-repository-noop.strategy.d.ts +0 -12
- package/dist/build-info-repository-noop.strategy.d.ts.map +0 -1
- package/dist/build-info-repository-noop.strategy.js +0 -16
- package/dist/build-info-repository-noop.strategy.js.map +0 -1
- package/dist/build-info-repository-package-json.strategy.d.ts +0 -14
- package/dist/build-info-repository-package-json.strategy.d.ts.map +0 -1
- package/dist/build-info-repository-package-json.strategy.js +0 -21
- package/dist/build-info-repository-package-json.strategy.js.map +0 -1
- package/dist/build-info-repository.strategy.d.ts +0 -12
- package/dist/build-info-repository.strategy.d.ts.map +0 -1
- package/dist/build-info-repository.strategy.js +0 -2
- package/dist/build-info-repository.strategy.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/build-info-repository-file.strategy.ts +0 -23
- package/src/build-info-repository-noop.strategy.ts +0 -16
- package/src/build-info-repository-package-json.strategy.ts +0 -25
- package/src/build-info-repository.strategy.ts +0 -13
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
import { Retry, type RetryConfig } from "./retry.service";
|
|
4
|
+
import type { SleeperPort } from "./sleeper.port";
|
|
5
|
+
|
|
6
|
+
export type AlertChannelWithRetryAdapterDependencies = { Sleeper: SleeperPort; inner: AlertChannelPort };
|
|
7
|
+
export type AlertChannelWithRetryAdapterConfig = { retry: RetryConfig };
|
|
8
|
+
|
|
9
|
+
export class AlertChannelWithRetryAdapter implements AlertChannelPort {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly config: AlertChannelWithRetryAdapterConfig,
|
|
12
|
+
private readonly deps: AlertChannelWithRetryAdapterDependencies,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
16
|
+
await new Retry(this.deps).run(async () => this.deps.inner.send(alert), this.config.retry);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async verify(): Promise<boolean> {
|
|
20
|
+
return this.deps.inner.verify();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
3
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
4
|
+
import type { TimeoutRunnerPort } from "./timeout-runner.port";
|
|
5
|
+
|
|
6
|
+
export type AlertChannelWithTimeoutAdapterDependencies = {
|
|
7
|
+
TimeoutRunner: TimeoutRunnerPort;
|
|
8
|
+
inner: AlertChannelPort;
|
|
9
|
+
};
|
|
10
|
+
export type AlertChannelWithTimeoutAdapterConfig = { timeout: tools.Duration };
|
|
11
|
+
|
|
12
|
+
export class AlertChannelWithTimeoutAdapter implements AlertChannelPort {
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly config: AlertChannelWithTimeoutAdapterConfig,
|
|
15
|
+
private readonly deps: AlertChannelWithTimeoutAdapterDependencies,
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
19
|
+
await this.deps.TimeoutRunner.run(this.deps.inner.send(alert), this.config.timeout);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async verify(): Promise<boolean> {
|
|
23
|
+
return this.deps.inner.verify();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import {
|
|
3
|
+
AlertChannelWithLoggerAdapter,
|
|
4
|
+
type AlertChannelWithLoggerAdapterDependencies,
|
|
5
|
+
} from "./alert-channel-with-logger.adapter";
|
|
6
|
+
import {
|
|
7
|
+
AlertChannelWithRetryAdapter,
|
|
8
|
+
type AlertChannelWithRetryAdapterConfig,
|
|
9
|
+
type AlertChannelWithRetryAdapterDependencies,
|
|
10
|
+
} from "./alert-channel-with-retry.adapter";
|
|
11
|
+
import {
|
|
12
|
+
AlertChannelWithTimeoutAdapter,
|
|
13
|
+
type AlertChannelWithTimeoutAdapterConfig,
|
|
14
|
+
type AlertChannelWithTimeoutAdapterDependencies,
|
|
15
|
+
} from "./alert-channel-with-timeout.adapter";
|
|
16
|
+
|
|
17
|
+
export class AlertChannelBuilder {
|
|
18
|
+
constructor(private inner: AlertChannelPort) {}
|
|
19
|
+
|
|
20
|
+
static of(channel: AlertChannelPort): AlertChannelBuilder {
|
|
21
|
+
return new AlertChannelBuilder(channel);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
withLogger(deps: Omit<AlertChannelWithLoggerAdapterDependencies, "inner">) {
|
|
25
|
+
this.inner = new AlertChannelWithLoggerAdapter({ ...deps, inner: this.inner });
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
withRetry(
|
|
30
|
+
config: AlertChannelWithRetryAdapterConfig,
|
|
31
|
+
deps: Omit<AlertChannelWithRetryAdapterDependencies, "inner">,
|
|
32
|
+
) {
|
|
33
|
+
this.inner = new AlertChannelWithRetryAdapter(config, { ...deps, inner: this.inner });
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
withTimeout(
|
|
38
|
+
config: AlertChannelWithTimeoutAdapterConfig,
|
|
39
|
+
deps: Omit<AlertChannelWithTimeoutAdapterDependencies, "inner">,
|
|
40
|
+
) {
|
|
41
|
+
this.inner = new AlertChannelWithTimeoutAdapter(config, { ...deps, inner: this.inner });
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
build(): AlertChannelPort {
|
|
46
|
+
return this.inner;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -29,7 +29,7 @@ export class AntivirusClamavAdapter implements AntivirusPort {
|
|
|
29
29
|
const signature = stdout.match(this.signature) ?? stderr.match(this.signature);
|
|
30
30
|
|
|
31
31
|
// Stryker disable all
|
|
32
|
-
return { clean: false, signature: signature?.groups?.signature?.trim() ?? "unknown" };
|
|
32
|
+
return { clean: false, signature: signature?.groups?.["signature"]?.trim() ?? "unknown" };
|
|
33
33
|
// Stryker restore all
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { MiddlewareHandler } from "hono";
|
|
2
2
|
import { ApiVersionMiddleware } from "./api-version.middleware";
|
|
3
|
-
import type {
|
|
3
|
+
import type { BuildInfoType } from "./build-info.vo";
|
|
4
4
|
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
5
5
|
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
6
6
|
import type { MiddlewareHonoPort } from "./middleware-hono.port";
|
|
7
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
7
8
|
|
|
8
9
|
type Dependencies = {
|
|
9
10
|
CacheResolver: CacheResolverStrategy;
|
|
10
11
|
HashContent: HashContentStrategy;
|
|
11
|
-
|
|
12
|
+
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export class ApiVersionHonoMiddleware implements MiddlewareHonoPort {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type * as tools from "@bgord/tools";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BuildInfoType } from "./build-info.vo";
|
|
3
3
|
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
4
4
|
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
5
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
5
6
|
import { SubjectApplicationResolver } from "./subject-application-resolver.vo";
|
|
6
7
|
import { SubjectSegmentFixedStrategy } from "./subject-segment-fixed.strategy";
|
|
7
8
|
|
|
8
9
|
type Dependencies = {
|
|
9
10
|
CacheResolver: CacheResolverStrategy;
|
|
10
11
|
HashContent: HashContentStrategy;
|
|
11
|
-
|
|
12
|
+
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export class ApiVersionMiddleware {
|
|
@@ -16,7 +17,7 @@ export class ApiVersionMiddleware {
|
|
|
16
17
|
|
|
17
18
|
constructor(private readonly deps: Dependencies) {}
|
|
18
19
|
|
|
19
|
-
async evaluate(): Promise<tools.
|
|
20
|
+
async evaluate(): Promise<tools.PackageVersionSchemaType> {
|
|
20
21
|
const resolver = new SubjectApplicationResolver(
|
|
21
22
|
[new SubjectSegmentFixedStrategy("api-version")],
|
|
22
23
|
this.deps,
|
|
@@ -24,7 +25,7 @@ export class ApiVersionMiddleware {
|
|
|
24
25
|
const subject = await resolver.resolve();
|
|
25
26
|
|
|
26
27
|
const build = await this.deps.CacheResolver.resolve(subject.hex, async () =>
|
|
27
|
-
this.deps.
|
|
28
|
+
this.deps.BuildInfoConfig.get(),
|
|
28
29
|
);
|
|
29
30
|
|
|
30
31
|
return build.version;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { CommitShaValue } from "./commit-sha-value.vo";
|
|
4
|
+
|
|
5
|
+
export const BuildInfo = v.object({
|
|
6
|
+
timestamp: tools.TimestampValue,
|
|
7
|
+
version: tools.PackageVersionSchema,
|
|
8
|
+
sha: CommitShaValue,
|
|
9
|
+
size: tools.SizeBytes,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type BuildInfoType = v.InferOutput<typeof BuildInfo>;
|
|
13
|
+
|
|
14
|
+
export const BUILD_INFO_FILE_PATH = tools.FilePathRelative.fromString("infra/build-info.json");
|
|
@@ -8,7 +8,7 @@ export class ErrorNormalizer {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
static isNormalizedError(value: unknown): value is NormalizedError {
|
|
11
|
-
return isPlainObject(value) && "message" in value && typeof value
|
|
11
|
+
return isPlainObject(value) && "message" in value && typeof value["message"] === "string";
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
private static normalizeWithGuard(error: unknown, seen: WeakSet<object>): NormalizedError {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { createFactory } from "hono/factory";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BuildInfoType } from "./build-info.vo";
|
|
3
3
|
import type { ClockPort } from "./clock.port";
|
|
4
4
|
import type { HandlerHonoPort } from "./handler-hono.port";
|
|
5
5
|
import { type HealthcheckConfig, HealthcheckHandler } from "./healthcheck.handler";
|
|
6
6
|
import type { LoggerStatsProviderPort } from "./logger-stats-provider.port";
|
|
7
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
7
8
|
|
|
8
9
|
type Dependencies = {
|
|
9
10
|
Clock: ClockPort;
|
|
10
|
-
|
|
11
|
+
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
11
12
|
LoggerStatsProvider?: LoggerStatsProviderPort;
|
|
12
13
|
};
|
|
13
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import * as tools from "@bgord/tools";
|
|
3
|
-
import type {
|
|
3
|
+
import type { BuildInfoType } from "./build-info.vo";
|
|
4
4
|
import type { ClockPort } from "./clock.port";
|
|
5
5
|
import type { CommitShaValueType } from "./commit-sha-value.vo";
|
|
6
6
|
import { EventLoopLag } from "./event-loop-lag.service";
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type PrerequisiteVerificationResult,
|
|
16
16
|
} from "./prerequisite-verifier.port";
|
|
17
17
|
import { PrerequisiteVerifierSelfAdapter } from "./prerequisite-verifier-self.adapter";
|
|
18
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
18
19
|
import type { RedactorStrategy } from "./redactor.strategy";
|
|
19
20
|
import { Stopwatch } from "./stopwatch.service";
|
|
20
21
|
import { Uptime, type UptimeResultType } from "./uptime.service";
|
|
@@ -27,7 +28,7 @@ export enum HealthcheckStatusEnum {
|
|
|
27
28
|
|
|
28
29
|
type Dependencies = {
|
|
29
30
|
Clock: ClockPort;
|
|
30
|
-
|
|
31
|
+
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
31
32
|
LoggerStatsProvider?: LoggerStatsProviderPort;
|
|
32
33
|
};
|
|
33
34
|
|
|
@@ -125,7 +126,7 @@ export class HealthcheckHandler {
|
|
|
125
126
|
? HealthcheckStatusEnum.degraded
|
|
126
127
|
: HealthcheckStatusEnum.healthy;
|
|
127
128
|
|
|
128
|
-
const build = await this.deps.
|
|
129
|
+
const build = await this.deps.BuildInfoConfig.get();
|
|
129
130
|
const uptime = Uptime.get(this.deps.Clock);
|
|
130
131
|
const histogram = EventLoopLag.snapshot();
|
|
131
132
|
const memory = MemoryConsumption.snapshot();
|
|
@@ -135,11 +136,11 @@ export class HealthcheckHandler {
|
|
|
135
136
|
code: HealthcheckStatusCode[status],
|
|
136
137
|
details,
|
|
137
138
|
deployment: {
|
|
138
|
-
version: build.version
|
|
139
|
-
timestamp: build.timestamp
|
|
140
|
-
date: new Date(build.timestamp
|
|
141
|
-
sha: build.sha
|
|
142
|
-
size: build.size.format(tools.Size.unit.MB),
|
|
139
|
+
version: build.version,
|
|
140
|
+
timestamp: build.timestamp,
|
|
141
|
+
date: new Date(build.timestamp).toISOString(),
|
|
142
|
+
sha: build.sha,
|
|
143
|
+
size: tools.Size.fromBytes(build.size).format(tools.Size.unit.MB),
|
|
143
144
|
environment: this.config.Env,
|
|
144
145
|
},
|
|
145
146
|
server: {
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,17 @@ export * from "./ab-variant.vo";
|
|
|
10
10
|
export * from "./ab-variant-selector.service";
|
|
11
11
|
export * from "./ab-variant-weight.vo";
|
|
12
12
|
export * from "./ab-variants.vo";
|
|
13
|
+
export * from "./alert-channel.builder";
|
|
14
|
+
export * from "./alert-channel.port";
|
|
15
|
+
export * from "./alert-channel-collecting.adapter";
|
|
16
|
+
export * from "./alert-channel-composite.adapter";
|
|
17
|
+
export * from "./alert-channel-mailer.adapter";
|
|
18
|
+
export * from "./alert-channel-noop.adapter";
|
|
19
|
+
export * from "./alert-channel-sms.adapter";
|
|
20
|
+
export * from "./alert-channel-with-logger.adapter";
|
|
21
|
+
export * from "./alert-channel-with-retry.adapter";
|
|
22
|
+
export * from "./alert-channel-with-timeout.adapter";
|
|
23
|
+
export * from "./alert-message.vo";
|
|
13
24
|
export * from "./antivirus.port";
|
|
14
25
|
export * from "./antivirus-clamav.adapter";
|
|
15
26
|
export * from "./antivirus-noop.adapter";
|
|
@@ -24,10 +35,7 @@ export * from "./basic-auth-username.vo";
|
|
|
24
35
|
export * from "./better-auth-logger.service";
|
|
25
36
|
export * from "./binary.vo";
|
|
26
37
|
export * from "./bots.vo";
|
|
27
|
-
export * from "./build-info
|
|
28
|
-
export * from "./build-info-repository-file.strategy";
|
|
29
|
-
export * from "./build-info-repository-noop.strategy";
|
|
30
|
-
export * from "./build-info-repository-package-json.strategy";
|
|
38
|
+
export * from "./build-info.vo";
|
|
31
39
|
export * from "./cache-file.service";
|
|
32
40
|
export * from "./cache-repository.port";
|
|
33
41
|
export * from "./cache-repository-node-cache.adapter";
|
|
@@ -222,6 +230,7 @@ export * from "./logger-stats-provider-noop.adapter";
|
|
|
222
230
|
export * from "./mailer.builder";
|
|
223
231
|
export * from "./mailer.builder";
|
|
224
232
|
export * from "./mailer.port";
|
|
233
|
+
export * from "./mailer-collecting.adapter";
|
|
225
234
|
export * from "./mailer-content-html.vo";
|
|
226
235
|
export * from "./mailer-noop.adapter";
|
|
227
236
|
export * from "./mailer-resend.adapter";
|
|
@@ -281,6 +290,7 @@ export * from "./prerequisite-verifier-port.adapter";
|
|
|
281
290
|
export * from "./prerequisite-verifier-ram.adapter";
|
|
282
291
|
export * from "./prerequisite-verifier-running-user.adapter";
|
|
283
292
|
export * from "./prerequisite-verifier-self.adapter";
|
|
293
|
+
export * from "./prerequisite-verifier-sms.adapter";
|
|
284
294
|
export * from "./prerequisite-verifier-space.adapter";
|
|
285
295
|
export * from "./prerequisite-verifier-sqlite.adapter";
|
|
286
296
|
export * from "./prerequisite-verifier-ssl-certificate-expiry.adapter";
|
|
@@ -290,6 +300,11 @@ export * from "./randomness.strategy";
|
|
|
290
300
|
export * from "./randomness-crypto.strategy";
|
|
291
301
|
export * from "./randomness-math.strategy";
|
|
292
302
|
export * from "./randomness-noop.strategy";
|
|
303
|
+
export * from "./reactive-config.port";
|
|
304
|
+
export * from "./reactive-config-file-json.adapter";
|
|
305
|
+
export * from "./reactive-config-noop.adapter";
|
|
306
|
+
export * from "./reactive-config-with-cache.adapter";
|
|
307
|
+
export * from "./reactive-config-with-fallback.adapter";
|
|
293
308
|
export * from "./readiness.handler";
|
|
294
309
|
export * from "./readiness-hono.handler";
|
|
295
310
|
export * from "./recaptcha-secret-key.vo";
|
|
@@ -373,6 +388,13 @@ export * from "./sleeper-noop.adapter";
|
|
|
373
388
|
export * from "./sleeper-system.adapter";
|
|
374
389
|
export * from "./slower.middleware";
|
|
375
390
|
export * from "./slower-hono.middleware";
|
|
391
|
+
export * from "./sms.builder";
|
|
392
|
+
export * from "./sms.port";
|
|
393
|
+
export * from "./sms-collecting.adapter";
|
|
394
|
+
export * from "./sms-noop.adapter";
|
|
395
|
+
export * from "./sms-with-logger.adapter";
|
|
396
|
+
export * from "./sms-with-retry.adapter";
|
|
397
|
+
export * from "./sms-with-timeout.adapter";
|
|
376
398
|
export * from "./smtp-host.vo";
|
|
377
399
|
export * from "./smtp-pass.vo";
|
|
378
400
|
export * from "./smtp-port.vo";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MailerPort } from "./mailer.port";
|
|
2
|
+
import type { MailerTemplate } from "./mailer-template.vo";
|
|
3
|
+
|
|
4
|
+
export class MailerCollectingAdapter implements MailerPort {
|
|
5
|
+
messages: Array<MailerTemplate> = [];
|
|
6
|
+
|
|
7
|
+
async send(template: MailerTemplate): Promise<void> {
|
|
8
|
+
this.messages.push(template);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async verify(): Promise<boolean> {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PrerequisiteVerification,
|
|
3
|
+
type PrerequisiteVerificationResult,
|
|
4
|
+
type PrerequisiteVerifierPort,
|
|
5
|
+
} from "./prerequisite-verifier.port";
|
|
6
|
+
import type { SmsPort } from "./sms.port";
|
|
7
|
+
|
|
8
|
+
type Dependencies = { Sms: SmsPort };
|
|
9
|
+
|
|
10
|
+
export class PrerequisiteVerifierSmsAdapter implements PrerequisiteVerifierPort {
|
|
11
|
+
constructor(private readonly deps: Dependencies) {}
|
|
12
|
+
|
|
13
|
+
async verify(): Promise<PrerequisiteVerificationResult> {
|
|
14
|
+
try {
|
|
15
|
+
await this.deps.Sms.verify();
|
|
16
|
+
|
|
17
|
+
return PrerequisiteVerification.success;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return PrerequisiteVerification.failure(error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get kind(): string {
|
|
24
|
+
return "sms";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { FileReaderJsonPort } from "./file-reader-json.port";
|
|
3
|
+
import {
|
|
4
|
+
ReactiveConfigError,
|
|
5
|
+
type ReactiveConfigPort,
|
|
6
|
+
type ReactiveConfigSchema,
|
|
7
|
+
} from "./reactive-config.port";
|
|
8
|
+
|
|
9
|
+
type Dependencies = { FileReaderJson: FileReaderJsonPort };
|
|
10
|
+
|
|
11
|
+
export class ReactiveConfigFileJsonAdapter<T extends object> implements ReactiveConfigPort<T> {
|
|
12
|
+
constructor(
|
|
13
|
+
private readonly path: tools.FilePathAbsolute | tools.FilePathRelative,
|
|
14
|
+
private readonly schema: ReactiveConfigSchema<T>,
|
|
15
|
+
private readonly deps: Dependencies,
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
async get(): Promise<Readonly<T>> {
|
|
19
|
+
const raw = await this.deps.FileReaderJson.read(this.path);
|
|
20
|
+
|
|
21
|
+
const result = this.schema["~standard"].validate(raw);
|
|
22
|
+
if (result instanceof Promise) throw new Error(ReactiveConfigError.NoAsyncSchema);
|
|
23
|
+
if (result.issues) throw new Error(result.issues[0]?.message);
|
|
24
|
+
return Object.freeze(result.value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReactiveConfigError,
|
|
3
|
+
type ReactiveConfigPort,
|
|
4
|
+
type ReactiveConfigSchema,
|
|
5
|
+
} from "./reactive-config.port";
|
|
6
|
+
|
|
7
|
+
export class ReactiveConfigNoopAdapter<T extends object> implements ReactiveConfigPort<T> {
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly schema: ReactiveConfigSchema<T>,
|
|
10
|
+
private readonly value: T,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
async get(): Promise<Readonly<T>> {
|
|
14
|
+
const result = this.schema["~standard"].validate(this.value);
|
|
15
|
+
if (result instanceof Promise) throw new Error(ReactiveConfigError.NoAsyncSchema);
|
|
16
|
+
if (result.issues) throw new Error(result.issues[0]?.message);
|
|
17
|
+
return Object.freeze(result.value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
2
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
3
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
4
|
+
|
|
5
|
+
type Dependencies = { CacheResolver: CacheResolverStrategy; HashContent: HashContentStrategy };
|
|
6
|
+
|
|
7
|
+
export class ReactiveConfigWithCacheAdapter<T extends object> implements ReactiveConfigPort<T> {
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly inner: ReactiveConfigPort<T>,
|
|
10
|
+
private readonly subject: string,
|
|
11
|
+
private readonly deps: Dependencies,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
14
|
+
async get(): Promise<Readonly<T>> {
|
|
15
|
+
const key = await this.deps.HashContent.hash(this.subject);
|
|
16
|
+
|
|
17
|
+
return this.deps.CacheResolver.resolve(key, () => this.inner.get());
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReactiveConfigError,
|
|
3
|
+
type ReactiveConfigPort,
|
|
4
|
+
type ReactiveConfigSchema,
|
|
5
|
+
} from "./reactive-config.port";
|
|
6
|
+
|
|
7
|
+
export class ReactiveConfigWithFallbackAdapter<T extends object> implements ReactiveConfigPort<T> {
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly inner: ReactiveConfigPort<T>,
|
|
10
|
+
private readonly schema: ReactiveConfigSchema<T>,
|
|
11
|
+
private readonly fallback: T,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
14
|
+
async get(): Promise<Readonly<T>> {
|
|
15
|
+
try {
|
|
16
|
+
return await this.inner.get();
|
|
17
|
+
} catch {
|
|
18
|
+
const result = this.schema["~standard"].validate(this.fallback);
|
|
19
|
+
if (result instanceof Promise) throw new Error(ReactiveConfigError.NoAsyncSchema);
|
|
20
|
+
if (result.issues) throw new Error(result.issues[0]?.message);
|
|
21
|
+
return Object.freeze(result.value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
export const ReactiveConfigError = { NoAsyncSchema: "reactive.config.no.async.schema" };
|
|
4
|
+
|
|
5
|
+
export type ReactiveConfigSchema<T extends object> = StandardSchemaV1<unknown, T>;
|
|
6
|
+
|
|
7
|
+
export interface ReactiveConfigPort<T extends object> {
|
|
8
|
+
get(): Promise<Readonly<T>>;
|
|
9
|
+
}
|
|
@@ -10,9 +10,8 @@ export class RedactorErrorCauseDepthLimit implements RedactorStrategy {
|
|
|
10
10
|
// Stryker disable all
|
|
11
11
|
if (!isPlainObject(input)) return input;
|
|
12
12
|
// Stryker restore all
|
|
13
|
-
if (!ErrorNormalizer.isNormalizedError(input
|
|
14
|
-
|
|
15
|
-
return { ...input, error: this.limit(input.error, tools.Int.nonNegative(0)) };
|
|
13
|
+
if (!ErrorNormalizer.isNormalizedError(input["error"])) return input;
|
|
14
|
+
return { ...input, error: this.limit(input["error"], tools.Int.nonNegative(0)) };
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
private limit(error: NormalizedError, depth: tools.IntegerNonNegativeType): NormalizedError {
|
|
@@ -7,9 +7,8 @@ export class RedactorErrorStackHide implements RedactorStrategy {
|
|
|
7
7
|
// Stryker disable all
|
|
8
8
|
if (!isPlainObject(input)) return input;
|
|
9
9
|
// Stryker restore all
|
|
10
|
-
if (!ErrorNormalizer.isNormalizedError(input
|
|
11
|
-
|
|
12
|
-
return { ...input, error: this.hide(input.error) };
|
|
10
|
+
if (!ErrorNormalizer.isNormalizedError(input["error"])) return input;
|
|
11
|
+
return { ...input, error: this.hide(input["error"]) };
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
private hide(error: NormalizedError): NormalizedError {
|
|
@@ -20,7 +20,7 @@ export class RedactorMetadataCompactArray implements RedactorStrategy {
|
|
|
20
20
|
return {
|
|
21
21
|
...input,
|
|
22
22
|
metadata: deepCloneWith(
|
|
23
|
-
input
|
|
23
|
+
input["metadata"],
|
|
24
24
|
(value) => {
|
|
25
25
|
if (!Array.isArray(value)) return undefined;
|
|
26
26
|
if (value.length <= this.maxItems) return undefined;
|
|
@@ -3,7 +3,7 @@ import type { MiddlewareHandler } from "hono";
|
|
|
3
3
|
import { cors } from "hono/cors";
|
|
4
4
|
import { secureHeaders } from "hono/secure-headers";
|
|
5
5
|
import { ApiVersionHonoMiddleware } from "./api-version-hono.middleware";
|
|
6
|
-
import type {
|
|
6
|
+
import type { BuildInfoType } from "./build-info.vo";
|
|
7
7
|
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
8
8
|
import type { ClockPort } from "./clock.port";
|
|
9
9
|
import { CorrelationHonoMiddleware } from "./correlation-hono.middleware";
|
|
@@ -15,6 +15,7 @@ import type { IdProviderPort } from "./id-provider.port";
|
|
|
15
15
|
import type { LanguageDetectorMiddlewareConfig } from "./language-detector.middleware";
|
|
16
16
|
import { LanguageDetectorHonoMiddleware } from "./language-detector-hono.middleware";
|
|
17
17
|
import type { LoggerPort } from "./logger.port";
|
|
18
|
+
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
18
19
|
import type { ShieldCsrfConfig } from "./shield-csrf.strategy";
|
|
19
20
|
import { ShieldCsrfHonoStrategy } from "./shield-csrf-hono.strategy";
|
|
20
21
|
import type { ShieldMaintenanceConfig } from "./shield-maintenance.strategy";
|
|
@@ -30,7 +31,7 @@ type Dependencies = {
|
|
|
30
31
|
Clock: ClockPort;
|
|
31
32
|
CacheResolver: CacheResolverStrategy;
|
|
32
33
|
HashContent: HashContentStrategy;
|
|
33
|
-
|
|
34
|
+
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
type Config<T extends tools.LanguageType> = {
|
|
@@ -19,7 +19,7 @@ export class ShieldRecaptchaStrategy {
|
|
|
19
19
|
async evaluate(context: HasRequestHeader & HasRequestQuery, formToken: string | null): Promise<boolean> {
|
|
20
20
|
try {
|
|
21
21
|
const header = context.request.header("x-recaptcha-token");
|
|
22
|
-
const query = context.request.query()
|
|
22
|
+
const query = context.request.query()["recaptchaToken"];
|
|
23
23
|
const remoteip = context.request.header("x-forwarded-for") ?? "";
|
|
24
24
|
|
|
25
25
|
const token = header ?? query ?? formToken;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { SmsPort } from "./sms.port";
|
|
3
|
+
|
|
4
|
+
export class SmsCollectingAdapter implements SmsPort {
|
|
5
|
+
readonly messages: Array<tools.SmsMessage> = [];
|
|
6
|
+
|
|
7
|
+
async send(message: tools.SmsMessage): Promise<void> {
|
|
8
|
+
this.messages.push(message);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async verify(): Promise<boolean> {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { SmsPort } from "./sms.port";
|
|
3
|
+
|
|
4
|
+
export class SmsNoopAdapter implements SmsPort {
|
|
5
|
+
async send(_message: tools.SmsMessage): Promise<void> {}
|
|
6
|
+
|
|
7
|
+
async verify(): Promise<boolean> {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { ClockPort } from "./clock.port";
|
|
3
|
+
import type { LoggerPort } from "./logger.port";
|
|
4
|
+
import type { SmsPort } from "./sms.port";
|
|
5
|
+
import { Stopwatch } from "./stopwatch.service";
|
|
6
|
+
|
|
7
|
+
export type SmsWithLoggerAdapterDependencies = { inner: SmsPort; Logger: LoggerPort; Clock: ClockPort };
|
|
8
|
+
|
|
9
|
+
export class SmsWithLoggerAdapter implements SmsPort {
|
|
10
|
+
private readonly base = { component: "infra", operation: "sms" };
|
|
11
|
+
|
|
12
|
+
constructor(private readonly deps: SmsWithLoggerAdapterDependencies) {}
|
|
13
|
+
|
|
14
|
+
async send(message: tools.SmsMessage): Promise<void> {
|
|
15
|
+
const duration = new Stopwatch(this.deps);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
this.deps.Logger.info({ message: "SMS attempt", metadata: message.toJSON(), ...this.base });
|
|
19
|
+
|
|
20
|
+
await this.deps.inner.send(message);
|
|
21
|
+
|
|
22
|
+
this.deps.Logger.info({
|
|
23
|
+
message: "SMS success",
|
|
24
|
+
metadata: { message: message.toJSON(), duration: duration.stop() },
|
|
25
|
+
...this.base,
|
|
26
|
+
});
|
|
27
|
+
} catch (error) {
|
|
28
|
+
this.deps.Logger.error({ message: "SMS error", error, metadata: duration.stop(), ...this.base });
|
|
29
|
+
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async verify(): Promise<boolean> {
|
|
35
|
+
return this.deps.inner.verify();
|
|
36
|
+
}
|
|
37
|
+
}
|