@bgord/bun 1.24.3 → 1.24.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.
Files changed (76) hide show
  1. package/dist/file-reader-raw-forgiving.adapter.js +1 -1
  2. package/dist/file-reader-raw-forgiving.adapter.js.map +1 -1
  3. package/dist/file-reader-text-forgiving.adapter.js +1 -1
  4. package/dist/file-reader-text-forgiving.adapter.js.map +1 -1
  5. package/dist/file-type-detector-text.strategy.js +1 -1
  6. package/dist/file-type-detector-text.strategy.js.map +1 -1
  7. package/dist/hash-file-metadata.adapter.d.ts +16 -0
  8. package/dist/hash-file-metadata.adapter.d.ts.map +1 -0
  9. package/dist/hash-file-metadata.adapter.js +18 -0
  10. package/dist/hash-file-metadata.adapter.js.map +1 -0
  11. package/dist/healthcheck.handler.d.ts +0 -2
  12. package/dist/healthcheck.handler.d.ts.map +1 -1
  13. package/dist/healthcheck.handler.js +0 -1
  14. package/dist/healthcheck.handler.js.map +1 -1
  15. package/dist/image-generator-web-view.adapter.d.ts +1 -0
  16. package/dist/image-generator-web-view.adapter.d.ts.map +1 -1
  17. package/dist/image-generator-web-view.adapter.js +3 -2
  18. package/dist/image-generator-web-view.adapter.js.map +1 -1
  19. package/dist/index.d.ts +2 -3
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/invariant.service.d.ts +2 -2
  24. package/dist/invariant.service.d.ts.map +1 -1
  25. package/dist/invariant.service.js +1 -0
  26. package/dist/invariant.service.js.map +1 -1
  27. package/dist/job-retry-policy-composite.strategy.js +2 -1
  28. package/dist/job-retry-policy-composite.strategy.js.map +1 -1
  29. package/dist/pdf-generator-with-logger.adapter.js +1 -1
  30. package/dist/pdf-generator-with-logger.adapter.js.map +1 -1
  31. package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts +13 -0
  32. package/dist/prerequisite-verifier-sqlite-connection.adapter.d.ts.map +1 -0
  33. package/dist/prerequisite-verifier-sqlite-connection.adapter.js +20 -0
  34. package/dist/prerequisite-verifier-sqlite-connection.adapter.js.map +1 -0
  35. package/dist/runtime-stats-provider-noop.adapter.js +1 -1
  36. package/dist/runtime-stats-provider-noop.adapter.js.map +1 -1
  37. package/dist/runtime-stats-provider-system.adapter.d.ts.map +1 -1
  38. package/dist/runtime-stats-provider-system.adapter.js +1 -2
  39. package/dist/runtime-stats-provider-system.adapter.js.map +1 -1
  40. package/dist/runtime-stats-provider.port.d.ts +0 -2
  41. package/dist/runtime-stats-provider.port.d.ts.map +1 -1
  42. package/dist/shield-rate-limit-hono.strategy.d.ts.map +1 -1
  43. package/dist/shield-rate-limit-hono.strategy.js +4 -2
  44. package/dist/shield-rate-limit-hono.strategy.js.map +1 -1
  45. package/package.json +7 -7
  46. package/readme.md +2 -3
  47. package/src/file-reader-raw-forgiving.adapter.ts +1 -1
  48. package/src/file-reader-text-forgiving.adapter.ts +1 -1
  49. package/src/file-type-detector-text.strategy.ts +1 -1
  50. package/src/hash-file-metadata.adapter.ts +27 -0
  51. package/src/healthcheck.handler.ts +0 -3
  52. package/src/image-generator-web-view.adapter.ts +6 -2
  53. package/src/index.ts +2 -3
  54. package/src/invariant.service.ts +4 -2
  55. package/src/job-retry-policy-composite.strategy.ts +1 -1
  56. package/src/pdf-generator-with-logger.adapter.ts +1 -1
  57. package/src/prerequisite-verifier-sqlite-connection.adapter.ts +27 -0
  58. package/src/runtime-stats-provider-noop.adapter.ts +1 -1
  59. package/src/runtime-stats-provider-system.adapter.ts +1 -2
  60. package/src/runtime-stats-provider.port.ts +1 -2
  61. package/src/shield-rate-limit-hono.strategy.ts +4 -2
  62. package/dist/checksum.service.d.ts +0 -5
  63. package/dist/checksum.service.d.ts.map +0 -1
  64. package/dist/checksum.service.js +0 -8
  65. package/dist/checksum.service.js.map +0 -1
  66. package/dist/clock-offset.adapter.d.ts +0 -13
  67. package/dist/clock-offset.adapter.d.ts.map +0 -1
  68. package/dist/clock-offset.adapter.js +0 -12
  69. package/dist/clock-offset.adapter.js.map +0 -1
  70. package/dist/event-loop-utilization.service.d.ts +0 -6
  71. package/dist/event-loop-utilization.service.d.ts.map +0 -1
  72. package/dist/event-loop-utilization.service.js +0 -15
  73. package/dist/event-loop-utilization.service.js.map +0 -1
  74. package/src/checksum.service.ts +0 -11
  75. package/src/clock-offset.adapter.ts +0 -15
  76. package/src/event-loop-utilization.service.ts +0 -23
