@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,17 @@
|
|
|
1
|
+
import type { Hash } from "./hash.vo";
|
|
2
|
+
|
|
3
|
+
export enum CacheSourceEnum {
|
|
4
|
+
hit = "hit",
|
|
5
|
+
miss = "miss",
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface CacheResolverStrategy {
|
|
9
|
+
resolve<T>(subject: Hash, producer: () => Promise<T>): Promise<T>;
|
|
10
|
+
|
|
11
|
+
resolveWithContext<T>(
|
|
12
|
+
subject: Hash,
|
|
13
|
+
producer: () => Promise<T>,
|
|
14
|
+
): Promise<{ value: T; source: CacheSourceEnum }>;
|
|
15
|
+
|
|
16
|
+
flush(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createMiddleware } from "hono/factory";
|
|
2
|
+
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
3
|
+
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
4
|
+
import type { CacheSubjectRequestResolver } from "./cache-subject-request-resolver.vo";
|
|
5
|
+
|
|
6
|
+
type Dependencies = { CacheResolver: CacheResolverStrategy };
|
|
7
|
+
|
|
8
|
+
type CacheResponseOptions = { enabled: boolean; resolver: CacheSubjectRequestResolver };
|
|
9
|
+
|
|
10
|
+
type CachedResponse = {
|
|
11
|
+
body: string;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
status: ContentfulStatusCode;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class CacheResponse {
|
|
17
|
+
static readonly CACHE_HIT_HEADER = "Cache-Hit";
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
private readonly config: CacheResponseOptions,
|
|
21
|
+
private readonly deps: Dependencies,
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
handle = createMiddleware(async (context, next) => {
|
|
25
|
+
if (!this.config.enabled) return next();
|
|
26
|
+
|
|
27
|
+
const subject = await this.config.resolver.resolve(context);
|
|
28
|
+
|
|
29
|
+
const result = await this.deps.CacheResolver.resolveWithContext<CachedResponse>(subject.hex, async () => {
|
|
30
|
+
await next();
|
|
31
|
+
|
|
32
|
+
const response = context.res.clone();
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
body: await response.text(),
|
|
36
|
+
headers: response.headers.toJSON(),
|
|
37
|
+
status: response.status as ContentfulStatusCode,
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
context.header(CacheResponse.CACHE_HIT_HEADER, result.source);
|
|
42
|
+
|
|
43
|
+
return context.newResponse(result.value.body, result.value.status, result.value.headers);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
clear = createMiddleware(async (_, next) => {
|
|
47
|
+
await this.deps.CacheResolver.flush();
|
|
48
|
+
|
|
49
|
+
return next();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CacheSubjectSegmentApplicationStrategy } from "./cache-subject-segment-application.strategy";
|
|
2
|
+
import type { CacheSubjectSegmentType } from "./cache-subject-segment-request.strategy";
|
|
3
|
+
import type { Hash } from "./hash.vo";
|
|
4
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
5
|
+
|
|
6
|
+
type Dependencies = { HashContent: HashContentStrategy };
|
|
7
|
+
|
|
8
|
+
export const CacheSubjectApplicationResolverError = {
|
|
9
|
+
NoSegments: "cache.subject.application.no.segments",
|
|
10
|
+
TooManySegments: "cache.subject.application.too.many.segments",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class CacheSubjectApplicationResolver {
|
|
14
|
+
private readonly SEPARATOR = "|";
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
private readonly segments: CacheSubjectSegmentApplicationStrategy[],
|
|
18
|
+
private readonly deps: Dependencies,
|
|
19
|
+
) {
|
|
20
|
+
if (this.segments.length === 0) throw new Error(CacheSubjectApplicationResolverError.NoSegments);
|
|
21
|
+
if (this.segments.length > 10) throw new Error(CacheSubjectApplicationResolverError.TooManySegments);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async resolve(): Promise<{ hex: Hash; raw: CacheSubjectSegmentType[] }> {
|
|
25
|
+
const segments = this.segments.map((segment) =>
|
|
26
|
+
segment.create().replaceAll(this.SEPARATOR, encodeURIComponent(this.SEPARATOR)),
|
|
27
|
+
);
|
|
28
|
+
const subject = segments.join(this.SEPARATOR);
|
|
29
|
+
|
|
30
|
+
const hex = await this.deps.HashContent.hash(subject);
|
|
31
|
+
|
|
32
|
+
return { hex, raw: segments };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type {
|
|
3
|
+
CacheSubjectSegmentRequestStrategy,
|
|
4
|
+
CacheSubjectSegmentType,
|
|
5
|
+
} from "./cache-subject-segment-request.strategy";
|
|
6
|
+
import type { Hash } from "./hash.vo";
|
|
7
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
8
|
+
|
|
9
|
+
type Dependencies = { HashContent: HashContentStrategy };
|
|
10
|
+
|
|
11
|
+
export const CacheSubjectRequestResolverError = {
|
|
12
|
+
NoSegments: "cache.subject.request.no.segments",
|
|
13
|
+
TooManySegments: "cache.subject.request.too.many.segments",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class CacheSubjectRequestResolver {
|
|
17
|
+
private readonly SEPARATOR = "|";
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
private readonly segments: CacheSubjectSegmentRequestStrategy[],
|
|
21
|
+
private readonly deps: Dependencies,
|
|
22
|
+
) {
|
|
23
|
+
if (this.segments.length === 0) throw new Error(CacheSubjectRequestResolverError.NoSegments);
|
|
24
|
+
if (this.segments.length > 10) throw new Error(CacheSubjectRequestResolverError.TooManySegments);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async resolve(context: Context): Promise<{ hex: Hash; raw: CacheSubjectSegmentType[] }> {
|
|
28
|
+
const segments = this.segments.map((segment) =>
|
|
29
|
+
segment.create(context).replaceAll(this.SEPARATOR, encodeURIComponent(this.SEPARATOR)),
|
|
30
|
+
);
|
|
31
|
+
const subject = segments.join(this.SEPARATOR);
|
|
32
|
+
|
|
33
|
+
const hex = await this.deps.HashContent.hash(subject);
|
|
34
|
+
|
|
35
|
+
return { hex, raw: segments };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CacheSubjectSegmentType } from "./cache-subject-segment-request.strategy";
|
|
2
|
+
|
|
3
|
+
export const CacheSubjectSegmentApplicationEmpty: CacheSubjectSegmentType = "__absent__";
|
|
4
|
+
|
|
5
|
+
export interface CacheSubjectSegmentApplicationStrategy {
|
|
6
|
+
create(): CacheSubjectSegmentType;
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import {
|
|
3
|
+
CacheSubjectSegmentApplicationEmpty,
|
|
4
|
+
type CacheSubjectSegmentApplicationStrategy,
|
|
5
|
+
} from "./cache-subject-segment-application.strategy";
|
|
6
|
+
|
|
7
|
+
export class CacheSubjectSegmentBuildStrategy implements CacheSubjectSegmentApplicationStrategy {
|
|
8
|
+
constructor(private readonly build?: tools.PackageVersion) {}
|
|
9
|
+
|
|
10
|
+
create() {
|
|
11
|
+
if (!this.build) return CacheSubjectSegmentApplicationEmpty;
|
|
12
|
+
return this.build.toString();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import { getCookie } from "hono/cookie";
|
|
3
|
+
import {
|
|
4
|
+
CacheSubjectSegmentRequestEmpty,
|
|
5
|
+
type CacheSubjectSegmentRequestStrategy,
|
|
6
|
+
} from "./cache-subject-segment-request.strategy";
|
|
7
|
+
|
|
8
|
+
export class CacheSubjectSegmentCookieStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
9
|
+
constructor(private readonly name: string) {}
|
|
10
|
+
|
|
11
|
+
create(context: Context) {
|
|
12
|
+
return getCookie(context, this.name) ?? CacheSubjectSegmentRequestEmpty;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CacheSubjectSegmentApplicationStrategy } from "./cache-subject-segment-application.strategy";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "./node-env.vo";
|
|
3
|
+
|
|
4
|
+
export class CacheSubjectSegmentEnvStrategy implements CacheSubjectSegmentApplicationStrategy {
|
|
5
|
+
constructor(private readonly type: NodeEnvironmentEnum) {}
|
|
6
|
+
|
|
7
|
+
create() {
|
|
8
|
+
return this.type;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CacheSubjectSegmentApplicationStrategy } from "./cache-subject-segment-application.strategy";
|
|
2
|
+
import type { CacheSubjectSegmentRequestStrategy } from "./cache-subject-segment-request.strategy";
|
|
3
|
+
|
|
4
|
+
export class CacheSubjectSegmentFixedStrategy
|
|
5
|
+
implements CacheSubjectSegmentRequestStrategy, CacheSubjectSegmentApplicationStrategy
|
|
6
|
+
{
|
|
7
|
+
constructor(private readonly value: string) {}
|
|
8
|
+
|
|
9
|
+
create() {
|
|
10
|
+
return this.value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import {
|
|
3
|
+
CacheSubjectSegmentRequestEmpty,
|
|
4
|
+
type CacheSubjectSegmentRequestStrategy,
|
|
5
|
+
} from "./cache-subject-segment-request.strategy";
|
|
6
|
+
|
|
7
|
+
export class CacheSubjectSegmentHeaderStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
8
|
+
constructor(private readonly name: string) {}
|
|
9
|
+
|
|
10
|
+
create(context: Context) {
|
|
11
|
+
return context.req.header(this.name) ?? CacheSubjectSegmentRequestEmpty;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { CacheSubjectSegmentRequestStrategy } from "./cache-subject-segment-request.strategy";
|
|
3
|
+
import { ClientFromHono } from "./client-from-hono.adapter";
|
|
4
|
+
|
|
5
|
+
export class CacheSubjectSegmentIpStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
6
|
+
create(context: Context) {
|
|
7
|
+
return ClientFromHono.translate(context).ip;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { CacheSubjectSegmentRequestStrategy } from "./cache-subject-segment-request.strategy";
|
|
3
|
+
|
|
4
|
+
export class CacheSubjectSegmentPathStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
5
|
+
create(context: Context) {
|
|
6
|
+
return context.req.path;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import {
|
|
3
|
+
CacheSubjectSegmentRequestEmpty,
|
|
4
|
+
type CacheSubjectSegmentRequestStrategy,
|
|
5
|
+
} from "./cache-subject-segment-request.strategy";
|
|
6
|
+
|
|
7
|
+
export class CacheSubjectSegmentQueryStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
8
|
+
create(context: Context) {
|
|
9
|
+
const query = context.req.query() ?? {};
|
|
10
|
+
|
|
11
|
+
const keys = Object.keys(query).toSorted();
|
|
12
|
+
|
|
13
|
+
const result = keys.map((key) => `${key}=${query[key]}`).join("&");
|
|
14
|
+
|
|
15
|
+
if (!result) return CacheSubjectSegmentRequestEmpty;
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
|
|
3
|
+
export const CacheSubjectSegmentRequestEmpty: CacheSubjectSegmentType = "__absent__";
|
|
4
|
+
|
|
5
|
+
export type CacheSubjectSegmentType = string;
|
|
6
|
+
|
|
7
|
+
export interface CacheSubjectSegmentRequestStrategy {
|
|
8
|
+
create(context: Context): CacheSubjectSegmentType;
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { CacheSubjectSegmentRequestStrategy } from "./cache-subject-segment-request.strategy";
|
|
3
|
+
|
|
4
|
+
export class CacheSubjectSegmentUserStrategy implements CacheSubjectSegmentRequestStrategy {
|
|
5
|
+
create(context: Context) {
|
|
6
|
+
return context.get("user")?.id ?? "anon";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { CertificateInspection, CertificateInspectorPort } from "./certificate-inspector.port";
|
|
3
|
+
|
|
4
|
+
export class CertificateInspectorNoopAdapter implements CertificateInspectorPort {
|
|
5
|
+
constructor(private readonly remaining: tools.Duration) {}
|
|
6
|
+
|
|
7
|
+
async inspect(_hostname: string): Promise<CertificateInspection> {
|
|
8
|
+
return { success: true, remaining: this.remaining };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import tls from "node:tls";
|
|
2
|
+
import * as tools from "@bgord/tools";
|
|
3
|
+
import type { CertificateInspection, CertificateInspectorPort } from "./certificate-inspector.port";
|
|
4
|
+
import type { ClockPort } from "./clock.port";
|
|
5
|
+
|
|
6
|
+
type Dependencies = { Clock: ClockPort };
|
|
7
|
+
|
|
8
|
+
// Stryker disable all
|
|
9
|
+
export class CertificateInspectorTLSAdapter implements CertificateInspectorPort {
|
|
10
|
+
constructor(private readonly deps: Dependencies) {}
|
|
11
|
+
|
|
12
|
+
async inspect(hostname: string): Promise<CertificateInspection> {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
const settle = (value: CertificateInspection) => {
|
|
15
|
+
try {
|
|
16
|
+
socket.end();
|
|
17
|
+
socket.destroy();
|
|
18
|
+
} finally {
|
|
19
|
+
resolve(value);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const socket = tls.connect(
|
|
24
|
+
{ host: hostname, port: 443, servername: hostname, rejectUnauthorized: false },
|
|
25
|
+
() => {
|
|
26
|
+
const certificate = socket.getPeerCertificate();
|
|
27
|
+
|
|
28
|
+
if (!certificate?.valid_to) return settle({ success: false });
|
|
29
|
+
|
|
30
|
+
const remaining = tools.Timestamp.fromDateLike(certificate.valid_to).difference(
|
|
31
|
+
this.deps.Clock.now(),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
settle({ success: true, remaining });
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
socket.once("error", () => settle({ success: false }));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Stryker restore all
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HashFileResult } from "./hash-file.port";
|
|
2
|
+
|
|
3
|
+
export class Checksum {
|
|
4
|
+
static compare(first: HashFileResult, second: HashFileResult): boolean {
|
|
5
|
+
return (
|
|
6
|
+
first.etag.matches(second.etag) &&
|
|
7
|
+
first.size.toBytes() === second.size.toBytes() &&
|
|
8
|
+
first.lastModified.equals(second.lastModified) &&
|
|
9
|
+
first.mime.isSatisfiedBy(second.mime)
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import { getConnInfo } from "hono/bun";
|
|
3
|
+
import { Client } from "./client.vo";
|
|
4
|
+
|
|
5
|
+
export class ClientFromHono {
|
|
6
|
+
static translate(context: Context): Client {
|
|
7
|
+
const info = ClientFromHono.retrieveConnInfo(context);
|
|
8
|
+
|
|
9
|
+
const ip =
|
|
10
|
+
context.req.header("x-real-ip") || context.req.header("x-forwarded-for") || info?.remote?.address;
|
|
11
|
+
|
|
12
|
+
const ua = context.req.header("user-agent");
|
|
13
|
+
|
|
14
|
+
return Client.fromParts(ip, ua);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static retrieveConnInfo(context: Context) {
|
|
18
|
+
return getConnInfo(context);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const ClientIpError = { Type: "client.ip.type", Empty: "client.ip.empty" };
|
|
4
|
+
|
|
5
|
+
// Stryker disable all
|
|
6
|
+
export const ClientIp = z
|
|
7
|
+
// Stryker restore all
|
|
8
|
+
.string(ClientIpError.Type)
|
|
9
|
+
.min(1, ClientIpError.Empty)
|
|
10
|
+
.transform((value) => {
|
|
11
|
+
const result = z.ipv4().safeParse(value);
|
|
12
|
+
|
|
13
|
+
return result.success ? result.data : "anon";
|
|
14
|
+
})
|
|
15
|
+
.brand("ClientIp");
|
|
16
|
+
|
|
17
|
+
export type ClientIpType = z.infer<typeof ClientIp>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const ClientUserAgentError = {
|
|
4
|
+
Type: "client.user.agent.type",
|
|
5
|
+
Empty: "client.user.agent.empty",
|
|
6
|
+
TooLong: "client.user.agent.too.long",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// Stryker disable all
|
|
10
|
+
export const ClientUserAgent = z
|
|
11
|
+
// Stryker restore all
|
|
12
|
+
.string(ClientUserAgentError.Type)
|
|
13
|
+
.min(1, ClientUserAgentError.Empty)
|
|
14
|
+
.max(128, ClientUserAgentError.TooLong)
|
|
15
|
+
.brand("ClientUserAgent");
|
|
16
|
+
|
|
17
|
+
export type ClientUserAgentType = z.infer<typeof ClientUserAgent>;
|
package/src/client.vo.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ClientIp, type ClientIpType } from "./client-ip.vo";
|
|
2
|
+
import { ClientUserAgent, type ClientUserAgentType } from "./client-user-agent.vo";
|
|
3
|
+
|
|
4
|
+
export type ClientType = { ip: ClientIpType; ua: ClientUserAgentType };
|
|
5
|
+
|
|
6
|
+
export class Client {
|
|
7
|
+
private static DEFAULT_IP = ClientIp.parse("anon");
|
|
8
|
+
private static DEFAULT_UA = ClientUserAgent.parse("anon");
|
|
9
|
+
|
|
10
|
+
private constructor(private readonly value: ClientType) {}
|
|
11
|
+
|
|
12
|
+
static fromPartsSafe(
|
|
13
|
+
ip: ClientIpType | null | undefined,
|
|
14
|
+
ua: ClientUserAgentType | null | undefined,
|
|
15
|
+
): Client {
|
|
16
|
+
return new Client({
|
|
17
|
+
ip: ip ?? Client.DEFAULT_IP,
|
|
18
|
+
ua: ClientUserAgent.parse((ua ?? Client.DEFAULT_UA).toLowerCase()),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static fromParts(ip: string | null | undefined, ua: string | null | undefined): Client {
|
|
23
|
+
return new Client({
|
|
24
|
+
ip: ClientIp.parse(ip ?? Client.DEFAULT_IP),
|
|
25
|
+
ua: ClientUserAgent.parse((ua ?? Client.DEFAULT_UA).toLowerCase()),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
equals(another: Client): boolean {
|
|
30
|
+
return this.value.ip === another.value.ip && this.value.ua === another.value.ua;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
matchesUa(ua: ClientUserAgentType): boolean {
|
|
34
|
+
return this.value.ua.includes(ua.toLowerCase());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
matchesIp(ip: ClientIpType): boolean {
|
|
38
|
+
return this.value.ip.includes(ip.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get ip(): ClientIpType {
|
|
42
|
+
return this.value.ip;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get ua(): ClientUserAgentType {
|
|
46
|
+
return this.value.ua;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
toJSON(): ClientType {
|
|
50
|
+
return this.value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { ClockPort } from "./clock.port";
|
|
3
|
+
|
|
4
|
+
export class ClockFixedAdapter implements ClockPort {
|
|
5
|
+
constructor(private value: tools.Timestamp) {}
|
|
6
|
+
|
|
7
|
+
now() {
|
|
8
|
+
return this.value;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
advanceBy(duration: tools.Duration): void {
|
|
12
|
+
this.value = this.value.add(duration);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { ClockPort } from "./clock.port";
|
|
3
|
+
|
|
4
|
+
type Dependencies = { Clock: ClockPort };
|
|
5
|
+
|
|
6
|
+
export class ClockOffsetAdapter implements ClockPort {
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly offset: tools.Duration,
|
|
9
|
+
private readonly deps: Dependencies,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
now() {
|
|
13
|
+
return this.deps.Clock.now().add(this.offset);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import type { ClockPort } from "./clock.port";
|
|
3
|
+
import { CorrelationStorage } from "./correlation-storage.service";
|
|
4
|
+
import type { IdProviderPort } from "./id-provider.port";
|
|
5
|
+
import { UUID } from "./uuid.vo";
|
|
6
|
+
|
|
7
|
+
type Dependencies = { IdProvider: IdProviderPort; Clock: ClockPort };
|
|
8
|
+
|
|
9
|
+
export const CommandEnvelopeSchema = { id: UUID, correlationId: UUID, createdAt: tools.TimestampValue };
|
|
10
|
+
|
|
11
|
+
export const createCommandEnvelope = (deps: Dependencies) =>
|
|
12
|
+
({
|
|
13
|
+
id: deps.IdProvider.generate(),
|
|
14
|
+
correlationId: CorrelationStorage.get(),
|
|
15
|
+
createdAt: deps.Clock.now().ms,
|
|
16
|
+
}) as const;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LoggerPort } from "./logger.port";
|
|
2
|
+
|
|
3
|
+
type Dependencies = { Logger: LoggerPort };
|
|
4
|
+
|
|
5
|
+
export class CommandLogger {
|
|
6
|
+
private readonly base = { component: "infra", operation: "command_emitted" };
|
|
7
|
+
|
|
8
|
+
constructor(private readonly deps: Dependencies) {}
|
|
9
|
+
|
|
10
|
+
private _handle(
|
|
11
|
+
type: string,
|
|
12
|
+
_debugName: string,
|
|
13
|
+
commandName: string | undefined,
|
|
14
|
+
commandData: Record<string, any> | undefined,
|
|
15
|
+
) {
|
|
16
|
+
if (type === "subscribe") return;
|
|
17
|
+
if (typeof commandName === "symbol") return;
|
|
18
|
+
|
|
19
|
+
this.deps.Logger.info({ message: `${commandName} emitted`, metadata: commandData, ...this.base });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
handle = this._handle.bind(this);
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as z from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export type GenericCommandSchema = z.ZodObject<{
|
|
4
|
+
id: z.ZodType<string>;
|
|
5
|
+
correlationId: z.ZodType<string>;
|
|
6
|
+
createdAt: z.ZodType<number>;
|
|
7
|
+
name: z.ZodLiteral<string>;
|
|
8
|
+
payload: z.ZodType<any>;
|
|
9
|
+
}>;
|
|
10
|
+
|
|
11
|
+
export type GenericParsedCommandSchema = z.ZodObject<
|
|
12
|
+
Omit<GenericCommandSchema["shape"], "payload"> & { payload: z.ZodString }
|
|
13
|
+
>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const CommitShaValueError = {
|
|
4
|
+
Type: "commit.sha.value.type",
|
|
5
|
+
InvalidHex: "commit.sha.value.invalid.hex",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// 40 hex chars allowed
|
|
9
|
+
const CHARS_WHITELIST = /^[a-fA-F0-9]{40}$/;
|
|
10
|
+
|
|
11
|
+
// Stryker disable all
|
|
12
|
+
export const CommitShaValue = z
|
|
13
|
+
// Stryker restore all
|
|
14
|
+
.string(CommitShaValueError.Type)
|
|
15
|
+
.regex(CHARS_WHITELIST, CommitShaValueError.InvalidHex)
|
|
16
|
+
.brand("CommitShaValue");
|
|
17
|
+
|
|
18
|
+
export type CommitShaValueType = z.infer<typeof CommitShaValue>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CommitShaValue, type CommitShaValueType } from "./commit-sha-value.vo";
|
|
2
|
+
|
|
3
|
+
export class CommitSha {
|
|
4
|
+
private constructor(private readonly value: CommitShaValueType) {}
|
|
5
|
+
|
|
6
|
+
static fromString(candidate: string): CommitSha {
|
|
7
|
+
return new CommitSha(CommitShaValue.parse(candidate));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static fromStringSafe(value: CommitShaValueType): CommitSha {
|
|
11
|
+
return new CommitSha(value);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
equals(another: CommitSha): boolean {
|
|
15
|
+
return this.value === another.value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toShortString(length = 7): string {
|
|
19
|
+
return this.value.slice(0, length);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
toString(): CommitShaValueType {
|
|
23
|
+
return this.value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toJSON(): string {
|
|
27
|
+
return this.value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createMiddleware } from "hono/factory";
|
|
2
|
+
import type { CorrelationIdType } from "./correlation-id.vo";
|
|
3
|
+
import type { TimeZoneOffsetVariables } from "./time-zone-offset.middleware";
|
|
4
|
+
|
|
5
|
+
export type ContextType = {
|
|
6
|
+
requestId: CorrelationIdType;
|
|
7
|
+
timeZoneOffset: TimeZoneOffsetVariables["timeZoneOffset"];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ContextVariables = {
|
|
11
|
+
context: ContextType;
|
|
12
|
+
requestId: CorrelationIdType;
|
|
13
|
+
} & TimeZoneOffsetVariables;
|
|
14
|
+
|
|
15
|
+
export class Context {
|
|
16
|
+
static attach = createMiddleware(async (context, next) => {
|
|
17
|
+
context.set("context", {
|
|
18
|
+
requestId: context.get("requestId"),
|
|
19
|
+
timeZoneOffset: context.get("timeZoneOffset"),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await next();
|
|
23
|
+
});
|
|
24
|
+
}
|