webapp-factory 0.1.0
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/README.md +145 -0
- package/dist/access-control/adapters/in-memory-relations.d.ts +7 -0
- package/dist/access-control/adapters/in-memory-relations.d.ts.map +1 -0
- package/dist/access-control/adapters/in-memory-relations.js +6 -0
- package/dist/access-control/adapters/in-memory-relations.js.map +1 -0
- package/dist/access-control/core/enforcement.d.ts +13 -0
- package/dist/access-control/core/enforcement.d.ts.map +1 -0
- package/dist/access-control/core/enforcement.js +38 -0
- package/dist/access-control/core/enforcement.js.map +1 -0
- package/dist/access-control/core/errors.d.ts +30 -0
- package/dist/access-control/core/errors.d.ts.map +1 -0
- package/dist/access-control/core/errors.js +46 -0
- package/dist/access-control/core/errors.js.map +1 -0
- package/dist/access-control/core/pdp.d.ts +14 -0
- package/dist/access-control/core/pdp.d.ts.map +1 -0
- package/dist/access-control/core/pdp.js +79 -0
- package/dist/access-control/core/pdp.js.map +1 -0
- package/dist/access-control/core/ports.d.ts +68 -0
- package/dist/access-control/core/ports.d.ts.map +1 -0
- package/dist/access-control/core/ports.js +6 -0
- package/dist/access-control/core/ports.js.map +1 -0
- package/dist/access-control/core/rbac.d.ts +10 -0
- package/dist/access-control/core/rbac.d.ts.map +1 -0
- package/dist/access-control/core/rbac.js +78 -0
- package/dist/access-control/core/rbac.js.map +1 -0
- package/dist/access-control/core/rebac.d.ts +15 -0
- package/dist/access-control/core/rebac.d.ts.map +1 -0
- package/dist/access-control/core/rebac.js +48 -0
- package/dist/access-control/core/rebac.js.map +1 -0
- package/dist/access-control/index.d.ts +15 -0
- package/dist/access-control/index.d.ts.map +1 -0
- package/dist/access-control/index.js +20 -0
- package/dist/access-control/index.js.map +1 -0
- package/dist/access-control/nestjs/access-control.module.d.ts +34 -0
- package/dist/access-control/nestjs/access-control.module.d.ts.map +1 -0
- package/dist/access-control/nestjs/access-control.module.js +80 -0
- package/dist/access-control/nestjs/access-control.module.js.map +1 -0
- package/dist/audit/adapters/in-memory-store.d.ts +3 -0
- package/dist/audit/adapters/in-memory-store.d.ts.map +1 -0
- package/dist/audit/adapters/in-memory-store.js +66 -0
- package/dist/audit/adapters/in-memory-store.js.map +1 -0
- package/dist/audit/adapters/pg-store.d.ts +22 -0
- package/dist/audit/adapters/pg-store.d.ts.map +1 -0
- package/dist/audit/adapters/pg-store.js +119 -0
- package/dist/audit/adapters/pg-store.js.map +1 -0
- package/dist/audit/core/audit-log.d.ts +41 -0
- package/dist/audit/core/audit-log.d.ts.map +1 -0
- package/dist/audit/core/audit-log.js +78 -0
- package/dist/audit/core/audit-log.js.map +1 -0
- package/dist/audit/core/errors.d.ts +22 -0
- package/dist/audit/core/errors.d.ts.map +1 -0
- package/dist/audit/core/errors.js +35 -0
- package/dist/audit/core/errors.js.map +1 -0
- package/dist/audit/core/hash.d.ts +9 -0
- package/dist/audit/core/hash.d.ts.map +1 -0
- package/dist/audit/core/hash.js +45 -0
- package/dist/audit/core/hash.js.map +1 -0
- package/dist/audit/core/ports.d.ts +68 -0
- package/dist/audit/core/ports.d.ts.map +1 -0
- package/dist/audit/core/ports.js +6 -0
- package/dist/audit/core/ports.js.map +1 -0
- package/dist/audit/index.d.ts +13 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +16 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/auth/adapters/argon2id-hasher.d.ts +15 -0
- package/dist/auth/adapters/argon2id-hasher.d.ts.map +1 -0
- package/dist/auth/adapters/argon2id-hasher.js +61 -0
- package/dist/auth/adapters/argon2id-hasher.js.map +1 -0
- package/dist/auth/adapters/in-memory-stores.d.ts +14 -0
- package/dist/auth/adapters/in-memory-stores.d.ts.map +1 -0
- package/dist/auth/adapters/in-memory-stores.js +78 -0
- package/dist/auth/adapters/in-memory-stores.js.map +1 -0
- package/dist/auth/core/auth-service.d.ts +40 -0
- package/dist/auth/core/auth-service.d.ts.map +1 -0
- package/dist/auth/core/auth-service.js +106 -0
- package/dist/auth/core/auth-service.js.map +1 -0
- package/dist/auth/core/credentials.d.ts +15 -0
- package/dist/auth/core/credentials.d.ts.map +1 -0
- package/dist/auth/core/credentials.js +15 -0
- package/dist/auth/core/credentials.js.map +1 -0
- package/dist/auth/core/crypto-util.d.ts +7 -0
- package/dist/auth/core/crypto-util.d.ts.map +1 -0
- package/dist/auth/core/crypto-util.js +15 -0
- package/dist/auth/core/crypto-util.js.map +1 -0
- package/dist/auth/core/errors.d.ts +33 -0
- package/dist/auth/core/errors.d.ts.map +1 -0
- package/dist/auth/core/errors.js +48 -0
- package/dist/auth/core/errors.js.map +1 -0
- package/dist/auth/core/jwt.d.ts +5 -0
- package/dist/auth/core/jwt.d.ts.map +1 -0
- package/dist/auth/core/jwt.js +40 -0
- package/dist/auth/core/jwt.js.map +1 -0
- package/dist/auth/core/ports.d.ts +95 -0
- package/dist/auth/core/ports.d.ts.map +1 -0
- package/dist/auth/core/ports.js +7 -0
- package/dist/auth/core/ports.js.map +1 -0
- package/dist/auth/core/single-use.d.ts +10 -0
- package/dist/auth/core/single-use.d.ts.map +1 -0
- package/dist/auth/core/single-use.js +47 -0
- package/dist/auth/core/single-use.js.map +1 -0
- package/dist/auth/core/tokens.d.ts +14 -0
- package/dist/auth/core/tokens.d.ts.map +1 -0
- package/dist/auth/core/tokens.js +85 -0
- package/dist/auth/core/tokens.js.map +1 -0
- package/dist/auth/index.d.ts +18 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +22 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/nestjs/auth.module.d.ts +17 -0
- package/dist/auth/nestjs/auth.module.d.ts.map +1 -0
- package/dist/auth/nestjs/auth.module.js +18 -0
- package/dist/auth/nestjs/auth.module.js.map +1 -0
- package/dist/cache/adapters/in-memory-store.d.ts +6 -0
- package/dist/cache/adapters/in-memory-store.d.ts.map +1 -0
- package/dist/cache/adapters/in-memory-store.js +65 -0
- package/dist/cache/adapters/in-memory-store.js.map +1 -0
- package/dist/cache/adapters/redis-store.d.ts +32 -0
- package/dist/cache/adapters/redis-store.d.ts.map +1 -0
- package/dist/cache/adapters/redis-store.js +59 -0
- package/dist/cache/adapters/redis-store.js.map +1 -0
- package/dist/cache/core/cache.d.ts +31 -0
- package/dist/cache/core/cache.d.ts.map +1 -0
- package/dist/cache/core/cache.js +89 -0
- package/dist/cache/core/cache.js.map +1 -0
- package/dist/cache/core/errors.d.ts +17 -0
- package/dist/cache/core/errors.d.ts.map +1 -0
- package/dist/cache/core/errors.js +27 -0
- package/dist/cache/core/errors.js.map +1 -0
- package/dist/cache/core/lock.d.ts +21 -0
- package/dist/cache/core/lock.d.ts.map +1 -0
- package/dist/cache/core/lock.js +47 -0
- package/dist/cache/core/lock.js.map +1 -0
- package/dist/cache/core/ports.d.ts +33 -0
- package/dist/cache/core/ports.d.ts.map +1 -0
- package/dist/cache/core/ports.js +6 -0
- package/dist/cache/core/ports.js.map +1 -0
- package/dist/cache/core/pubsub.d.ts +14 -0
- package/dist/cache/core/pubsub.d.ts.map +1 -0
- package/dist/cache/core/pubsub.js +13 -0
- package/dist/cache/core/pubsub.js.map +1 -0
- package/dist/cache/core/serializer.d.ts +4 -0
- package/dist/cache/core/serializer.d.ts.map +1 -0
- package/dist/cache/core/serializer.js +6 -0
- package/dist/cache/core/serializer.js.map +1 -0
- package/dist/cache/index.d.ts +14 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +19 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/config/adapters/reporters.d.ts +17 -0
- package/dist/config/adapters/reporters.d.ts.map +1 -0
- package/dist/config/adapters/reporters.js +35 -0
- package/dist/config/adapters/reporters.js.map +1 -0
- package/dist/config/adapters/secret-resolvers.d.ts +21 -0
- package/dist/config/adapters/secret-resolvers.d.ts.map +1 -0
- package/dist/config/adapters/secret-resolvers.js +60 -0
- package/dist/config/adapters/secret-resolvers.js.map +1 -0
- package/dist/config/adapters/zod-schema.d.ts +20 -0
- package/dist/config/adapters/zod-schema.d.ts.map +1 -0
- package/dist/config/adapters/zod-schema.js +35 -0
- package/dist/config/adapters/zod-schema.js.map +1 -0
- package/dist/config/core/env-loader.d.ts +47 -0
- package/dist/config/core/env-loader.d.ts.map +1 -0
- package/dist/config/core/env-loader.js +155 -0
- package/dist/config/core/env-loader.js.map +1 -0
- package/dist/config/core/errors.d.ts +34 -0
- package/dist/config/core/errors.d.ts.map +1 -0
- package/dist/config/core/errors.js +49 -0
- package/dist/config/core/errors.js.map +1 -0
- package/dist/config/core/freeze.d.ts +7 -0
- package/dist/config/core/freeze.d.ts.map +1 -0
- package/dist/config/core/freeze.js +20 -0
- package/dist/config/core/freeze.js.map +1 -0
- package/dist/config/core/load-config.d.ts +43 -0
- package/dist/config/core/load-config.d.ts.map +1 -0
- package/dist/config/core/load-config.js +74 -0
- package/dist/config/core/load-config.js.map +1 -0
- package/dist/config/core/merge.d.ts +19 -0
- package/dist/config/core/merge.d.ts.map +1 -0
- package/dist/config/core/merge.js +31 -0
- package/dist/config/core/merge.js.map +1 -0
- package/dist/config/core/ports.d.ts +58 -0
- package/dist/config/core/ports.d.ts.map +1 -0
- package/dist/config/core/ports.js +2 -0
- package/dist/config/core/ports.js.map +1 -0
- package/dist/config/core/secret-resolver.d.ts +16 -0
- package/dist/config/core/secret-resolver.d.ts.map +1 -0
- package/dist/config/core/secret-resolver.js +73 -0
- package/dist/config/core/secret-resolver.js.map +1 -0
- package/dist/config/core/secret.d.ts +21 -0
- package/dist/config/core/secret.d.ts.map +1 -0
- package/dist/config/core/secret.js +40 -0
- package/dist/config/core/secret.js.map +1 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +23 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/nestjs/config-kit.module.d.ts +37 -0
- package/dist/config/nestjs/config-kit.module.d.ts.map +1 -0
- package/dist/config/nestjs/config-kit.module.js +24 -0
- package/dist/config/nestjs/config-kit.module.js.map +1 -0
- package/dist/http/adapters/zod-schema.d.ts +11 -0
- package/dist/http/adapters/zod-schema.d.ts.map +1 -0
- package/dist/http/adapters/zod-schema.js +74 -0
- package/dist/http/adapters/zod-schema.js.map +1 -0
- package/dist/http/core/context.d.ts +25 -0
- package/dist/http/core/context.d.ts.map +1 -0
- package/dist/http/core/context.js +60 -0
- package/dist/http/core/context.js.map +1 -0
- package/dist/http/core/errors.d.ts +41 -0
- package/dist/http/core/errors.d.ts.map +1 -0
- package/dist/http/core/errors.js +99 -0
- package/dist/http/core/errors.js.map +1 -0
- package/dist/http/core/kernel.d.ts +54 -0
- package/dist/http/core/kernel.d.ts.map +1 -0
- package/dist/http/core/kernel.js +122 -0
- package/dist/http/core/kernel.js.map +1 -0
- package/dist/http/core/openapi.d.ts +37 -0
- package/dist/http/core/openapi.d.ts.map +1 -0
- package/dist/http/core/openapi.js +99 -0
- package/dist/http/core/openapi.js.map +1 -0
- package/dist/http/core/pagination.d.ts +17 -0
- package/dist/http/core/pagination.d.ts.map +1 -0
- package/dist/http/core/pagination.js +108 -0
- package/dist/http/core/pagination.js.map +1 -0
- package/dist/http/core/ports.d.ts +106 -0
- package/dist/http/core/ports.d.ts.map +1 -0
- package/dist/http/core/ports.js +6 -0
- package/dist/http/core/ports.js.map +1 -0
- package/dist/http/core/redaction.d.ts +8 -0
- package/dist/http/core/redaction.d.ts.map +1 -0
- package/dist/http/core/redaction.js +45 -0
- package/dist/http/core/redaction.js.map +1 -0
- package/dist/http/core/router.d.ts +37 -0
- package/dist/http/core/router.d.ts.map +1 -0
- package/dist/http/core/router.js +120 -0
- package/dist/http/core/router.js.map +1 -0
- package/dist/http/core/security.d.ts +43 -0
- package/dist/http/core/security.d.ts.map +1 -0
- package/dist/http/core/security.js +66 -0
- package/dist/http/core/security.js.map +1 -0
- package/dist/http/core/validation.d.ts +9 -0
- package/dist/http/core/validation.d.ts.map +1 -0
- package/dist/http/core/validation.js +36 -0
- package/dist/http/core/validation.js.map +1 -0
- package/dist/http/index.d.ts +20 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +29 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/nestjs/http-kernel.module.d.ts +37 -0
- package/dist/http/nestjs/http-kernel.module.d.ts.map +1 -0
- package/dist/http/nestjs/http-kernel.module.js +77 -0
- package/dist/http/nestjs/http-kernel.module.js.map +1 -0
- package/dist/http/nodejs/http-adapter.d.ts +11 -0
- package/dist/http/nodejs/http-adapter.d.ts.map +1 -0
- package/dist/http/nodejs/http-adapter.js +60 -0
- package/dist/http/nodejs/http-adapter.js.map +1 -0
- package/dist/i18n/core/catalog.d.ts +23 -0
- package/dist/i18n/core/catalog.d.ts.map +1 -0
- package/dist/i18n/core/catalog.js +31 -0
- package/dist/i18n/core/catalog.js.map +1 -0
- package/dist/i18n/core/errors.d.ts +14 -0
- package/dist/i18n/core/errors.d.ts.map +1 -0
- package/dist/i18n/core/errors.js +22 -0
- package/dist/i18n/core/errors.js.map +1 -0
- package/dist/i18n/core/i18n.d.ts +20 -0
- package/dist/i18n/core/i18n.d.ts.map +1 -0
- package/dist/i18n/core/i18n.js +48 -0
- package/dist/i18n/core/i18n.js.map +1 -0
- package/dist/i18n/core/message.d.ts +8 -0
- package/dist/i18n/core/message.d.ts.map +1 -0
- package/dist/i18n/core/message.js +38 -0
- package/dist/i18n/core/message.js.map +1 -0
- package/dist/i18n/core/negotiate.d.ts +13 -0
- package/dist/i18n/core/negotiate.d.ts.map +1 -0
- package/dist/i18n/core/negotiate.js +46 -0
- package/dist/i18n/core/negotiate.js.map +1 -0
- package/dist/i18n/core/ports.d.ts +35 -0
- package/dist/i18n/core/ports.d.ts.map +1 -0
- package/dist/i18n/core/ports.js +6 -0
- package/dist/i18n/core/ports.js.map +1 -0
- package/dist/i18n/index.d.ts +14 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +18 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/nestjs/i18n.module.d.ts +16 -0
- package/dist/i18n/nestjs/i18n.module.d.ts.map +1 -0
- package/dist/i18n/nestjs/i18n.module.js +17 -0
- package/dist/i18n/nestjs/i18n.module.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/adapters/in-memory-idempotency.d.ts +9 -0
- package/dist/jobs/adapters/in-memory-idempotency.d.ts.map +1 -0
- package/dist/jobs/adapters/in-memory-idempotency.js +34 -0
- package/dist/jobs/adapters/in-memory-idempotency.js.map +1 -0
- package/dist/jobs/adapters/in-memory-queue-store.d.ts +7 -0
- package/dist/jobs/adapters/in-memory-queue-store.d.ts.map +1 -0
- package/dist/jobs/adapters/in-memory-queue-store.js +70 -0
- package/dist/jobs/adapters/in-memory-queue-store.js.map +1 -0
- package/dist/jobs/adapters/redis-queue-store.d.ts +28 -0
- package/dist/jobs/adapters/redis-queue-store.d.ts.map +1 -0
- package/dist/jobs/adapters/redis-queue-store.js +86 -0
- package/dist/jobs/adapters/redis-queue-store.js.map +1 -0
- package/dist/jobs/core/backoff.d.ts +15 -0
- package/dist/jobs/core/backoff.d.ts.map +1 -0
- package/dist/jobs/core/backoff.js +20 -0
- package/dist/jobs/core/backoff.js.map +1 -0
- package/dist/jobs/core/cron.d.ts +13 -0
- package/dist/jobs/core/cron.d.ts.map +1 -0
- package/dist/jobs/core/cron.js +101 -0
- package/dist/jobs/core/cron.js.map +1 -0
- package/dist/jobs/core/errors.d.ts +18 -0
- package/dist/jobs/core/errors.d.ts.map +1 -0
- package/dist/jobs/core/errors.js +30 -0
- package/dist/jobs/core/errors.js.map +1 -0
- package/dist/jobs/core/ports.d.ts +80 -0
- package/dist/jobs/core/ports.d.ts.map +1 -0
- package/dist/jobs/core/ports.js +6 -0
- package/dist/jobs/core/ports.js.map +1 -0
- package/dist/jobs/core/queue.d.ts +16 -0
- package/dist/jobs/core/queue.d.ts.map +1 -0
- package/dist/jobs/core/queue.js +29 -0
- package/dist/jobs/core/queue.js.map +1 -0
- package/dist/jobs/core/registry.d.ts +4 -0
- package/dist/jobs/core/registry.d.ts.map +1 -0
- package/dist/jobs/core/registry.js +11 -0
- package/dist/jobs/core/registry.js.map +1 -0
- package/dist/jobs/core/scheduler.d.ts +30 -0
- package/dist/jobs/core/scheduler.d.ts.map +1 -0
- package/dist/jobs/core/scheduler.js +53 -0
- package/dist/jobs/core/scheduler.js.map +1 -0
- package/dist/jobs/core/serializer.d.ts +3 -0
- package/dist/jobs/core/serializer.d.ts.map +1 -0
- package/dist/jobs/core/serializer.js +5 -0
- package/dist/jobs/core/serializer.js.map +1 -0
- package/dist/jobs/core/worker.d.ts +28 -0
- package/dist/jobs/core/worker.d.ts.map +1 -0
- package/dist/jobs/core/worker.js +118 -0
- package/dist/jobs/core/worker.js.map +1 -0
- package/dist/jobs/index.d.ts +18 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +23 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/mailer/adapters/dev-inbox.d.ts +17 -0
- package/dist/mailer/adapters/dev-inbox.d.ts.map +1 -0
- package/dist/mailer/adapters/dev-inbox.js +29 -0
- package/dist/mailer/adapters/dev-inbox.js.map +1 -0
- package/dist/mailer/adapters/i18n-renderer.d.ts +13 -0
- package/dist/mailer/adapters/i18n-renderer.d.ts.map +1 -0
- package/dist/mailer/adapters/i18n-renderer.js +27 -0
- package/dist/mailer/adapters/i18n-renderer.js.map +1 -0
- package/dist/mailer/adapters/in-memory-templates.d.ts +6 -0
- package/dist/mailer/adapters/in-memory-templates.d.ts.map +1 -0
- package/dist/mailer/adapters/in-memory-templates.js +6 -0
- package/dist/mailer/adapters/in-memory-templates.js.map +1 -0
- package/dist/mailer/adapters/transports.d.ts +19 -0
- package/dist/mailer/adapters/transports.d.ts.map +1 -0
- package/dist/mailer/adapters/transports.js +38 -0
- package/dist/mailer/adapters/transports.js.map +1 -0
- package/dist/mailer/core/errors.d.ts +23 -0
- package/dist/mailer/core/errors.d.ts.map +1 -0
- package/dist/mailer/core/errors.js +40 -0
- package/dist/mailer/core/errors.js.map +1 -0
- package/dist/mailer/core/failover.d.ts +3 -0
- package/dist/mailer/core/failover.d.ts.map +1 -0
- package/dist/mailer/core/failover.js +30 -0
- package/dist/mailer/core/failover.js.map +1 -0
- package/dist/mailer/core/mailer.d.ts +25 -0
- package/dist/mailer/core/mailer.d.ts.map +1 -0
- package/dist/mailer/core/mailer.js +61 -0
- package/dist/mailer/core/mailer.js.map +1 -0
- package/dist/mailer/core/ports.d.ts +54 -0
- package/dist/mailer/core/ports.d.ts.map +1 -0
- package/dist/mailer/core/ports.js +6 -0
- package/dist/mailer/core/ports.js.map +1 -0
- package/dist/mailer/core/render.d.ts +4 -0
- package/dist/mailer/core/render.d.ts.map +1 -0
- package/dist/mailer/core/render.js +29 -0
- package/dist/mailer/core/render.js.map +1 -0
- package/dist/mailer/index.d.ts +17 -0
- package/dist/mailer/index.d.ts.map +1 -0
- package/dist/mailer/index.js +21 -0
- package/dist/mailer/index.js.map +1 -0
- package/dist/mailer/nestjs/mailer.module.d.ts +17 -0
- package/dist/mailer/nestjs/mailer.module.d.ts.map +1 -0
- package/dist/mailer/nestjs/mailer.module.js +15 -0
- package/dist/mailer/nestjs/mailer.module.js.map +1 -0
- package/dist/observability/core/context.d.ts +9 -0
- package/dist/observability/core/context.d.ts.map +1 -0
- package/dist/observability/core/context.js +15 -0
- package/dist/observability/core/context.js.map +1 -0
- package/dist/observability/core/health.d.ts +40 -0
- package/dist/observability/core/health.d.ts.map +1 -0
- package/dist/observability/core/health.js +51 -0
- package/dist/observability/core/health.js.map +1 -0
- package/dist/observability/core/logger.d.ts +22 -0
- package/dist/observability/core/logger.d.ts.map +1 -0
- package/dist/observability/core/logger.js +45 -0
- package/dist/observability/core/logger.js.map +1 -0
- package/dist/observability/core/metrics.d.ts +63 -0
- package/dist/observability/core/metrics.d.ts.map +1 -0
- package/dist/observability/core/metrics.js +172 -0
- package/dist/observability/core/metrics.js.map +1 -0
- package/dist/observability/core/redaction.d.ts +10 -0
- package/dist/observability/core/redaction.d.ts.map +1 -0
- package/dist/observability/core/redaction.js +48 -0
- package/dist/observability/core/redaction.js.map +1 -0
- package/dist/observability/core/tracing.d.ts +52 -0
- package/dist/observability/core/tracing.d.ts.map +1 -0
- package/dist/observability/core/tracing.js +88 -0
- package/dist/observability/core/tracing.js.map +1 -0
- package/dist/observability/index.d.ts +14 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +19 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/nestjs/observability.module.d.ts +35 -0
- package/dist/observability/nestjs/observability.module.d.ts.map +1 -0
- package/dist/observability/nestjs/observability.module.js +87 -0
- package/dist/observability/nestjs/observability.module.js.map +1 -0
- package/dist/persistence/adapters/in-memory-driver.d.ts +18 -0
- package/dist/persistence/adapters/in-memory-driver.d.ts.map +1 -0
- package/dist/persistence/adapters/in-memory-driver.js +229 -0
- package/dist/persistence/adapters/in-memory-driver.js.map +1 -0
- package/dist/persistence/adapters/pg-driver.d.ts +21 -0
- package/dist/persistence/adapters/pg-driver.d.ts.map +1 -0
- package/dist/persistence/adapters/pg-driver.js +42 -0
- package/dist/persistence/adapters/pg-driver.js.map +1 -0
- package/dist/persistence/adapters/testcontainer-harness.d.ts +37 -0
- package/dist/persistence/adapters/testcontainer-harness.d.ts.map +1 -0
- package/dist/persistence/adapters/testcontainer-harness.js +79 -0
- package/dist/persistence/adapters/testcontainer-harness.js.map +1 -0
- package/dist/persistence/core/errors.d.ts +36 -0
- package/dist/persistence/core/errors.d.ts.map +1 -0
- package/dist/persistence/core/errors.js +58 -0
- package/dist/persistence/core/errors.js.map +1 -0
- package/dist/persistence/core/migrations.d.ts +16 -0
- package/dist/persistence/core/migrations.d.ts.map +1 -0
- package/dist/persistence/core/migrations.js +95 -0
- package/dist/persistence/core/migrations.js.map +1 -0
- package/dist/persistence/core/pool.d.ts +4 -0
- package/dist/persistence/core/pool.d.ts.map +1 -0
- package/dist/persistence/core/pool.js +180 -0
- package/dist/persistence/core/pool.js.map +1 -0
- package/dist/persistence/core/ports.d.ts +91 -0
- package/dist/persistence/core/ports.d.ts.map +1 -0
- package/dist/persistence/core/ports.js +6 -0
- package/dist/persistence/core/ports.js.map +1 -0
- package/dist/persistence/core/repository.d.ts +18 -0
- package/dist/persistence/core/repository.d.ts.map +1 -0
- package/dist/persistence/core/repository.js +113 -0
- package/dist/persistence/core/repository.js.map +1 -0
- package/dist/persistence/core/sql.d.ts +13 -0
- package/dist/persistence/core/sql.d.ts.map +1 -0
- package/dist/persistence/core/sql.js +35 -0
- package/dist/persistence/core/sql.js.map +1 -0
- package/dist/persistence/index.d.ts +14 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +22 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/pg.d.ts +7 -0
- package/dist/persistence/pg.d.ts.map +1 -0
- package/dist/persistence/pg.js +7 -0
- package/dist/persistence/pg.js.map +1 -0
- package/dist/privacy/adapters/audit-sink.d.ts +19 -0
- package/dist/privacy/adapters/audit-sink.d.ts.map +1 -0
- package/dist/privacy/adapters/audit-sink.js +13 -0
- package/dist/privacy/adapters/audit-sink.js.map +1 -0
- package/dist/privacy/adapters/in-memory-consent-store.d.ts +7 -0
- package/dist/privacy/adapters/in-memory-consent-store.d.ts.map +1 -0
- package/dist/privacy/adapters/in-memory-consent-store.js +18 -0
- package/dist/privacy/adapters/in-memory-consent-store.js.map +1 -0
- package/dist/privacy/adapters/pg-consent-store.d.ts +26 -0
- package/dist/privacy/adapters/pg-consent-store.d.ts.map +1 -0
- package/dist/privacy/adapters/pg-consent-store.js +43 -0
- package/dist/privacy/adapters/pg-consent-store.js.map +1 -0
- package/dist/privacy/core/consent.d.ts +35 -0
- package/dist/privacy/core/consent.d.ts.map +1 -0
- package/dist/privacy/core/consent.js +49 -0
- package/dist/privacy/core/consent.js.map +1 -0
- package/dist/privacy/core/erasure.d.ts +22 -0
- package/dist/privacy/core/erasure.d.ts.map +1 -0
- package/dist/privacy/core/erasure.js +35 -0
- package/dist/privacy/core/erasure.js.map +1 -0
- package/dist/privacy/core/errors.d.ts +18 -0
- package/dist/privacy/core/errors.d.ts.map +1 -0
- package/dist/privacy/core/errors.js +30 -0
- package/dist/privacy/core/errors.js.map +1 -0
- package/dist/privacy/core/export.d.ts +20 -0
- package/dist/privacy/core/export.d.ts.map +1 -0
- package/dist/privacy/core/export.js +30 -0
- package/dist/privacy/core/export.js.map +1 -0
- package/dist/privacy/core/ports.d.ts +48 -0
- package/dist/privacy/core/ports.d.ts.map +1 -0
- package/dist/privacy/core/ports.js +6 -0
- package/dist/privacy/core/ports.js.map +1 -0
- package/dist/privacy/core/registry.d.ts +17 -0
- package/dist/privacy/core/registry.d.ts.map +1 -0
- package/dist/privacy/core/registry.js +31 -0
- package/dist/privacy/core/registry.js.map +1 -0
- package/dist/privacy/index.d.ts +16 -0
- package/dist/privacy/index.d.ts.map +1 -0
- package/dist/privacy/index.js +21 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/rate-limit/adapters/in-memory-store.d.ts +7 -0
- package/dist/rate-limit/adapters/in-memory-store.d.ts.map +1 -0
- package/dist/rate-limit/adapters/in-memory-store.js +50 -0
- package/dist/rate-limit/adapters/in-memory-store.js.map +1 -0
- package/dist/rate-limit/adapters/redis-store.d.ts +11 -0
- package/dist/rate-limit/adapters/redis-store.d.ts.map +1 -0
- package/dist/rate-limit/adapters/redis-store.js +93 -0
- package/dist/rate-limit/adapters/redis-store.js.map +1 -0
- package/dist/rate-limit/core/enforcer.d.ts +23 -0
- package/dist/rate-limit/core/enforcer.d.ts.map +1 -0
- package/dist/rate-limit/core/enforcer.js +27 -0
- package/dist/rate-limit/core/enforcer.js.map +1 -0
- package/dist/rate-limit/core/errors.d.ts +19 -0
- package/dist/rate-limit/core/errors.d.ts.map +1 -0
- package/dist/rate-limit/core/errors.js +32 -0
- package/dist/rate-limit/core/errors.js.map +1 -0
- package/dist/rate-limit/core/ports.d.ts +50 -0
- package/dist/rate-limit/core/ports.d.ts.map +1 -0
- package/dist/rate-limit/core/ports.js +6 -0
- package/dist/rate-limit/core/ports.js.map +1 -0
- package/dist/rate-limit/core/sliding-window.d.ts +9 -0
- package/dist/rate-limit/core/sliding-window.d.ts.map +1 -0
- package/dist/rate-limit/core/sliding-window.js +24 -0
- package/dist/rate-limit/core/sliding-window.js.map +1 -0
- package/dist/rate-limit/core/token-bucket.d.ts +9 -0
- package/dist/rate-limit/core/token-bucket.d.ts.map +1 -0
- package/dist/rate-limit/core/token-bucket.js +24 -0
- package/dist/rate-limit/core/token-bucket.js.map +1 -0
- package/dist/rate-limit/index.d.ts +15 -0
- package/dist/rate-limit/index.d.ts.map +1 -0
- package/dist/rate-limit/index.js +19 -0
- package/dist/rate-limit/index.js.map +1 -0
- package/dist/rate-limit/nestjs/rate-limit.module.d.ts +25 -0
- package/dist/rate-limit/nestjs/rate-limit.module.d.ts.map +1 -0
- package/dist/rate-limit/nestjs/rate-limit.module.js +63 -0
- package/dist/rate-limit/nestjs/rate-limit.module.js.map +1 -0
- package/dist/rate-limit/nodejs/middleware.d.ts +16 -0
- package/dist/rate-limit/nodejs/middleware.d.ts.map +1 -0
- package/dist/rate-limit/nodejs/middleware.js +26 -0
- package/dist/rate-limit/nodejs/middleware.js.map +1 -0
- package/dist/test-kit/adapters/infra-bootstrap.d.ts +40 -0
- package/dist/test-kit/adapters/infra-bootstrap.d.ts.map +1 -0
- package/dist/test-kit/adapters/infra-bootstrap.js +64 -0
- package/dist/test-kit/adapters/infra-bootstrap.js.map +1 -0
- package/dist/test-kit/core/contract.d.ts +49 -0
- package/dist/test-kit/core/contract.d.ts.map +1 -0
- package/dist/test-kit/core/contract.js +52 -0
- package/dist/test-kit/core/contract.js.map +1 -0
- package/dist/test-kit/core/errors.d.ts +12 -0
- package/dist/test-kit/core/errors.d.ts.map +1 -0
- package/dist/test-kit/core/errors.js +19 -0
- package/dist/test-kit/core/errors.js.map +1 -0
- package/dist/test-kit/core/factories.d.ts +24 -0
- package/dist/test-kit/core/factories.d.ts.map +1 -0
- package/dist/test-kit/core/factories.js +57 -0
- package/dist/test-kit/core/factories.js.map +1 -0
- package/dist/test-kit/core/http-client.d.ts +46 -0
- package/dist/test-kit/core/http-client.d.ts.map +1 -0
- package/dist/test-kit/core/http-client.js +63 -0
- package/dist/test-kit/core/http-client.js.map +1 -0
- package/dist/test-kit/index.d.ts +10 -0
- package/dist/test-kit/index.d.ts.map +1 -0
- package/dist/test-kit/index.js +14 -0
- package/dist/test-kit/index.js.map +1 -0
- package/dist/test-kit/infra.d.ts +6 -0
- package/dist/test-kit/infra.d.ts.map +1 -0
- package/dist/test-kit/infra.js +6 -0
- package/dist/test-kit/infra.js.map +1 -0
- package/package.json +170 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Echte Postgres-{@link Driver} bovenop `node-postgres` (`pg`). Verbindingsparameters komen via
|
|
3
|
+
* config-injectie binnen; secrets worden nooit gelogd. `pg` is een optionele peer-dependency.
|
|
4
|
+
*/
|
|
5
|
+
import { Client } from 'pg';
|
|
6
|
+
class PgConnection {
|
|
7
|
+
#client;
|
|
8
|
+
constructor(client) {
|
|
9
|
+
this.#client = client;
|
|
10
|
+
}
|
|
11
|
+
async execute(sql, params = []) {
|
|
12
|
+
const result = await this.#client.query(sql, params);
|
|
13
|
+
return { rows: result.rows, rowCount: result.rowCount ?? result.rows.length };
|
|
14
|
+
}
|
|
15
|
+
async close() {
|
|
16
|
+
await this.#client.end();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Maakt een Postgres-driver; elke `create()` opent een nieuwe fysieke verbinding. */
|
|
20
|
+
export function pgDriver(config) {
|
|
21
|
+
const clientConfig = {
|
|
22
|
+
host: config.host,
|
|
23
|
+
port: config.port ?? 5432,
|
|
24
|
+
database: config.database,
|
|
25
|
+
user: config.user,
|
|
26
|
+
};
|
|
27
|
+
if (config.password !== undefined)
|
|
28
|
+
clientConfig.password = config.password;
|
|
29
|
+
if (config.ssl !== undefined)
|
|
30
|
+
clientConfig.ssl = config.ssl;
|
|
31
|
+
if (config.connectionTimeoutMs !== undefined) {
|
|
32
|
+
clientConfig.connectionTimeoutMillis = config.connectionTimeoutMs;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
create: async () => {
|
|
36
|
+
const client = new Client(clientConfig);
|
|
37
|
+
await client.connect();
|
|
38
|
+
return new PgConnection(client);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=pg-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-driver.js","sourceRoot":"","sources":["../../../src/persistence/adapters/pg-driver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAqB,MAAM,IAAI,CAAC;AAgB/C,MAAM,YAAY;IACP,OAAO,CAAS;IACzB,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,OAAO,CACX,GAAW,EACX,SAA6B,EAAE;QAE/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,MAAmB,CAAC,CAAC;QAClE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACvF,CAAC;IACD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,sFAAsF;AACtF,MAAM,UAAU,QAAQ,CAAC,MAA0B;IACjD,MAAM,YAAY,GAAiB;QACjC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAC;IACF,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;QAAE,YAAY,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3E,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;QAAE,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAC5D,IAAI,MAAM,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC7C,YAAY,CAAC,uBAAuB,GAAG,MAAM,CAAC,mBAAmB,CAAC;IACpE,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,IAA+B,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;YACxC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Driver, Migration, Pool, PoolConfig } from '../core/ports.js';
|
|
2
|
+
import { type PgConnectionConfig } from './pg-driver.js';
|
|
3
|
+
export interface StartedDatabase {
|
|
4
|
+
driver: Driver;
|
|
5
|
+
connection?: PgConnectionConfig;
|
|
6
|
+
stop(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface ContainerFactory {
|
|
9
|
+
start(): Promise<StartedDatabase>;
|
|
10
|
+
}
|
|
11
|
+
export interface TestDatabaseOptions {
|
|
12
|
+
migrations: Migration[];
|
|
13
|
+
/** Tabellen die de reset-helper leegmaakt (exclusief de ledger). */
|
|
14
|
+
managedTables?: string[];
|
|
15
|
+
poolConfig?: PoolConfig;
|
|
16
|
+
ledgerTable?: string;
|
|
17
|
+
/** Injecteerbare factory; default een echte Postgres-testcontainer. */
|
|
18
|
+
containerFactory?: ContainerFactory;
|
|
19
|
+
}
|
|
20
|
+
export interface TestDatabase {
|
|
21
|
+
pool: Pool;
|
|
22
|
+
/** Leegt de beheerde tabellen tussen tests (US-0305 AC2). */
|
|
23
|
+
reset(): Promise<void>;
|
|
24
|
+
/** Stopt de pool en ruimt de container op (US-0305 AC3). */
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/** Start een wegwerp-database, past migraties toe en levert een {@link TestDatabase}. */
|
|
28
|
+
export declare function startTestDatabase(options: TestDatabaseOptions): Promise<TestDatabase>;
|
|
29
|
+
export interface PostgresContainerOptions {
|
|
30
|
+
image?: string;
|
|
31
|
+
database?: string;
|
|
32
|
+
user?: string;
|
|
33
|
+
password?: string;
|
|
34
|
+
}
|
|
35
|
+
/** Echte Postgres-testcontainer-factory (vereist een Docker-runtime). */
|
|
36
|
+
export declare function postgresContainerFactory(options?: PostgresContainerOptions): ContainerFactory;
|
|
37
|
+
//# sourceMappingURL=testcontainer-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testcontainer-harness.d.ts","sourceRoot":"","sources":["../../../src/persistence/adapters/testcontainer-harness.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAY,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,6DAA6D;IAC7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4DAA4D;IAC5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,yFAAyF;AACzF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8B3F;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,wBAA6B,GAAG,gBAAgB,CA8CjG"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ConnectionError, redactReason } from '../core/errors.js';
|
|
2
|
+
import { MigrationRunner } from '../core/migrations.js';
|
|
3
|
+
import { createPool } from '../core/pool.js';
|
|
4
|
+
import { quoteIdent } from '../core/sql.js';
|
|
5
|
+
import { pgDriver } from './pg-driver.js';
|
|
6
|
+
/** Start een wegwerp-database, past migraties toe en levert een {@link TestDatabase}. */
|
|
7
|
+
export async function startTestDatabase(options) {
|
|
8
|
+
const factory = options.containerFactory ?? postgresContainerFactory();
|
|
9
|
+
const started = await factory.start();
|
|
10
|
+
const pool = createPool(started.driver, options.poolConfig ?? {});
|
|
11
|
+
try {
|
|
12
|
+
await pool.init();
|
|
13
|
+
const runnerOptions = options.ledgerTable ? { ledgerTable: options.ledgerTable } : {};
|
|
14
|
+
await new MigrationRunner(pool, options.migrations, runnerOptions).up();
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
await pool.close().catch(() => undefined);
|
|
18
|
+
await started.stop().catch(() => undefined);
|
|
19
|
+
throw error instanceof ConnectionError
|
|
20
|
+
? error
|
|
21
|
+
: new ConnectionError(`Testdatabase kon niet worden voorbereid: ${redactReason(error)}`);
|
|
22
|
+
}
|
|
23
|
+
const managed = options.managedTables ?? [];
|
|
24
|
+
return {
|
|
25
|
+
pool,
|
|
26
|
+
reset: async () => {
|
|
27
|
+
if (managed.length === 0)
|
|
28
|
+
return;
|
|
29
|
+
const list = managed.map(quoteIdent).join(', ');
|
|
30
|
+
await pool.execute(`TRUNCATE TABLE ${list} RESTART IDENTITY CASCADE`);
|
|
31
|
+
},
|
|
32
|
+
stop: async () => {
|
|
33
|
+
await pool.close().catch(() => undefined);
|
|
34
|
+
await started.stop().catch(() => undefined);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Echte Postgres-testcontainer-factory (vereist een Docker-runtime). */
|
|
39
|
+
export function postgresContainerFactory(options = {}) {
|
|
40
|
+
const image = options.image ?? 'postgres:16-alpine';
|
|
41
|
+
const database = options.database ?? 'test';
|
|
42
|
+
const user = options.user ?? 'test';
|
|
43
|
+
const password = options.password ?? 'test';
|
|
44
|
+
return {
|
|
45
|
+
start: async () => {
|
|
46
|
+
let container;
|
|
47
|
+
try {
|
|
48
|
+
const { GenericContainer, Wait } = await import('testcontainers');
|
|
49
|
+
container = await new GenericContainer(image)
|
|
50
|
+
.withEnvironment({
|
|
51
|
+
POSTGRES_USER: user,
|
|
52
|
+
POSTGRES_PASSWORD: password,
|
|
53
|
+
POSTGRES_DB: database,
|
|
54
|
+
})
|
|
55
|
+
.withExposedPorts(5432)
|
|
56
|
+
.withWaitStrategy(Wait.forLogMessage(/database system is ready to accept connections/, 2))
|
|
57
|
+
.start();
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new ConnectionError(`Postgres-testcontainer kon niet starten (is de Docker-runtime beschikbaar?): ${redactReason(error)}`);
|
|
61
|
+
}
|
|
62
|
+
const connection = {
|
|
63
|
+
host: container.getHost(),
|
|
64
|
+
port: container.getMappedPort(5432),
|
|
65
|
+
database,
|
|
66
|
+
user,
|
|
67
|
+
password,
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
driver: pgDriver(connection),
|
|
71
|
+
connection,
|
|
72
|
+
stop: async () => {
|
|
73
|
+
await container.stop();
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=testcontainer-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testcontainer-harness.js","sourceRoot":"","sources":["../../../src/persistence/adapters/testcontainer-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foutentaxonomie voor de persistence-kit. Fouten lekken nooit ruwe SQL of verbindingsgeheimen
|
|
3
|
+
* (US-0301 AC3, US-0304 AC3).
|
|
4
|
+
*/
|
|
5
|
+
export declare class PersistenceError extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
constructor(message: string, code?: string);
|
|
8
|
+
}
|
|
9
|
+
/** Verbinding kon niet worden opgezet/gevalideerd (fail-fast). Bevat geen wachtwoord. */
|
|
10
|
+
export declare class ConnectionError extends PersistenceError {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/** Geen verbinding beschikbaar binnen de acquire-timeout (pool verzadigd). */
|
|
14
|
+
export declare class PoolTimeoutError extends PersistenceError {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
17
|
+
/** Generieke query-fout; bevat bewust geen ruwe SQL. */
|
|
18
|
+
export declare class QueryError extends PersistenceError {
|
|
19
|
+
constructor(message?: string);
|
|
20
|
+
}
|
|
21
|
+
/** Schending van een unieke constraint (US-0304 AC3). */
|
|
22
|
+
export declare class UniqueConstraintError extends PersistenceError {
|
|
23
|
+
readonly constraint: string | undefined;
|
|
24
|
+
constructor(constraint?: string);
|
|
25
|
+
}
|
|
26
|
+
/** Fout tijdens een migratie; benoemt de migratie-id, geen ruwe SQL. */
|
|
27
|
+
export declare class MigrationError extends PersistenceError {
|
|
28
|
+
readonly migrationId: string;
|
|
29
|
+
constructor(migrationId: string, reason: string);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Redigeert een reden/melding: verwijdert `password=...`, `://user:pass@` en losse secret-achtige
|
|
33
|
+
* fragmenten zodat verbindingsgeheimen niet in fouten of logs belanden.
|
|
34
|
+
*/
|
|
35
|
+
export declare function redactReason(input: unknown): string;
|
|
36
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/persistence/core/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,OAAO,EAAE,MAAM,EAAE,IAAI,SAAsB;CAMxD;AAED,yFAAyF;AACzF,qBAAa,eAAgB,SAAQ,gBAAgB;gBACvC,OAAO,EAAE,MAAM;CAG5B;AAED,8EAA8E;AAC9E,qBAAa,gBAAiB,SAAQ,gBAAgB;gBACxC,OAAO,SAA0D;CAG9E;AAED,wDAAwD;AACxD,qBAAa,UAAW,SAAQ,gBAAgB;gBAClC,OAAO,SAA0B;CAG9C;AAED,yDAAyD;AACzD,qBAAa,qBAAsB,SAAQ,gBAAgB;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;gBAC5B,UAAU,CAAC,EAAE,MAAM;CAOhC;AAED,wEAAwE;AACxE,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBACjB,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKnD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foutentaxonomie voor de persistence-kit. Fouten lekken nooit ruwe SQL of verbindingsgeheimen
|
|
3
|
+
* (US-0301 AC3, US-0304 AC3).
|
|
4
|
+
*/
|
|
5
|
+
export class PersistenceError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(message, code = 'PERSISTENCE_ERROR') {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = new.target.name;
|
|
10
|
+
this.code = code;
|
|
11
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Verbinding kon niet worden opgezet/gevalideerd (fail-fast). Bevat geen wachtwoord. */
|
|
15
|
+
export class ConnectionError extends PersistenceError {
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message, 'CONNECTION_ERROR');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Geen verbinding beschikbaar binnen de acquire-timeout (pool verzadigd). */
|
|
21
|
+
export class PoolTimeoutError extends PersistenceError {
|
|
22
|
+
constructor(message = 'Geen databaseverbinding beschikbaar binnen de timeout') {
|
|
23
|
+
super(message, 'POOL_TIMEOUT');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Generieke query-fout; bevat bewust geen ruwe SQL. */
|
|
27
|
+
export class QueryError extends PersistenceError {
|
|
28
|
+
constructor(message = 'Databasequery mislukt') {
|
|
29
|
+
super(message, 'QUERY_ERROR');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Schending van een unieke constraint (US-0304 AC3). */
|
|
33
|
+
export class UniqueConstraintError extends PersistenceError {
|
|
34
|
+
constraint;
|
|
35
|
+
constructor(constraint) {
|
|
36
|
+
super(`Unieke constraint geschonden${constraint ? ` (${constraint})` : ''}`, 'UNIQUE_VIOLATION');
|
|
37
|
+
this.constraint = constraint;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Fout tijdens een migratie; benoemt de migratie-id, geen ruwe SQL. */
|
|
41
|
+
export class MigrationError extends PersistenceError {
|
|
42
|
+
migrationId;
|
|
43
|
+
constructor(migrationId, reason) {
|
|
44
|
+
super(`Migratie "${migrationId}" mislukt: ${reason}`, 'MIGRATION_ERROR');
|
|
45
|
+
this.migrationId = migrationId;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Redigeert een reden/melding: verwijdert `password=...`, `://user:pass@` en losse secret-achtige
|
|
50
|
+
* fragmenten zodat verbindingsgeheimen niet in fouten of logs belanden.
|
|
51
|
+
*/
|
|
52
|
+
export function redactReason(input) {
|
|
53
|
+
let text = input instanceof Error ? input.message : String(input);
|
|
54
|
+
text = text.replace(/(password|pwd)\s*=\s*[^\s;&]+/gi, '$1=***');
|
|
55
|
+
text = text.replace(/(:\/\/[^:@/\s]+:)[^@/\s]+@/g, '$1***@');
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/persistence/core/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAS;IACtB,YAAY,OAAe,EAAE,IAAI,GAAG,mBAAmB;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,yFAAyF;AACzF,MAAM,OAAO,eAAgB,SAAQ,gBAAgB;IACnD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IACrC,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,OAAO,gBAAiB,SAAQ,gBAAgB;IACpD,YAAY,OAAO,GAAG,uDAAuD;QAC3E,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACjC,CAAC;CACF;AAED,wDAAwD;AACxD,MAAM,OAAO,UAAW,SAAQ,gBAAgB;IAC9C,YAAY,OAAO,GAAG,uBAAuB;QAC3C,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAChC,CAAC;CACF;AAED,yDAAyD;AACzD,MAAM,OAAO,qBAAsB,SAAQ,gBAAgB;IAChD,UAAU,CAAqB;IACxC,YAAY,UAAmB;QAC7B,KAAK,CACH,+BAA+B,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EACrE,kBAAkB,CACnB,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,wEAAwE;AACxE,MAAM,OAAO,cAAe,SAAQ,gBAAgB;IACzC,WAAW,CAAS;IAC7B,YAAY,WAAmB,EAAE,MAAc;QAC7C,KAAK,CAAC,aAAa,WAAW,cAAc,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iCAAiC,EAAE,QAAQ,CAAC,CAAC;IACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Migration, MigrationStatus, Pool } from './ports.js';
|
|
2
|
+
export interface MigrationRunnerOptions {
|
|
3
|
+
/** Naam van de ledgertabel. Default `schema_migrations`. */
|
|
4
|
+
ledgerTable?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class MigrationRunner {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(pool: Pool, migrations: Migration[], options?: MigrationRunnerOptions);
|
|
9
|
+
/** Overzicht van toegepaste vs. openstaande migraties. */
|
|
10
|
+
status(): Promise<MigrationStatus>;
|
|
11
|
+
/** Past alle openstaande migraties in volgorde toe. Retourneert de toegepaste ids. */
|
|
12
|
+
up(): Promise<string[]>;
|
|
13
|
+
/** Draait de laatste `steps` toegepaste migraties terug. Retourneert de teruggedraaide ids. */
|
|
14
|
+
down(steps?: number): Promise<string[]>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/persistence/core/migrations.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,WAAW,sBAAsB;IACrC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,eAAe;;gBAKd,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,sBAA2B;IAOrF,0DAA0D;IACpD,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC;IAUxC,sFAAsF;IAChF,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAsB7B,+FAA+F;IACzF,IAAI,CAAC,KAAK,SAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CA+CzC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0303 — Migratie-runner (up/down/status).
|
|
3
|
+
*
|
|
4
|
+
* Voert geïnjecteerde migraties uit (elk met een stabiele `id`, `up` en `down`), houdt een
|
|
5
|
+
* ledgertabel bij van toegepaste migraties en draait elke migratie transactioneel: bij een fout rolt
|
|
6
|
+
* die migratie terug en stopt de runner met een duidelijke fout; eerder toegepaste migraties blijven
|
|
7
|
+
* intact. Idempotent: reeds toegepaste migraties worden overgeslagen. Bevat geen concrete migraties.
|
|
8
|
+
*/
|
|
9
|
+
import { MigrationError, redactReason } from './errors.js';
|
|
10
|
+
import { quoteIdent } from './sql.js';
|
|
11
|
+
export class MigrationRunner {
|
|
12
|
+
#pool;
|
|
13
|
+
#migrations;
|
|
14
|
+
#ledger;
|
|
15
|
+
constructor(pool, migrations, options = {}) {
|
|
16
|
+
this.#pool = pool;
|
|
17
|
+
this.#ledger = options.ledgerTable ?? 'schema_migrations';
|
|
18
|
+
this.#migrations = [...migrations].sort((a, b) => a.id.localeCompare(b.id));
|
|
19
|
+
this.#assertUniqueIds();
|
|
20
|
+
}
|
|
21
|
+
/** Overzicht van toegepaste vs. openstaande migraties. */
|
|
22
|
+
async status() {
|
|
23
|
+
await this.#ensureLedger();
|
|
24
|
+
const applied = await this.#appliedIds();
|
|
25
|
+
const appliedSet = new Set(applied);
|
|
26
|
+
return {
|
|
27
|
+
applied,
|
|
28
|
+
pending: this.#migrations.filter((m) => !appliedSet.has(m.id)).map((m) => m.id),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Past alle openstaande migraties in volgorde toe. Retourneert de toegepaste ids. */
|
|
32
|
+
async up() {
|
|
33
|
+
await this.#ensureLedger();
|
|
34
|
+
const applied = new Set(await this.#appliedIds());
|
|
35
|
+
const pending = this.#migrations.filter((m) => !applied.has(m.id));
|
|
36
|
+
const done = [];
|
|
37
|
+
for (const migration of pending) {
|
|
38
|
+
try {
|
|
39
|
+
await this.#pool.withTransaction(async (exec) => {
|
|
40
|
+
await migration.up({ execute: (sql, params) => exec.execute(sql, params) });
|
|
41
|
+
await exec.execute(`INSERT INTO ${quoteIdent(this.#ledger)} ("id") VALUES ($1)`, [
|
|
42
|
+
migration.id,
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new MigrationError(migration.id, redactReason(error));
|
|
48
|
+
}
|
|
49
|
+
done.push(migration.id);
|
|
50
|
+
}
|
|
51
|
+
return done;
|
|
52
|
+
}
|
|
53
|
+
/** Draait de laatste `steps` toegepaste migraties terug. Retourneert de teruggedraaide ids. */
|
|
54
|
+
async down(steps = 1) {
|
|
55
|
+
await this.#ensureLedger();
|
|
56
|
+
const applied = await this.#appliedIds();
|
|
57
|
+
const toRevert = applied.slice(-steps).reverse();
|
|
58
|
+
const reverted = [];
|
|
59
|
+
for (const id of toRevert) {
|
|
60
|
+
const migration = this.#migrations.find((m) => m.id === id);
|
|
61
|
+
if (!migration) {
|
|
62
|
+
throw new MigrationError(id, 'migratie niet gevonden in de geïnjecteerde set');
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await this.#pool.withTransaction(async (exec) => {
|
|
66
|
+
await migration.down({ execute: (sql, params) => exec.execute(sql, params) });
|
|
67
|
+
await exec.execute(`DELETE FROM ${quoteIdent(this.#ledger)} WHERE "id" = $1`, [id]);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new MigrationError(id, redactReason(error));
|
|
72
|
+
}
|
|
73
|
+
reverted.push(id);
|
|
74
|
+
}
|
|
75
|
+
return reverted;
|
|
76
|
+
}
|
|
77
|
+
async #ensureLedger() {
|
|
78
|
+
await this.#pool.execute(`CREATE TABLE IF NOT EXISTS ${quoteIdent(this.#ledger)} ` +
|
|
79
|
+
`("id" text PRIMARY KEY, "applied_at" timestamptz NOT NULL DEFAULT now())`);
|
|
80
|
+
}
|
|
81
|
+
async #appliedIds() {
|
|
82
|
+
const result = await this.#pool.execute(`SELECT "id" FROM ${quoteIdent(this.#ledger)} ORDER BY "id" ASC`);
|
|
83
|
+
return result.rows.map((r) => r.id);
|
|
84
|
+
}
|
|
85
|
+
#assertUniqueIds() {
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
for (const m of this.#migrations) {
|
|
88
|
+
if (seen.has(m.id)) {
|
|
89
|
+
throw new MigrationError(m.id, 'dubbele migratie-id in de geïnjecteerde set');
|
|
90
|
+
}
|
|
91
|
+
seen.add(m.id);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/persistence/core/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAOtC,MAAM,OAAO,eAAe;IACjB,KAAK,CAAO;IACZ,WAAW,CAAc;IACzB,OAAO,CAAS;IAEzB,YAAY,IAAU,EAAE,UAAuB,EAAE,UAAkC,EAAE;QACnF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,mBAAmB,CAAC;QAC1D,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO;YACL,OAAO;YACP,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChF,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,KAAK,CAAC,EAAE;QACN,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;oBAC9C,MAAM,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC5E,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE;wBAC/E,SAAS,CAAC,EAAE;qBACb,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CAAC,SAAS,CAAC,EAAE,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+FAA+F;IAC/F,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;QAClB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CAAC,EAAE,EAAE,gDAAgD,CAAC,CAAC;YACjF,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;oBAC9C,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC9E,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtF,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,cAAc,CAAC,EAAE,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CACtB,8BAA8B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;YACvD,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CACrC,oBAAoB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CACjE,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,gBAAgB;QACd,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,6CAA6C,CAAC,CAAC;YAChF,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../src/persistence/core/pool.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,MAAM,EAIN,IAAI,EACJ,UAAU,EAIX,MAAM,YAAY,CAAC;AAsLpB,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,UAAe,GAAG,IAAI,CAExE"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0301 — Connectie-pool + health-probe, en US-0302 — Transactie-scope / unit-of-work.
|
|
3
|
+
*
|
|
4
|
+
* Beheert fysieke verbindingen via de {@link Driver}-poort met een max-grootte en acquire-timeout,
|
|
5
|
+
* valideert de verbinding fail-fast bij opstart en biedt een health-probe (`healthy`/`degraded`/
|
|
6
|
+
* `down`). `withTransaction` orkestreert commit/rollback; geneste aanroepen hergebruiken de
|
|
7
|
+
* transactie via savepoints (geen globale state — de context loopt via AsyncLocalStorage).
|
|
8
|
+
*/
|
|
9
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
10
|
+
import { ConnectionError, PoolTimeoutError, redactReason, } from './errors.js';
|
|
11
|
+
const DEFAULT_MAX = 10;
|
|
12
|
+
const DEFAULT_ACQUIRE_TIMEOUT = 5000;
|
|
13
|
+
const DEFAULT_HEALTH_TIMEOUT = 1000;
|
|
14
|
+
class ConnectionPool {
|
|
15
|
+
#driver;
|
|
16
|
+
#max;
|
|
17
|
+
#acquireTimeout;
|
|
18
|
+
#healthTimeout;
|
|
19
|
+
#leases = [];
|
|
20
|
+
#waiters = [];
|
|
21
|
+
#als = new AsyncLocalStorage();
|
|
22
|
+
#savepointSeq = 0;
|
|
23
|
+
#closed = false;
|
|
24
|
+
constructor(driver, config = {}) {
|
|
25
|
+
this.#driver = driver;
|
|
26
|
+
this.#max = config.max ?? DEFAULT_MAX;
|
|
27
|
+
this.#acquireTimeout = config.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT;
|
|
28
|
+
this.#healthTimeout = config.healthTimeoutMs ?? DEFAULT_HEALTH_TIMEOUT;
|
|
29
|
+
}
|
|
30
|
+
get stats() {
|
|
31
|
+
const inUse = this.#leases.filter((l) => l.inUse).length;
|
|
32
|
+
return { total: this.#leases.length, idle: this.#leases.length - inUse, inUse };
|
|
33
|
+
}
|
|
34
|
+
async init() {
|
|
35
|
+
try {
|
|
36
|
+
const lease = await this.#acquire(this.#acquireTimeout);
|
|
37
|
+
try {
|
|
38
|
+
await lease.conn.execute('SELECT 1');
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
this.#release(lease);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new ConnectionError(`Databaseverbinding kon niet worden opgezet: ${redactReason(error)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async execute(sql, params) {
|
|
49
|
+
const scope = this.#als.getStore();
|
|
50
|
+
if (scope)
|
|
51
|
+
return scope.exec.execute(sql, params);
|
|
52
|
+
return this.withConnection((exec) => exec.execute(sql, params));
|
|
53
|
+
}
|
|
54
|
+
async withConnection(fn) {
|
|
55
|
+
const lease = await this.#acquire(this.#acquireTimeout);
|
|
56
|
+
try {
|
|
57
|
+
return await fn(this.#executorFor(lease));
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
this.#release(lease);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async withTransaction(fn) {
|
|
64
|
+
const scope = this.#als.getStore();
|
|
65
|
+
if (scope)
|
|
66
|
+
return this.#nestedTransaction(scope, fn);
|
|
67
|
+
const lease = await this.#acquire(this.#acquireTimeout);
|
|
68
|
+
const exec = this.#executorFor(lease);
|
|
69
|
+
try {
|
|
70
|
+
await lease.conn.execute('BEGIN');
|
|
71
|
+
const result = await this.#als.run({ exec }, () => fn(exec));
|
|
72
|
+
await lease.conn.execute('COMMIT');
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
try {
|
|
77
|
+
await lease.conn.execute('ROLLBACK');
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// rollback-fout onderdrukken; de oorspronkelijke fout is leidend
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
this.#release(lease);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async #nestedTransaction(scope, fn) {
|
|
89
|
+
const name = `sp_${++this.#savepointSeq}`;
|
|
90
|
+
await scope.exec.execute(`SAVEPOINT "${name}"`);
|
|
91
|
+
try {
|
|
92
|
+
const result = await fn(scope.exec);
|
|
93
|
+
await scope.exec.execute(`RELEASE SAVEPOINT "${name}"`);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
await scope.exec.execute(`ROLLBACK TO SAVEPOINT "${name}"`);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async checkHealth() {
|
|
102
|
+
const start = performance.now();
|
|
103
|
+
let lease;
|
|
104
|
+
try {
|
|
105
|
+
lease = await this.#acquire(this.#healthTimeout);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
const latencyMs = Math.round(performance.now() - start);
|
|
109
|
+
if (error instanceof PoolTimeoutError) {
|
|
110
|
+
return { status: 'degraded', latencyMs };
|
|
111
|
+
}
|
|
112
|
+
return { status: 'down', latencyMs, error: redactReason(error) };
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
await lease.conn.execute('SELECT 1');
|
|
116
|
+
return { status: 'healthy', latencyMs: Math.round(performance.now() - start) };
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
return {
|
|
120
|
+
status: 'down',
|
|
121
|
+
latencyMs: Math.round(performance.now() - start),
|
|
122
|
+
error: redactReason(error),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
this.#release(lease);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async close() {
|
|
130
|
+
this.#closed = true;
|
|
131
|
+
for (const waiter of this.#waiters.splice(0)) {
|
|
132
|
+
clearTimeout(waiter.timer);
|
|
133
|
+
waiter.reject(new ConnectionError('Pool is gesloten'));
|
|
134
|
+
}
|
|
135
|
+
await Promise.all(this.#leases.map((l) => l.conn.close().catch(() => undefined)));
|
|
136
|
+
this.#leases.length = 0;
|
|
137
|
+
}
|
|
138
|
+
#executorFor(lease) {
|
|
139
|
+
return { execute: (sql, params) => lease.conn.execute(sql, params) };
|
|
140
|
+
}
|
|
141
|
+
async #acquire(timeoutMs) {
|
|
142
|
+
if (this.#closed)
|
|
143
|
+
throw new ConnectionError('Pool is gesloten');
|
|
144
|
+
const idle = this.#leases.find((l) => !l.inUse);
|
|
145
|
+
if (idle) {
|
|
146
|
+
idle.inUse = true;
|
|
147
|
+
return idle;
|
|
148
|
+
}
|
|
149
|
+
if (this.#leases.length < this.#max) {
|
|
150
|
+
const conn = await this.#driver.create();
|
|
151
|
+
const lease = { conn, inUse: true };
|
|
152
|
+
this.#leases.push(lease);
|
|
153
|
+
return lease;
|
|
154
|
+
}
|
|
155
|
+
// Verzadigd: wacht tot een verbinding vrijkomt, of timeout (-> degraded in health).
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const timer = setTimeout(() => {
|
|
158
|
+
const idx = this.#waiters.findIndex((w) => w.timer === timer);
|
|
159
|
+
if (idx >= 0)
|
|
160
|
+
this.#waiters.splice(idx, 1);
|
|
161
|
+
reject(new PoolTimeoutError());
|
|
162
|
+
}, timeoutMs);
|
|
163
|
+
this.#waiters.push({ resolve, reject, timer });
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
#release(lease) {
|
|
167
|
+
const waiter = this.#waiters.shift();
|
|
168
|
+
if (waiter) {
|
|
169
|
+
clearTimeout(waiter.timer);
|
|
170
|
+
waiter.resolve(lease); // blijft inUse voor de volgende wachter
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
lease.inUse = false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** Maakt een beheerde connectie-pool over een {@link Driver}-adapter. */
|
|
177
|
+
export function createPool(driver, config = {}) {
|
|
178
|
+
return new ConnectionPool(driver, config);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../src/persistence/core/pool.ts"],"names":[],"mappings":"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"}
|