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 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/http/core/context.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIhE,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAOD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,+FAA+F;IAC/F,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,EACjC,MAAM,GAAE,aAAkB,GACzB,YAAY,CAoBd;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAC5B,OAAO,EAAE,cAAc,EACvB,MAAM,GAAE,aAAkB,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEzE;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0202 — Request-context (request-id/correlation).
|
|
3
|
+
*
|
|
4
|
+
* Bouwt per request een context met een gegenereerd request-id en een correlation-id (overgenomen
|
|
5
|
+
* uit een inkomende header of anders aangemaakt), beschikbaar via AsyncLocalStorage gedurende de
|
|
6
|
+
* hele verwerking. Header-namen, id-generatie en het geldige correlation-formaat zijn configureerbaar
|
|
7
|
+
* (config-injectie); de kern is domein-loos.
|
|
8
|
+
*/
|
|
9
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
const storage = new AsyncLocalStorage();
|
|
12
|
+
const DEFAULT_CORRELATION_HEADER = 'x-correlation-id';
|
|
13
|
+
const DEFAULT_REQUEST_ID_HEADER = 'x-request-id';
|
|
14
|
+
// Veilig, generiek token: letters/cijfers/._- , 1..128 tekens.
|
|
15
|
+
const DEFAULT_CORRELATION_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;
|
|
16
|
+
/** Bouwt de request-context uit de inkomende headers en de configuratie. */
|
|
17
|
+
export function buildRequestContext(headers, config = {}) {
|
|
18
|
+
const correlationHeader = (config.correlationHeader ?? DEFAULT_CORRELATION_HEADER).toLowerCase();
|
|
19
|
+
const pattern = config.correlationPattern ?? DEFAULT_CORRELATION_PATTERN;
|
|
20
|
+
const generate = config.idGenerator ?? randomUUID;
|
|
21
|
+
const requestId = generate();
|
|
22
|
+
const incoming = readHeader(headers, correlationHeader);
|
|
23
|
+
let correlationId;
|
|
24
|
+
let invalidCorrelation = false;
|
|
25
|
+
if (incoming === undefined) {
|
|
26
|
+
correlationId = generate();
|
|
27
|
+
}
|
|
28
|
+
else if (pattern.test(incoming)) {
|
|
29
|
+
correlationId = incoming; // AC2: ongewijzigd overnemen
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
correlationId = generate(); // AC3: verwerpen en nieuwe genereren
|
|
33
|
+
invalidCorrelation = true;
|
|
34
|
+
}
|
|
35
|
+
return { context: { requestId, correlationId }, invalidCorrelation };
|
|
36
|
+
}
|
|
37
|
+
/** Response-headers voor de context (request-id + correlation-id). */
|
|
38
|
+
export function contextHeaders(context, config = {}) {
|
|
39
|
+
const correlationHeader = config.correlationHeader ?? DEFAULT_CORRELATION_HEADER;
|
|
40
|
+
const requestIdHeader = config.requestIdHeader ?? DEFAULT_REQUEST_ID_HEADER;
|
|
41
|
+
return {
|
|
42
|
+
[requestIdHeader]: context.requestId,
|
|
43
|
+
[correlationHeader]: context.correlationId,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Draait `fn` met de gegeven context beschikbaar via {@link getRequestContext}. */
|
|
47
|
+
export function runWithContext(context, fn) {
|
|
48
|
+
return storage.run(context, fn);
|
|
49
|
+
}
|
|
50
|
+
/** Haalt de huidige request-context op (undefined buiten een request). */
|
|
51
|
+
export function getRequestContext() {
|
|
52
|
+
return storage.getStore();
|
|
53
|
+
}
|
|
54
|
+
function readHeader(headers, name) {
|
|
55
|
+
const value = headers[name] ?? headers[name.toLowerCase()];
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
return Array.isArray(value) ? value[0] : value;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/http/core/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAkB,CAAC;AAaxD,MAAM,0BAA0B,GAAG,kBAAkB,CAAC;AACtD,MAAM,yBAAyB,GAAG,cAAc,CAAC;AACjD,+DAA+D;AAC/D,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AAQ9D,4EAA4E;AAC5E,MAAM,UAAU,mBAAmB,CACjC,OAAiC,EACjC,SAAwB,EAAE;IAE1B,MAAM,iBAAiB,GAAG,CAAC,MAAM,CAAC,iBAAiB,IAAI,0BAA0B,CAAC,CAAC,WAAW,EAAE,CAAC;IACjG,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,IAAI,2BAA2B,CAAC;IACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,IAAI,UAAU,CAAC;IAElD,MAAM,SAAS,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAExD,IAAI,aAAqB,CAAC;IAC1B,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,aAAa,GAAG,QAAQ,EAAE,CAAC;IAC7B,CAAC;SAAM,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,aAAa,GAAG,QAAQ,CAAC,CAAC,6BAA6B;IACzD,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,QAAQ,EAAE,CAAC,CAAC,qCAAqC;QACjE,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,kBAAkB,EAAE,CAAC;AACvE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAC5B,OAAuB,EACvB,SAAwB,EAAE;IAE1B,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,0BAA0B,CAAC;IACjF,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,yBAAyB,CAAC;IAC5E,OAAO;QACL,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,SAAS;QACpC,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,aAAa;KAC3C,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,cAAc,CAAI,OAAuB,EAAE,EAAW;IACpE,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,UAAU,CAAC,OAAiC,EAAE,IAAY;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { KernelResponse, ValidationIssue } from './ports.js';
|
|
2
|
+
export type ErrorCategory = 'bad_request' | 'validation' | 'unauthorized' | 'forbidden' | 'not_found' | 'conflict' | 'unprocessable' | 'rate_limited' | 'internal';
|
|
3
|
+
export interface HttpErrorOptions {
|
|
4
|
+
code?: string;
|
|
5
|
+
details?: unknown;
|
|
6
|
+
cause?: unknown;
|
|
7
|
+
}
|
|
8
|
+
/** Basisklasse van de kernel-fout-taxonomie. */
|
|
9
|
+
export declare class HttpError extends Error {
|
|
10
|
+
readonly category: ErrorCategory;
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly code: string;
|
|
13
|
+
readonly details: unknown;
|
|
14
|
+
constructor(category: ErrorCategory, message: string, options?: HttpErrorOptions);
|
|
15
|
+
}
|
|
16
|
+
/** Validatiefout met een gestructureerde lijst overtredingen (US-0203/US-0205). */
|
|
17
|
+
export declare class ValidationError extends HttpError {
|
|
18
|
+
readonly issues: ValidationIssue[];
|
|
19
|
+
constructor(issues: ValidationIssue[], message?: string);
|
|
20
|
+
}
|
|
21
|
+
export declare const badRequest: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
22
|
+
export declare const unauthorized: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
23
|
+
export declare const forbidden: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
24
|
+
export declare const notFound: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
25
|
+
export declare const conflict: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
26
|
+
export declare const unprocessable: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
27
|
+
export declare const internal: (message?: string, options?: HttpErrorOptions) => HttpError;
|
|
28
|
+
export declare function isHttpError(value: unknown): value is HttpError;
|
|
29
|
+
export interface ErrorResponseOptions {
|
|
30
|
+
correlationId?: string;
|
|
31
|
+
sensitiveKeys?: string[];
|
|
32
|
+
/** Interne fout-details tonen (alleen voor dev). Default false. */
|
|
33
|
+
exposeInternal?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Mapt een willekeurige geworpen waarde naar een consistente {@link KernelResponse}. Bekende
|
|
37
|
+
* {@link HttpError}s behouden hun status; onbekende fouten worden 500 zonder stacktrace/interne
|
|
38
|
+
* details (US-0204 AC2). Gevoelige velden in details worden geredigeerd (AC3).
|
|
39
|
+
*/
|
|
40
|
+
export declare function toErrorResponse(error: unknown, options?: ErrorResponseOptions): KernelResponse;
|
|
41
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/http/core/errors.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,aAAa,GACrB,aAAa,GACb,YAAY,GACZ,cAAc,GACd,WAAW,GACX,WAAW,GACX,UAAU,GACV,eAAe,GACf,cAAc,GACd,UAAU,CAAC;AA0Bf,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,gDAAgD;AAChD,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;CAUrF;AAED,mFAAmF;AACnF,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;gBAEvB,MAAM,EAAE,eAAe,EAAE,EAAE,OAAO,SAAsB;CAIrE;AAED,eAAO,MAAM,UAAU,GAAI,gBAAuB,EAAE,UAAU,gBAAgB,KAAG,SACjC,CAAC;AACjD,eAAO,MAAM,YAAY,GAAI,gBAAwB,EAAE,UAAU,gBAAgB,KAAG,SACnC,CAAC;AAClD,eAAO,MAAM,SAAS,GAAI,gBAAqB,EAAE,UAAU,gBAAgB,KAAG,SAChC,CAAC;AAC/C,eAAO,MAAM,QAAQ,GAAI,gBAAqB,EAAE,UAAU,gBAAgB,KAAG,SAC/B,CAAC;AAC/C,eAAO,MAAM,QAAQ,GAAI,gBAAoB,EAAE,UAAU,gBAAgB,KAAG,SAC/B,CAAC;AAC9C,eAAO,MAAM,aAAa,GAAI,gBAAgC,EAAE,UAAU,gBAAgB,KAAG,SAC3C,CAAC;AACnD,eAAO,MAAM,QAAQ,GAAI,gBAAiC,EAAE,UAAU,gBAAgB,KAAG,SAC5C,CAAC;AAE9C,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,oBAAyB,GAAG,cAAc,CA2BlG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0204 — Uniforme error-taxonomie met deterministische mapping naar HTTP-statuscodes en een
|
|
3
|
+
* consistent response-body-formaat. Onbekende fouten mappen veilig naar 500 zonder interne details
|
|
4
|
+
* of PII te lekken. Domein-loos: concrete domeinfouten worden hierop afgebeeld.
|
|
5
|
+
*/
|
|
6
|
+
import { redactSensitive } from './redaction.js';
|
|
7
|
+
const STATUS_BY_CATEGORY = {
|
|
8
|
+
bad_request: 400,
|
|
9
|
+
validation: 400,
|
|
10
|
+
unauthorized: 401,
|
|
11
|
+
forbidden: 403,
|
|
12
|
+
not_found: 404,
|
|
13
|
+
conflict: 409,
|
|
14
|
+
unprocessable: 422,
|
|
15
|
+
rate_limited: 429,
|
|
16
|
+
internal: 500,
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_CODE = {
|
|
19
|
+
bad_request: 'BAD_REQUEST',
|
|
20
|
+
validation: 'VALIDATION_ERROR',
|
|
21
|
+
unauthorized: 'UNAUTHORIZED',
|
|
22
|
+
forbidden: 'FORBIDDEN',
|
|
23
|
+
not_found: 'NOT_FOUND',
|
|
24
|
+
conflict: 'CONFLICT',
|
|
25
|
+
unprocessable: 'UNPROCESSABLE_ENTITY',
|
|
26
|
+
rate_limited: 'RATE_LIMITED',
|
|
27
|
+
internal: 'INTERNAL_ERROR',
|
|
28
|
+
};
|
|
29
|
+
/** Basisklasse van de kernel-fout-taxonomie. */
|
|
30
|
+
export class HttpError extends Error {
|
|
31
|
+
category;
|
|
32
|
+
status;
|
|
33
|
+
code;
|
|
34
|
+
details;
|
|
35
|
+
constructor(category, message, options = {}) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = new.target.name;
|
|
38
|
+
this.category = category;
|
|
39
|
+
this.status = STATUS_BY_CATEGORY[category];
|
|
40
|
+
this.code = options.code ?? DEFAULT_CODE[category];
|
|
41
|
+
this.details = options.details;
|
|
42
|
+
if (options.cause !== undefined)
|
|
43
|
+
this.cause = options.cause;
|
|
44
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Validatiefout met een gestructureerde lijst overtredingen (US-0203/US-0205). */
|
|
48
|
+
export class ValidationError extends HttpError {
|
|
49
|
+
issues;
|
|
50
|
+
constructor(issues, message = 'Validatie mislukt') {
|
|
51
|
+
super('validation', message, { code: 'VALIDATION_ERROR', details: { issues } });
|
|
52
|
+
this.issues = issues;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const badRequest = (message = 'Bad request', options) => new HttpError('bad_request', message, options);
|
|
56
|
+
export const unauthorized = (message = 'Unauthorized', options) => new HttpError('unauthorized', message, options);
|
|
57
|
+
export const forbidden = (message = 'Forbidden', options) => new HttpError('forbidden', message, options);
|
|
58
|
+
export const notFound = (message = 'Not found', options) => new HttpError('not_found', message, options);
|
|
59
|
+
export const conflict = (message = 'Conflict', options) => new HttpError('conflict', message, options);
|
|
60
|
+
export const unprocessable = (message = 'Unprocessable entity', options) => new HttpError('unprocessable', message, options);
|
|
61
|
+
export const internal = (message = 'Internal server error', options) => new HttpError('internal', message, options);
|
|
62
|
+
export function isHttpError(value) {
|
|
63
|
+
return value instanceof HttpError;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Mapt een willekeurige geworpen waarde naar een consistente {@link KernelResponse}. Bekende
|
|
67
|
+
* {@link HttpError}s behouden hun status; onbekende fouten worden 500 zonder stacktrace/interne
|
|
68
|
+
* details (US-0204 AC2). Gevoelige velden in details worden geredigeerd (AC3).
|
|
69
|
+
*/
|
|
70
|
+
export function toErrorResponse(error, options = {}) {
|
|
71
|
+
const correlationId = options.correlationId;
|
|
72
|
+
if (isHttpError(error)) {
|
|
73
|
+
const body = {
|
|
74
|
+
code: error.code,
|
|
75
|
+
message: error.message,
|
|
76
|
+
};
|
|
77
|
+
if (correlationId)
|
|
78
|
+
body['correlationId'] = correlationId;
|
|
79
|
+
if (error instanceof ValidationError) {
|
|
80
|
+
body['issues'] = error.issues;
|
|
81
|
+
}
|
|
82
|
+
else if (error.details !== undefined) {
|
|
83
|
+
body['details'] = redactSensitive(error.details, options.sensitiveKeys);
|
|
84
|
+
}
|
|
85
|
+
return { status: error.status, headers: {}, body: { error: body } };
|
|
86
|
+
}
|
|
87
|
+
// Onbekende fout -> veilig 500, geen interne details/PII.
|
|
88
|
+
const body = {
|
|
89
|
+
code: DEFAULT_CODE.internal,
|
|
90
|
+
message: 'Internal server error',
|
|
91
|
+
};
|
|
92
|
+
if (correlationId)
|
|
93
|
+
body['correlationId'] = correlationId;
|
|
94
|
+
if (options.exposeInternal && error instanceof Error) {
|
|
95
|
+
body['details'] = { name: error.name, message: error.message };
|
|
96
|
+
}
|
|
97
|
+
return { status: 500, headers: {}, body: { error: body } };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/http/core/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* De framework-agnostische http-kernel: bootstrap + request-dispatch. Bindt US-0201 t/m US-0207:
|
|
3
|
+
* route-modules mounten, request-context, input-validatie, error-taxonomie, paginatie, OpenAPI en
|
|
4
|
+
* CORS/security-headers. Adapters (Node http, NestJS) vertalen hun request/response naar
|
|
5
|
+
* {@link KernelRequest}/{@link KernelResponse} en roepen {@link Kernel.handle} aan.
|
|
6
|
+
*/
|
|
7
|
+
import { type ContextConfig } from './context.js';
|
|
8
|
+
import { type OpenApiDocument, type OpenApiInfo } from './openapi.js';
|
|
9
|
+
import type { KernelRequest, KernelResponse, RouteModule } from './ports.js';
|
|
10
|
+
import { type CompiledRoute } from './router.js';
|
|
11
|
+
import { type CorsConfig, type SecurityHeadersConfig } from './security.js';
|
|
12
|
+
export interface KernelConfig {
|
|
13
|
+
/** Base-path waaronder alle routes gemount worden, bv. `/api`. */
|
|
14
|
+
basePath?: string;
|
|
15
|
+
context?: ContextConfig;
|
|
16
|
+
cors?: CorsConfig;
|
|
17
|
+
security?: SecurityHeadersConfig;
|
|
18
|
+
/** OpenAPI-metadata + spec-endpoint. Zonder `info` wordt geen spec-endpoint aangeboden. */
|
|
19
|
+
openapi?: {
|
|
20
|
+
info: OpenApiInfo;
|
|
21
|
+
servers?: {
|
|
22
|
+
url: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
}[];
|
|
25
|
+
path?: string;
|
|
26
|
+
};
|
|
27
|
+
/** Extra gevoelige key-namen voor redactie in foutresponses. */
|
|
28
|
+
sensitiveKeys?: string[];
|
|
29
|
+
/** Interne fout-details tonen (alleen dev). Default false. */
|
|
30
|
+
exposeInternalErrors?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export type KernelLogEvent = {
|
|
33
|
+
type: 'invalid-correlation';
|
|
34
|
+
requestId: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'unhandled-error';
|
|
37
|
+
requestId: string;
|
|
38
|
+
error: unknown;
|
|
39
|
+
};
|
|
40
|
+
export interface CreateKernelOptions {
|
|
41
|
+
config?: KernelConfig;
|
|
42
|
+
/** Geïnjecteerde route-modules (US-0201). */
|
|
43
|
+
routeModules: RouteModule[];
|
|
44
|
+
/** Optionele log-hook (bv. voor US-0202 AC3). */
|
|
45
|
+
onLog?: (event: KernelLogEvent) => void;
|
|
46
|
+
}
|
|
47
|
+
export interface Kernel {
|
|
48
|
+
handle(req: KernelRequest): Promise<KernelResponse>;
|
|
49
|
+
openapi(): OpenApiDocument;
|
|
50
|
+
readonly routes: ReadonlyArray<CompiledRoute>;
|
|
51
|
+
}
|
|
52
|
+
/** Bootstrap: valideert de route-modules (fail-fast) en levert een dispatch-klare kernel. */
|
|
53
|
+
export declare function createKernel(options: CreateKernelOptions): Kernel;
|
|
54
|
+
//# sourceMappingURL=kernel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../../../src/http/core/kernel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAmB,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEvF,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAGd,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAgC,KAAK,UAAU,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG1G,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,2FAA2F;IAC3F,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClG,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,6CAA6C;IAC7C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,iDAAiD;IACjD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACpD,OAAO,IAAI,eAAe,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC/C;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAsFjE"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* De framework-agnostische http-kernel: bootstrap + request-dispatch. Bindt US-0201 t/m US-0207:
|
|
3
|
+
* route-modules mounten, request-context, input-validatie, error-taxonomie, paginatie, OpenAPI en
|
|
4
|
+
* CORS/security-headers. Adapters (Node http, NestJS) vertalen hun request/response naar
|
|
5
|
+
* {@link KernelRequest}/{@link KernelResponse} en roepen {@link Kernel.handle} aan.
|
|
6
|
+
*/
|
|
7
|
+
import { buildRequestContext, contextHeaders, runWithContext, } from './context.js';
|
|
8
|
+
import { notFound, toErrorResponse } from './errors.js';
|
|
9
|
+
import { generateOpenApi } from './openapi.js';
|
|
10
|
+
import { paginate, parseListQuery } from './pagination.js';
|
|
11
|
+
import { compileRoutes, matchRoute } from './router.js';
|
|
12
|
+
import { resolveCors, securityHeaders } from './security.js';
|
|
13
|
+
import { validateRequest } from './validation.js';
|
|
14
|
+
/** Bootstrap: valideert de route-modules (fail-fast) en levert een dispatch-klare kernel. */
|
|
15
|
+
export function createKernel(options) {
|
|
16
|
+
const config = options.config ?? {};
|
|
17
|
+
const routes = compileRoutes(options.routeModules, config.basePath ?? '');
|
|
18
|
+
const openapiPath = config.openapi ? config.openapi.path ?? '/openapi.json' : undefined;
|
|
19
|
+
const buildDoc = () => {
|
|
20
|
+
if (!config.openapi) {
|
|
21
|
+
throw new Error('OpenAPI is niet geconfigureerd (config.openapi ontbreekt).');
|
|
22
|
+
}
|
|
23
|
+
const opts = { info: config.openapi.info };
|
|
24
|
+
if (config.openapi.servers)
|
|
25
|
+
opts.servers = config.openapi.servers;
|
|
26
|
+
return generateOpenApi(routes, opts);
|
|
27
|
+
};
|
|
28
|
+
async function handle(req) {
|
|
29
|
+
const baseHeaders = securityHeaders(config.security);
|
|
30
|
+
const origin = header(req.headers, 'origin');
|
|
31
|
+
const cors = resolveCors(origin, req.method, config.cors ?? {}, header(req.headers, 'access-control-request-method') !== undefined);
|
|
32
|
+
Object.assign(baseHeaders, cors.headers);
|
|
33
|
+
// CORS-preflight kort-sluiten zonder de handler (US-0207 AC2).
|
|
34
|
+
if (cors.isPreflight) {
|
|
35
|
+
return { status: 204, headers: baseHeaders, body: null };
|
|
36
|
+
}
|
|
37
|
+
const built = buildRequestContext(req.headers, config.context);
|
|
38
|
+
if (built.invalidCorrelation) {
|
|
39
|
+
options.onLog?.({ type: 'invalid-correlation', requestId: built.context.requestId });
|
|
40
|
+
}
|
|
41
|
+
Object.assign(baseHeaders, contextHeaders(built.context, config.context));
|
|
42
|
+
return runWithContext(built.context, async () => {
|
|
43
|
+
try {
|
|
44
|
+
// OpenAPI-spec-endpoint (US-0206).
|
|
45
|
+
if (openapiPath && req.method.toUpperCase() === 'GET' && req.path === openapiPath) {
|
|
46
|
+
return withHeaders({ status: 200, headers: {}, body: buildDoc() }, baseHeaders);
|
|
47
|
+
}
|
|
48
|
+
const match = matchRoute(routes, req.method, req.path);
|
|
49
|
+
if (!match) {
|
|
50
|
+
throw notFound(`Geen route voor ${req.method} ${req.path}`);
|
|
51
|
+
}
|
|
52
|
+
const reqWithParams = { ...req, params: match.params };
|
|
53
|
+
const validated = validateRequest(reqWithParams, match.route.definition.schemas);
|
|
54
|
+
const input = {
|
|
55
|
+
body: validated.body,
|
|
56
|
+
query: validated.query,
|
|
57
|
+
params: validated.params,
|
|
58
|
+
raw: reqWithParams,
|
|
59
|
+
context: built.context,
|
|
60
|
+
};
|
|
61
|
+
const listConfig = listConfigOf(match.route);
|
|
62
|
+
if (listConfig) {
|
|
63
|
+
input.list = parseListQuery(req.query ?? {}, listConfig);
|
|
64
|
+
}
|
|
65
|
+
const result = await match.route.definition.handler(input);
|
|
66
|
+
return withHeaders(buildSuccess(match.route, result, input.list), baseHeaders);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const response = toErrorResponse(error, {
|
|
70
|
+
correlationId: built.context.correlationId,
|
|
71
|
+
sensitiveKeys: config.sensitiveKeys,
|
|
72
|
+
exposeInternal: config.exposeInternalErrors ?? false,
|
|
73
|
+
});
|
|
74
|
+
if (response.status >= 500) {
|
|
75
|
+
options.onLog?.({ type: 'unhandled-error', requestId: built.context.requestId, error });
|
|
76
|
+
}
|
|
77
|
+
return withHeaders(response, baseHeaders);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
handle,
|
|
83
|
+
openapi: buildDoc,
|
|
84
|
+
routes,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function buildSuccess(route, result, list) {
|
|
88
|
+
const explicitStatus = route.definition.status;
|
|
89
|
+
if (list && isListResult(result)) {
|
|
90
|
+
return {
|
|
91
|
+
status: explicitStatus ?? 200,
|
|
92
|
+
headers: {},
|
|
93
|
+
body: paginate(result.items, result.total, list),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (result === undefined || result === null) {
|
|
97
|
+
return { status: explicitStatus ?? 204, headers: {}, body: null };
|
|
98
|
+
}
|
|
99
|
+
return { status: explicitStatus ?? 200, headers: {}, body: result };
|
|
100
|
+
}
|
|
101
|
+
function isListResult(value) {
|
|
102
|
+
return (typeof value === 'object' &&
|
|
103
|
+
value !== null &&
|
|
104
|
+
Array.isArray(value.items) &&
|
|
105
|
+
typeof value.total === 'number');
|
|
106
|
+
}
|
|
107
|
+
function listConfigOf(route) {
|
|
108
|
+
const list = route.definition.list;
|
|
109
|
+
if (!list)
|
|
110
|
+
return undefined;
|
|
111
|
+
return list === true ? {} : list;
|
|
112
|
+
}
|
|
113
|
+
function withHeaders(response, base) {
|
|
114
|
+
return { ...response, headers: { ...base, ...response.headers } };
|
|
115
|
+
}
|
|
116
|
+
function header(headers, name) {
|
|
117
|
+
const value = headers[name] ?? headers[name.toLowerCase()];
|
|
118
|
+
if (value === undefined)
|
|
119
|
+
return undefined;
|
|
120
|
+
return Array.isArray(value) ? value[0] : value;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=kernel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel.js","sourceRoot":"","sources":["../../../src/http/core/kernel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0206 — OpenAPI-generatie.
|
|
3
|
+
*
|
|
4
|
+
* Genereert een OpenAPI 3.1-document uit de gecompileerde routes: paden, methodes, request-/response-
|
|
5
|
+
* schema's (uit de DTO-validatie) en foutresponses (uit de error-taxonomie). Routes zonder expliciet
|
|
6
|
+
* schema krijgen een veilige generieke fallback (AC2). Conflicterende registraties worden al bij het
|
|
7
|
+
* compileren (router) fail-fast afgevangen (AC3). Document-metadata is configureerbaar (AC4).
|
|
8
|
+
*/
|
|
9
|
+
import type { CompiledRoute } from './router.js';
|
|
10
|
+
import type { JsonSchema } from './ports.js';
|
|
11
|
+
export interface OpenApiInfo {
|
|
12
|
+
title: string;
|
|
13
|
+
version: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface OpenApiOptions {
|
|
17
|
+
info: OpenApiInfo;
|
|
18
|
+
servers?: {
|
|
19
|
+
url: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
export interface OpenApiDocument {
|
|
24
|
+
openapi: string;
|
|
25
|
+
info: OpenApiInfo;
|
|
26
|
+
servers?: {
|
|
27
|
+
url: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
}[];
|
|
30
|
+
paths: Record<string, Record<string, unknown>>;
|
|
31
|
+
components: {
|
|
32
|
+
schemas: Record<string, JsonSchema>;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Bouwt het OpenAPI-document. */
|
|
36
|
+
export declare function generateOpenApi(routes: CompiledRoute[], options: OpenApiOptions): OpenApiDocument;
|
|
37
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/http/core/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE,CAAC;CACrD;AAoBD,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,OAAO,EAAE,cAAc,GAAG,eAAe,CAkBjG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const GENERIC_OBJECT = { type: 'object', additionalProperties: true };
|
|
2
|
+
const ERROR_SCHEMA = {
|
|
3
|
+
type: 'object',
|
|
4
|
+
properties: {
|
|
5
|
+
error: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
code: { type: 'string' },
|
|
9
|
+
message: { type: 'string' },
|
|
10
|
+
correlationId: { type: 'string' },
|
|
11
|
+
},
|
|
12
|
+
required: ['code', 'message'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
required: ['error'],
|
|
16
|
+
};
|
|
17
|
+
/** Bouwt het OpenAPI-document. */
|
|
18
|
+
export function generateOpenApi(routes, options) {
|
|
19
|
+
const paths = {};
|
|
20
|
+
for (const route of routes) {
|
|
21
|
+
const openapiPath = toOpenApiPath(route.fullPath);
|
|
22
|
+
const operation = buildOperation(route);
|
|
23
|
+
paths[openapiPath] ??= {};
|
|
24
|
+
paths[openapiPath][route.method.toLowerCase()] = operation;
|
|
25
|
+
}
|
|
26
|
+
const doc = {
|
|
27
|
+
openapi: '3.1.0',
|
|
28
|
+
info: options.info,
|
|
29
|
+
paths,
|
|
30
|
+
components: { schemas: { Error: ERROR_SCHEMA } },
|
|
31
|
+
};
|
|
32
|
+
if (options.servers)
|
|
33
|
+
doc.servers = options.servers;
|
|
34
|
+
return doc;
|
|
35
|
+
}
|
|
36
|
+
function buildOperation(route) {
|
|
37
|
+
const def = route.definition;
|
|
38
|
+
const operation = {};
|
|
39
|
+
if (def.summary)
|
|
40
|
+
operation['summary'] = def.summary;
|
|
41
|
+
const parameters = buildParameters(route);
|
|
42
|
+
if (parameters.length > 0)
|
|
43
|
+
operation['parameters'] = parameters;
|
|
44
|
+
if (def.schemas?.body && def.method !== 'GET' && def.method !== 'HEAD') {
|
|
45
|
+
operation['requestBody'] = {
|
|
46
|
+
required: true,
|
|
47
|
+
content: { 'application/json': { schema: schemaOf(def.schemas.body) } },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const successStatus = String(def.status ?? 200);
|
|
51
|
+
const responses = {
|
|
52
|
+
[successStatus]: {
|
|
53
|
+
description: 'Success',
|
|
54
|
+
content: { 'application/json': { schema: schemaOf(def.schemas?.response) } },
|
|
55
|
+
},
|
|
56
|
+
'400': errorResponse('Bad request / validation error'),
|
|
57
|
+
'500': errorResponse('Internal server error'),
|
|
58
|
+
};
|
|
59
|
+
operation['responses'] = responses;
|
|
60
|
+
return operation;
|
|
61
|
+
}
|
|
62
|
+
function buildParameters(route) {
|
|
63
|
+
const params = [];
|
|
64
|
+
for (const seg of route.segments) {
|
|
65
|
+
if (seg.param) {
|
|
66
|
+
params.push({
|
|
67
|
+
name: seg.value,
|
|
68
|
+
in: 'path',
|
|
69
|
+
required: true,
|
|
70
|
+
schema: { type: 'string' },
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (route.definition.list) {
|
|
75
|
+
params.push({ name: 'page', in: 'query', required: false, schema: { type: 'integer', minimum: 1 } }, { name: 'pageSize', in: 'query', required: false, schema: { type: 'integer', minimum: 1 } }, { name: 'sort', in: 'query', required: false, schema: { type: 'string' } });
|
|
76
|
+
}
|
|
77
|
+
return params;
|
|
78
|
+
}
|
|
79
|
+
function schemaOf(schema) {
|
|
80
|
+
if (schema?.jsonSchema) {
|
|
81
|
+
try {
|
|
82
|
+
return schema.jsonSchema();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return GENERIC_OBJECT;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return GENERIC_OBJECT;
|
|
89
|
+
}
|
|
90
|
+
function errorResponse(description) {
|
|
91
|
+
return {
|
|
92
|
+
description,
|
|
93
|
+
content: { 'application/json': { schema: { $ref: '#/components/schemas/Error' } } },
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function toOpenApiPath(path) {
|
|
97
|
+
return path.replace(/:([A-Za-z0-9_]+)/g, '{$1}');
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../../src/http/core/openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ListConfig, ListParams } from './ports.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parset `page`, `pageSize`, `sort` en filters uit de query. `sort` heeft de vorm
|
|
4
|
+
* `veld:asc,ander:desc` of `veld,-ander`. Ongeldige/niet-toegestane velden -> {@link ValidationError}.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseListQuery(query?: Record<string, unknown>, config?: ListConfig): ListParams;
|
|
7
|
+
/** Bouwt een consistente response-envelope met paginatie-metadata. */
|
|
8
|
+
export declare function paginate<T>(items: T[], total: number, params: Pick<ListParams, 'page' | 'pageSize'>): {
|
|
9
|
+
data: T[];
|
|
10
|
+
meta: {
|
|
11
|
+
page: number;
|
|
12
|
+
pageSize: number;
|
|
13
|
+
total: number;
|
|
14
|
+
totalPages: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/http/core/pagination.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAA8B,MAAM,YAAY,CAAC;AAKrF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,MAAM,GAAE,UAAe,GAAG,UAAU,CAwBvG;AAED,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAC,GAC5C;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAU5F"}
|