@bgord/bun 1.9.0 → 1.9.2
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/basic-auth-password.vo.d.ts +1 -1
- package/dist/basic-auth-password.vo.d.ts.map +1 -1
- package/dist/basic-auth-password.vo.js +1 -1
- package/dist/basic-auth-password.vo.js.map +1 -1
- package/dist/basic-auth-username.vo.d.ts +1 -1
- package/dist/basic-auth-username.vo.d.ts.map +1 -1
- package/dist/basic-auth-username.vo.js +1 -1
- package/dist/basic-auth-username.vo.js.map +1 -1
- package/dist/binary.vo.d.ts +1 -1
- package/dist/binary.vo.d.ts.map +1 -1
- package/dist/binary.vo.js +1 -1
- package/dist/binary.vo.js.map +1 -1
- package/dist/cache-subject-segment-env.strategy.d.ts +3 -3
- package/dist/client-ip.vo.d.ts +1 -1
- package/dist/client-ip.vo.d.ts.map +1 -1
- package/dist/client-ip.vo.js +1 -1
- package/dist/client-ip.vo.js.map +1 -1
- package/dist/client-user-agent.vo.d.ts +1 -1
- package/dist/client-user-agent.vo.d.ts.map +1 -1
- package/dist/client-user-agent.vo.js +1 -1
- package/dist/client-user-agent.vo.js.map +1 -1
- package/dist/command.types.d.ts +1 -1
- package/dist/command.types.d.ts.map +1 -1
- package/dist/commit-sha-value.vo.d.ts +1 -1
- package/dist/commit-sha-value.vo.d.ts.map +1 -1
- package/dist/commit-sha-value.vo.js +1 -1
- package/dist/commit-sha-value.vo.js.map +1 -1
- package/dist/correlation-id.vo.d.ts +1 -1
- package/dist/correlation-id.vo.d.ts.map +1 -1
- package/dist/dispatching-event-store.d.ts +1 -1
- package/dist/dispatching-event-store.d.ts.map +1 -1
- package/dist/encryption-key-value.vo.d.ts +1 -1
- package/dist/encryption-key-value.vo.d.ts.map +1 -1
- package/dist/encryption-key-value.vo.js +1 -1
- package/dist/encryption-key-value.vo.js.map +1 -1
- package/dist/environment-loader-encrypted.adapter.d.ts +4 -4
- package/dist/environment-loader-encrypted.adapter.d.ts.map +1 -1
- package/dist/environment-loader-noop.adapter.d.ts +3 -3
- package/dist/environment-loader-noop.adapter.d.ts.map +1 -1
- package/dist/environment-loader-process-safe.adapter.d.ts +4 -4
- package/dist/environment-loader-process-safe.adapter.d.ts.map +1 -1
- package/dist/environment-loader-process.adapter.d.ts +4 -4
- package/dist/environment-loader-process.adapter.d.ts.map +1 -1
- package/dist/environment-loader.port.d.ts +3 -3
- package/dist/environment-loader.port.d.ts.map +1 -1
- package/dist/event-envelope.d.ts +1 -1
- package/dist/event-envelope.d.ts.map +1 -1
- package/dist/event-envelope.js +1 -1
- package/dist/event-envelope.js.map +1 -1
- package/dist/event-handler-bare.strategy.d.ts +1 -1
- package/dist/event-handler-bare.strategy.d.ts.map +1 -1
- package/dist/event-handler-noop.strategy.d.ts +1 -1
- package/dist/event-handler-noop.strategy.d.ts.map +1 -1
- package/dist/event-handler-with-logger.strategy.d.ts +1 -1
- package/dist/event-handler-with-logger.strategy.d.ts.map +1 -1
- package/dist/event-handler.strategy.d.ts +1 -1
- package/dist/event-handler.strategy.d.ts.map +1 -1
- package/dist/event-store.d.ts +1 -1
- package/dist/event-store.d.ts.map +1 -1
- package/dist/event-stream.vo.d.ts +1 -1
- package/dist/event-stream.vo.d.ts.map +1 -1
- package/dist/event-stream.vo.js +1 -1
- package/dist/event-stream.vo.js.map +1 -1
- package/dist/event.types.d.ts +1 -1
- package/dist/event.types.d.ts.map +1 -1
- package/dist/hash-value.vo.d.ts +1 -1
- package/dist/hash-value.vo.d.ts.map +1 -1
- package/dist/hash-value.vo.js +1 -1
- package/dist/hash-value.vo.js.map +1 -1
- package/dist/hcaptcha-secret-key.vo.d.ts +1 -1
- package/dist/hcaptcha-secret-key.vo.d.ts.map +1 -1
- package/dist/hcaptcha-secret-key.vo.js +1 -1
- package/dist/hcaptcha-secret-key.vo.js.map +1 -1
- package/dist/hcaptcha-site-key.vo.d.ts +1 -1
- package/dist/hcaptcha-site-key.vo.d.ts.map +1 -1
- package/dist/hcaptcha-site-key.vo.js +1 -1
- package/dist/hcaptcha-site-key.vo.js.map +1 -1
- package/dist/healthcheck.service.d.ts +3 -3
- package/dist/logger-winston-local.adapter.d.ts.map +1 -1
- package/dist/logger-winston-local.adapter.js +2 -1
- package/dist/logger-winston-local.adapter.js.map +1 -1
- package/dist/logger-winston-production.adapter.d.ts.map +1 -1
- package/dist/logger-winston-production.adapter.js +3 -2
- package/dist/logger-winston-production.adapter.js.map +1 -1
- package/dist/logger-winston.adapter.d.ts +2 -2
- package/dist/logger.port.d.ts +3 -3
- package/dist/logger.port.d.ts.map +1 -1
- package/dist/logger.port.js +1 -1
- package/dist/logger.port.js.map +1 -1
- package/dist/mailer-content-html.vo.d.ts +1 -1
- package/dist/mailer-content-html.vo.d.ts.map +1 -1
- package/dist/mailer-content-html.vo.js +1 -1
- package/dist/mailer-content-html.vo.js.map +1 -1
- package/dist/mailer-subject.vo.d.ts +1 -1
- package/dist/mailer-subject.vo.d.ts.map +1 -1
- package/dist/mailer-subject.vo.js +1 -1
- package/dist/mailer-subject.vo.js.map +1 -1
- package/dist/modules/history/events/HISTORY_CLEARED_EVENT.d.ts +1 -1
- package/dist/modules/history/events/HISTORY_CLEARED_EVENT.d.ts.map +1 -1
- package/dist/modules/history/events/HISTORY_CLEARED_EVENT.js +1 -1
- package/dist/modules/history/events/HISTORY_CLEARED_EVENT.js.map +1 -1
- package/dist/modules/history/events/HISTORY_POPULATED_EVENT.d.ts +1 -1
- package/dist/modules/history/events/HISTORY_POPULATED_EVENT.d.ts.map +1 -1
- package/dist/modules/history/events/HISTORY_POPULATED_EVENT.js +1 -1
- package/dist/modules/history/events/HISTORY_POPULATED_EVENT.js.map +1 -1
- package/dist/modules/history/value-objects/history-created-at.d.ts +1 -1
- package/dist/modules/history/value-objects/history-created-at.d.ts.map +1 -1
- package/dist/modules/history/value-objects/history-operation.d.ts +1 -1
- package/dist/modules/history/value-objects/history-operation.d.ts.map +1 -1
- package/dist/modules/history/value-objects/history-operation.js +1 -1
- package/dist/modules/history/value-objects/history-operation.js.map +1 -1
- package/dist/modules/history/value-objects/history-payload.d.ts +1 -1
- package/dist/modules/history/value-objects/history-payload.d.ts.map +1 -1
- package/dist/modules/history/value-objects/history-payload.js +1 -1
- package/dist/modules/history/value-objects/history-payload.js.map +1 -1
- package/dist/modules/history/value-objects/history-subject.d.ts +1 -1
- package/dist/modules/history/value-objects/history-subject.d.ts.map +1 -1
- package/dist/modules/history/value-objects/history-subject.js +1 -1
- package/dist/modules/history/value-objects/history-subject.js.map +1 -1
- package/dist/modules/history/value-objects/history.d.ts +1 -1
- package/dist/modules/history/value-objects/history.d.ts.map +1 -1
- package/dist/modules/history/value-objects/history.js +1 -1
- package/dist/modules/history/value-objects/history.js.map +1 -1
- package/dist/modules/preferences/commands/SET_USER_LANGUAGE_COMMAND.d.ts +1 -1
- package/dist/modules/preferences/commands/SET_USER_LANGUAGE_COMMAND.d.ts.map +1 -1
- package/dist/modules/preferences/commands/SET_USER_LANGUAGE_COMMAND.js +1 -1
- package/dist/modules/preferences/commands/SET_USER_LANGUAGE_COMMAND.js.map +1 -1
- package/dist/modules/preferences/events/USER_LANGUAGE_SET_EVENT.d.ts +1 -1
- package/dist/modules/preferences/events/USER_LANGUAGE_SET_EVENT.d.ts.map +1 -1
- package/dist/modules/preferences/events/USER_LANGUAGE_SET_EVENT.js +1 -1
- package/dist/modules/preferences/events/USER_LANGUAGE_SET_EVENT.js.map +1 -1
- package/dist/modules/system/events/HOUR_HAS_PASSED_EVENT.d.ts +1 -1
- package/dist/modules/system/events/HOUR_HAS_PASSED_EVENT.d.ts.map +1 -1
- package/dist/modules/system/events/HOUR_HAS_PASSED_EVENT.js +1 -1
- package/dist/modules/system/events/HOUR_HAS_PASSED_EVENT.js.map +1 -1
- package/dist/modules/system/events/MINUTE_HAS_PASSED_EVENT.d.ts +1 -1
- package/dist/modules/system/events/MINUTE_HAS_PASSED_EVENT.d.ts.map +1 -1
- package/dist/modules/system/events/MINUTE_HAS_PASSED_EVENT.js +1 -1
- package/dist/modules/system/events/MINUTE_HAS_PASSED_EVENT.js.map +1 -1
- package/dist/modules/system/events/SECURITY_VIOLATION_DETECTED_EVENT.d.ts +1 -1
- package/dist/modules/system/events/SECURITY_VIOLATION_DETECTED_EVENT.d.ts.map +1 -1
- package/dist/modules/system/events/SECURITY_VIOLATION_DETECTED_EVENT.js +1 -1
- package/dist/modules/system/events/SECURITY_VIOLATION_DETECTED_EVENT.js.map +1 -1
- package/dist/node-env.vo.d.ts +11 -9
- package/dist/node-env.vo.d.ts.map +1 -1
- package/dist/node-env.vo.js +10 -3
- package/dist/node-env.vo.js.map +1 -1
- package/dist/nonce-value.vo.d.ts +1 -1
- package/dist/nonce-value.vo.d.ts.map +1 -1
- package/dist/nonce-value.vo.js +1 -1
- package/dist/nonce-value.vo.js.map +1 -1
- package/dist/port.vo.d.ts +1 -1
- package/dist/port.vo.d.ts.map +1 -1
- package/dist/port.vo.js +1 -1
- package/dist/port.vo.js.map +1 -1
- package/dist/prerequisite-verifier-timezone-utc.adapter.d.ts +1 -1
- package/dist/prerequisite-verifier-timezone-utc.adapter.d.ts.map +1 -1
- package/dist/prerequisite-verifier-timezone-utc.adapter.js +1 -1
- package/dist/prerequisite-verifier-timezone-utc.adapter.js.map +1 -1
- package/dist/recaptcha-secret-key.vo.d.ts +1 -1
- package/dist/recaptcha-secret-key.vo.d.ts.map +1 -1
- package/dist/recaptcha-secret-key.vo.js +1 -1
- package/dist/recaptcha-secret-key.vo.js.map +1 -1
- package/dist/recaptcha-site-key.vo.d.ts +1 -1
- package/dist/recaptcha-site-key.vo.d.ts.map +1 -1
- package/dist/recaptcha-site-key.vo.js +1 -1
- package/dist/recaptcha-site-key.vo.js.map +1 -1
- package/dist/security-countermeasure-name.vo.d.ts +1 -1
- package/dist/security-countermeasure-name.vo.d.ts.map +1 -1
- package/dist/security-countermeasure-name.vo.js +1 -1
- package/dist/security-countermeasure-name.vo.js.map +1 -1
- package/dist/security-rule-name.vo.d.ts +1 -1
- package/dist/security-rule-name.vo.d.ts.map +1 -1
- package/dist/security-rule-name.vo.js +1 -1
- package/dist/security-rule-name.vo.js.map +1 -1
- package/dist/smtp-host.vo.d.ts +1 -1
- package/dist/smtp-host.vo.d.ts.map +1 -1
- package/dist/smtp-host.vo.js +1 -1
- package/dist/smtp-host.vo.js.map +1 -1
- package/dist/smtp-pass.vo.d.ts +1 -1
- package/dist/smtp-pass.vo.d.ts.map +1 -1
- package/dist/smtp-pass.vo.js +1 -1
- package/dist/smtp-pass.vo.js.map +1 -1
- package/dist/smtp-port.vo.d.ts +1 -1
- package/dist/smtp-port.vo.d.ts.map +1 -1
- package/dist/smtp-user.vo.d.ts +1 -1
- package/dist/smtp-user.vo.d.ts.map +1 -1
- package/dist/smtp-user.vo.js +1 -1
- package/dist/smtp-user.vo.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/uuid.vo.d.ts +1 -1
- package/dist/uuid.vo.d.ts.map +1 -1
- package/dist/uuid.vo.js +1 -1
- package/dist/uuid.vo.js.map +1 -1
- package/package.json +4 -3
- package/src/antivirus-clamav.adapter.ts +34 -0
- package/src/antivirus-noop.adapter.ts +8 -0
- package/src/antivirus.port.ts +9 -0
- package/src/api-version.middleware.ts +31 -0
- package/src/basic-auth-password.vo.ts +17 -0
- package/src/basic-auth-username.vo.ts +17 -0
- package/src/basic-auth.service.ts +14 -0
- package/src/better-auth-logger.service.ts +45 -0
- package/src/binary.vo.ts +22 -0
- package/src/bots.vo.ts +132 -0
- package/src/build-info-repository-file.strategy.ts +23 -0
- package/src/build-info-repository-noop.strategy.ts +16 -0
- package/src/build-info-repository-package-json.strategy.ts +25 -0
- package/src/build-info-repository.strategy.ts +13 -0
- package/src/cache-file.service.ts +37 -0
- package/src/cache-repository-lru-cache.adapter.ts +58 -0
- package/src/cache-repository-node-cache.adapter.ts +32 -0
- package/src/cache-repository-noop.adapter.ts +15 -0
- package/src/cache-repository.port.ts +11 -0
- package/src/cache-resolver-simple.strategy.ts +33 -0
- package/src/cache-resolver.strategy.ts +17 -0
- package/src/cache-response.middleware.ts +51 -0
- package/src/cache-subject-application-resolver.vo.ts +34 -0
- package/src/cache-subject-request-resolver.vo.ts +37 -0
- package/src/cache-subject-segment-application.strategy.ts +7 -0
- package/src/cache-subject-segment-build.strategy.ts +14 -0
- package/src/cache-subject-segment-cookie.strategy.ts +14 -0
- package/src/cache-subject-segment-env.strategy.ts +10 -0
- package/src/cache-subject-segment-fixed.strategy.ts +12 -0
- package/src/cache-subject-segment-header.strategy.ts +13 -0
- package/src/cache-subject-segment-ip.strategy.ts +9 -0
- package/src/cache-subject-segment-path.strategy.ts +8 -0
- package/src/cache-subject-segment-query.strategy.ts +18 -0
- package/src/cache-subject-segment-request.strategy.ts +9 -0
- package/src/cache-subject-segment-user.strategy.ts +8 -0
- package/src/certificate-inspector-noop.adapter.ts +10 -0
- package/src/certificate-inspector-tls.adapter.ts +42 -0
- package/src/certificate-inspector.port.ts +7 -0
- package/src/checksum.service.ts +12 -0
- package/src/client-from-hono.adapter.ts +20 -0
- package/src/client-ip.vo.ts +17 -0
- package/src/client-user-agent.vo.ts +17 -0
- package/src/client.vo.ts +52 -0
- package/src/clock-fixed.adapter.ts +14 -0
- package/src/clock-offset.adapter.ts +15 -0
- package/src/clock-system.adapter.ts +8 -0
- package/src/clock.port.ts +5 -0
- package/src/command-envelope.ts +16 -0
- package/src/command-logger.service.ts +23 -0
- package/src/command.types.ts +13 -0
- package/src/commit-sha-value.vo.ts +18 -0
- package/src/commit-sha.vo.ts +29 -0
- package/src/context.middleware.ts +24 -0
- package/src/correlation-id.vo.ts +6 -0
- package/src/correlation-storage.service.ts +31 -0
- package/src/crypto-aes-gcm.service.ts +37 -0
- package/src/crypto-key-provider-file.adapter.ts +29 -0
- package/src/crypto-key-provider-memory.adapter.ts +17 -0
- package/src/crypto-key-provider-noop.adapter.ts +9 -0
- package/src/crypto-key-provider-with-cache.adapter.ts +28 -0
- package/src/crypto-key-provider.port.ts +3 -0
- package/src/csv-stringifier.adapter.ts +8 -0
- package/src/csv-stringifier.port.ts +8 -0
- package/src/disk-space-checker-bun.adapter.ts +18 -0
- package/src/disk-space-checker-noop.adapter.ts +10 -0
- package/src/disk-space-checker.port.ts +5 -0
- package/src/dispatching-event-store.ts +36 -0
- package/src/encryption-aes-gcm.adapter.ts +57 -0
- package/src/encryption-iv.vo.ts +9 -0
- package/src/encryption-key-value.vo.ts +18 -0
- package/src/encryption-key.vo.ts +41 -0
- package/src/encryption-noop.adapter.ts +18 -0
- package/src/encryption.port.ts +12 -0
- package/src/environment-file-parser.service.ts +35 -0
- package/src/environment-loader-encrypted.adapter.ts +31 -0
- package/src/environment-loader-noop.adapter.ts +16 -0
- package/src/environment-loader-process-safe.adapter.ts +35 -0
- package/src/environment-loader-process.adapter.ts +16 -0
- package/src/environment-loader.port.ts +8 -0
- package/src/etag-extractor.middleware.ts +18 -0
- package/src/event-bus-like.types.ts +10 -0
- package/src/event-envelope.ts +27 -0
- package/src/event-handler-bare.strategy.ts +9 -0
- package/src/event-handler-noop.strategy.ts +9 -0
- package/src/event-handler-with-logger.strategy.ts +31 -0
- package/src/event-handler.strategy.ts +8 -0
- package/src/event-logger.service.ts +23 -0
- package/src/event-loop-lag.service.ts +32 -0
- package/src/event-loop-utilization.service.ts +21 -0
- package/src/event-publisher.types.ts +3 -0
- package/src/event-store-like.types.ts +3 -0
- package/src/event-store.ts +64 -0
- package/src/event-stream.vo.ts +14 -0
- package/src/event.types.ts +16 -0
- package/src/file-cleaner-bun-forgiving.adapter.ts +10 -0
- package/src/file-cleaner-bun.adapter.ts +8 -0
- package/src/file-cleaner-noop.adapter.ts +6 -0
- package/src/file-cleaner.port.ts +5 -0
- package/src/file-draft-zip.service.ts +34 -0
- package/src/file-draft.service.ts +33 -0
- package/src/file-reader-json-bun-forgiving.adapter.ts +14 -0
- package/src/file-reader-json-bun.adapter.ts +10 -0
- package/src/file-reader-json-noop.adapter.ts +12 -0
- package/src/file-reader-json-with-cache.adapter.ts +34 -0
- package/src/file-reader-json.port.ts +7 -0
- package/src/file-renamer-fs-forgiving.adapter.ts +17 -0
- package/src/file-renamer-fs.adapter.ts +15 -0
- package/src/file-renamer-noop.adapter.ts +9 -0
- package/src/file-renamer.port.ts +8 -0
- package/src/file-uploader.middleware.ts +39 -0
- package/src/graceful-shutdown.service.ts +68 -0
- package/src/gzip-bun.adapter.ts +12 -0
- package/src/gzip-noop.adapter.ts +7 -0
- package/src/gzip-stream.adapter.ts +19 -0
- package/src/gzip.port.ts +10 -0
- package/src/hash-content-noop.strategy.ts +8 -0
- package/src/hash-content-sha256-bun.strategy.ts +11 -0
- package/src/hash-content.strategy.ts +5 -0
- package/src/hash-file-noop.adapter.ts +14 -0
- package/src/hash-file-sha256-bun.adapter.ts +23 -0
- package/src/hash-file.port.ts +13 -0
- package/src/hash-value.vo.ts +15 -0
- package/src/hash.vo.ts +29 -0
- package/src/hcaptcha-secret-key.vo.ts +15 -0
- package/src/hcaptcha-site-key.vo.ts +12 -0
- package/src/healthcheck.service.ts +138 -0
- package/src/http-logger.middleware.ts +100 -0
- package/src/i18n.service.ts +62 -0
- package/src/id-provider-crypto.adapter.ts +8 -0
- package/src/id-provider-deterministic.adapter.ts +21 -0
- package/src/id-provider.port.ts +5 -0
- package/src/image-alpha-noop.adapter.ts +7 -0
- package/src/image-alpha-sharp.adapter.ts +38 -0
- package/src/image-alpha.port.ts +19 -0
- package/src/image-blur-noop.adapter.ts +7 -0
- package/src/image-blur-sharp.adapter.ts +33 -0
- package/src/image-blur.port.ts +18 -0
- package/src/image-compressor-noop.adapter.ts +7 -0
- package/src/image-compressor-sharp.adapter.ts +36 -0
- package/src/image-compressor.port.ts +18 -0
- package/src/image-exif-clear-noop.adapter.ts +7 -0
- package/src/image-exif-clear-sharp.adapter.ts +30 -0
- package/src/image-exif-clear.port.ts +16 -0
- package/src/image-formatter-noop.adapter.ts +10 -0
- package/src/image-formatter-sharp.adapter.ts +40 -0
- package/src/image-formatter.port.ts +17 -0
- package/src/image-info-noop.adapter.ts +15 -0
- package/src/image-info-sharp.adapter.ts +27 -0
- package/src/image-info.port.ts +12 -0
- package/src/image-processor-noop.adapter.ts +10 -0
- package/src/image-processor-sharp.adapter.ts +60 -0
- package/src/image-processor.port.ts +25 -0
- package/src/image-resizer-noop.adapter.ts +7 -0
- package/src/image-resizer-sharp.adapter.ts +41 -0
- package/src/image-resizer.port.ts +18 -0
- package/src/in-flight-requests-tracker.service.ts +22 -0
- package/src/in-flight-requests.middleware.ts +15 -0
- package/src/index.ts +307 -0
- package/src/instrumentation.service.ts +39 -0
- package/src/invariant-error-handler.service.ts +22 -0
- package/src/invariant.service.ts +27 -0
- package/src/job-handler-bare.strategy.ts +15 -0
- package/src/job-handler-noop.strategy.ts +9 -0
- package/src/job-handler-with-logger.strategy.ts +44 -0
- package/src/job-handler.strategy.ts +10 -0
- package/src/jobs.service.ts +16 -0
- package/src/logger-format-error.service.ts +27 -0
- package/src/logger-noop.adapter.ts +17 -0
- package/src/logger-winston-local.adapter.ts +24 -0
- package/src/logger-winston-production.adapter.ts +38 -0
- package/src/logger-winston.adapter.ts +63 -0
- package/src/logger.port.ts +64 -0
- package/src/mailer-content-html.vo.ts +11 -0
- package/src/mailer-noop.adapter.ts +21 -0
- package/src/mailer-smtp-with-logger.adapter.ts +33 -0
- package/src/mailer-smtp.adapter.ts +33 -0
- package/src/mailer-subject.vo.ts +10 -0
- package/src/mailer.port.ts +6 -0
- package/src/maintenance-mode.middleware.ts +15 -0
- package/src/memory-consumption.service.ts +23 -0
- package/src/modules/history/event-handlers/index.ts +2 -0
- package/src/modules/history/event-handlers/onHistoryClearedEvent.ts +6 -0
- package/src/modules/history/event-handlers/onHistoryPopulatedEvent.ts +10 -0
- package/src/modules/history/events/HISTORY_CLEARED_EVENT.ts +13 -0
- package/src/modules/history/events/HISTORY_POPULATED_EVENT.ts +17 -0
- package/src/modules/history/events/index.ts +2 -0
- package/src/modules/history/index.ts +4 -0
- package/src/modules/history/ports/history-projection.ts +7 -0
- package/src/modules/history/ports/history-reader.ts +5 -0
- package/src/modules/history/ports/history-writer.ts +7 -0
- package/src/modules/history/ports/index.ts +3 -0
- package/src/modules/history/value-objects/history-created-at.ts +6 -0
- package/src/modules/history/value-objects/history-id.ts +3 -0
- package/src/modules/history/value-objects/history-operation.ts +12 -0
- package/src/modules/history/value-objects/history-payload.ts +15 -0
- package/src/modules/history/value-objects/history-subject.ts +14 -0
- package/src/modules/history/value-objects/history.ts +26 -0
- package/src/modules/history/value-objects/index.ts +6 -0
- package/src/modules/preferences/command-handlers/handleSetUserLanguageCommand.ts +36 -0
- package/src/modules/preferences/command-handlers/index.ts +1 -0
- package/src/modules/preferences/commands/SET_USER_LANGUAGE_COMMAND.ts +14 -0
- package/src/modules/preferences/commands/index.ts +1 -0
- package/src/modules/preferences/events/USER_LANGUAGE_SET_EVENT.ts +14 -0
- package/src/modules/preferences/events/index.ts +1 -0
- package/src/modules/preferences/index.ts +7 -0
- package/src/modules/preferences/invariants/index.ts +1 -0
- package/src/modules/preferences/invariants/user-language-has-changed.ts +26 -0
- package/src/modules/preferences/open-host-queries/index.ts +1 -0
- package/src/modules/preferences/open-host-queries/user-language.ts +23 -0
- package/src/modules/preferences/ports/index.ts +2 -0
- package/src/modules/preferences/ports/user-language-query.ts +5 -0
- package/src/modules/preferences/ports/user-language-resolver.ts +22 -0
- package/src/modules/preferences/value-objects/index.ts +1 -0
- package/src/modules/preferences/value-objects/supported-languages-set.ts +17 -0
- package/src/modules/system/events/HOUR_HAS_PASSED_EVENT.ts +13 -0
- package/src/modules/system/events/MINUTE_HAS_PASSED_EVENT.ts +13 -0
- package/src/modules/system/events/SECURITY_VIOLATION_DETECTED_EVENT.ts +23 -0
- package/src/modules/system/events/index.ts +3 -0
- package/src/modules/system/index.ts +2 -0
- package/src/modules/system/services/index.ts +2 -0
- package/src/modules/system/services/passage-of-time-hourly.service.ts +35 -0
- package/src/modules/system/services/passage-of-time-minute.service.ts +35 -0
- package/src/node-env.vo.ts +12 -0
- package/src/nonce-provider-crypto.adapter.ts +18 -0
- package/src/nonce-provider-deterministic.adapter.ts +21 -0
- package/src/nonce-provider-noop.adapter.ts +8 -0
- package/src/nonce-provider.port.ts +5 -0
- package/src/nonce-value.vo.ts +18 -0
- package/src/pdf-generator-noop.adapter.ts +23 -0
- package/src/pdf-generator.port.ts +5 -0
- package/src/ping.service.ts +7 -0
- package/src/port.vo.ts +14 -0
- package/src/prerequisite-runner-startup.service.ts +44 -0
- package/src/prerequisite-verifier-binary.adapter.ts +21 -0
- package/src/prerequisite-verifier-bun.adapter.ts +21 -0
- package/src/prerequisite-verifier-clock-drift.adapter.ts +32 -0
- package/src/prerequisite-verifier-directory.adapter.ts +48 -0
- package/src/prerequisite-verifier-dns.adapter.ts +20 -0
- package/src/prerequisite-verifier-external-api.adapter.ts +20 -0
- package/src/prerequisite-verifier-file.adapter.ts +49 -0
- package/src/prerequisite-verifier-jobs.adapter.ts +15 -0
- package/src/prerequisite-verifier-log-file.adapter.ts +29 -0
- package/src/prerequisite-verifier-mailer.adapter.ts +22 -0
- package/src/prerequisite-verifier-memory.adapter.ts +22 -0
- package/src/prerequisite-verifier-node.adapter.ts +21 -0
- package/src/prerequisite-verifier-os.adapter.ts +22 -0
- package/src/prerequisite-verifier-outside-connectivity.adapter.ts +23 -0
- package/src/prerequisite-verifier-port.adapter.ts +23 -0
- package/src/prerequisite-verifier-ram.adapter.ts +20 -0
- package/src/prerequisite-verifier-running-user.adapter.ts +17 -0
- package/src/prerequisite-verifier-self.adapter.ts +11 -0
- package/src/prerequisite-verifier-space.adapter.ts +32 -0
- package/src/prerequisite-verifier-sqlite.adapter.ts +25 -0
- package/src/prerequisite-verifier-ssl-certificate-expiry.adapter.ts +28 -0
- package/src/prerequisite-verifier-timezone-utc.adapter.ts +20 -0
- package/src/prerequisite-verifier-translations.adapter.ts +65 -0
- package/src/prerequisite-verifier-with-cache.adapter.ts +35 -0
- package/src/prerequisite-verifier-with-fail-safe.adapter.ts +37 -0
- package/src/prerequisite-verifier-with-logger.adapter.ts +51 -0
- package/src/prerequisite-verifier-with-retry.adapter.ts +35 -0
- package/src/prerequisite-verifier-with-timeout.adapter.ts +31 -0
- package/src/prerequisite-verifier.decorator.ts +49 -0
- package/src/prerequisite-verifier.port.ts +38 -0
- package/src/prerequisite.vo.ts +28 -0
- package/src/recaptcha-secret-key.vo.ts +15 -0
- package/src/recaptcha-site-key.vo.ts +12 -0
- package/src/redactor-compact-array.strategy.ts +10 -0
- package/src/redactor-compact-object.strategy.ts +25 -0
- package/src/redactor-composite.strategy.ts +9 -0
- package/src/redactor-mask.strategy.ts +38 -0
- package/src/redactor-noop.strategy.ts +7 -0
- package/src/redactor.strategy.ts +3 -0
- package/src/remote-file-storage-disk.adapter.ts +72 -0
- package/src/remote-file-storage-noop.adapter.ts +70 -0
- package/src/remote-file-storage.port.ts +17 -0
- package/src/retry-backoff-exponential.strategy.ts +10 -0
- package/src/retry-backoff-fibonacci.strategy.ts +16 -0
- package/src/retry-backoff-linear.strategy.ts +10 -0
- package/src/retry-backoff-noop.strategy.ts +8 -0
- package/src/retry-backoff.strategy.ts +5 -0
- package/src/retry.service.ts +37 -0
- package/src/safe-parse-body.service.ts +12 -0
- package/src/sealer-aes-gcm.adapter.ts +38 -0
- package/src/sealer-noop.adapter.ts +11 -0
- package/src/sealer.port.ts +4 -0
- package/src/security-context.vo.ts +13 -0
- package/src/security-countermeasure-ban.strategy.ts +63 -0
- package/src/security-countermeasure-mirage.strategy.ts +31 -0
- package/src/security-countermeasure-name.vo.ts +22 -0
- package/src/security-countermeasure-noop.strategy.ts +12 -0
- package/src/security-countermeasure-report.strategy.ts +27 -0
- package/src/security-countermeasure-tarpit.strategy.ts +31 -0
- package/src/security-countermeasure.strategy.ts +16 -0
- package/src/security-policy.vo.ts +9 -0
- package/src/security-rule-and.strategy.ts +25 -0
- package/src/security-rule-bait-routes.strategy.ts +15 -0
- package/src/security-rule-fail.strategy.ts +12 -0
- package/src/security-rule-honey-pot-field.strategy.ts +20 -0
- package/src/security-rule-name.vo.ts +22 -0
- package/src/security-rule-or.strategy.ts +25 -0
- package/src/security-rule-pass.strategy.ts +12 -0
- package/src/security-rule-user-agent.strategy.ts +20 -0
- package/src/security-rule-violation-threshold.strategy.ts +50 -0
- package/src/security-rule.strategy.ts +8 -0
- package/src/setup.service.ts +102 -0
- package/src/shield-api-key.strategy.ts +20 -0
- package/src/shield-auth.strategy.ts +38 -0
- package/src/shield-basic-auth.strategy.ts +17 -0
- package/src/shield-csrf.strategy.ts +23 -0
- package/src/shield-hcaptcha-local.strategy.ts +22 -0
- package/src/shield-hcaptcha.strategy.ts +24 -0
- package/src/shield-noop.strategy.ts +6 -0
- package/src/shield-rate-limit.strategy.ts +41 -0
- package/src/shield-recaptcha.strategy.ts +49 -0
- package/src/shield-security.strategy.ts +80 -0
- package/src/shield-timeout.strategy.ts +19 -0
- package/src/shield.strategy.ts +5 -0
- package/src/simulated-error.middleware.ts +8 -0
- package/src/sleeper-noop.adapter.ts +5 -0
- package/src/sleeper-system.adapter.ts +8 -0
- package/src/sleeper.port.ts +5 -0
- package/src/slower.middleware.ts +14 -0
- package/src/smtp-host.vo.ts +17 -0
- package/src/smtp-pass.vo.ts +17 -0
- package/src/smtp-port.vo.ts +5 -0
- package/src/smtp-user.vo.ts +17 -0
- package/src/ssr.ts +57 -0
- package/src/static-files.service.ts +85 -0
- package/src/stopwatch.service.ts +30 -0
- package/src/temporary-file-absolute.adapter.ts +31 -0
- package/src/temporary-file-noop.adapter.ts +16 -0
- package/src/temporary-file.port.ts +9 -0
- package/src/time-zone-offset.middleware.ts +24 -0
- package/src/timekeeper-google.adapter.ts +18 -0
- package/src/timekeeper-noop.adapter.ts +12 -0
- package/src/timekeeper.port.ts +5 -0
- package/src/timeout-cancellable-runner-bare.adapter.ts +35 -0
- package/src/timeout-cancellable-runner-noop.adapter.ts +9 -0
- package/src/timeout-cancellable-runner.port.ts +7 -0
- package/src/timeout-runner-bare.adapter.ts +23 -0
- package/src/timeout-runner-error.adapter.ts +8 -0
- package/src/timeout-runner-monitor.adapter.ts +24 -0
- package/src/timeout-runner-noop.adapter.ts +8 -0
- package/src/timeout-runner.port.ts +7 -0
- package/src/to-event-map.types.ts +3 -0
- package/src/translations.service.ts +20 -0
- package/src/uptime.service.ts +17 -0
- package/src/uuid.vo.ts +7 -0
- package/src/visitor-id-client.strategy.ts +20 -0
- package/src/visitor-id.strategy.ts +5 -0
- package/src/weak-etag-extractor.middleware.ts +17 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { createMiddleware } from "hono/factory";
|
|
3
|
+
import type { CorrelationIdType } from "./correlation-id.vo";
|
|
4
|
+
|
|
5
|
+
type CorrelationContext = { correlationId: CorrelationIdType };
|
|
6
|
+
|
|
7
|
+
export const CorrelationStorageError = { Missing: "correlation.storage.missing" } as const;
|
|
8
|
+
|
|
9
|
+
export class CorrelationStorage {
|
|
10
|
+
static readonly GLOBAL_KEY = Symbol.for("bgord.CorrelationStorage");
|
|
11
|
+
|
|
12
|
+
// biome-ignore lint: lint/suspicious/noAssignInExpressions
|
|
13
|
+
private static readonly als: AsyncLocalStorage<CorrelationContext> = ((globalThis as any)[
|
|
14
|
+
this.GLOBAL_KEY
|
|
15
|
+
] ??=
|
|
16
|
+
new AsyncLocalStorage<CorrelationContext>());
|
|
17
|
+
|
|
18
|
+
static run<T>(correlationId: CorrelationIdType, action: () => T | Promise<T>): T | Promise<T> {
|
|
19
|
+
return CorrelationStorage.als.run({ correlationId }, action);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static get(): CorrelationIdType {
|
|
23
|
+
const store = CorrelationStorage.als.getStore();
|
|
24
|
+
|
|
25
|
+
if (!store) throw new Error(CorrelationStorageError.Missing);
|
|
26
|
+
return store.correlationId;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static handle = () =>
|
|
30
|
+
createMiddleware(async (context, next) => CorrelationStorage.run(context.get("requestId"), next));
|
|
31
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { EncryptionIV } from "./encryption-iv.vo";
|
|
2
|
+
|
|
3
|
+
/** @public */
|
|
4
|
+
export const CryptoAesGcmError = { InvalidPayload: "aes.gcm.crypto.invalid.payload" };
|
|
5
|
+
|
|
6
|
+
export class CryptoAesGcm {
|
|
7
|
+
static readonly ALGORITHM = "AES-GCM";
|
|
8
|
+
|
|
9
|
+
static async encrypt(key: CryptoKey, plaintext: ArrayBuffer, iv: Uint8Array): Promise<Uint8Array> {
|
|
10
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
11
|
+
{ name: CryptoAesGcm.ALGORITHM, iv: iv as BufferSource },
|
|
12
|
+
key,
|
|
13
|
+
plaintext,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const ciphertext = new Uint8Array(encrypted);
|
|
17
|
+
const output = new Uint8Array(iv.length + ciphertext.length);
|
|
18
|
+
|
|
19
|
+
output.set(iv, 0);
|
|
20
|
+
output.set(ciphertext, iv.length);
|
|
21
|
+
|
|
22
|
+
return output;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static async decrypt(key: CryptoKey, payload: Uint8Array): Promise<ArrayBuffer> {
|
|
26
|
+
if (payload.length < EncryptionIV.LENGTH + 1) throw new Error(CryptoAesGcmError.InvalidPayload);
|
|
27
|
+
|
|
28
|
+
const iv = payload.subarray(0, EncryptionIV.LENGTH);
|
|
29
|
+
const ciphertext = payload.subarray(EncryptionIV.LENGTH);
|
|
30
|
+
|
|
31
|
+
return crypto.subtle.decrypt(
|
|
32
|
+
{ name: CryptoAesGcm.ALGORITHM, iv: iv as BufferSource },
|
|
33
|
+
key,
|
|
34
|
+
ciphertext as BufferSource,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
3
|
+
import { EncryptionKey } from "./encryption-key.vo";
|
|
4
|
+
|
|
5
|
+
export const CryptoKeyProviderFileAdapterError = {
|
|
6
|
+
MissingFile: "crypto.key.provider.file.adapter.missing.file",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class CryptoKeyProviderFileAdapter implements CryptoKeyProviderPort {
|
|
10
|
+
constructor(private readonly path: tools.FilePathAbsolute | tools.FilePathRelative) {}
|
|
11
|
+
|
|
12
|
+
async get() {
|
|
13
|
+
const file = Bun.file(this.path.get());
|
|
14
|
+
const exists = await file.exists();
|
|
15
|
+
|
|
16
|
+
if (!exists) throw new Error(CryptoKeyProviderFileAdapterError.MissingFile);
|
|
17
|
+
|
|
18
|
+
const content = await file.text();
|
|
19
|
+
const encryptionKey = EncryptionKey.fromString(content.trim());
|
|
20
|
+
|
|
21
|
+
return crypto.subtle.importKey(
|
|
22
|
+
"raw",
|
|
23
|
+
encryptionKey.toBuffer() as BufferSource,
|
|
24
|
+
{ name: "AES-GCM" },
|
|
25
|
+
false,
|
|
26
|
+
["encrypt", "decrypt"],
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
2
|
+
import { EncryptionKey } from "./encryption-key.vo";
|
|
3
|
+
import type { EncryptionKeyValueType } from "./encryption-key-value.vo";
|
|
4
|
+
|
|
5
|
+
export class CryptoKeyProviderMemoryAdapter implements CryptoKeyProviderPort {
|
|
6
|
+
constructor(private readonly ENCRYPTION_KEY_VALUE: EncryptionKeyValueType) {}
|
|
7
|
+
|
|
8
|
+
async get(): Promise<CryptoKey> {
|
|
9
|
+
return crypto.subtle.importKey(
|
|
10
|
+
"raw",
|
|
11
|
+
EncryptionKey.fromString(this.ENCRYPTION_KEY_VALUE).toBuffer() as BufferSource,
|
|
12
|
+
{ name: "AES-GCM" },
|
|
13
|
+
false,
|
|
14
|
+
["encrypt", "decrypt"],
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
2
|
+
|
|
3
|
+
export class CryptoKeyProviderNoopAdapter implements CryptoKeyProviderPort {
|
|
4
|
+
async get(): Promise<CryptoKey> {
|
|
5
|
+
const bytes = new Uint8Array(32);
|
|
6
|
+
|
|
7
|
+
return crypto.subtle.importKey("raw", bytes, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
2
|
+
import { CacheSubjectApplicationResolver } from "./cache-subject-application-resolver.vo";
|
|
3
|
+
import { CacheSubjectSegmentFixedStrategy } from "./cache-subject-segment-fixed.strategy";
|
|
4
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
5
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
6
|
+
|
|
7
|
+
type Dependencies = { CacheResolver: CacheResolverStrategy; HashContent: HashContentStrategy };
|
|
8
|
+
|
|
9
|
+
export class CryptoKeyProviderWithCacheAdapter implements CryptoKeyProviderPort {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly config: { id: string; inner: CryptoKeyProviderPort },
|
|
12
|
+
private readonly deps: Dependencies,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async get(): Promise<CryptoKey> {
|
|
16
|
+
const resolver = new CacheSubjectApplicationResolver(
|
|
17
|
+
[
|
|
18
|
+
new CacheSubjectSegmentFixedStrategy("crypto_key_provider"),
|
|
19
|
+
new CacheSubjectSegmentFixedStrategy(this.config.id),
|
|
20
|
+
],
|
|
21
|
+
this.deps,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const subject = await resolver.resolve();
|
|
25
|
+
|
|
26
|
+
return this.deps.CacheResolver.resolve<CryptoKey>(subject.hex, () => this.config.inner.get());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { stringify } from "csv";
|
|
2
|
+
import type { CsvColumnType, CsvRowType, CsvStringifierPort } from "./csv-stringifier.port";
|
|
3
|
+
|
|
4
|
+
export class CsvStringifierAdapter implements CsvStringifierPort {
|
|
5
|
+
process(columns: CsvColumnType[], data: CsvRowType[]) {
|
|
6
|
+
return stringify(data, { header: true, columns });
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import bun from "bun";
|
|
2
|
+
import * as tools from "@bgord/tools";
|
|
3
|
+
import type { DiskSpaceCheckerPort } from "./disk-space-checker.port";
|
|
4
|
+
|
|
5
|
+
// Example command output:
|
|
6
|
+
// Filesystem 1024-blocks Used Available Capacity Mounted on
|
|
7
|
+
// /dev/disk3s1s1 239362496 10997540 43650948 21% /
|
|
8
|
+
|
|
9
|
+
export class DiskSpaceCheckerBunAdapter implements DiskSpaceCheckerPort {
|
|
10
|
+
async get(root: string) {
|
|
11
|
+
const stdout = await bun.$`df -kP ${root}`.text();
|
|
12
|
+
|
|
13
|
+
const line = stdout.trim().split(/\r?\n/)[1]; // Select the second line
|
|
14
|
+
const free = Number(line?.trim().split(/\s+/)[3]); // Get the fourth block
|
|
15
|
+
|
|
16
|
+
return tools.Size.fromKb(free);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { DiskSpaceCheckerPort } from "./disk-space-checker.port";
|
|
3
|
+
|
|
4
|
+
export class DiskSpaceCheckerNoopAdapter implements DiskSpaceCheckerPort {
|
|
5
|
+
constructor(private readonly value: tools.Size) {}
|
|
6
|
+
|
|
7
|
+
async get(_root: string) {
|
|
8
|
+
return this.value;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Stryker disable all
|
|
2
|
+
import type * as z from "zod/v4";
|
|
3
|
+
import type { GenericEventSchema, GenericParsedEventSchema } from "./event.types";
|
|
4
|
+
import type { EventPublisher } from "./event-publisher.types";
|
|
5
|
+
import { EventStore as BaseStore } from "./event-store";
|
|
6
|
+
import type { EventStreamType } from "./event-stream.vo";
|
|
7
|
+
import type { ToEventMap } from "./to-event-map.types";
|
|
8
|
+
|
|
9
|
+
export class DispatchingEventStore<AllEvents extends GenericEventSchema> extends BaseStore<AllEvents> {
|
|
10
|
+
static EMPTY_STREAM_REVISION = -1;
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
config: {
|
|
14
|
+
finder: (stream: EventStreamType, names: string[]) => Promise<z.infer<GenericEventSchema>[]>;
|
|
15
|
+
inserter: (events: z.infer<GenericParsedEventSchema>[]) => Promise<z.infer<GenericParsedEventSchema>[]>;
|
|
16
|
+
},
|
|
17
|
+
private readonly publisher: EventPublisher<ToEventMap<z.infer<AllEvents>>>,
|
|
18
|
+
) {
|
|
19
|
+
super(config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async save(_events: z.infer<AllEvents>[]): Promise<z.infer<AllEvents>[]> {
|
|
23
|
+
// We receive the events with the `revision` fields added by the inserter,
|
|
24
|
+
// so the read models can receive them.
|
|
25
|
+
const events = await super.save(_events);
|
|
26
|
+
|
|
27
|
+
await Promise.all(
|
|
28
|
+
events.map((event) =>
|
|
29
|
+
this.publisher.emit(event.name as keyof ToEventMap<z.infer<AllEvents>>, event as any),
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return events;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Stryker restore all
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import { CryptoAesGcm } from "./crypto-aes-gcm.service";
|
|
3
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
4
|
+
import type { EncryptionPort, EncryptionRecipe } from "./encryption.port";
|
|
5
|
+
import { EncryptionIV } from "./encryption-iv.vo";
|
|
6
|
+
|
|
7
|
+
type Dependencies = { CryptoKeyProvider: CryptoKeyProviderPort };
|
|
8
|
+
|
|
9
|
+
export const EncryptionAesGcmAdapterError = { MissingFile: "encryption.aes.gcm.adapter.missing.file" };
|
|
10
|
+
|
|
11
|
+
export class EncryptionAesGcmAdapter implements EncryptionPort {
|
|
12
|
+
constructor(private readonly deps: Dependencies) {}
|
|
13
|
+
|
|
14
|
+
async encrypt(recipe: EncryptionRecipe) {
|
|
15
|
+
const key = await this.deps.CryptoKeyProvider.get();
|
|
16
|
+
const iv = EncryptionIV.generate();
|
|
17
|
+
|
|
18
|
+
const file = Bun.file(recipe.input.get());
|
|
19
|
+
const exists = await file.exists();
|
|
20
|
+
if (!exists) throw new Error(EncryptionAesGcmAdapterError.MissingFile);
|
|
21
|
+
|
|
22
|
+
const plaintext = await file.arrayBuffer();
|
|
23
|
+
const output = await CryptoAesGcm.encrypt(key, plaintext, iv);
|
|
24
|
+
|
|
25
|
+
await Bun.write(recipe.output.get(), output);
|
|
26
|
+
|
|
27
|
+
return recipe.output;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async decrypt(recipe: EncryptionRecipe) {
|
|
31
|
+
const key = await this.deps.CryptoKeyProvider.get();
|
|
32
|
+
|
|
33
|
+
const file = Bun.file(recipe.input.get());
|
|
34
|
+
const exists = await file.exists();
|
|
35
|
+
if (!exists) throw new Error(EncryptionAesGcmAdapterError.MissingFile);
|
|
36
|
+
|
|
37
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
38
|
+
|
|
39
|
+
const decrypted = await CryptoAesGcm.decrypt(key, bytes);
|
|
40
|
+
|
|
41
|
+
await Bun.write(recipe.output.get(), decrypted);
|
|
42
|
+
|
|
43
|
+
return recipe.output;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async view(input: tools.FilePathRelative | tools.FilePathAbsolute) {
|
|
47
|
+
const key = await this.deps.CryptoKeyProvider.get();
|
|
48
|
+
|
|
49
|
+
const file = Bun.file(input.get());
|
|
50
|
+
const exists = await file.exists();
|
|
51
|
+
if (!exists) throw new Error(EncryptionAesGcmAdapterError.MissingFile);
|
|
52
|
+
|
|
53
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
54
|
+
|
|
55
|
+
return CryptoAesGcm.decrypt(key, bytes);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const EncryptionKeyValueError = {
|
|
4
|
+
Type: "encryption.key.value.type",
|
|
5
|
+
InvalidHex: "encryption.key.value.invalid.hex",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// 64 hex chars allowed
|
|
9
|
+
const CHARS_WHITELIST = /^[a-fA-F0-9]{64}$/;
|
|
10
|
+
|
|
11
|
+
// Stryker disable all
|
|
12
|
+
export const EncryptionKeyValue = z
|
|
13
|
+
// Stryker restore all
|
|
14
|
+
.string(EncryptionKeyValueError.Type)
|
|
15
|
+
.regex(CHARS_WHITELIST, EncryptionKeyValueError.InvalidHex)
|
|
16
|
+
.brand("EncryptionKeyValue");
|
|
17
|
+
|
|
18
|
+
export type EncryptionKeyValueType = z.infer<typeof EncryptionKeyValue>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EncryptionKeyValue, type EncryptionKeyValueType } from "./encryption-key-value.vo";
|
|
2
|
+
|
|
3
|
+
export const EncryptionKeyError = { InvalidBuffer: "encryption.key.invalid.buffer" };
|
|
4
|
+
|
|
5
|
+
export class EncryptionKey {
|
|
6
|
+
private constructor(private readonly value: EncryptionKeyValueType) {}
|
|
7
|
+
|
|
8
|
+
static fromStringSafe(value: EncryptionKeyValueType): EncryptionKey {
|
|
9
|
+
return new EncryptionKey(value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static fromString(candidate: string): EncryptionKey {
|
|
13
|
+
return new EncryptionKey(EncryptionKeyValue.parse(candidate));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static fromBuffer(buffer: Uint8Array): EncryptionKey {
|
|
17
|
+
if (buffer.length !== 32) throw new Error(EncryptionKeyError.InvalidBuffer);
|
|
18
|
+
|
|
19
|
+
const hex = Array.from(buffer)
|
|
20
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
21
|
+
.join("");
|
|
22
|
+
|
|
23
|
+
return EncryptionKey.fromString(hex);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
equals(another: EncryptionKey): boolean {
|
|
27
|
+
return this.value === another.value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
toBuffer(): Uint8Array {
|
|
31
|
+
return Uint8Array.from(Buffer.from(this.value, "hex"));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
toString(): string {
|
|
35
|
+
return "EncryptionKey";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
toJSON(): string {
|
|
39
|
+
return "EncryptionKey";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { EncryptionPort, EncryptionRecipe } from "./encryption.port";
|
|
3
|
+
|
|
4
|
+
export class EncryptionNoopAdapter implements EncryptionPort {
|
|
5
|
+
constructor(private readonly buffer: ArrayBuffer = new TextEncoder().encode("noop").buffer) {}
|
|
6
|
+
|
|
7
|
+
async encrypt(recipe: EncryptionRecipe) {
|
|
8
|
+
return recipe.output;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async decrypt(recipe: EncryptionRecipe) {
|
|
12
|
+
return recipe.output;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async view(_input: tools.FilePathRelative | tools.FilePathAbsolute) {
|
|
16
|
+
return this.buffer;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
|
|
3
|
+
export type EncryptionRecipe = {
|
|
4
|
+
input: tools.FilePathRelative | tools.FilePathAbsolute;
|
|
5
|
+
output: tools.FilePathRelative | tools.FilePathAbsolute;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export interface EncryptionPort {
|
|
9
|
+
encrypt(recipe: EncryptionRecipe): Promise<tools.FilePathRelative | tools.FilePathAbsolute>;
|
|
10
|
+
decrypt(recipe: EncryptionRecipe): Promise<tools.FilePathRelative | tools.FilePathAbsolute>;
|
|
11
|
+
view(input: tools.FilePathRelative | tools.FilePathAbsolute): Promise<ArrayBuffer>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class EnvironmentFileParser {
|
|
2
|
+
static parse(content: string): Record<string, string> {
|
|
3
|
+
const result: Record<string, string> = {};
|
|
4
|
+
|
|
5
|
+
const lines = content.split(/\r?\n/);
|
|
6
|
+
|
|
7
|
+
for (const line of lines) {
|
|
8
|
+
// Stryker disable all
|
|
9
|
+
const trimmed = line.trim();
|
|
10
|
+
// Stryker restore all
|
|
11
|
+
|
|
12
|
+
// Stryker disable all
|
|
13
|
+
if (!trimmed) continue;
|
|
14
|
+
// Stryker restore all
|
|
15
|
+
|
|
16
|
+
if (trimmed.startsWith("#")) continue;
|
|
17
|
+
|
|
18
|
+
const separatorIndex = trimmed.indexOf("=");
|
|
19
|
+
|
|
20
|
+
if (separatorIndex === -1) continue;
|
|
21
|
+
|
|
22
|
+
const key = trimmed.slice(0, separatorIndex).trim();
|
|
23
|
+
|
|
24
|
+
let value = trimmed.slice(separatorIndex + 1).trim();
|
|
25
|
+
|
|
26
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
27
|
+
value = value.slice(1, -1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
result[key] = value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type * as z from "zod/v4";
|
|
3
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
4
|
+
import type { EncryptionPort } from "./encryption.port";
|
|
5
|
+
import { EnvironmentFileParser } from "./environment-file-parser.service";
|
|
6
|
+
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
7
|
+
|
|
8
|
+
type Dependencies = { Encryption: EncryptionPort };
|
|
9
|
+
|
|
10
|
+
export class EnvironmentLoaderEncryptedAdapter<Schema extends z.ZodObject<any>>
|
|
11
|
+
implements EnvironmentLoaderPort<Schema>
|
|
12
|
+
{
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly config: {
|
|
15
|
+
type: NodeEnvironmentEnum;
|
|
16
|
+
Schema: Schema;
|
|
17
|
+
path: tools.FilePathAbsolute | tools.FilePathRelative;
|
|
18
|
+
},
|
|
19
|
+
private readonly deps: Dependencies,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
async load() {
|
|
23
|
+
const file = await this.deps.Encryption.view(this.config.path);
|
|
24
|
+
const content = new TextDecoder().decode(file);
|
|
25
|
+
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
...this.config.Schema.parse(EnvironmentFileParser.parse(content)),
|
|
28
|
+
type: this.config.type,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
+
import type { EnvironmentLoaderPort, EnvironmentResultType } from "./environment-loader.port";
|
|
4
|
+
|
|
5
|
+
export class EnvironmentLoaderNoopAdapter<Schema extends z.ZodObject<any>>
|
|
6
|
+
implements EnvironmentLoaderPort<Schema>
|
|
7
|
+
{
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly config: { type: NodeEnvironmentEnum; Schema: Schema },
|
|
10
|
+
private readonly deterministic: Omit<EnvironmentResultType<Schema>, "type">,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
async load(): Promise<Readonly<EnvironmentResultType<Schema>>> {
|
|
14
|
+
return Object.freeze({ ...this.config.Schema.parse(this.deterministic), type: this.config.type });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
+
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
4
|
+
import { CacheSubjectApplicationResolver } from "./cache-subject-application-resolver.vo";
|
|
5
|
+
import { CacheSubjectSegmentFixedStrategy } from "./cache-subject-segment-fixed.strategy";
|
|
6
|
+
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
7
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
8
|
+
|
|
9
|
+
type Dependencies = { CacheResolver: CacheResolverStrategy; HashContent: HashContentStrategy };
|
|
10
|
+
|
|
11
|
+
export class EnvironmentLoaderProcessSafeAdapter<Schema extends z.ZodObject<any>>
|
|
12
|
+
implements EnvironmentLoaderPort<Schema>
|
|
13
|
+
{
|
|
14
|
+
constructor(
|
|
15
|
+
private env: NodeJS.ProcessEnv,
|
|
16
|
+
private readonly config: { type: NodeEnvironmentEnum; Schema: Schema },
|
|
17
|
+
private readonly deps: Dependencies,
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
async load() {
|
|
21
|
+
const resolver = new CacheSubjectApplicationResolver(
|
|
22
|
+
[new CacheSubjectSegmentFixedStrategy("env")],
|
|
23
|
+
this.deps,
|
|
24
|
+
);
|
|
25
|
+
const subject = await resolver.resolve();
|
|
26
|
+
|
|
27
|
+
const result = await this.deps.CacheResolver.resolve(subject.hex, async () =>
|
|
28
|
+
this.config.Schema.parse(this.env),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
for (const key of Object.keys(result)) delete process.env[key];
|
|
32
|
+
|
|
33
|
+
return Object.freeze({ ...result, type: this.config.type });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
+
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
4
|
+
|
|
5
|
+
export class EnvironmentLoaderProcessAdapter<Schema extends z.ZodObject<any>>
|
|
6
|
+
implements EnvironmentLoaderPort<Schema>
|
|
7
|
+
{
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly config: { type: NodeEnvironmentEnum; Schema: Schema },
|
|
10
|
+
private env: NodeJS.ProcessEnv,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
async load() {
|
|
14
|
+
return Object.freeze({ ...this.config.Schema.parse(this.env), type: this.config.type });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
+
|
|
4
|
+
export type EnvironmentResultType<Schema> = z.infer<Schema> & { type: NodeEnvironmentEnum };
|
|
5
|
+
|
|
6
|
+
export interface EnvironmentLoaderPort<Schema extends z.ZodObject<any>> {
|
|
7
|
+
load(): Promise<Readonly<EnvironmentResultType<Schema>>>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import { createMiddleware } from "hono/factory";
|
|
3
|
+
|
|
4
|
+
export type EtagVariables = { ETag: tools.ETag | null; WeakETag: tools.WeakETag | null };
|
|
5
|
+
|
|
6
|
+
export class ETagExtractor {
|
|
7
|
+
static attach = createMiddleware<{ Variables: EtagVariables }>(async (context, next) => {
|
|
8
|
+
try {
|
|
9
|
+
const header = context.req.header(tools.ETag.IF_MATCH_HEADER_NAME);
|
|
10
|
+
|
|
11
|
+
context.set("ETag", tools.ETag.fromHeader(header));
|
|
12
|
+
} catch {
|
|
13
|
+
context.set("ETag", null);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
await next();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ToEventMap } from "./to-event-map.types";
|
|
2
|
+
|
|
3
|
+
export type EventBusLike<E extends { name: string }> = {
|
|
4
|
+
on<K extends keyof ToEventMap<E> & string>(
|
|
5
|
+
name: K,
|
|
6
|
+
handler: (event: ToEventMap<E>[K]) => void | Promise<void>,
|
|
7
|
+
): void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type CommandBusLike<C extends { name: string }> = { emit(name: C["name"], command: C): Promise<void> };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
import type { ClockPort } from "./clock.port";
|
|
4
|
+
import { CorrelationStorage } from "./correlation-storage.service";
|
|
5
|
+
import type { EventStreamType } from "./event-stream.vo";
|
|
6
|
+
import type { IdProviderPort } from "./id-provider.port";
|
|
7
|
+
import { UUID } from "./uuid.vo";
|
|
8
|
+
|
|
9
|
+
type Dependencies = { IdProvider: IdProviderPort; Clock: ClockPort };
|
|
10
|
+
|
|
11
|
+
export const EventEnvelopeSchema = {
|
|
12
|
+
id: UUID,
|
|
13
|
+
correlationId: UUID,
|
|
14
|
+
createdAt: tools.TimestampValue,
|
|
15
|
+
stream: z.string().min(1),
|
|
16
|
+
version: z.literal(1),
|
|
17
|
+
revision: tools.RevisionValue.optional(),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const createEventEnvelope = (stream: EventStreamType, deps: Dependencies) =>
|
|
21
|
+
({
|
|
22
|
+
id: deps.IdProvider.generate(),
|
|
23
|
+
correlationId: CorrelationStorage.get(),
|
|
24
|
+
createdAt: deps.Clock.now().ms,
|
|
25
|
+
stream,
|
|
26
|
+
version: 1,
|
|
27
|
+
}) as const;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { GenericEventSchema } from "./event.types";
|
|
3
|
+
import type { EventHandlerStrategy } from "./event-handler.strategy";
|
|
4
|
+
|
|
5
|
+
export class EventHandlerBareStrategy implements EventHandlerStrategy {
|
|
6
|
+
handle<T extends { name: z.infer<GenericEventSchema["shape"]["name"]> }>(fn: (event: T) => Promise<void>) {
|
|
7
|
+
return async (event: T) => fn(event);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
import type { GenericEventSchema } from "./event.types";
|
|
3
|
+
import type { EventHandlerStrategy } from "./event-handler.strategy";
|
|
4
|
+
|
|
5
|
+
export class EventHandlerNoopStrategy implements EventHandlerStrategy {
|
|
6
|
+
handle<T extends { name: z.infer<GenericEventSchema["shape"]["name"]> }>(_fn: (event: T) => Promise<void>) {
|
|
7
|
+
return async (_event: T) => {};
|
|
8
|
+
}
|
|
9
|
+
}
|