@bgord/bun 1.15.3 → 1.15.5
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/cache-repository-redis.adapter.d.ts +13 -0
- package/dist/cache-repository-redis.adapter.d.ts.map +1 -0
- package/dist/cache-repository-redis.adapter.js +27 -0
- package/dist/cache-repository-redis.adapter.js.map +1 -0
- 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 +1 -2
- package/dist/healthcheck-hono.handler.js.map +1 -1
- package/dist/healthcheck.handler.d.ts +12 -1
- package/dist/healthcheck.handler.d.ts.map +1 -1
- package/dist/healthcheck.handler.js +20 -2
- package/dist/healthcheck.handler.js.map +1 -1
- package/dist/image-grayscale-noop.adapter.d.ts +6 -0
- package/dist/image-grayscale-noop.adapter.d.ts.map +1 -0
- package/dist/image-grayscale-noop.adapter.js +6 -0
- package/dist/image-grayscale-noop.adapter.js.map +1 -0
- package/dist/image-grayscale-sharp.adapter.d.ts +19 -0
- package/dist/image-grayscale-sharp.adapter.d.ts.map +1 -0
- package/dist/image-grayscale-sharp.adapter.js +28 -0
- package/dist/image-grayscale-sharp.adapter.js.map +1 -0
- package/dist/image-grayscale.port.d.ts +15 -0
- package/dist/image-grayscale.port.d.ts.map +1 -0
- package/dist/image-grayscale.port.js +2 -0
- package/dist/image-grayscale.port.js.map +1 -0
- package/dist/index.d.ts +37 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -3
- package/dist/index.js.map +1 -1
- package/dist/liveness-hono.handler.d.ts +8 -0
- package/dist/liveness-hono.handler.d.ts.map +1 -0
- package/dist/liveness-hono.handler.js +10 -0
- package/dist/liveness-hono.handler.js.map +1 -0
- package/dist/liveness.handler.d.ts +6 -0
- package/dist/liveness.handler.d.ts.map +1 -0
- package/dist/liveness.handler.js +6 -0
- package/dist/liveness.handler.js.map +1 -0
- 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/randomness-crypto.strategy.d.ts +5 -0
- package/dist/randomness-crypto.strategy.d.ts.map +1 -0
- package/dist/randomness-crypto.strategy.js +8 -0
- package/dist/randomness-crypto.strategy.js.map +1 -0
- package/dist/randomness-math.strategy.d.ts +5 -0
- package/dist/randomness-math.strategy.d.ts.map +1 -0
- package/dist/randomness-math.strategy.js +6 -0
- package/dist/randomness-math.strategy.js.map +1 -0
- package/dist/randomness-noop.strategy.d.ts +7 -0
- package/dist/randomness-noop.strategy.d.ts.map +1 -0
- package/dist/randomness-noop.strategy.js +10 -0
- package/dist/randomness-noop.strategy.js.map +1 -0
- package/dist/randomness.strategy.d.ts +4 -0
- package/dist/randomness.strategy.d.ts.map +1 -0
- package/dist/randomness.strategy.js +2 -0
- package/dist/randomness.strategy.js.map +1 -0
- package/dist/readiness-hono.handler.d.ts +26 -0
- package/dist/readiness-hono.handler.d.ts.map +1 -0
- package/dist/readiness-hono.handler.js +17 -0
- package/dist/readiness-hono.handler.js.map +1 -0
- package/dist/readiness.handler.d.ts +19 -0
- package/dist/readiness.handler.d.ts.map +1 -0
- package/dist/readiness.handler.js +19 -0
- package/dist/readiness.handler.js.map +1 -0
- package/dist/retry-backoff-jitter.strategy.d.ts +10 -0
- package/dist/retry-backoff-jitter.strategy.d.ts.map +1 -0
- package/dist/retry-backoff-jitter.strategy.js +14 -0
- package/dist/retry-backoff-jitter.strategy.js.map +1 -0
- package/dist/shield-ip-blacklist-hono.strategy.d.ts +11 -0
- package/dist/shield-ip-blacklist-hono.strategy.d.ts.map +1 -0
- package/dist/shield-ip-blacklist-hono.strategy.js +21 -0
- package/dist/shield-ip-blacklist-hono.strategy.js.map +1 -0
- package/dist/shield-ip-blacklist.strategy.d.ts +14 -0
- package/dist/shield-ip-blacklist.strategy.d.ts.map +1 -0
- package/dist/shield-ip-blacklist.strategy.js +16 -0
- package/dist/shield-ip-blacklist.strategy.js.map +1 -0
- package/dist/shield-ip-whitelist-hono.strategy.d.ts +11 -0
- package/dist/shield-ip-whitelist-hono.strategy.d.ts.map +1 -0
- package/dist/shield-ip-whitelist-hono.strategy.js +21 -0
- package/dist/shield-ip-whitelist-hono.strategy.js.map +1 -0
- package/dist/shield-ip-whitelist.strategy.d.ts +14 -0
- package/dist/shield-ip-whitelist.strategy.d.ts.map +1 -0
- package/dist/shield-ip-whitelist.strategy.js +16 -0
- package/dist/shield-ip-whitelist.strategy.js.map +1 -0
- 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/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/readme.md +37 -3
- 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/cache-repository-redis.adapter.ts +31 -0
- package/src/healthcheck-hono.handler.ts +1 -2
- package/src/healthcheck.handler.ts +28 -3
- package/src/image-grayscale-noop.adapter.ts +8 -0
- package/src/image-grayscale-sharp.adapter.ts +45 -0
- package/src/image-grayscale.port.ts +16 -0
- package/src/index.ts +37 -3
- package/src/liveness-hono.handler.ts +13 -0
- package/src/liveness.handler.ts +5 -0
- package/src/mailer-collecting.adapter.ts +14 -0
- package/src/prerequisite-verifier-sms.adapter.ts +26 -0
- package/src/randomness-crypto.strategy.ts +9 -0
- package/src/randomness-math.strategy.ts +7 -0
- package/src/randomness-noop.strategy.ts +9 -0
- package/src/randomness.strategy.ts +3 -0
- package/src/readiness-hono.handler.ts +22 -0
- package/src/readiness.handler.ts +33 -0
- package/src/retry-backoff-jitter.strategy.ts +15 -0
- package/src/shield-ip-blacklist-hono.strategy.ts +30 -0
- package/src/shield-ip-blacklist.strategy.ts +18 -0
- package/src/shield-ip-whitelist-hono.strategy.ts +30 -0
- package/src/shield-ip-whitelist.strategy.ts +18 -0
- 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/ping-hono.handler.d.ts +0 -6
- package/dist/ping-hono.handler.d.ts.map +0 -1
- package/dist/ping-hono.handler.js +0 -13
- package/dist/ping-hono.handler.js.map +0 -1
- package/dist/ping.handler.d.ts +0 -4
- package/dist/ping.handler.d.ts.map +0 -1
- package/dist/ping.handler.js +0 -6
- package/dist/ping.handler.js.map +0 -1
- package/dist/retry-backoff-fibonacci.strategy.d.ts +0 -9
- package/dist/retry-backoff-fibonacci.strategy.d.ts.map +0 -1
- package/dist/retry-backoff-fibonacci.strategy.js +0 -19
- package/dist/retry-backoff-fibonacci.strategy.js.map +0 -1
- package/src/ping-hono.handler.ts +0 -17
- package/src/ping.handler.ts +0 -5
- package/src/retry-backoff-fibonacci.strategy.ts +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/bun",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Bartosz Gordon",
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
"preinstall": "bunx only-allow bun"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@biomejs/biome": "2.4.
|
|
23
|
+
"@biomejs/biome": "2.4.8",
|
|
24
24
|
"@commitlint/cli": "20.5.0",
|
|
25
25
|
"@commitlint/config-conventional": "20.5.0",
|
|
26
26
|
"@standard-schema/spec": "1.1.0",
|
|
27
27
|
"@stryker-mutator/core": "9.6.0",
|
|
28
|
-
"@types/bun": "1.3.
|
|
28
|
+
"@types/bun": "1.3.11",
|
|
29
29
|
"@types/nodemailer": "7.0.11",
|
|
30
30
|
"@types/yazl": "3.3.0",
|
|
31
|
-
"better-auth": "1.5.
|
|
31
|
+
"better-auth": "1.5.6",
|
|
32
32
|
"cspell": "9.7.0",
|
|
33
|
-
"csv": "6.5.
|
|
34
|
-
"knip": "
|
|
33
|
+
"csv": "6.5.1",
|
|
34
|
+
"knip": "6.0.2",
|
|
35
35
|
"lefthook": "2.1.4",
|
|
36
36
|
"lockfile-lint": "5.0.0",
|
|
37
|
-
"nodemailer": "8.0.
|
|
37
|
+
"nodemailer": "8.0.3",
|
|
38
38
|
"only-allow": "1.2.2",
|
|
39
39
|
"resend": "6.9.4",
|
|
40
40
|
"sharp": "0.34.5",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"yazl": "3.3.1"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@bgord/tools": "1.4.
|
|
46
|
+
"@bgord/tools": "1.4.4",
|
|
47
47
|
"emittery": "2.0.0",
|
|
48
48
|
"hono": "4.12.8",
|
|
49
49
|
"node-cache": "5.1.2"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"better-auth": "1.5.
|
|
53
|
-
"csv": "6.5.
|
|
54
|
-
"nodemailer": "8.0.
|
|
52
|
+
"better-auth": "1.5.6",
|
|
53
|
+
"csv": "6.5.1",
|
|
54
|
+
"nodemailer": "8.0.3",
|
|
55
55
|
"resend": "6.9.4",
|
|
56
56
|
"sharp": "0.34.5",
|
|
57
57
|
"yazl": "3.3.1"
|
package/readme.md
CHANGED
|
@@ -36,6 +36,17 @@ src/
|
|
|
36
36
|
├── ab-variant.vo.ts
|
|
37
37
|
├── ab-variants.vo.ts
|
|
38
38
|
├── ab.middleware.ts
|
|
39
|
+
├── alert-channel-collecting.adapter.ts
|
|
40
|
+
├── alert-channel-composite.adapter.ts
|
|
41
|
+
├── alert-channel-mailer.adapter.ts
|
|
42
|
+
├── alert-channel-noop.adapter.ts
|
|
43
|
+
├── alert-channel-sms.adapter.ts
|
|
44
|
+
├── alert-channel-with-logger.adapter.ts
|
|
45
|
+
├── alert-channel-with-retry.adapter.ts
|
|
46
|
+
├── alert-channel-with-timeout.adapter.ts
|
|
47
|
+
├── alert-channel.builder.ts
|
|
48
|
+
├── alert-channel.port.ts
|
|
49
|
+
├── alert-message.vo.ts
|
|
39
50
|
├── antivirus-clamav.adapter.ts
|
|
40
51
|
├── antivirus-noop.adapter.ts
|
|
41
52
|
├── antivirus.port.ts
|
|
@@ -57,6 +68,7 @@ src/
|
|
|
57
68
|
├── cache-file.service.ts
|
|
58
69
|
├── cache-repository-node-cache.adapter.ts
|
|
59
70
|
├── cache-repository-noop.adapter.ts
|
|
71
|
+
├── cache-repository-redis.adapter.ts
|
|
60
72
|
├── cache-repository.port.ts
|
|
61
73
|
├── cache-resolver-simple.strategy.ts
|
|
62
74
|
├── cache-resolver.strategy.ts
|
|
@@ -209,6 +221,9 @@ src/
|
|
|
209
221
|
├── image-formatter-noop.adapter.ts
|
|
210
222
|
├── image-formatter-sharp.adapter.ts
|
|
211
223
|
├── image-formatter.port.ts
|
|
224
|
+
├── image-grayscale-noop.adapter.ts
|
|
225
|
+
├── image-grayscale-sharp.adapter.ts
|
|
226
|
+
├── image-grayscale.port.ts
|
|
212
227
|
├── image-info-noop.adapter.ts
|
|
213
228
|
├── image-info-sharp.adapter.ts
|
|
214
229
|
├── image-info.port.ts
|
|
@@ -237,11 +252,14 @@ src/
|
|
|
237
252
|
├── language-detector.middleware.ts
|
|
238
253
|
├── language-detector.strategy.ts
|
|
239
254
|
├── languages.vo.ts
|
|
255
|
+
├── liveness-hono.handler.ts
|
|
256
|
+
├── liveness.handler.ts
|
|
240
257
|
├── logger-collecting.adapter.ts
|
|
241
258
|
├── logger-noop.adapter.ts
|
|
242
259
|
├── logger-stats-provider-noop.adapter.ts
|
|
243
260
|
├── logger-stats-provider.port.ts
|
|
244
261
|
├── logger.port.ts
|
|
262
|
+
├── mailer-collecting.adapter.ts
|
|
245
263
|
├── mailer-content-html.vo.ts
|
|
246
264
|
├── mailer-noop.adapter.ts
|
|
247
265
|
├── mailer-resend.adapter.ts
|
|
@@ -319,8 +337,6 @@ src/
|
|
|
319
337
|
├── pdf-generator-noop.adapter.ts
|
|
320
338
|
├── pdf-generator-with-logger.adapter.ts
|
|
321
339
|
├── pdf-generator.port.ts
|
|
322
|
-
├── ping-hono.handler.ts
|
|
323
|
-
├── ping.handler.ts
|
|
324
340
|
├── port.vo.ts
|
|
325
341
|
├── prerequisite-runner-startup.service.ts
|
|
326
342
|
├── prerequisite-verifier-binary.adapter.ts
|
|
@@ -340,6 +356,7 @@ src/
|
|
|
340
356
|
├── prerequisite-verifier-ram.adapter.ts
|
|
341
357
|
├── prerequisite-verifier-running-user.adapter.ts
|
|
342
358
|
├── prerequisite-verifier-self.adapter.ts
|
|
359
|
+
├── prerequisite-verifier-sms.adapter.ts
|
|
343
360
|
├── prerequisite-verifier-space.adapter.ts
|
|
344
361
|
├── prerequisite-verifier-sqlite.adapter.ts
|
|
345
362
|
├── prerequisite-verifier-ssl-certificate-expiry.adapter.ts
|
|
@@ -353,6 +370,12 @@ src/
|
|
|
353
370
|
├── prerequisite-verifier.decorator.ts
|
|
354
371
|
├── prerequisite-verifier.port.ts
|
|
355
372
|
├── prerequisite.vo.ts
|
|
373
|
+
├── randomness-crypto.strategy.ts
|
|
374
|
+
├── randomness-math.strategy.ts
|
|
375
|
+
├── randomness-noop.strategy.ts
|
|
376
|
+
├── randomness.strategy.ts
|
|
377
|
+
├── readiness-hono.handler.ts
|
|
378
|
+
├── readiness.handler.ts
|
|
356
379
|
├── recaptcha-secret-key.vo.ts
|
|
357
380
|
├── recaptcha-site-key.vo.ts
|
|
358
381
|
├── redactor-composite.strategy.ts
|
|
@@ -369,7 +392,7 @@ src/
|
|
|
369
392
|
├── request-context-hono.adapter.ts
|
|
370
393
|
├── request-context.port.ts
|
|
371
394
|
├── retry-backoff-exponential.strategy.ts
|
|
372
|
-
├── retry-backoff-
|
|
395
|
+
├── retry-backoff-jitter.strategy.ts
|
|
373
396
|
├── retry-backoff-linear.strategy.ts
|
|
374
397
|
├── retry-backoff-noop.strategy.ts
|
|
375
398
|
├── retry-backoff.strategy.ts
|
|
@@ -413,6 +436,10 @@ src/
|
|
|
413
436
|
├── shield-hcaptcha-hono-local.strategy.ts
|
|
414
437
|
├── shield-hcaptcha-hono.strategy.ts
|
|
415
438
|
├── shield-hcaptcha.strategy.ts
|
|
439
|
+
├── shield-ip-blacklist-hono.strategy.ts
|
|
440
|
+
├── shield-ip-blacklist.strategy.ts
|
|
441
|
+
├── shield-ip-whitelist-hono.strategy.ts
|
|
442
|
+
├── shield-ip-whitelist.strategy.ts
|
|
416
443
|
├── shield-maintenance-hono.strategy.ts
|
|
417
444
|
├── shield-maintenance.strategy.ts
|
|
418
445
|
├── shield-rate-limit-hono.strategy.ts
|
|
@@ -430,6 +457,13 @@ src/
|
|
|
430
457
|
├── sleeper.port.ts
|
|
431
458
|
├── slower-hono.middleware.ts
|
|
432
459
|
├── slower.middleware.ts
|
|
460
|
+
├── sms-collecting.adapter.ts
|
|
461
|
+
├── sms-noop.adapter.ts
|
|
462
|
+
├── sms-with-logger.adapter.ts
|
|
463
|
+
├── sms-with-retry.adapter.ts
|
|
464
|
+
├── sms-with-timeout.adapter.ts
|
|
465
|
+
├── sms.builder.ts
|
|
466
|
+
├── sms.port.ts
|
|
433
467
|
├── smtp-host.vo.ts
|
|
434
468
|
├── smtp-pass.vo.ts
|
|
435
469
|
├── smtp-port.vo.ts
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
|
|
4
|
+
export class AlertChannelCollectingAdapter implements AlertChannelPort {
|
|
5
|
+
readonly alerts: Array<AlertMessage> = [];
|
|
6
|
+
|
|
7
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
8
|
+
this.alerts.push(alert);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async verify(): Promise<boolean> {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
|
|
4
|
+
export const AlertChannelCompositeError = {
|
|
5
|
+
Min: "alert.channel.composite.channels.min",
|
|
6
|
+
Max: "alert.channel.composite.channels.max",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class AlertChannelCompositeAdapter implements AlertChannelPort {
|
|
10
|
+
constructor(private readonly channels: ReadonlyArray<AlertChannelPort>) {
|
|
11
|
+
if (this.channels.length === 0) throw new Error(AlertChannelCompositeError.Min);
|
|
12
|
+
if (this.channels.length > 5) throw new Error(AlertChannelCompositeError.Max);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
16
|
+
await Promise.allSettled(this.channels.map((channel) => channel.send(alert)));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async verify(): Promise<boolean> {
|
|
20
|
+
const checks = await Promise.all(this.channels.map((channel) => channel.verify()));
|
|
21
|
+
|
|
22
|
+
return checks.every(Boolean);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
import type { MailerPort } from "./mailer.port";
|
|
4
|
+
import type { MailerTemplate } from "./mailer-template.vo";
|
|
5
|
+
|
|
6
|
+
export type AlertChannelMailerAdapterConfig = { template: (alert: AlertMessage) => MailerTemplate };
|
|
7
|
+
export type AlertChannelMailerAdapterDependencies = { Mailer: MailerPort };
|
|
8
|
+
|
|
9
|
+
export class AlertChannelMailerAdapter implements AlertChannelPort {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly config: AlertChannelMailerAdapterConfig,
|
|
12
|
+
private readonly deps: AlertChannelMailerAdapterDependencies,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
16
|
+
await this.deps.Mailer.send(this.config.template(alert));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async verify(): Promise<boolean> {
|
|
20
|
+
return this.deps.Mailer.verify();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
|
|
4
|
+
export class AlertChannelNoopAdapter implements AlertChannelPort {
|
|
5
|
+
async send(_alert: AlertMessage): Promise<void> {}
|
|
6
|
+
|
|
7
|
+
async verify(): Promise<boolean> {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 { SmsPort } from "./sms.port";
|
|
5
|
+
|
|
6
|
+
export type AlertChannelSmsAdapterConfig = { message: (alert: AlertMessage) => tools.SmsMessage };
|
|
7
|
+
export type AlertChannelSmsAdapterDependencies = { Sms: SmsPort };
|
|
8
|
+
|
|
9
|
+
export class AlertChannelSmsAdapter implements AlertChannelPort {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly config: AlertChannelSmsAdapterConfig,
|
|
12
|
+
private readonly deps: AlertChannelSmsAdapterDependencies,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
16
|
+
await this.deps.Sms.send(this.config.message(alert));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async verify(): Promise<boolean> {
|
|
20
|
+
return this.deps.Sms.verify();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AlertChannelPort } from "./alert-channel.port";
|
|
2
|
+
import type { AlertMessage } from "./alert-message.vo";
|
|
3
|
+
import type { ClockPort } from "./clock.port";
|
|
4
|
+
import type { LoggerPort } from "./logger.port";
|
|
5
|
+
import { Stopwatch } from "./stopwatch.service";
|
|
6
|
+
|
|
7
|
+
export type AlertChannelWithLoggerAdapterDependencies = {
|
|
8
|
+
inner: AlertChannelPort;
|
|
9
|
+
Logger: LoggerPort;
|
|
10
|
+
Clock: ClockPort;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class AlertChannelWithLoggerAdapter implements AlertChannelPort {
|
|
14
|
+
private readonly base = { component: "infra", operation: "alert_channel" };
|
|
15
|
+
|
|
16
|
+
constructor(private readonly deps: AlertChannelWithLoggerAdapterDependencies) {}
|
|
17
|
+
|
|
18
|
+
async send(alert: AlertMessage): Promise<void> {
|
|
19
|
+
const duration = new Stopwatch(this.deps);
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
this.deps.Logger.info({ message: "Alert channel attempt", metadata: alert.toJSON(), ...this.base });
|
|
23
|
+
|
|
24
|
+
await this.deps.inner.send(alert);
|
|
25
|
+
|
|
26
|
+
this.deps.Logger.info({
|
|
27
|
+
message: "Alert channel success",
|
|
28
|
+
metadata: { alert: alert.toJSON(), duration: duration.stop() },
|
|
29
|
+
...this.base,
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {
|
|
32
|
+
this.deps.Logger.error({
|
|
33
|
+
message: "Alert channel error",
|
|
34
|
+
error,
|
|
35
|
+
metadata: duration.stop(),
|
|
36
|
+
...this.base,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async verify(): Promise<boolean> {
|
|
44
|
+
return this.deps.inner.verify();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RedisClient } from "bun";
|
|
2
|
+
import type { CacheRepositoryPort, CacheRepositoryTtlType } from "./cache-repository.port";
|
|
3
|
+
import type { Hash } from "./hash.vo";
|
|
4
|
+
|
|
5
|
+
export class CacheRepositoryRedisAdapter implements CacheRepositoryPort {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly client: RedisClient,
|
|
8
|
+
private readonly config: CacheRepositoryTtlType,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
async get<T>(subject: Hash): Promise<T | null> {
|
|
12
|
+
const value = await this.client.get(subject.get());
|
|
13
|
+
if (value === null) return null;
|
|
14
|
+
return JSON.parse(value) as T;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async set<T>(subject: Hash, value: T): Promise<void> {
|
|
18
|
+
await this.client.set(subject.get(), JSON.stringify(value));
|
|
19
|
+
if (this.config.type === "finite") {
|
|
20
|
+
await this.client.expire(subject.get(), this.config.ttl.seconds);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async delete(subject: Hash): Promise<void> {
|
|
25
|
+
await this.client.del(subject.get());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async flush(): Promise<void> {
|
|
29
|
+
await this.client.send("FLUSHALL", []);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -23,9 +23,8 @@ export class HealthcheckHonoHandler implements HandlerHonoPort {
|
|
|
23
23
|
handle() {
|
|
24
24
|
return factory.createHandlers(async (c) => {
|
|
25
25
|
const healthcheck = await this.handler.check();
|
|
26
|
-
const code = healthcheck.ok ? 200 : 424;
|
|
27
26
|
|
|
28
|
-
return c.json(healthcheck, code);
|
|
27
|
+
return c.json(healthcheck, healthcheck.code);
|
|
29
28
|
});
|
|
30
29
|
}
|
|
31
30
|
}
|
|
@@ -19,6 +19,12 @@ import type { RedactorStrategy } from "./redactor.strategy";
|
|
|
19
19
|
import { Stopwatch } from "./stopwatch.service";
|
|
20
20
|
import { Uptime, type UptimeResultType } from "./uptime.service";
|
|
21
21
|
|
|
22
|
+
export enum HealthcheckStatusEnum {
|
|
23
|
+
healthy = "healthy",
|
|
24
|
+
degraded = "degraded",
|
|
25
|
+
unhealthy = "unhealthy",
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
type Dependencies = {
|
|
23
29
|
Clock: ClockPort;
|
|
24
30
|
BuildInfoRepository: BuildInfoRepositoryStrategy;
|
|
@@ -33,8 +39,15 @@ export type HealthcheckConfig = {
|
|
|
33
39
|
|
|
34
40
|
const self = new Prerequisite("self", new PrerequisiteVerifierSelfAdapter());
|
|
35
41
|
|
|
42
|
+
export const HealthcheckStatusCode = {
|
|
43
|
+
[HealthcheckStatusEnum.healthy]: 200,
|
|
44
|
+
[HealthcheckStatusEnum.degraded]: 207,
|
|
45
|
+
[HealthcheckStatusEnum.unhealthy]: 424,
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
36
48
|
export type HealthcheckResult = {
|
|
37
|
-
|
|
49
|
+
status: HealthcheckStatusEnum;
|
|
50
|
+
code: (typeof HealthcheckStatusCode)[keyof typeof HealthcheckStatusCode];
|
|
38
51
|
deployment: {
|
|
39
52
|
version: string;
|
|
40
53
|
timestamp: tools.TimestampValueType;
|
|
@@ -99,7 +112,18 @@ export class HealthcheckHandler {
|
|
|
99
112
|
}),
|
|
100
113
|
);
|
|
101
114
|
|
|
102
|
-
const
|
|
115
|
+
const hasFailure = details.some(
|
|
116
|
+
(result) => result.outcome.outcome === PrerequisiteVerificationOutcome.failure,
|
|
117
|
+
);
|
|
118
|
+
const hasUndetermined = details.some(
|
|
119
|
+
(result) => result.outcome.outcome === PrerequisiteVerificationOutcome.undetermined,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const status = hasFailure
|
|
123
|
+
? HealthcheckStatusEnum.unhealthy
|
|
124
|
+
: hasUndetermined
|
|
125
|
+
? HealthcheckStatusEnum.degraded
|
|
126
|
+
: HealthcheckStatusEnum.healthy;
|
|
103
127
|
|
|
104
128
|
const build = await this.deps.BuildInfoRepository.extract();
|
|
105
129
|
const uptime = Uptime.get(this.deps.Clock);
|
|
@@ -107,7 +131,8 @@ export class HealthcheckHandler {
|
|
|
107
131
|
const memory = MemoryConsumption.snapshot();
|
|
108
132
|
|
|
109
133
|
return {
|
|
110
|
-
|
|
134
|
+
status,
|
|
135
|
+
code: HealthcheckStatusCode[status],
|
|
111
136
|
details,
|
|
112
137
|
deployment: {
|
|
113
138
|
version: build.version.toString(),
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { ImageGrayscalePort, ImageGrayscaleStrategy } from "./image-grayscale.port";
|
|
3
|
+
|
|
4
|
+
export class ImageGrayscaleNoopAdapter implements ImageGrayscalePort {
|
|
5
|
+
async grayscale(recipe: ImageGrayscaleStrategy): Promise<tools.FilePathRelative | tools.FilePathAbsolute> {
|
|
6
|
+
return recipe.strategy === "output_path" ? recipe.output : recipe.input;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type sharp from "sharp";
|
|
3
|
+
import { DynamicImport } from "./dynamic-import.service";
|
|
4
|
+
import type { FileRenamerPort } from "./file-renamer.port";
|
|
5
|
+
import type { ImageGrayscalePort, ImageGrayscaleStrategy } from "./image-grayscale.port";
|
|
6
|
+
|
|
7
|
+
export const ImageGrayscaleSharpAdapterError = {
|
|
8
|
+
MissingDependency: "image.grayscale.sharp.adapter.error.missing.dependency",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type Dependencies = { FileRenamer: FileRenamerPort };
|
|
12
|
+
type Sharp = typeof sharp;
|
|
13
|
+
|
|
14
|
+
export class ImageGrayscaleSharpAdapter implements ImageGrayscalePort {
|
|
15
|
+
private static readonly importer = DynamicImport.for<{ default: Sharp }>(
|
|
16
|
+
"sharp",
|
|
17
|
+
ImageGrayscaleSharpAdapterError.MissingDependency,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
private constructor(
|
|
21
|
+
private readonly sharp: Sharp,
|
|
22
|
+
private readonly deps: Dependencies,
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
static async build(deps: Dependencies): Promise<ImageGrayscaleSharpAdapter> {
|
|
26
|
+
const library = await ImageGrayscaleSharpAdapter.importer.resolve();
|
|
27
|
+
|
|
28
|
+
return new ImageGrayscaleSharpAdapter(library.default, deps);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async grayscale(recipe: ImageGrayscaleStrategy): Promise<tools.FilePathRelative | tools.FilePathAbsolute> {
|
|
32
|
+
const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
|
|
33
|
+
|
|
34
|
+
const filename = final.getFilename();
|
|
35
|
+
const temporary = final.withFilename(filename.withSuffix("-grayscale"));
|
|
36
|
+
|
|
37
|
+
const pipeline = this.sharp(recipe.input.get());
|
|
38
|
+
using _sharp_ = { [Symbol.dispose]: () => pipeline.destroy() };
|
|
39
|
+
|
|
40
|
+
await pipeline.rotate().grayscale().toFile(temporary.get());
|
|
41
|
+
await this.deps.FileRenamer.rename(temporary, final);
|
|
42
|
+
|
|
43
|
+
return final;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
|
|
3
|
+
export type ImageGrayscaleOutputPathStrategy = {
|
|
4
|
+
strategy: "output_path";
|
|
5
|
+
input: tools.FilePathRelative | tools.FilePathAbsolute;
|
|
6
|
+
output: tools.FilePathRelative | tools.FilePathAbsolute;
|
|
7
|
+
};
|
|
8
|
+
export type ImageGrayscaleInPlaceStrategy = {
|
|
9
|
+
strategy: "in_place";
|
|
10
|
+
input: tools.FilePathRelative | tools.FilePathAbsolute;
|
|
11
|
+
};
|
|
12
|
+
export type ImageGrayscaleStrategy = ImageGrayscaleInPlaceStrategy | ImageGrayscaleOutputPathStrategy;
|
|
13
|
+
|
|
14
|
+
export interface ImageGrayscalePort {
|
|
15
|
+
grayscale(recipe: ImageGrayscaleStrategy): Promise<tools.FilePathRelative | tools.FilePathAbsolute>;
|
|
16
|
+
}
|