@@ -1,6 +1,5 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { EventLoopLagSnapshotType } from "./event-loop-lag.service";
3
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
4
3
  import type { MemoryConsumptionSnapshotType } from "./memory-consumption.service";
5
4
  import type { UptimeResultType } from "./uptime.service";
6
5
  export type RuntimeStatsSnapshot = {
@@ -8,7 +7,6 @@ export type RuntimeStatsSnapshot = {
8
7
  memory: MemoryConsumptionSnapshotType;
9
8
  eventLoop: {
10
9
  lag: EventLoopLagSnapshotType;
11
- utilization: EventLoopUtilizationSnapshot;
12
10
  };
13
11
  inFlight: tools.IntegerType;
14
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-stats-provider.port.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,6BAA6B,CAAC;IACtC,SAAS,EAAE;QAAE,GAAG,EAAE,wBAAwB,CAAC;QAAC,WAAW,EAAE,4BAA4B,CAAA;KAAE,CAAC;IACxF,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,oBAAoB,CAAC;CAClC"}
1
+ {"version":3,"file":"runtime-stats-provider.port.d.ts","sourceRoot":"","sources":["../src/runtime-stats-provider.port.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,6BAA6B,CAAC;IACtC,SAAS,EAAE;QAAE,GAAG,EAAE,wBAAwB,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC;CAC7B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,oBAAoB,CAAC;CAClC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shield-rate-limit-hono.strategy.d.ts","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,8BAA8B,CAAC;AAEtC,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,eAAe,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE/E,qBAAa,2BAA4B,YAAW,kBAAkB;IACpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAEnD,YAAY,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,EAE5D;IAED,MAAM,IAAI,iBAAiB,CAW1B;CACF"}
1
+ {"version":3,"file":"shield-rate-limit-hono.strategy.d.ts","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EACL,KAAK,qBAAqB,EAG3B,MAAM,8BAA8B,CAAC;AAEtC,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,eAAe,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE/E,qBAAa,2BAA4B,YAAW,kBAAkB;IACpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IAEnD,YAAY,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,YAAY,EAE5D;IAED,MAAM,IAAI,iBAAiB,CAa1B;CACF"}
@@ -12,8 +12,10 @@ export class ShieldRateLimitHonoStrategy {
12
12
  const result = await this.strategy.evaluate(context);
13
13
  if (result.allowed)
14
14
  return next();
15
- c.header("Retry-After", result.retryAfter.seconds.toString());
16
- throw new HTTPException(429, { message: ShieldRateLimitStrategyError.Rejected });
15
+ throw new HTTPException(429, {
16
+ message: ShieldRateLimitStrategyError.Rejected,
17
+ res: new Response(null, { headers: { "Retry-After": result.retryAfter.seconds.toString() } }),
18
+ });
17
19
  };
18
20
  }
19
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shield-rate-limit-hono.strategy.js","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAEL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AAItC,MAAM,OAAO,2BAA2B;IACrB,QAAQ,CAA0B;IAEnD,YAAY,MAA6B,EAAE,IAAkB;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9D,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,4BAA4B,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"shield-rate-limit-hono.strategy.js","sourceRoot":"","sources":["../src/shield-rate-limit-hono.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAEL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,8BAA8B,CAAC;AAItC,MAAM,OAAO,2BAA2B;IACrB,QAAQ,CAA0B;IAEnD,YAAY,MAA6B,EAAE,IAAkB;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE;gBAC3B,OAAO,EAAE,4BAA4B,CAAC,QAAQ;gBAC9C,GAAG,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;aAC9F,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgord/bun",
3
- "version": "1.24.3",
3
+ "version": "1.24.5",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Bartosz Gordon",
@@ -24,14 +24,14 @@
24
24
  "@standard-schema/spec": "1.1.0",
25
25
  "@stryker-mutator/core": "10.0.0",
26
26
  "@stryker-mutator/typescript-checker": "10.0.0",
27
- "@types/bun": "1.4.2",
27
+ "@types/bun": "1.4.3",
28
28
  "@types/nodemailer": "8.0.2",
29
29
  "better-auth": "1.7.7",
30
30
  "cspell": "10.3.6",
31
- "fallow": "3.31.0",
32
- "lefthook": "2.1.14",
33
- "lockfile-lint": "5.0.1",
34
- "nodemailer": "10.0.10",
31
+ "fallow": "3.33.1",
32
+ "lefthook": "2.2.1",
33
+ "lockfile-lint": "5.1.0",
34
+ "nodemailer": "10.1.0",
35
35
  "publint": "0.3.25",
36
36
  "shellcheck": "4.1.0",
37
37
  "typescript": "7.0.2"
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "peerDependencies": {
46
46
  "better-auth": "1.7.7",
47
- "nodemailer": "10.0.10"
47
+ "nodemailer": "10.1.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "better-auth": {
package/readme.md CHANGED
@@ -94,12 +94,10 @@ src/
94
94
  ├── certificate-inspector-noop.adapter.ts
95
95
  ├── certificate-inspector-tls.adapter.ts
96
96
  ├── certificate-inspector.port.ts
97
- ├── checksum.service.ts
98
97
  ├── client-ip.vo.ts
99
98
  ├── client-user-agent.vo.ts
100
99
  ├── client.vo.ts
101
100
  ├── clock-fixed.adapter.ts
102
- ├── clock-offset.adapter.ts
103
101
  ├── clock-system.adapter.ts
104
102
  ├── clock.port.ts
105
103
  ├── command-envelope.ts
@@ -177,7 +175,6 @@ src/
177
175
  ├── event-log-reader-memory.adapter.ts
178
176
  ├── event-log-reader.port.ts
179
177
  ├── event-loop-lag.service.ts
180
- ├── event-loop-utilization.service.ts
181
178
  ├── event-revision-assigner.adapter.ts
182
179
  ├── event-revision-assigner.port.ts
183
180
  ├── event-sourced-repository.adapter.ts
@@ -254,6 +251,7 @@ src/
254
251
  ├── hash-content-noop.strategy.ts
255
252
  ├── hash-content-sha256.strategy.ts
256
253
  ├── hash-content.strategy.ts
254
+ ├── hash-file-metadata.adapter.ts
257
255
  ├── hash-file-noop.adapter.ts
258
256
  ├── hash-file-sha256.adapter.ts
259
257
  ├── hash-file.port.ts
@@ -484,6 +482,7 @@ src/
484
482
  ├── prerequisite-verifier-self.adapter.ts
485
483
  ├── prerequisite-verifier-sms.adapter.ts
486
484
  ├── prerequisite-verifier-space.adapter.ts
485
+ ├── prerequisite-verifier-sqlite-connection.adapter.ts
487
486
  ├── prerequisite-verifier-sqlite.adapter.ts
488
487
  ├── prerequisite-verifier-ssl-certificate-expiry.adapter.ts
489
488
  ├── prerequisite-verifier-timezone-utc.adapter.ts
@@ -7,7 +7,7 @@ export class FileReaderRawForgivingAdapter implements FileReaderRawPort {
7
7
 
8
8
  async read(path: tools.FilePathRelative | tools.FilePathAbsolute | string): Promise<ArrayBuffer> {
9
9
  try {
10
- return Bun.file(typeof path === "string" ? path : path.get()).arrayBuffer();
10
+ return await Bun.file(typeof path === "string" ? path : path.get()).arrayBuffer();
11
11
  } catch {
12
12
  return this.fallback;
13
13
  }
@@ -7,7 +7,7 @@ export class FileReaderTextForgivingAdapter implements FileReaderTextPort {
7
7
 
8
8
  async read(path: tools.FilePathRelative | tools.FilePathAbsolute | string): Promise<string> {
9
9
  try {
10
- return Bun.file(typeof path === "string" ? path : path.get()).text();
10
+ return await Bun.file(typeof path === "string" ? path : path.get()).text();
11
11
  } catch {
12
12
  return this.fallback;
13
13
  }
@@ -15,7 +15,7 @@ export class FileTypeDetectorTextStrategy implements FileTypeDetectorStrategy {
15
15
  if (bytes.length === 0) return null;
16
16
  if (bytes.some(isControlByte)) return null;
17
17
 
18
- const text = new TextDecoder().decode(bytes);
18
+ const text = new TextDecoder().decode(bytes, { stream: file.size > bytes.length });
19
19
 
20
20
  if (text.includes("\ufffd")) return null;
21
21
  if (text.trimStart().startsWith("<")) return null;
@@ -0,0 +1,27 @@
1
+ import * as tools from "@bgord/tools";
2
+ import type { FileInspectionPort } from "./file-inspection.port";
3
+ import type { HashContentStrategy } from "./hash-content.strategy";
4
+ import type { HashFilePort, HashFileResult } from "./hash-file.port";
5
+
6
+ type Dependencies = {
7
+ HashContent: HashContentStrategy;
8
+ FileInspection: FileInspectionPort;
9
+ MimeRegistry: tools.MimeRegistry;
10
+ };
11
+
12
+ export class HashFileMetadataAdapter implements HashFilePort {
13
+ constructor(private readonly deps: Dependencies) {}
14
+
15
+ async hash(path: tools.FilePathAbsolute | tools.FilePathRelative): Promise<HashFileResult> {
16
+ const extension = path.getFilename().getExtension();
17
+ const mime = this.deps.MimeRegistry.fromExtension(extension);
18
+
19
+ if (!mime) throw new Error(tools.MimeRegistryError.MimeNotFound);
20
+
21
+ const size = await this.deps.FileInspection.size(path);
22
+ const lastModified = await this.deps.FileInspection.lastModified(path);
23
+ const etag = await this.deps.HashContent.hash(`${size.toBytes()}:${lastModified.ms}`);
24
+
25
+ return { etag, size, lastModified, mime };
26
+ }
27
+ }
@@ -3,7 +3,6 @@ import * as tools from "@bgord/tools";
3
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
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
7
6
  import type { JobQueueStatsProviderPort, JobQueueStatsSnapshot } from "./job-queue-stats-provider.port";
8
7
  import type { LoggerStatsProviderPort, LoggerStatsSnapshot } from "./logger-stats-provider.port";
9
8
  import type { NodeEnvironmentEnum } from "./node-env.vo";
@@ -73,7 +72,6 @@ export type HealthcheckResult = {
73
72
  };
74
73
  eventLoop: {
75
74
  lag: { p50: tools.DurationMsType; p95: tools.DurationMsType; p99: tools.DurationMsType };
76
- utilization: EventLoopUtilizationSnapshot;
77
75
  };
78
76
  inFlight: tools.IntegerType;
79
77
  };
@@ -171,7 +169,6 @@ export class HealthcheckHandler {
171
169
  },
172
170
  eventLoop: {
173
171
  lag: { p50: eventLoop.lag.p50.ms, p95: eventLoop.lag.p95.ms, p99: eventLoop.lag.p99.ms },
174
- utilization: eventLoop.utilization,
175
172
  },
176
173
  inFlight,
177
174
  },
@@ -6,11 +6,15 @@ import type {
6
6
  } from "./image-generator.port";
7
7
 
8
8
  export class ImageGeneratorWebViewAdapter implements ImageGeneratorPort {
9
+ static readonly CSP =
10
+ `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src data: http: https:; font-src data:">`;
11
+
9
12
  async generate(config: ImageGeneratorConfig): Promise<Uint8Array<ArrayBuffer>> {
10
13
  await using view = new Bun.WebView(config);
11
14
 
12
- // TODO: Potential XSS risk
13
- await view.navigate(`data:text/html;charset=utf-8,${encodeURIComponent(config.template)}`);
15
+ const html = ImageGeneratorWebViewAdapter.CSP + config.template;
16
+
17
+ await view.navigate(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`);
14
18
 
15
19
  const image = await view.screenshot({
16
20
  encoding: "buffer",
package/src/index.ts CHANGED
@@ -69,13 +69,11 @@ export * from "./cache-value.vo";
69
69
  export * from "./certificate-inspector.port";
70
70
  export * from "./certificate-inspector-noop.adapter";
71
71
  export * from "./certificate-inspector-tls.adapter";
72
- export * from "./checksum.service";
73
72
  export * from "./client.vo";
74
73
  export * from "./client-ip.vo";
75
74
  export * from "./client-user-agent.vo";
76
75
  export * from "./clock.port";
77
76
  export * from "./clock-fixed.adapter";
78
- export * from "./clock-offset.adapter";
79
77
  export * from "./clock-system.adapter";
80
78
  export * from "./command-envelope";
81
79
  export * from "./commit-sha.vo";
@@ -151,7 +149,6 @@ export * from "./event-inserter-noop.adapter";
151
149
  export * from "./event-log-reader.port";
152
150
  export * from "./event-log-reader-memory.adapter";
153
151
  export * from "./event-loop-lag.service";
154
- export * from "./event-loop-utilization.service";
155
152
  export * from "./event-revision-assigner.adapter";
156
153
  export * from "./event-revision-assigner.port";
157
154
  export * from "./event-sourced-repository.adapter";
@@ -228,6 +225,7 @@ export * from "./hash-content.strategy";
228
225
  export * from "./hash-content-noop.strategy";
229
226
  export * from "./hash-content-sha256.strategy";
230
227
  export * from "./hash-file.port";
228
+ export * from "./hash-file-metadata.adapter";
231
229
  export * from "./hash-file-noop.adapter";
232
230
  export * from "./hash-file-sha256.adapter";
233
231
  export * from "./hash-value.vo";
@@ -414,6 +412,7 @@ export * from "./prerequisite-verifier-self.adapter";
414
412
  export * from "./prerequisite-verifier-sms.adapter";
415
413
  export * from "./prerequisite-verifier-space.adapter";
416
414
  export * from "./prerequisite-verifier-sqlite.adapter";
415
+ export * from "./prerequisite-verifier-sqlite-connection.adapter";
417
416
  export * from "./prerequisite-verifier-ssl-certificate-expiry.adapter";
418
417
  export * from "./prerequisite-verifier-timezone-utc.adapter";
419
418
  export * from "./prerequisite-verifier-translations.adapter";
@@ -8,7 +8,7 @@ export enum InvariantFailureKind {
8
8
  not_found = "not_found",
9
9
  }
10
10
 
11
- export abstract class Invariant<T extends Config> {
11
+ export abstract class Invariant<T extends Config, N extends T = T> {
12
12
  abstract passes(config: T): boolean;
13
13
 
14
14
  abstract error: Constructor<Error>;
@@ -21,7 +21,9 @@ export abstract class Invariant<T extends Config> {
21
21
  throw new this.error(this.message);
22
22
  }
23
23
 
24
- enforce(config: T) {
24
+ enforce(config: T): N {
25
25
  if (!this.passes(config)) this.throw();
26
+
27
+ return config as N;
26
28
  }
27
29
  }
@@ -21,7 +21,7 @@ export class JobRetryPolicyCompositeStrategy implements JobRetryPolicyStrategy {
21
21
 
22
22
  if (!result) return false;
23
23
 
24
- delay = result;
24
+ if (result.isLongerThan(delay)) delay = result;
25
25
  }
26
26
 
27
27
  return delay;
@@ -19,7 +19,7 @@ export class PdfGeneratorWithLoggerAdapter implements PdfGeneratorPort {
19
19
  this.deps.Logger.info({
20
20
  message: "PDF generator attempt",
21
21
  correlationId: CorrelationStorage.get(),
22
- metadata: { template, data },
22
+ metadata: { template },
23
23
  ...this.base,
24
24
  });
25
25
 
@@ -0,0 +1,27 @@
1
+ // [BUN DEPENDENCY]
2
+ import type { Database } from "bun:sqlite";
3
+ import {
4
+ PrerequisiteVerification,
5
+ type PrerequisiteVerificationResult,
6
+ type PrerequisiteVerifierPort,
7
+ } from "./prerequisite-verifier.port";
8
+
9
+ type Config = { sqlite: Database };
10
+
11
+ export class PrerequisiteVerifierSQLiteConnectionAdapter implements PrerequisiteVerifierPort {
12
+ constructor(private readonly config: Config) {}
13
+
14
+ async verify(): Promise<PrerequisiteVerificationResult> {
15
+ try {
16
+ this.config.sqlite.query("SELECT 1").get();
17
+
18
+ return PrerequisiteVerification.success;
19
+ } catch (error) {
20
+ return PrerequisiteVerification.failure(error);
21
+ }
22
+ }
23
+
24
+ get kind(): string {
25
+ return "sqlite-connection";
26
+ }
27
+ }
@@ -9,7 +9,7 @@ export class RuntimeStatsProviderNoopAdapter implements RuntimeStatsProviderPort
9
9
  return {
10
10
  uptime: { duration: zero, formatted: "0 seconds ago" },
11
11
  memory: { total: empty, heap: { used: empty, total: empty } },
12
- eventLoop: { lag: { p50: zero, p95: zero, p99: zero }, utilization: 0 },
12
+ eventLoop: { lag: { p50: zero, p95: zero, p99: zero } },
13
13
  inFlight: tools.Int.of(0),
14
14
  };
15
15
  }
@@ -1,6 +1,5 @@
1
1
  import type { ClockPort } from "./clock.port";
2
2
  import { EventLoopLag } from "./event-loop-lag.service";
3
- import { EventLoopUtilization } from "./event-loop-utilization.service";
4
3
  import { InFlightRequestsTracker } from "./in-flight-requests-tracker.service";
5
4
  import { MemoryConsumption } from "./memory-consumption.service";
6
5
  import type { RuntimeStatsProviderPort, RuntimeStatsSnapshot } from "./runtime-stats-provider.port";
@@ -17,7 +16,7 @@ export class RuntimeStatsProviderSystemAdapter implements RuntimeStatsProviderPo
17
16
  return {
18
17
  uptime: Uptime.get(this.deps.Clock),
19
18
  memory: MemoryConsumption.snapshot(),
20
- eventLoop: { lag: EventLoopLag.snapshot(), utilization: EventLoopUtilization.snapshot() },
19
+ eventLoop: { lag: EventLoopLag.snapshot() },
21
20
  inFlight: InFlightRequestsTracker.get(),
22
21
  };
23
22
  }
@@ -1,13 +1,12 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { EventLoopLagSnapshotType } from "./event-loop-lag.service";
3
- import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
4
3
  import type { MemoryConsumptionSnapshotType } from "./memory-consumption.service";
5
4
  import type { UptimeResultType } from "./uptime.service";
6
5
 
7
6
  export type RuntimeStatsSnapshot = {
8
7
  uptime: UptimeResultType;
9
8
  memory: MemoryConsumptionSnapshotType;
10
- eventLoop: { lag: EventLoopLagSnapshotType; utilization: EventLoopUtilizationSnapshot };
9
+ eventLoop: { lag: EventLoopLagSnapshotType };
11
10
  inFlight: tools.IntegerType;
12
11
  };
13
12
 
@@ -27,8 +27,10 @@ export class ShieldRateLimitHonoStrategy implements MiddlewareHonoPort {
27
27
 
28
28
  if (result.allowed) return next();
29
29
 
30
- c.header("Retry-After", result.retryAfter.seconds.toString());
31
- throw new HTTPException(429, { message: ShieldRateLimitStrategyError.Rejected });
30
+ throw new HTTPException(429, {
31
+ message: ShieldRateLimitStrategyError.Rejected,
32
+ res: new Response(null, { headers: { "Retry-After": result.retryAfter.seconds.toString() } }),
33
+ });
32
34
  };
33
35
  }
34
36
  }
@@ -1,5 +0,0 @@
1
- import type { HashFileResult } from "./hash-file.port";
2
- export declare class Checksum {
3
- static compare(first: HashFileResult, second: HashFileResult): boolean;
4
- }
5
- //# sourceMappingURL=checksum.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"checksum.service.d.ts","sourceRoot":"","sources":["../src/checksum.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,qBAAa,QAAQ;IACnB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAMrE;CACF"}
@@ -1,8 +0,0 @@
1
- export class Checksum {
2
- static compare(first, second) {
3
- return (first.etag.matches(second.etag) &&
4
- first.size.toBytes() === second.size.toBytes() &&
5
- first.lastModified.equals(second.lastModified));
6
- }
7
- }
8
- //# sourceMappingURL=checksum.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"checksum.service.js","sourceRoot":"","sources":["../src/checksum.service.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,QAAQ;IACnB,MAAM,CAAC,OAAO,CAAC,KAAqB,EAAE,MAAsB;QAC1D,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;YAC9C,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAC/C,CAAC;IACJ,CAAC;CACF"}
@@ -1,13 +0,0 @@
1
- import type * as tools from "@bgord/tools";
2
- import type { ClockPort } from "./clock.port";
3
- type Dependencies = {
4
- Clock: ClockPort;
5
- };
6
- export declare class ClockOffsetAdapter implements ClockPort {
7
- private readonly offset;
8
- private readonly deps;
9
- constructor(offset: tools.Duration, deps: Dependencies);
10
- now(): tools.Timestamp;
11
- }
12
- export {};
13
- //# sourceMappingURL=clock-offset.adapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clock-offset.adapter.d.ts","sourceRoot":"","sources":["../src/clock-offset.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEzC,qBAAa,kBAAmB,YAAW,SAAS;IAEhD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,MAAM,EAAE,KAAK,CAAC,QAAQ,EACtB,IAAI,EAAE,YAAY,EACjC;IAEJ,GAAG,IAAI,KAAK,CAAC,SAAS,CAErB;CACF"}
@@ -1,12 +0,0 @@
1
- export class ClockOffsetAdapter {
2
- offset;
3
- deps;
4
- constructor(offset, deps) {
5
- this.offset = offset;
6
- this.deps = deps;
7
- }
8
- now() {
9
- return this.deps.Clock.now().add(this.offset);
10
- }
11
- }
12
- //# sourceMappingURL=clock-offset.adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clock-offset.adapter.js","sourceRoot":"","sources":["../src/clock-offset.adapter.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,kBAAkB;IAEV,MAAM;IACN,IAAI;IAFvB,YACmB,MAAsB,EACtB,IAAkB;sBADlB,MAAM;oBACN,IAAI;IACpB,CAAC;IAEJ,GAAG;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;CACF"}
@@ -1,6 +0,0 @@
1
- export type EventLoopUtilizationSnapshot = number;
2
- export declare class EventLoopUtilization {
3
- private static previous;
4
- static snapshot(): EventLoopUtilizationSnapshot;
5
- }
6
- //# sourceMappingURL=event-loop-utilization.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-loop-utilization.service.d.ts","sourceRoot":"","sources":["../src/event-loop-utilization.service.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAElD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAoE;IAE3F,MAAM,CAAC,QAAQ,IAAI,4BAA4B,CAM9C;CAQF"}
@@ -1,15 +0,0 @@
1
- import { performance } from "node:perf_hooks";
2
- export class EventLoopUtilization {
3
- static previous = null;
4
- static snapshot() {
5
- const current = performance.eventLoopUtilization(EventLoopUtilization.previous ?? undefined);
6
- EventLoopUtilization.previous = current;
7
- return current.utilization;
8
- }
9
- // Stryker disable all
10
- /** @internal */
11
- static _resetForTest() {
12
- EventLoopUtilization.previous = null;
13
- }
14
- }
15
- //# sourceMappingURL=event-loop-utilization.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-loop-utilization.service.js","sourceRoot":"","sources":["../src/event-loop-utilization.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAK9C,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAC,QAAQ,GAA+D,IAAI,CAAC;IAE3F,MAAM,CAAC,QAAQ;QACb,MAAM,OAAO,GAAG,WAAW,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAE7F,oBAAoB,CAAC,QAAQ,GAAG,OAAO,CAAC;QAExC,OAAO,OAAO,CAAC,WAAW,CAAC;IAC7B,CAAC;IAED,sBAAsB;IACtB,gBAAgB;IAChB,MAAM,CAAC,aAAa;QAClB,oBAAoB,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvC,CAAC;CAEF"}
@@ -1,11 +0,0 @@
1
- import type { HashFileResult } from "./hash-file.port";
2
-
3
- export class Checksum {
4
- static compare(first: HashFileResult, second: HashFileResult): boolean {
5
- return (
6
- first.etag.matches(second.etag) &&
7
- first.size.toBytes() === second.size.toBytes() &&
8
- first.lastModified.equals(second.lastModified)
9
- );
10
- }
11
- }
@@ -1,15 +0,0 @@
1
- import type * as tools from "@bgord/tools";
2
- import type { ClockPort } from "./clock.port";
3
-
4
- type Dependencies = { Clock: ClockPort };
5
-
6
- export class ClockOffsetAdapter implements ClockPort {
7
- constructor(
8
- private readonly offset: tools.Duration,
9
- private readonly deps: Dependencies,
10
- ) {}
11
-
12
- now(): tools.Timestamp {
13
- return this.deps.Clock.now().add(this.offset);
14
- }
15
- }
@@ -1,23 +0,0 @@
1
- import { performance } from "node:perf_hooks";
2
-
3
- // 0.0 – 1.0
4
- export type EventLoopUtilizationSnapshot = number;
5
-
6
- export class EventLoopUtilization {
7
- private static previous: ReturnType<typeof performance.eventLoopUtilization> | null = null;
8
-
9
- static snapshot(): EventLoopUtilizationSnapshot {
10
- const current = performance.eventLoopUtilization(EventLoopUtilization.previous ?? undefined);
11
-
12
- EventLoopUtilization.previous = current;
13
-
14
- return current.utilization;
15
- }
16
-
17
- // Stryker disable all
18
- /** @internal */
19
- static _resetForTest(): void {
20
- EventLoopUtilization.previous = null;
21
- }
22
- // Stryker restore all
23
- }