@bgord/bun 1.23.12 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomic-file-writer-collecting.adapter.d.ts +8 -0
- package/dist/atomic-file-writer-collecting.adapter.d.ts.map +1 -0
- package/dist/atomic-file-writer-collecting.adapter.js +7 -0
- package/dist/atomic-file-writer-collecting.adapter.js.map +1 -0
- package/dist/atomic-file-writer-noop.adapter.d.ts +7 -0
- package/dist/atomic-file-writer-noop.adapter.d.ts.map +1 -0
- package/dist/atomic-file-writer-noop.adapter.js +4 -0
- package/dist/atomic-file-writer-noop.adapter.js.map +1 -0
- package/dist/atomic-file-writer.adapter.d.ts +19 -0
- package/dist/atomic-file-writer.adapter.d.ts.map +1 -0
- package/dist/atomic-file-writer.adapter.js +18 -0
- package/dist/atomic-file-writer.adapter.js.map +1 -0
- package/dist/atomic-file-writer.port.d.ts +6 -0
- package/dist/atomic-file-writer.port.d.ts.map +1 -0
- package/dist/atomic-file-writer.port.js +2 -0
- package/dist/atomic-file-writer.port.js.map +1 -0
- package/dist/encryption-aes-gcm.adapter.d.ts +2 -2
- package/dist/encryption-aes-gcm.adapter.d.ts.map +1 -1
- package/dist/encryption-aes-gcm.adapter.js +2 -2
- package/dist/encryption-aes-gcm.adapter.js.map +1 -1
- package/dist/event-sourced-repository.adapter.d.ts +27 -0
- package/dist/event-sourced-repository.adapter.d.ts.map +1 -0
- package/dist/event-sourced-repository.adapter.js +16 -0
- package/dist/event-sourced-repository.adapter.js.map +1 -0
- package/dist/event-stream-accept.service.d.ts +4 -0
- package/dist/event-stream-accept.service.d.ts.map +1 -0
- package/dist/event-stream-accept.service.js +11 -0
- package/dist/event-stream-accept.service.js.map +1 -0
- package/dist/gzip.adapter.d.ts +2 -2
- package/dist/gzip.adapter.d.ts.map +1 -1
- package/dist/gzip.adapter.js +1 -1
- package/dist/gzip.adapter.js.map +1 -1
- package/dist/healthcheck.handler.d.ts +4 -2
- package/dist/healthcheck.handler.d.ts.map +1 -1
- package/dist/healthcheck.handler.js +4 -11
- package/dist/healthcheck.handler.js.map +1 -1
- package/dist/http-exception-errors.js +2 -2
- package/dist/http-exception-errors.js.map +1 -1
- package/dist/http-logger-hono.middleware.d.ts +1 -0
- package/dist/http-logger-hono.middleware.d.ts.map +1 -1
- package/dist/http-logger-hono.middleware.js +10 -6
- package/dist/http-logger-hono.middleware.js.map +1 -1
- package/dist/http-logger.middleware.d.ts.map +1 -1
- package/dist/http-logger.middleware.js +4 -6
- package/dist/http-logger.middleware.js.map +1 -1
- package/dist/image-blur.adapter.d.ts +2 -6
- package/dist/image-blur.adapter.d.ts.map +1 -1
- package/dist/image-blur.adapter.js +1 -4
- package/dist/image-blur.adapter.js.map +1 -1
- package/dist/image-compressor.adapter.d.ts +2 -6
- package/dist/image-compressor.adapter.d.ts.map +1 -1
- package/dist/image-compressor.adapter.js +1 -4
- package/dist/image-compressor.adapter.js.map +1 -1
- package/dist/image-exif-clear.adapter.d.ts +2 -6
- package/dist/image-exif-clear.adapter.d.ts.map +1 -1
- package/dist/image-exif-clear.adapter.js +1 -3
- package/dist/image-exif-clear.adapter.js.map +1 -1
- package/dist/image-formatter.adapter.d.ts +2 -6
- package/dist/image-formatter.adapter.d.ts.map +1 -1
- package/dist/image-formatter.adapter.js +1 -3
- package/dist/image-formatter.adapter.js.map +1 -1
- package/dist/image-grayscale.adapter.d.ts +2 -6
- package/dist/image-grayscale.adapter.d.ts.map +1 -1
- package/dist/image-grayscale.adapter.js +1 -4
- package/dist/image-grayscale.adapter.js.map +1 -1
- package/dist/image-processor.adapter.d.ts +2 -6
- package/dist/image-processor.adapter.d.ts.map +1 -1
- package/dist/image-processor.adapter.js +1 -3
- package/dist/image-processor.adapter.js.map +1 -1
- package/dist/image-resizer.adapter.d.ts +2 -6
- package/dist/image-resizer.adapter.d.ts.map +1 -1
- package/dist/image-resizer.adapter.js +1 -4
- package/dist/image-resizer.adapter.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/job-pruner-sqlite.adapter.d.ts.map +1 -1
- package/dist/job-pruner-sqlite.adapter.js +2 -1
- package/dist/job-pruner-sqlite.adapter.js.map +1 -1
- package/dist/job-queue-stats-provider-sqlite.adapter.js +4 -4
- package/dist/job-queue-stats-provider-sqlite.adapter.js.map +1 -1
- package/dist/job-recoverer-collecting.adapter.d.ts +7 -0
- package/dist/job-recoverer-collecting.adapter.d.ts.map +1 -0
- package/dist/job-recoverer-collecting.adapter.js +10 -0
- package/dist/job-recoverer-collecting.adapter.js.map +1 -0
- package/dist/job-recoverer-noop.adapter.d.ts +6 -0
- package/dist/job-recoverer-noop.adapter.d.ts.map +1 -0
- package/dist/job-recoverer-noop.adapter.js +7 -0
- package/dist/job-recoverer-noop.adapter.js.map +1 -0
- package/dist/job-recoverer-sqlite.adapter.d.ts +13 -0
- package/dist/job-recoverer-sqlite.adapter.d.ts.map +1 -0
- package/dist/job-recoverer-sqlite.adapter.js +14 -0
- package/dist/job-recoverer-sqlite.adapter.js.map +1 -0
- package/dist/job-recoverer.port.d.ts +5 -0
- package/dist/job-recoverer.port.d.ts.map +1 -0
- package/dist/job-recoverer.port.js +2 -0
- package/dist/job-recoverer.port.js.map +1 -0
- package/dist/memory-consumption.service.d.ts +1 -2
- package/dist/memory-consumption.service.d.ts.map +1 -1
- package/dist/memory-consumption.service.js.map +1 -1
- package/dist/message-bus-strict.adapter.d.ts +19 -0
- package/dist/message-bus-strict.adapter.d.ts.map +1 -0
- package/dist/message-bus-strict.adapter.js +24 -0
- package/dist/message-bus-strict.adapter.js.map +1 -0
- package/dist/path-matcher.service.d.ts +6 -0
- package/dist/path-matcher.service.d.ts.map +1 -0
- package/dist/path-matcher.service.js +13 -0
- package/dist/path-matcher.service.js.map +1 -0
- package/dist/remote-file-storage-disk.adapter.d.ts +2 -6
- package/dist/remote-file-storage-disk.adapter.d.ts.map +1 -1
- package/dist/remote-file-storage-disk.adapter.js +1 -9
- package/dist/remote-file-storage-disk.adapter.js.map +1 -1
- package/dist/request-context-hono.adapter.d.ts +1 -1
- package/dist/request-context-hono.adapter.d.ts.map +1 -1
- package/dist/request-context-hono.adapter.js +3 -3
- package/dist/request-context-hono.adapter.js.map +1 -1
- package/dist/request-context.port.d.ts +4 -0
- package/dist/request-context.port.d.ts.map +1 -1
- package/dist/request-context.port.js +4 -1
- package/dist/request-context.port.js.map +1 -1
- package/dist/runtime-stats-provider-noop.adapter.d.ts +5 -0
- package/dist/runtime-stats-provider-noop.adapter.d.ts.map +1 -0
- package/dist/runtime-stats-provider-noop.adapter.js +14 -0
- package/dist/runtime-stats-provider-noop.adapter.js.map +1 -0
- package/dist/runtime-stats-provider-system.adapter.d.ts +12 -0
- package/dist/runtime-stats-provider-system.adapter.d.ts.map +1 -0
- package/dist/runtime-stats-provider-system.adapter.js +21 -0
- package/dist/runtime-stats-provider-system.adapter.js.map +1 -0
- package/dist/runtime-stats-provider.port.d.ts +18 -0
- package/dist/runtime-stats-provider.port.d.ts.map +1 -0
- package/dist/runtime-stats-provider.port.js +2 -0
- package/dist/runtime-stats-provider.port.js.map +1 -0
- package/dist/security-rule-violation-threshold.strategy.js +1 -1
- package/dist/security-rule-violation-threshold.strategy.js.map +1 -1
- package/dist/setup-hono.service.js +1 -1
- package/dist/setup-hono.service.js.map +1 -1
- package/dist/shield-auth-hono.strategy.d.ts.map +1 -1
- package/dist/shield-auth-hono.strategy.js +4 -3
- package/dist/shield-auth-hono.strategy.js.map +1 -1
- package/dist/shield-auth.strategy.d.ts +1 -5
- package/dist/shield-auth.strategy.d.ts.map +1 -1
- package/dist/shield-auth.strategy.js +3 -6
- package/dist/shield-auth.strategy.js.map +1 -1
- package/dist/shield-maintenance.strategy.d.ts.map +1 -1
- package/dist/shield-maintenance.strategy.js +2 -5
- package/dist/shield-maintenance.strategy.js.map +1 -1
- package/dist/temporary-file-absolute.adapter.d.ts +2 -6
- package/dist/temporary-file-absolute.adapter.d.ts.map +1 -1
- package/dist/temporary-file-absolute.adapter.js +1 -9
- package/dist/temporary-file-absolute.adapter.js.map +1 -1
- package/dist/timing.middleware.d.ts +0 -1
- package/dist/timing.middleware.d.ts.map +1 -1
- package/dist/timing.middleware.js +2 -9
- package/dist/timing.middleware.js.map +1 -1
- package/package.json +5 -5
- package/readme.md +15 -0
- package/src/atomic-file-writer-collecting.adapter.ts +14 -0
- package/src/atomic-file-writer-noop.adapter.ts +10 -0
- package/src/atomic-file-writer.adapter.ts +34 -0
- package/src/atomic-file-writer.port.ts +6 -0
- package/src/encryption-aes-gcm.adapter.ts +4 -4
- package/src/event-sourced-repository.adapter.ts +48 -0
- package/src/event-stream-accept.service.ts +10 -0
- package/src/gzip.adapter.ts +3 -3
- package/src/healthcheck.handler.ts +8 -11
- package/src/http-exception-errors.ts +2 -2
- package/src/http-logger-hono.middleware.ts +12 -6
- package/src/http-logger.middleware.ts +4 -7
- package/src/image-blur.adapter.ts +3 -13
- package/src/image-compressor.adapter.ts +3 -12
- package/src/image-exif-clear.adapter.ts +3 -11
- package/src/image-formatter.adapter.ts +3 -12
- package/src/image-grayscale.adapter.ts +3 -13
- package/src/image-processor.adapter.ts +3 -11
- package/src/image-resizer.adapter.ts +3 -12
- package/src/index.ts +13 -0
- package/src/job-pruner-sqlite.adapter.ts +2 -1
- package/src/job-queue-stats-provider-sqlite.adapter.ts +4 -4
- package/src/job-recoverer-collecting.adapter.ts +14 -0
- package/src/job-recoverer-noop.adapter.ts +8 -0
- package/src/job-recoverer-sqlite.adapter.ts +20 -0
- package/src/job-recoverer.port.ts +5 -0
- package/src/memory-consumption.service.ts +4 -1
- package/src/message-bus-strict.adapter.ts +33 -0
- package/src/path-matcher.service.ts +14 -0
- package/src/remote-file-storage-disk.adapter.ts +3 -17
- package/src/request-context-hono.adapter.ts +3 -4
- package/src/request-context.port.ts +5 -0
- package/src/runtime-stats-provider-noop.adapter.ts +16 -0
- package/src/runtime-stats-provider-system.adapter.ts +24 -0
- package/src/runtime-stats-provider.port.ts +16 -0
- package/src/security-rule-violation-threshold.strategy.ts +2 -2
- package/src/setup-hono.service.ts +1 -1
- package/src/shield-auth-hono.strategy.ts +4 -3
- package/src/shield-auth.strategy.ts +3 -8
- package/src/shield-maintenance.strategy.ts +2 -6
- package/src/temporary-file-absolute.adapter.ts +3 -18
- package/src/timing.middleware.ts +2 -10
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { AuthSessionReaderPort, AuthSessionType } from "./auth-session-reader.port";
|
|
2
|
-
import type
|
|
2
|
+
import { type HasRequestHeaders } from "./request-context.port";
|
|
3
3
|
type Dependencies<User, Session> = {
|
|
4
4
|
AuthSessionReader: AuthSessionReaderPort<User, Session>;
|
|
5
5
|
};
|
|
6
|
-
export declare const ShieldAuthStrategyError: {
|
|
7
|
-
Rejected: string;
|
|
8
|
-
NotAttached: string;
|
|
9
|
-
};
|
|
10
6
|
export declare class ShieldAuthStrategy<User, Session> {
|
|
11
7
|
private readonly deps;
|
|
12
8
|
constructor(deps: Dependencies<User, Session>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-auth.strategy.d.ts","sourceRoot":"","sources":["../src/shield-auth.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"shield-auth.strategy.d.ts","sourceRoot":"","sources":["../src/shield-auth.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,wBAAwB,CAAC;AAEtF,KAAK,YAAY,CAAC,IAAI,EAAE,OAAO,IAAI;IAAE,iBAAiB,EAAE,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE/F,qBAAa,kBAAkB,CAAC,IAAI,EAAE,OAAO;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAI;IAE5D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAEhF;IAED,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7C;IAED,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9C;CACF"}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Rejected: "shield.auth.rejected",
|
|
3
|
-
NotAttached: "shield.auth.not.attached",
|
|
4
|
-
};
|
|
1
|
+
import { RequestIdentityError } from "./request-context.port";
|
|
5
2
|
export class ShieldAuthStrategy {
|
|
6
3
|
deps;
|
|
7
4
|
constructor(deps) {
|
|
@@ -12,12 +9,12 @@ export class ShieldAuthStrategy {
|
|
|
12
9
|
}
|
|
13
10
|
verify(user) {
|
|
14
11
|
if (user === undefined)
|
|
15
|
-
throw new Error(
|
|
12
|
+
throw new Error(RequestIdentityError.NotAttached);
|
|
16
13
|
return user !== null;
|
|
17
14
|
}
|
|
18
15
|
reverse(user) {
|
|
19
16
|
if (user === undefined)
|
|
20
|
-
throw new Error(
|
|
17
|
+
throw new Error(RequestIdentityError.NotAttached);
|
|
21
18
|
return user === null;
|
|
22
19
|
}
|
|
23
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-auth.strategy.js","sourceRoot":"","sources":["../src/shield-auth.strategy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shield-auth.strategy.js","sourceRoot":"","sources":["../src/shield-auth.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAItF,MAAM,OAAO,kBAAkB;IACA,IAAI;IAAjC,YAA6B,IAAiC;oBAAjC,IAAI;IAAgC,CAAC;IAElE,KAAK,CAAC,MAAM,CAAC,OAA0B;QACrC,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,CAAC,IAA6B;QAClC,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC1E,OAAO,IAAI,KAAK,IAAI,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,IAA6B;QACnC,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC1E,OAAO,IAAI,KAAK,IAAI,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-maintenance.strategy.d.ts","sourceRoot":"","sources":["../src/shield-maintenance.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"shield-maintenance.strategy.d.ts","sourceRoot":"","sources":["../src/shield-maintenance.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,eAAO,MAAM,WAAW;;aAAgD,CAAC;AAEzE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG;IACpC,iBAAiB,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IAC5B,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,qBAAa,yBAAyB;IAKxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAJpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAsC;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAE5C,YAA6B,MAAM,CAAC,EAAE,uBAAuB,YAAA,EAG5D;IAED,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAE3C;IAEK,QAAQ,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAUjD;CACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
2
|
import * as v from "valibot";
|
|
3
|
+
import { PathMatcher } from "./path-matcher.service";
|
|
3
4
|
export const Maintenance = v.object({ enabled: tools.FeatureFlagValue });
|
|
4
5
|
export class ShieldMaintenanceStrategy {
|
|
5
6
|
config;
|
|
@@ -12,11 +13,7 @@ export class ShieldMaintenanceStrategy {
|
|
|
12
13
|
this.RetryAfter = config?.RetryAfter ?? tools.Duration.Hours(1);
|
|
13
14
|
}
|
|
14
15
|
shouldSkip(context) {
|
|
15
|
-
return (this.config?.skip
|
|
16
|
-
if (rule instanceof URLPattern)
|
|
17
|
-
return rule.test({ pathname: context.request.path });
|
|
18
|
-
return context.request.path.startsWith(rule);
|
|
19
|
-
}) ?? false);
|
|
16
|
+
return PathMatcher.matches(this.config?.skip, context.request.path);
|
|
20
17
|
}
|
|
21
18
|
async evaluate() {
|
|
22
19
|
const maintenance = await this.MaintenanceConfig?.get();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-maintenance.strategy.js","sourceRoot":"","sources":["../src/shield-maintenance.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"shield-maintenance.strategy.js","sourceRoot":"","sources":["../src/shield-maintenance.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAiBzE,MAAM,OAAO,yBAAyB;IAKP,MAAM;IAJlB,QAAQ,GAAG,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;IAC1C,iBAAiB,CAAuC;IACxD,UAAU,CAAiB;IAE5C,YAA6B,MAAgC;sBAAhC,MAAM;QACjC,IAAI,CAAC,iBAAiB,GAAG,MAAM,EAAE,iBAAiB,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,UAAU,CAAC,OAAuB;QAChC,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAE9F,OAAO;YACL,OAAO;YACP,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;YAC/B,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;SACpF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
2
3
|
import type { FileCleanerPort } from "./file-cleaner.port";
|
|
3
|
-
import type { FileRenamerPort } from "./file-renamer.port";
|
|
4
|
-
import type { FileWriterPort } from "./file-writer.port";
|
|
5
|
-
import type { NonceProviderPort } from "./nonce-provider.port";
|
|
6
4
|
import type { TemporaryFilePort } from "./temporary-file.port";
|
|
7
5
|
type Dependencies = {
|
|
6
|
+
AtomicFileWriter: AtomicFileWriterPort;
|
|
8
7
|
FileCleaner: FileCleanerPort;
|
|
9
|
-
FileRenamer: FileRenamerPort;
|
|
10
|
-
FileWriter: FileWriterPort;
|
|
11
|
-
NonceProvider: NonceProviderPort;
|
|
12
8
|
};
|
|
13
9
|
export declare class TemporaryFileAbsoluteAdapter implements TemporaryFilePort {
|
|
14
10
|
private readonly directory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temporary-file-absolute.adapter.d.ts","sourceRoot":"","sources":["../src/temporary-file-absolute.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"temporary-file-absolute.adapter.d.ts","sourceRoot":"","sources":["../src/temporary-file-absolute.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,KAAK,YAAY,GAAG;IAClB,gBAAgB,EAAE,oBAAoB,CAAC;IACvC,WAAW,EAAE,eAAe,CAAC;CAC9B,CAAC;AAEF,qBAAa,4BAA6B,YAAW,iBAAiB;IAElE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,SAAS,EAAE,KAAK,CAAC,yBAAyB,EAC1C,IAAI,EAAE,YAAY,EACjC;IAEE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAMpF;IAEK,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAErD;IAED,IAAI,IAAI,IAAI,KAAK,CAAC,yBAAyB,CAE1C;CACF"}
|
|
@@ -7,16 +7,8 @@ export class TemporaryFileAbsoluteAdapter {
|
|
|
7
7
|
this.deps = deps;
|
|
8
8
|
}
|
|
9
9
|
async write(filename, content) {
|
|
10
|
-
const temporary = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename.withSuffix(`-part-${this.deps.NonceProvider.generate()}`));
|
|
11
10
|
const final = tools.FilePathAbsolute.fromPartsSafe(this.directory, filename);
|
|
12
|
-
await this.deps.
|
|
13
|
-
try {
|
|
14
|
-
await this.deps.FileRenamer.rename(temporary, final);
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
await this.deps.FileCleaner.delete(temporary);
|
|
18
|
-
throw error;
|
|
19
|
-
}
|
|
11
|
+
await this.deps.AtomicFileWriter.write(final, content);
|
|
20
12
|
return final;
|
|
21
13
|
}
|
|
22
14
|
async cleanup(filename) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temporary-file-absolute.adapter.js","sourceRoot":"","sources":["../src/temporary-file-absolute.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"temporary-file-absolute.adapter.js","sourceRoot":"","sources":["../src/temporary-file-absolute.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAUtC,MAAM,OAAO,4BAA4B;IAEpB,SAAS;IACT,IAAI;IAFvB,YACmB,SAA0C,EAC1C,IAAkB;yBADlB,SAAS;oBACT,IAAI;IACpB,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,QAAwB,EAAE,OAAa;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAE7E,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEvD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAwB;QACpC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -8,6 +8,5 @@ export declare class TimingMiddleware {
|
|
|
8
8
|
static readonly HEADER_NAME = "Server-Timing";
|
|
9
9
|
constructor(deps: TimingMiddlewareDependencies);
|
|
10
10
|
measure(context: HasRequestHeader, action: () => void | Promise<void>): Promise<string | null>;
|
|
11
|
-
private static isEventStream;
|
|
12
11
|
}
|
|
13
12
|
//# sourceMappingURL=timing.middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.middleware.d.ts","sourceRoot":"","sources":["../src/timing.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"timing.middleware.d.ts","sourceRoot":"","sources":["../src/timing.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,MAAM,MAAM,4BAA4B,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAEhE,qBAAa,gBAAgB;IAGf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,MAAM,CAAC,QAAQ,CAAC,WAAW,mBAAmB;IAE9C,YAA6B,IAAI,EAAE,4BAA4B,EAAI;IAE7D,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnG;CACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventStreamAccept } from "./event-stream-accept.service";
|
|
1
2
|
import { Stopwatch } from "./stopwatch.service";
|
|
2
3
|
export class TimingMiddleware {
|
|
3
4
|
deps;
|
|
@@ -6,19 +7,11 @@ export class TimingMiddleware {
|
|
|
6
7
|
this.deps = deps;
|
|
7
8
|
}
|
|
8
9
|
async measure(context, action) {
|
|
9
|
-
if (
|
|
10
|
+
if (EventStreamAccept.matches(context.request.header("accept")))
|
|
10
11
|
return null;
|
|
11
12
|
const stopwatch = new Stopwatch(this.deps);
|
|
12
13
|
await action();
|
|
13
14
|
return `total;dur=${Math.max(0, stopwatch.stop().ms)}`;
|
|
14
15
|
}
|
|
15
|
-
static isEventStream(accept) {
|
|
16
|
-
if (!accept)
|
|
17
|
-
return false;
|
|
18
|
-
return accept
|
|
19
|
-
.toLowerCase()
|
|
20
|
-
.split(",")
|
|
21
|
-
.some((type) => type.split(";")[0]?.trim() === "text/event-stream");
|
|
22
|
-
}
|
|
23
16
|
}
|
|
24
17
|
//# sourceMappingURL=timing.middleware.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.middleware.js","sourceRoot":"","sources":["../src/timing.middleware.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timing.middleware.js","sourceRoot":"","sources":["../src/timing.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIhD,MAAM,OAAO,gBAAgB;IAGE,IAAI;IAFjC,MAAM,CAAU,WAAW,GAAG,eAAe,CAAC;IAE9C,YAA6B,IAAkC;oBAAlC,IAAI;IAAiC,CAAC;IAEnE,KAAK,CAAC,OAAO,CAAC,OAAyB,EAAE,MAAkC;QACzE,IAAI,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7E,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,MAAM,EAAE,CAAC;QAEf,OAAO,aAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACzD,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/bun",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bartosz Gordon",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"build": "bash scripts/package-build.sh"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@biomejs/biome": "2.5.
|
|
23
|
+
"@biomejs/biome": "2.5.15",
|
|
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
27
|
"@types/bun": "1.4.2",
|
|
28
28
|
"@types/nodemailer": "8.0.2",
|
|
29
|
-
"better-auth": "1.7.
|
|
29
|
+
"better-auth": "1.7.7",
|
|
30
30
|
"cspell": "10.3.6",
|
|
31
|
-
"fallow": "3.
|
|
31
|
+
"fallow": "3.31.0",
|
|
32
32
|
"lefthook": "2.1.14",
|
|
33
33
|
"lockfile-lint": "5.0.1",
|
|
34
34
|
"nodemailer": "10.0.10",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"node-cache": "5.1.2"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"better-auth": "1.7.
|
|
46
|
+
"better-auth": "1.7.7",
|
|
47
47
|
"nodemailer": "10.0.10"
|
|
48
48
|
},
|
|
49
49
|
"peerDependenciesMeta": {
|
package/readme.md
CHANGED
|
@@ -61,6 +61,10 @@ src/
|
|
|
61
61
|
├── antivirus.port.ts
|
|
62
62
|
├── api-version-hono.middleware.ts
|
|
63
63
|
├── api-version.middleware.ts
|
|
64
|
+
├── atomic-file-writer-collecting.adapter.ts
|
|
65
|
+
├── atomic-file-writer-noop.adapter.ts
|
|
66
|
+
├── atomic-file-writer.adapter.ts
|
|
67
|
+
├── atomic-file-writer.port.ts
|
|
64
68
|
├── auth-session-reader-better-auth.adapter.ts
|
|
65
69
|
├── auth-session-reader-noop.adapter.ts
|
|
66
70
|
├── auth-session-reader.port.ts
|
|
@@ -174,12 +178,14 @@ src/
|
|
|
174
178
|
├── event-loop-utilization.service.ts
|
|
175
179
|
├── event-revision-assigner.adapter.ts
|
|
176
180
|
├── event-revision-assigner.port.ts
|
|
181
|
+
├── event-sourced-repository.adapter.ts
|
|
177
182
|
├── event-store-collecting.adapter.ts
|
|
178
183
|
├── event-store-dispatching.adapter.ts
|
|
179
184
|
├── event-store-noop.adapter.ts
|
|
180
185
|
├── event-store-with-logger.adapter.ts
|
|
181
186
|
├── event-store.adapter.ts
|
|
182
187
|
├── event-store.port.ts
|
|
188
|
+
├── event-stream-accept.service.ts
|
|
183
189
|
├── event-stream.vo.ts
|
|
184
190
|
├── event-upcaster-chain.adapter.ts
|
|
185
191
|
├── event-upcaster-noop.adapter.ts
|
|
@@ -338,6 +344,10 @@ src/
|
|
|
338
344
|
├── job-queue-worker.service.ts
|
|
339
345
|
├── job-queue.adapter.ts
|
|
340
346
|
├── job-queue.port.ts
|
|
347
|
+
├── job-recoverer-collecting.adapter.ts
|
|
348
|
+
├── job-recoverer-noop.adapter.ts
|
|
349
|
+
├── job-recoverer-sqlite.adapter.ts
|
|
350
|
+
├── job-recoverer.port.ts
|
|
341
351
|
├── job-registry.adapter.ts
|
|
342
352
|
├── job-registry.port.ts
|
|
343
353
|
├── job-requeuer-collecting.adapter.ts
|
|
@@ -385,6 +395,7 @@ src/
|
|
|
385
395
|
├── message-bus-collecting.adapter.ts
|
|
386
396
|
├── message-bus-emittery.adapter.ts
|
|
387
397
|
├── message-bus-noop.adapter.ts
|
|
398
|
+
├── message-bus-strict.adapter.ts
|
|
388
399
|
├── message-bus-with-logger.adapter.ts
|
|
389
400
|
├── message-bus.port.ts
|
|
390
401
|
├── message.types.ts
|
|
@@ -443,6 +454,7 @@ src/
|
|
|
443
454
|
├── nonce-provider-noop.adapter.ts
|
|
444
455
|
├── nonce-provider.port.ts
|
|
445
456
|
├── nonce-value.vo.ts
|
|
457
|
+
├── path-matcher.service.ts
|
|
446
458
|
├── payload-serializer-collecting.adapter.ts
|
|
447
459
|
├── payload-serializer-json.adapter.ts
|
|
448
460
|
├── payload-serializer.port.ts
|
|
@@ -519,6 +531,9 @@ src/
|
|
|
519
531
|
├── retry-backoff-noop.strategy.ts
|
|
520
532
|
├── retry-backoff.strategy.ts
|
|
521
533
|
├── retry.service.ts
|
|
534
|
+
├── runtime-stats-provider-noop.adapter.ts
|
|
535
|
+
├── runtime-stats-provider-system.adapter.ts
|
|
536
|
+
├── runtime-stats-provider.port.ts
|
|
522
537
|
├── sealer-aes-gcm.adapter.ts
|
|
523
538
|
├── sealer-noop.adapter.ts
|
|
524
539
|
├── sealer.port.ts
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
3
|
+
import type { FileWriterContent } from "./file-writer.port";
|
|
4
|
+
|
|
5
|
+
export class AtomicFileWriterCollectingAdapter implements AtomicFileWriterPort {
|
|
6
|
+
readonly written: Array<[tools.FilePathRelative | tools.FilePathAbsolute, FileWriterContent]> = [];
|
|
7
|
+
|
|
8
|
+
async write(
|
|
9
|
+
path: tools.FilePathRelative | tools.FilePathAbsolute,
|
|
10
|
+
content: FileWriterContent,
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
this.written.push([path, content]);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
3
|
+
import type { FileWriterContent } from "./file-writer.port";
|
|
4
|
+
|
|
5
|
+
export class AtomicFileWriterNoopAdapter implements AtomicFileWriterPort {
|
|
6
|
+
async write(
|
|
7
|
+
_path: tools.FilePathRelative | tools.FilePathAbsolute,
|
|
8
|
+
_content: FileWriterContent,
|
|
9
|
+
): Promise<void> {}
|
|
10
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
3
|
+
import type { FileCleanerPort } from "./file-cleaner.port";
|
|
4
|
+
import type { FileRenamerPort } from "./file-renamer.port";
|
|
5
|
+
import type { FileWriterContent, FileWriterPort } from "./file-writer.port";
|
|
6
|
+
import type { NonceProviderPort } from "./nonce-provider.port";
|
|
7
|
+
|
|
8
|
+
type Dependencies = {
|
|
9
|
+
FileCleaner: FileCleanerPort;
|
|
10
|
+
FileRenamer: FileRenamerPort;
|
|
11
|
+
FileWriter: FileWriterPort;
|
|
12
|
+
NonceProvider: NonceProviderPort;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class AtomicFileWriterAdapter implements AtomicFileWriterPort {
|
|
16
|
+
constructor(private readonly deps: Dependencies) {}
|
|
17
|
+
|
|
18
|
+
async write(
|
|
19
|
+
path: tools.FilePathRelative | tools.FilePathAbsolute,
|
|
20
|
+
content: FileWriterContent,
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
const temporary = path.withFilename(
|
|
23
|
+
path.getFilename().withSuffix(`-part-${this.deps.NonceProvider.generate()}`),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await this.deps.FileWriter.write(temporary.get(), content);
|
|
28
|
+
await this.deps.FileRenamer.rename(temporary, path);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
await this.deps.FileCleaner.delete(temporary).catch(() => {});
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
2
3
|
import { CryptoAesGcm } from "./crypto-aes-gcm.service";
|
|
3
4
|
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
4
5
|
import type { EncryptionPort, EncryptionRecipe } from "./encryption.port";
|
|
5
6
|
import { EncryptionIV } from "./encryption-iv.vo";
|
|
6
7
|
import type { FileInspectionPort } from "./file-inspection.port";
|
|
7
8
|
import type { FileReaderRawPort } from "./file-reader-raw.port";
|
|
8
|
-
import type { FileWriterPort } from "./file-writer.port";
|
|
9
9
|
|
|
10
10
|
type Dependencies = {
|
|
11
11
|
FileReaderRaw: FileReaderRawPort;
|
|
12
|
-
|
|
12
|
+
AtomicFileWriter: AtomicFileWriterPort;
|
|
13
13
|
CryptoKeyProvider: CryptoKeyProviderPort;
|
|
14
14
|
FileInspection: FileInspectionPort;
|
|
15
15
|
};
|
|
@@ -29,7 +29,7 @@ export class EncryptionAesGcmAdapter implements EncryptionPort {
|
|
|
29
29
|
const plaintext = await this.deps.FileReaderRaw.read(recipe.input);
|
|
30
30
|
const encrypted = await CryptoAesGcm.encrypt(key, plaintext, iv);
|
|
31
31
|
|
|
32
|
-
await this.deps.
|
|
32
|
+
await this.deps.AtomicFileWriter.write(recipe.output, encrypted);
|
|
33
33
|
|
|
34
34
|
return recipe.output;
|
|
35
35
|
}
|
|
@@ -43,7 +43,7 @@ export class EncryptionAesGcmAdapter implements EncryptionPort {
|
|
|
43
43
|
const encrypted = new Uint8Array(await this.deps.FileReaderRaw.read(recipe.input));
|
|
44
44
|
const plaintext = await CryptoAesGcm.decrypt(key, encrypted);
|
|
45
45
|
|
|
46
|
-
await this.deps.
|
|
46
|
+
await this.deps.AtomicFileWriter.write(recipe.output, plaintext);
|
|
47
47
|
|
|
48
48
|
return recipe.output;
|
|
49
49
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { GenericEvent } from "./event.types";
|
|
2
|
+
import type { EventStorePort } from "./event-store.port";
|
|
3
|
+
import type { EventStreamType } from "./event-stream.vo";
|
|
4
|
+
import type { EventValidatorRegistryPort } from "./event-validator-registry.port";
|
|
5
|
+
|
|
6
|
+
type EventSourcedAggregate<Event extends GenericEvent> = { pullEvents(): ReadonlyArray<Event> };
|
|
7
|
+
|
|
8
|
+
type EventSourcedAggregateFactory<
|
|
9
|
+
Id,
|
|
10
|
+
Event extends GenericEvent,
|
|
11
|
+
Aggregate extends EventSourcedAggregate<Event>,
|
|
12
|
+
Deps,
|
|
13
|
+
> = {
|
|
14
|
+
registry: EventValidatorRegistryPort<Event>;
|
|
15
|
+
getStream: (id: Id) => EventStreamType;
|
|
16
|
+
build: (id: Id, events: ReadonlyArray<Event>, deps: Deps) => Aggregate;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type Config<Id, Event extends GenericEvent, Aggregate extends EventSourcedAggregate<Event>, Deps> = {
|
|
20
|
+
aggregate: EventSourcedAggregateFactory<Id, Event, Aggregate, Deps>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Dependencies<Event extends GenericEvent, Deps> = Deps & { EventStore: EventStorePort<Event> };
|
|
24
|
+
|
|
25
|
+
export class EventSourcedRepositoryAdapter<
|
|
26
|
+
Id,
|
|
27
|
+
Event extends GenericEvent,
|
|
28
|
+
Aggregate extends EventSourcedAggregate<Event>,
|
|
29
|
+
Deps,
|
|
30
|
+
> {
|
|
31
|
+
constructor(
|
|
32
|
+
private readonly config: Config<Id, Event, Aggregate, Deps>,
|
|
33
|
+
private readonly deps: NoInfer<Dependencies<Event, Deps>>,
|
|
34
|
+
) {}
|
|
35
|
+
|
|
36
|
+
async load(id: Id): Promise<Aggregate> {
|
|
37
|
+
const history = await this.deps.EventStore.find(
|
|
38
|
+
this.config.aggregate.registry,
|
|
39
|
+
this.config.aggregate.getStream(id),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return this.config.aggregate.build(id, history, this.deps);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async save(aggregate: Aggregate): Promise<void> {
|
|
46
|
+
await this.deps.EventStore.save(aggregate.pullEvents());
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/gzip.adapter.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// [BUN DEPENDENCY]
|
|
2
2
|
import type * as tools from "@bgord/tools";
|
|
3
|
+
import type { AtomicFileWriterPort } from "./atomic-file-writer.port";
|
|
3
4
|
import type { FileReaderRawPort } from "./file-reader-raw.port";
|
|
4
|
-
import type { FileWriterPort } from "./file-writer.port";
|
|
5
5
|
import type { GzipPort, GzipRecipe } from "./gzip.port";
|
|
6
6
|
|
|
7
|
-
type Dependencies = { FileReaderRaw: FileReaderRawPort;
|
|
7
|
+
type Dependencies = { FileReaderRaw: FileReaderRawPort; AtomicFileWriter: AtomicFileWriterPort };
|
|
8
8
|
|
|
9
9
|
export class GzipAdapter implements GzipPort {
|
|
10
10
|
constructor(private readonly deps: Dependencies) {}
|
|
@@ -13,7 +13,7 @@ export class GzipAdapter implements GzipPort {
|
|
|
13
13
|
const file = await this.deps.FileReaderRaw.read(recipe.input);
|
|
14
14
|
const archive = Bun.gzipSync(file);
|
|
15
15
|
|
|
16
|
-
await this.deps.
|
|
16
|
+
await this.deps.AtomicFileWriter.write(recipe.output, archive);
|
|
17
17
|
|
|
18
18
|
return recipe.output;
|
|
19
19
|
}
|
|
@@ -3,12 +3,9 @@ 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 {
|
|
7
|
-
import { EventLoopUtilization, type EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
|
|
8
|
-
import { InFlightRequestsTracker } from "./in-flight-requests-tracker.service";
|
|
6
|
+
import type { EventLoopUtilizationSnapshot } from "./event-loop-utilization.service";
|
|
9
7
|
import type { JobQueueStatsProviderPort, JobQueueStatsSnapshot } from "./job-queue-stats-provider.port";
|
|
10
8
|
import type { LoggerStatsProviderPort, LoggerStatsSnapshot } from "./logger-stats-provider.port";
|
|
11
|
-
import { MemoryConsumption } from "./memory-consumption.service";
|
|
12
9
|
import type { NodeEnvironmentEnum } from "./node-env.vo";
|
|
13
10
|
import { Prerequisite, type PrerequisiteLabelType } from "./prerequisite.vo";
|
|
14
11
|
import {
|
|
@@ -18,8 +15,9 @@ import {
|
|
|
18
15
|
import { PrerequisiteVerifierSelfAdapter } from "./prerequisite-verifier-self.adapter";
|
|
19
16
|
import type { ReactiveConfigPort } from "./reactive-config.port";
|
|
20
17
|
import type { RedactorStrategy } from "./redactor.strategy";
|
|
18
|
+
import type { RuntimeStatsProviderPort } from "./runtime-stats-provider.port";
|
|
21
19
|
import { Stopwatch } from "./stopwatch.service";
|
|
22
|
-
import {
|
|
20
|
+
import type { UptimeResultType } from "./uptime.service";
|
|
23
21
|
|
|
24
22
|
export enum HealthcheckStatusEnum {
|
|
25
23
|
healthy = "healthy",
|
|
@@ -30,6 +28,7 @@ export enum HealthcheckStatusEnum {
|
|
|
30
28
|
export type HealthcheckDependencies = {
|
|
31
29
|
Clock: ClockPort;
|
|
32
30
|
BuildInfoConfig: ReactiveConfigPort<BuildInfoType>;
|
|
31
|
+
RuntimeStatsProvider: RuntimeStatsProviderPort;
|
|
33
32
|
LoggerStatsProvider?: LoggerStatsProviderPort;
|
|
34
33
|
JobQueueStatsProvider?: JobQueueStatsProviderPort;
|
|
35
34
|
};
|
|
@@ -131,9 +130,7 @@ export class HealthcheckHandler {
|
|
|
131
130
|
: HealthcheckStatusEnum.healthy;
|
|
132
131
|
|
|
133
132
|
const build = await this.deps.BuildInfoConfig.get();
|
|
134
|
-
const uptime =
|
|
135
|
-
const histogram = EventLoopLag.snapshot();
|
|
136
|
-
const memory = MemoryConsumption.snapshot();
|
|
133
|
+
const { uptime, memory, eventLoop, inFlight } = this.deps.RuntimeStatsProvider.getStats();
|
|
137
134
|
|
|
138
135
|
return {
|
|
139
136
|
status,
|
|
@@ -173,10 +170,10 @@ export class HealthcheckHandler {
|
|
|
173
170
|
},
|
|
174
171
|
},
|
|
175
172
|
eventLoop: {
|
|
176
|
-
lag: { p50:
|
|
177
|
-
utilization:
|
|
173
|
+
lag: { p50: eventLoop.lag.p50.ms, p95: eventLoop.lag.p95.ms, p99: eventLoop.lag.p99.ms },
|
|
174
|
+
utilization: eventLoop.utilization,
|
|
178
175
|
},
|
|
179
|
-
inFlight
|
|
176
|
+
inFlight,
|
|
180
177
|
},
|
|
181
178
|
logger: this.deps.LoggerStatsProvider?.getStats(),
|
|
182
179
|
queue: await this.deps.JobQueueStatsProvider?.getStats(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FileUploaderError } from "./file-uploader.middleware";
|
|
2
|
+
import { RequestIdentityError } from "./request-context.port";
|
|
2
3
|
import { ShieldApiKeyStrategyError } from "./shield-api-key.strategy";
|
|
3
|
-
import { ShieldAuthStrategyError } from "./shield-auth.strategy";
|
|
4
4
|
import { ShieldBasicAuthStrategyError } from "./shield-basic-auth.strategy";
|
|
5
5
|
import { ShieldBodyLimitError } from "./shield-body-limit.strategy";
|
|
6
6
|
import { ShieldCsrfStrategyError } from "./shield-csrf.strategy";
|
|
@@ -15,7 +15,7 @@ import { ShieldWebhookStrategyError } from "./shield-webhook.strategy";
|
|
|
15
15
|
|
|
16
16
|
export const HttpExceptionErrors = {
|
|
17
17
|
ShieldApiKeyRejected: ShieldApiKeyStrategyError.Rejected,
|
|
18
|
-
ShieldAuthRejected:
|
|
18
|
+
ShieldAuthRejected: RequestIdentityError.Rejected,
|
|
19
19
|
ShieldBasicAuthRejected: ShieldBasicAuthStrategyError.Rejected,
|
|
20
20
|
ShieldBodyLimitTooBig: ShieldBodyLimitError.TooBig,
|
|
21
21
|
ShieldCsrfRejected: ShieldCsrfStrategyError.Rejected,
|
|
@@ -20,28 +20,34 @@ export class HttpLoggerHonoMiddleware implements MiddlewareHonoPort {
|
|
|
20
20
|
|
|
21
21
|
if (this.middleware.shouldSkip(context)) return await next();
|
|
22
22
|
|
|
23
|
-
const request = c.req.raw.clone();
|
|
24
23
|
const correlationId = c.get("correlationId");
|
|
25
|
-
const body = await HttpLoggerHonoMiddleware.parseJSON(
|
|
24
|
+
const body = await HttpLoggerHonoMiddleware.parseJSON(c.req.raw);
|
|
26
25
|
|
|
27
26
|
const { stopwatch } = this.middleware.before(context, correlationId, body);
|
|
28
27
|
|
|
29
28
|
await next();
|
|
30
29
|
|
|
31
|
-
const
|
|
32
|
-
const responseBody = await HttpLoggerHonoMiddleware.parseJSON(response);
|
|
30
|
+
const responseBody = await HttpLoggerHonoMiddleware.parseJSON(c.res);
|
|
33
31
|
|
|
34
32
|
this.middleware.after(context, correlationId, {
|
|
35
33
|
stopwatch,
|
|
36
|
-
status:
|
|
34
|
+
status: c.res.status,
|
|
37
35
|
responseBody,
|
|
38
36
|
});
|
|
39
37
|
};
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
private static async parseJSON(resource: Request | Response): Promise<any> {
|
|
41
|
+
if (!HttpLoggerHonoMiddleware.isJSON(resource.headers.get("content-type"))) return undefined;
|
|
42
|
+
|
|
43
43
|
try {
|
|
44
|
-
return await resource.json();
|
|
44
|
+
return await resource.clone().json();
|
|
45
45
|
} catch {}
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
private static isJSON(contentType: string | null): boolean {
|
|
49
|
+
const type = contentType?.split(";")[0]?.trim().toLowerCase();
|
|
50
|
+
|
|
51
|
+
return type === "application/json" || Boolean(type?.endsWith("+json"));
|
|
52
|
+
}
|
|
47
53
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ClockPort } from "./clock.port";
|
|
2
2
|
import type { CorrelationIdType } from "./correlation-id.vo";
|
|
3
|
+
import { EventStreamAccept } from "./event-stream-accept.service";
|
|
3
4
|
import { type LoggerPort, LogLevelEnum } from "./logger.port";
|
|
5
|
+
import { PathMatcher } from "./path-matcher.service";
|
|
4
6
|
import type { HasRequestHeader, HasRequestPath, RequestContext } from "./request-context.port";
|
|
5
7
|
import { Stopwatch } from "./stopwatch.service";
|
|
6
8
|
|
|
@@ -44,14 +46,9 @@ export class HttpLoggerMiddleware {
|
|
|
44
46
|
) {}
|
|
45
47
|
|
|
46
48
|
shouldSkip(context: HasRequestPath & HasRequestHeader): boolean {
|
|
47
|
-
if (context.request.header("accept")
|
|
49
|
+
if (EventStreamAccept.matches(context.request.header("accept"))) return true;
|
|
48
50
|
|
|
49
|
-
return (
|
|
50
|
-
this.config?.skip?.some((rule) => {
|
|
51
|
-
if (rule instanceof URLPattern) return rule.test({ pathname: context.request.path });
|
|
52
|
-
return context.request.path.startsWith(rule);
|
|
53
|
-
}) ?? false
|
|
54
|
-
);
|
|
51
|
+
return PathMatcher.matches(this.config?.skip, context.request.path);
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
before(context: RequestContext, correlationId: CorrelationIdType, body: any = {}): HttpLoggerBeforeResult {
|