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,49 @@
|
|
|
1
|
+
export function createConsentRegistry(store, options = {}) {
|
|
2
|
+
const clock = options.clock ?? Date.now;
|
|
3
|
+
const write = async (subjectId, purpose, status, policyVersion) => {
|
|
4
|
+
const record = {
|
|
5
|
+
subjectId,
|
|
6
|
+
purpose,
|
|
7
|
+
status,
|
|
8
|
+
timestamp: clock(),
|
|
9
|
+
...(policyVersion !== undefined ? { policyVersion } : {}),
|
|
10
|
+
};
|
|
11
|
+
await store.append(record);
|
|
12
|
+
await options.audit?.record({
|
|
13
|
+
action: `privacy.consent.${status}`,
|
|
14
|
+
subjectId,
|
|
15
|
+
complete: true,
|
|
16
|
+
meta: { purpose, ...(policyVersion !== undefined ? { policyVersion } : {}) },
|
|
17
|
+
});
|
|
18
|
+
return record;
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
grant: (subjectId, purpose, opts = {}) => write(subjectId, purpose, 'granted', opts.policyVersion),
|
|
22
|
+
withdraw: (subjectId, purpose) => write(subjectId, purpose, 'withdrawn'),
|
|
23
|
+
async status(subjectId, purpose) {
|
|
24
|
+
const latest = await store.latest(subjectId, purpose);
|
|
25
|
+
if (!latest)
|
|
26
|
+
return { status: 'none' };
|
|
27
|
+
return {
|
|
28
|
+
status: latest.status,
|
|
29
|
+
...(latest.policyVersion !== undefined ? { policyVersion: latest.policyVersion } : {}),
|
|
30
|
+
timestamp: latest.timestamp,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
history: (subjectId, purpose) => store.history(subjectId, purpose),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Leidt een boolean opt-out-flag af uit de consent-status voor het doel "analytics". Leest live uit de
|
|
38
|
+
* consent-registry (geen cache), zodat een intrekking direct doorwerkt; default is opt-out.
|
|
39
|
+
*/
|
|
40
|
+
export function analyticsOptOut(consent, options = {}) {
|
|
41
|
+
const purpose = options.purpose ?? 'analytics';
|
|
42
|
+
return {
|
|
43
|
+
async isAnalyticsAllowed(subjectId) {
|
|
44
|
+
const result = await consent.status(subjectId, purpose);
|
|
45
|
+
return result.status === 'granted';
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=consent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consent.js","sourceRoot":"","sources":["../../../src/privacy/core/consent.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,qBAAqB,CAAC,KAAmB,EAAE,UAA0B,EAAE;IACrF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;IAExC,MAAM,KAAK,GAAG,KAAK,EACjB,SAAiB,EACjB,OAAe,EACf,MAAqB,EACrB,aAAsB,EACE,EAAE;QAC1B,MAAM,MAAM,GAAkB;YAC5B,SAAS;YACT,OAAO;YACP,MAAM;YACN,SAAS,EAAE,KAAK,EAAE;YAClB,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D,CAAC;QACF,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;YAC1B,MAAM,EAAE,mBAAmB,MAAM,EAAE;YACnC,SAAS;YACT,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;SAC7E,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC;QAClG,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC;QACxE,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO;YAC7B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YACvC,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtF,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC;KACnE,CAAC;AACJ,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAwB,EAAE,UAAgC,EAAE;IAC1F,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC;IAC/C,OAAO;QACL,KAAK,CAAC,kBAAkB,CAAC,SAAS;YAChC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC;QACrC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AuditSink, Clock, EraseStrategy } from './ports.js';
|
|
2
|
+
import type { ProviderRegistry } from './registry.js';
|
|
3
|
+
export interface ErasureReportEntry {
|
|
4
|
+
providerId: string;
|
|
5
|
+
status: 'erased' | 'failed';
|
|
6
|
+
strategy?: EraseStrategy;
|
|
7
|
+
affected?: number;
|
|
8
|
+
reason?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ErasureReport {
|
|
11
|
+
subjectId: string;
|
|
12
|
+
generatedAt: number;
|
|
13
|
+
complete: boolean;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
entries: ErasureReportEntry[];
|
|
16
|
+
}
|
|
17
|
+
export interface ErasureOptions {
|
|
18
|
+
audit?: AuditSink;
|
|
19
|
+
clock?: Clock;
|
|
20
|
+
}
|
|
21
|
+
export declare function eraseSubject(registry: ProviderRegistry, subjectId: string, options?: ErasureOptions): Promise<ErasureReport>;
|
|
22
|
+
//# sourceMappingURL=erasure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erasure.d.ts","sourceRoot":"","sources":["../../../src/privacy/core/erasure.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA4BxB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-1203 — Erasure-orkestratie (recht op vergetelheid, AVG art. 17). Roept `erase(subjectId)` aan op
|
|
3
|
+
* elke provider en verzamelt per provider de strategie (deleted/anonymized) + aantal getroffen records.
|
|
4
|
+
* Een gedeeltelijke mislukking maakt het rapport `incomplete` + `retryable`, zodat het subject
|
|
5
|
+
* aangemerkt blijft voor herhaling.
|
|
6
|
+
*/
|
|
7
|
+
import { redactReason } from './errors.js';
|
|
8
|
+
export async function eraseSubject(registry, subjectId, options = {}) {
|
|
9
|
+
const clock = options.clock ?? Date.now;
|
|
10
|
+
const entries = [];
|
|
11
|
+
let complete = true;
|
|
12
|
+
for (const provider of registry.list()) {
|
|
13
|
+
try {
|
|
14
|
+
const result = await provider.erase(subjectId);
|
|
15
|
+
entries.push({
|
|
16
|
+
providerId: provider.id,
|
|
17
|
+
status: 'erased',
|
|
18
|
+
strategy: result.strategy,
|
|
19
|
+
affected: result.affected,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
complete = false;
|
|
24
|
+
entries.push({ providerId: provider.id, status: 'failed', reason: redactReason(error) });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
await options.audit?.record({
|
|
28
|
+
action: 'privacy.erasure',
|
|
29
|
+
subjectId,
|
|
30
|
+
complete,
|
|
31
|
+
meta: { entries: entries.map((e) => ({ id: e.providerId, status: e.status })) },
|
|
32
|
+
});
|
|
33
|
+
return { subjectId, generatedAt: clock(), complete, retryable: !complete, entries };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=erasure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erasure.js","sourceRoot":"","sources":["../../../src/privacy/core/erasure.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyB3C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAA0B,EAC1B,SAAiB,EACjB,UAA0B,EAAE;IAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;IACxC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC;gBACX,UAAU,EAAE,QAAQ,CAAC,EAAE;gBACvB,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,GAAG,KAAK,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;QAC1B,MAAM,EAAE,iBAAiB;QACzB,SAAS;QACT,QAAQ;QACR,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;KAChF,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foutentaxonomie voor privacy-kit. Foutredenen in export-/erasure-rapporten worden geredigeerd.
|
|
3
|
+
*/
|
|
4
|
+
export declare class PrivacyError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(message: string, code: string);
|
|
7
|
+
}
|
|
8
|
+
/** Twee providers met hetzelfde id (US-1201 AC2). */
|
|
9
|
+
export declare class DuplicateProviderError extends PrivacyError {
|
|
10
|
+
constructor(id: string);
|
|
11
|
+
}
|
|
12
|
+
/** Registratie na het afsluiten (sealen) van de registry (US-1201 AC3). */
|
|
13
|
+
export declare class SealedRegistryError extends PrivacyError {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
/** Redigeert een foutreden zodat er geen payload/secret in een rapport belandt. */
|
|
17
|
+
export declare function redactReason(input: unknown): string;
|
|
18
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/privacy/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAM1C;AAED,qDAAqD;AACrD,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,EAAE,EAAE,MAAM;CAGvB;AAED,2EAA2E;AAC3E,qBAAa,mBAAoB,SAAQ,YAAY;;CAIpD;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foutentaxonomie voor privacy-kit. Foutredenen in export-/erasure-rapporten worden geredigeerd.
|
|
3
|
+
*/
|
|
4
|
+
export class PrivacyError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = new.target.name;
|
|
9
|
+
this.code = code;
|
|
10
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Twee providers met hetzelfde id (US-1201 AC2). */
|
|
14
|
+
export class DuplicateProviderError extends PrivacyError {
|
|
15
|
+
constructor(id) {
|
|
16
|
+
super(`Data-provider met id "${id}" is al geregistreerd`, 'DUPLICATE_PROVIDER');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Registratie na het afsluiten (sealen) van de registry (US-1201 AC3). */
|
|
20
|
+
export class SealedRegistryError extends PrivacyError {
|
|
21
|
+
constructor() {
|
|
22
|
+
super('Provider-registry is afgesloten (sealed); registratie is niet meer toegestaan', 'REGISTRY_SEALED');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Redigeert een foutreden zodat er geen payload/secret in een rapport belandt. */
|
|
26
|
+
export function redactReason(input) {
|
|
27
|
+
const text = input instanceof Error ? input.message : String(input);
|
|
28
|
+
return text.replace(/(password|pwd|token|secret|api[-_]?key)\s*[=:]\s*[^\s;,&]+/gi, '$1=***');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/privacy/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAS;IACtB,YAAY,OAAe,EAAE,IAAY;QACvC,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,qDAAqD;AACrD,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IACtD,YAAY,EAAU;QACpB,KAAK,CAAC,yBAAyB,EAAE,uBAAuB,EAAE,oBAAoB,CAAC,CAAC;IAClF,CAAC;CACF;AAED,2EAA2E;AAC3E,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACnD;QACE,KAAK,CAAC,+EAA+E,EAAE,iBAAiB,CAAC,CAAC;IAC5G,CAAC;CACF;AAED,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,OAAO,CAAC,8DAA8D,EAAE,QAAQ,CAAC,CAAC;AAChG,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AuditSink, Clock } from './ports.js';
|
|
2
|
+
import type { ProviderRegistry } from './registry.js';
|
|
3
|
+
export interface ExportManifestEntry {
|
|
4
|
+
providerId: string;
|
|
5
|
+
status: 'covered' | 'failed';
|
|
6
|
+
reason?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ExportBundle {
|
|
9
|
+
subjectId: string;
|
|
10
|
+
generatedAt: number;
|
|
11
|
+
complete: boolean;
|
|
12
|
+
sections: Record<string, unknown>;
|
|
13
|
+
manifest: ExportManifestEntry[];
|
|
14
|
+
}
|
|
15
|
+
export interface ExportOptions {
|
|
16
|
+
audit?: AuditSink;
|
|
17
|
+
clock?: Clock;
|
|
18
|
+
}
|
|
19
|
+
export declare function exportSubject(registry: ProviderRegistry, subjectId: string, options?: ExportOptions): Promise<ExportBundle>;
|
|
20
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/privacy/core/export.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAwBvB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-1202 — Export-orkestratie (dataportabiliteit, AVG art. 15/20). Itereert over alle geregistreerde
|
|
3
|
+
* providers, bundelt hun output per sectie en levert een manifest dat volledigheid aantoonbaar maakt.
|
|
4
|
+
* Een falende provider wordt expliciet als `failed` gerapporteerd; de export wordt dan `incomplete`.
|
|
5
|
+
*/
|
|
6
|
+
import { redactReason } from './errors.js';
|
|
7
|
+
export async function exportSubject(registry, subjectId, options = {}) {
|
|
8
|
+
const clock = options.clock ?? Date.now;
|
|
9
|
+
const sections = {};
|
|
10
|
+
const manifest = [];
|
|
11
|
+
let complete = true;
|
|
12
|
+
for (const provider of registry.list()) {
|
|
13
|
+
try {
|
|
14
|
+
sections[provider.id] = await provider.export(subjectId);
|
|
15
|
+
manifest.push({ providerId: provider.id, status: 'covered' });
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
complete = false;
|
|
19
|
+
manifest.push({ providerId: provider.id, status: 'failed', reason: redactReason(error) });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
await options.audit?.record({
|
|
23
|
+
action: 'privacy.export',
|
|
24
|
+
subjectId,
|
|
25
|
+
complete,
|
|
26
|
+
meta: { providers: manifest.map((m) => m.providerId) },
|
|
27
|
+
});
|
|
28
|
+
return { subjectId, generatedAt: clock(), complete, sections, manifest };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/privacy/core/export.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAuB3C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAA0B,EAC1B,SAAiB,EACjB,UAAyB,EAAE;IAE3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;IACxC,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,GAAG,KAAK,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;QAC1B,MAAM,EAAE,gBAAgB;QACxB,SAAS;QACT,QAAQ;QACR,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;KACvD,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Poorten & types voor de privacy-kit. Data-providers, de consent-store en de audit-sink worden
|
|
3
|
+
* geïnjecteerd; de kit kent geen domeintabellen, PII-velden of bewaartermijnen.
|
|
4
|
+
*/
|
|
5
|
+
/** Strategie waarmee een provider persoonsgegevens heeft gewist. */
|
|
6
|
+
export type EraseStrategy = 'deleted' | 'anonymized';
|
|
7
|
+
export interface EraseResult {
|
|
8
|
+
strategy: EraseStrategy;
|
|
9
|
+
/** Aantal getroffen records. */
|
|
10
|
+
affected: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Data-provider-poort (US-1201): een domeinmodule weet hoe het per subject persoonsgegevens
|
|
14
|
+
* exporteert en wist. Wordt door de consumer geïnjecteerd/geregistreerd.
|
|
15
|
+
*/
|
|
16
|
+
export interface DataProvider {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
describe(): string;
|
|
19
|
+
export(subjectId: string): Promise<unknown>;
|
|
20
|
+
erase(subjectId: string): Promise<EraseResult>;
|
|
21
|
+
}
|
|
22
|
+
export interface PrivacyAuditEvent {
|
|
23
|
+
action: string;
|
|
24
|
+
subjectId: string;
|
|
25
|
+
complete: boolean;
|
|
26
|
+
meta?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/** Audit-sink-poort: privacy-kit publiceert hierheen (bv. naar audit-log). */
|
|
29
|
+
export interface AuditSink {
|
|
30
|
+
record(event: PrivacyAuditEvent): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export type ConsentStatus = 'granted' | 'withdrawn';
|
|
33
|
+
export interface ConsentRecord {
|
|
34
|
+
subjectId: string;
|
|
35
|
+
purpose: string;
|
|
36
|
+
status: ConsentStatus;
|
|
37
|
+
policyVersion?: string;
|
|
38
|
+
/** ms epoch. */
|
|
39
|
+
timestamp: number;
|
|
40
|
+
}
|
|
41
|
+
/** Append-only consent-store-poort. */
|
|
42
|
+
export interface ConsentStore {
|
|
43
|
+
append(record: ConsentRecord): Promise<void>;
|
|
44
|
+
history(subjectId: string, purpose: string): Promise<ConsentRecord[]>;
|
|
45
|
+
latest(subjectId: string, purpose: string): Promise<ConsentRecord | null>;
|
|
46
|
+
}
|
|
47
|
+
export type Clock = () => number;
|
|
48
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../src/privacy/core/ports.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,IAAI,MAAM,CAAC;IACnB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAChD;AAID,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAID,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/privacy/core/ports.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DataProvider } from './ports.js';
|
|
2
|
+
export interface ProviderInfo {
|
|
3
|
+
id: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ProviderRegistry {
|
|
7
|
+
register(provider: DataProvider): void;
|
|
8
|
+
/** Sluit de registry af; verdere registraties falen. */
|
|
9
|
+
seal(): void;
|
|
10
|
+
list(): DataProvider[];
|
|
11
|
+
/** Introspectie: id + beschrijving per provider. */
|
|
12
|
+
describe(): ProviderInfo[];
|
|
13
|
+
get(id: string): DataProvider | undefined;
|
|
14
|
+
readonly size: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function createProviderRegistry(initial?: DataProvider[]): ProviderRegistry;
|
|
17
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/privacy/core/registry.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACvC,wDAAwD;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,YAAY,EAAE,CAAC;IACvB,oDAAoD;IACpD,QAAQ,IAAI,YAAY,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,YAAY,EAAO,GAAG,gBAAgB,CAwBrF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-1201 — Data-provider-registry. Valideert unieke provider-id's, kan na bootstrap worden afgesloten
|
|
3
|
+
* (sealed) en biedt introspectie zodat aantoonbaar is welke datastores gedekt zijn. Geen domeinkennis.
|
|
4
|
+
*/
|
|
5
|
+
import { DuplicateProviderError, SealedRegistryError } from './errors.js';
|
|
6
|
+
export function createProviderRegistry(initial = []) {
|
|
7
|
+
const providers = new Map();
|
|
8
|
+
let sealed = false;
|
|
9
|
+
const register = (provider) => {
|
|
10
|
+
if (sealed)
|
|
11
|
+
throw new SealedRegistryError();
|
|
12
|
+
if (providers.has(provider.id))
|
|
13
|
+
throw new DuplicateProviderError(provider.id);
|
|
14
|
+
providers.set(provider.id, provider);
|
|
15
|
+
};
|
|
16
|
+
for (const provider of initial)
|
|
17
|
+
register(provider);
|
|
18
|
+
return {
|
|
19
|
+
register,
|
|
20
|
+
seal: () => {
|
|
21
|
+
sealed = true;
|
|
22
|
+
},
|
|
23
|
+
list: () => [...providers.values()],
|
|
24
|
+
describe: () => [...providers.values()].map((p) => ({ id: p.id, description: p.describe() })),
|
|
25
|
+
get: (id) => providers.get(id),
|
|
26
|
+
get size() {
|
|
27
|
+
return providers.size;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/privacy/core/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAmB1E,MAAM,UAAU,sBAAsB,CAAC,UAA0B,EAAE;IACjE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;IAClD,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,QAAQ,GAAG,CAAC,QAAsB,EAAQ,EAAE;QAChD,IAAI,MAAM;YAAE,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAC5C,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9E,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,OAAO;QAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEnD,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,GAAG,EAAE;YACT,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACnC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7F,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,IAAI;YACN,OAAO,SAAS,CAAC,IAAI,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `privacy` kit — domein-loze AVG/GDPR data-subject-rechten: een data-provider-registry (US-1201),
|
|
3
|
+
* export- (US-1202) en erasure-orkestratie (US-1203) over geregistreerde providers, een append-only
|
|
4
|
+
* consent-registry (US-1204) en een analytics-opt-out-flag met privacy-by-default (US-1205). Providers,
|
|
5
|
+
* consent-store en audit-sink worden geïnjecteerd.
|
|
6
|
+
*/
|
|
7
|
+
export { createProviderRegistry, type ProviderRegistry, type ProviderInfo } from './core/registry.js';
|
|
8
|
+
export { exportSubject, type ExportBundle, type ExportManifestEntry, type ExportOptions, } from './core/export.js';
|
|
9
|
+
export { eraseSubject, type ErasureReport, type ErasureReportEntry, type ErasureOptions, } from './core/erasure.js';
|
|
10
|
+
export { createConsentRegistry, analyticsOptOut, type ConsentRegistry, type ConsentOptions, type ConsentStatusResult, type AnalyticsOptOut, } from './core/consent.js';
|
|
11
|
+
export { inMemoryConsentStore } from './adapters/in-memory-consent-store.js';
|
|
12
|
+
export { pgConsentStore, consentMigration, type PgConsentStoreOptions, type SqlExec, } from './adapters/pg-consent-store.js';
|
|
13
|
+
export { auditLogSink, type AuditLogLike } from './adapters/audit-sink.js';
|
|
14
|
+
export type { DataProvider, EraseResult, EraseStrategy, AuditSink, PrivacyAuditEvent, ConsentRecord, ConsentStatus, ConsentStore, } from './core/ports.js';
|
|
15
|
+
export { PrivacyError, DuplicateProviderError, SealedRegistryError } from './core/errors.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/privacy/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGtG,OAAO,EACL,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,OAAO,GACb,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG3E,YAAY,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `privacy` kit — domein-loze AVG/GDPR data-subject-rechten: een data-provider-registry (US-1201),
|
|
3
|
+
* export- (US-1202) en erasure-orkestratie (US-1203) over geregistreerde providers, een append-only
|
|
4
|
+
* consent-registry (US-1204) en een analytics-opt-out-flag met privacy-by-default (US-1205). Providers,
|
|
5
|
+
* consent-store en audit-sink worden geïnjecteerd.
|
|
6
|
+
*/
|
|
7
|
+
// Registry (US-1201)
|
|
8
|
+
export { createProviderRegistry } from './core/registry.js';
|
|
9
|
+
// Export-orkestratie (US-1202)
|
|
10
|
+
export { exportSubject, } from './core/export.js';
|
|
11
|
+
// Erasure-orkestratie (US-1203)
|
|
12
|
+
export { eraseSubject, } from './core/erasure.js';
|
|
13
|
+
// Consent + analytics-opt-out (US-1204/US-1205)
|
|
14
|
+
export { createConsentRegistry, analyticsOptOut, } from './core/consent.js';
|
|
15
|
+
// Adapters
|
|
16
|
+
export { inMemoryConsentStore } from './adapters/in-memory-consent-store.js';
|
|
17
|
+
export { pgConsentStore, consentMigration, } from './adapters/pg-consent-store.js';
|
|
18
|
+
export { auditLogSink } from './adapters/audit-sink.js';
|
|
19
|
+
// Fouten
|
|
20
|
+
export { PrivacyError, DuplicateProviderError, SealedRegistryError } from './core/errors.js';
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/privacy/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qBAAqB;AACrB,OAAO,EAAE,sBAAsB,EAA4C,MAAM,oBAAoB,CAAC;AAEtG,+BAA+B;AAC/B,OAAO,EACL,aAAa,GAId,MAAM,kBAAkB,CAAC;AAE1B,gCAAgC;AAChC,OAAO,EACL,YAAY,GAIb,MAAM,mBAAmB,CAAC;AAE3B,gDAAgD;AAChD,OAAO,EACL,qBAAqB,EACrB,eAAe,GAKhB,MAAM,mBAAmB,CAAC;AAE3B,WAAW;AACX,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAqB,MAAM,0BAA0B,CAAC;AAc3E,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0603 — In-memory {@link RateLimitStore} (single-instance/dev). Atomair door Node's single-threaded
|
|
3
|
+
* uitvoering. Geen externe afhankelijkheid. De algoritme-logica is identiek aan de Redis-Lua-varianten.
|
|
4
|
+
*/
|
|
5
|
+
import type { RateLimitStore } from '../core/ports.js';
|
|
6
|
+
export declare function inMemoryRateLimitStore(): RateLimitStore;
|
|
7
|
+
//# sourceMappingURL=in-memory-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-store.d.ts","sourceRoot":"","sources":["../../../src/rate-limit/adapters/in-memory-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAuD,MAAM,kBAAkB,CAAC;AAY5G,wBAAgB,sBAAsB,IAAI,cAAc,CAuDvD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export function inMemoryRateLimitStore() {
|
|
2
|
+
const buckets = new Map();
|
|
3
|
+
const windows = new Map();
|
|
4
|
+
return {
|
|
5
|
+
async consumeTokenBucket(key, params) {
|
|
6
|
+
const { capacity, refillPerMs, cost, nowMs } = params;
|
|
7
|
+
const state = buckets.get(key) ?? { tokens: capacity, ts: nowMs };
|
|
8
|
+
const elapsed = Math.max(0, nowMs - state.ts);
|
|
9
|
+
let tokens = Math.min(capacity, state.tokens + elapsed * refillPerMs);
|
|
10
|
+
let allowed = false;
|
|
11
|
+
if (tokens >= cost) {
|
|
12
|
+
tokens -= cost;
|
|
13
|
+
allowed = true;
|
|
14
|
+
}
|
|
15
|
+
buckets.set(key, { tokens, ts: nowMs });
|
|
16
|
+
return {
|
|
17
|
+
allowed,
|
|
18
|
+
remaining: Math.floor(tokens),
|
|
19
|
+
resetMs: Math.ceil((capacity - tokens) / refillPerMs),
|
|
20
|
+
retryAfterMs: allowed ? 0 : Math.ceil((cost - tokens) / refillPerMs),
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
async consumeSlidingWindow(key, params) {
|
|
24
|
+
const { limit, windowMs, cost, nowMs } = params;
|
|
25
|
+
const nominal = Math.floor(nowMs / windowMs) * windowMs;
|
|
26
|
+
let state = windows.get(key) ?? { start: nominal, cur: 0, prev: 0 };
|
|
27
|
+
if (state.start !== nominal) {
|
|
28
|
+
state = { start: nominal, cur: 0, prev: nominal - state.start === windowMs ? state.cur : 0 };
|
|
29
|
+
}
|
|
30
|
+
const elapsed = nowMs - nominal;
|
|
31
|
+
const weight = (windowMs - elapsed) / windowMs;
|
|
32
|
+
let weighted = state.prev * weight + state.cur;
|
|
33
|
+
let allowed = false;
|
|
34
|
+
if (weighted + cost <= limit) {
|
|
35
|
+
state.cur += cost;
|
|
36
|
+
weighted += cost;
|
|
37
|
+
allowed = true;
|
|
38
|
+
}
|
|
39
|
+
windows.set(key, state);
|
|
40
|
+
const resetMs = Math.ceil(windowMs - elapsed);
|
|
41
|
+
return {
|
|
42
|
+
allowed,
|
|
43
|
+
remaining: Math.max(0, Math.floor(limit - weighted)),
|
|
44
|
+
resetMs,
|
|
45
|
+
retryAfterMs: allowed ? 0 : resetMs,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=in-memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../../src/rate-limit/adapters/in-memory-store.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,sBAAsB;IACpC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,OAAO;QACL,KAAK,CAAC,kBAAkB,CAAC,GAAW,EAAE,MAAyB;YAC7D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;YAEtE,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,IAAI,CAAC;gBACf,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAExC,OAAO;gBACL,OAAO;gBACP,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;gBAC7B,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,WAAW,CAAC;gBACrD,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,WAAW,CAAC;aACrE,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,GAAW,EAAE,MAA2B;YACjE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC;YACxD,IAAI,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACpE,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;gBAC5B,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/F,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;YAChC,MAAM,MAAM,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC;YAC/C,IAAI,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC;YAE/C,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,QAAQ,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC7B,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC;gBAClB,QAAQ,IAAI,IAAI,CAAC;gBACjB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAExB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO;gBACP,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;gBACpD,OAAO;gBACP,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;aACpC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RateLimitStore } from '../core/ports.js';
|
|
2
|
+
/** Minimale Redis-client-vorm (compatibel met ioredis' `eval`). */
|
|
3
|
+
export interface RedisLike {
|
|
4
|
+
eval(script: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
|
|
5
|
+
}
|
|
6
|
+
export interface RedisRateLimitStoreOptions {
|
|
7
|
+
/** Prefix voor alle sleutels. Default `rl:`. */
|
|
8
|
+
keyPrefix?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function redisRateLimitStore(client: RedisLike, options?: RedisRateLimitStoreOptions): RateLimitStore;
|
|
11
|
+
//# sourceMappingURL=redis-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-store.d.ts","sourceRoot":"","sources":["../../../src/rate-limit/adapters/redis-store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,kBAAkB,CAAC;AAE1B,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF;AA4DD,MAAM,WAAW,0BAA0B;IACzC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,0BAA+B,GACvC,cAAc,CA+BhB"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0603 — Redis {@link RateLimitStore} (gedistribueerd). Gebruikt Lua-scripts zodat lezen +
|
|
3
|
+
* bijwerken van de teller atomair over instances gebeurt (geen race/dubbeltelling). Accepteert een
|
|
4
|
+
* minimale `RedisLike`-client (bv. ioredis) zodat de kit niet hard aan één redis-lib hangt. Bij een
|
|
5
|
+
* store-fout wordt een geredigeerde {@link StoreUnavailableError} geworpen (geen connectiestring).
|
|
6
|
+
*/
|
|
7
|
+
import { StoreUnavailableError } from '../core/errors.js';
|
|
8
|
+
// Retourneert {allowed, remaining, resetMs, retryAfterMs} — atomair.
|
|
9
|
+
const TOKEN_BUCKET_LUA = `
|
|
10
|
+
local key = KEYS[1]
|
|
11
|
+
local capacity = tonumber(ARGV[1])
|
|
12
|
+
local refill = tonumber(ARGV[2])
|
|
13
|
+
local cost = tonumber(ARGV[3])
|
|
14
|
+
local now = tonumber(ARGV[4])
|
|
15
|
+
local ttl = tonumber(ARGV[5])
|
|
16
|
+
local data = redis.call('HMGET', key, 'tokens', 'ts')
|
|
17
|
+
local tokens = tonumber(data[1])
|
|
18
|
+
local ts = tonumber(data[2])
|
|
19
|
+
if tokens == nil then tokens = capacity; ts = now end
|
|
20
|
+
local elapsed = now - ts
|
|
21
|
+
if elapsed < 0 then elapsed = 0 end
|
|
22
|
+
tokens = math.min(capacity, tokens + elapsed * refill)
|
|
23
|
+
local allowed = 0
|
|
24
|
+
if tokens >= cost then tokens = tokens - cost; allowed = 1 end
|
|
25
|
+
redis.call('HSET', key, 'tokens', tokens, 'ts', now)
|
|
26
|
+
redis.call('PEXPIRE', key, ttl)
|
|
27
|
+
local retry = 0
|
|
28
|
+
if allowed == 0 then retry = math.ceil((cost - tokens) / refill) end
|
|
29
|
+
local reset = math.ceil((capacity - tokens) / refill)
|
|
30
|
+
return { allowed, math.floor(tokens), reset, retry }
|
|
31
|
+
`;
|
|
32
|
+
const SLIDING_WINDOW_LUA = `
|
|
33
|
+
local key = KEYS[1]
|
|
34
|
+
local limit = tonumber(ARGV[1])
|
|
35
|
+
local window = tonumber(ARGV[2])
|
|
36
|
+
local cost = tonumber(ARGV[3])
|
|
37
|
+
local now = tonumber(ARGV[4])
|
|
38
|
+
local ttl = tonumber(ARGV[5])
|
|
39
|
+
local nominal = math.floor(now / window) * window
|
|
40
|
+
local d = redis.call('HMGET', key, 'start', 'cur', 'prev')
|
|
41
|
+
local start = tonumber(d[1])
|
|
42
|
+
local cur = tonumber(d[2])
|
|
43
|
+
local prev = tonumber(d[3])
|
|
44
|
+
if start == nil then start = nominal; cur = 0; prev = 0 end
|
|
45
|
+
if start ~= nominal then
|
|
46
|
+
if nominal - start == window then prev = cur else prev = 0 end
|
|
47
|
+
cur = 0
|
|
48
|
+
start = nominal
|
|
49
|
+
end
|
|
50
|
+
local elapsed = now - nominal
|
|
51
|
+
local weight = (window - elapsed) / window
|
|
52
|
+
local weighted = prev * weight + cur
|
|
53
|
+
local allowed = 0
|
|
54
|
+
if weighted + cost <= limit then cur = cur + cost; weighted = weighted + cost; allowed = 1 end
|
|
55
|
+
redis.call('HSET', key, 'start', start, 'cur', cur, 'prev', prev)
|
|
56
|
+
redis.call('PEXPIRE', key, ttl)
|
|
57
|
+
local remaining = math.floor(limit - weighted)
|
|
58
|
+
if remaining < 0 then remaining = 0 end
|
|
59
|
+
local reset = math.ceil(window - elapsed)
|
|
60
|
+
local retry = 0
|
|
61
|
+
if allowed == 0 then retry = reset end
|
|
62
|
+
return { allowed, remaining, reset, retry }
|
|
63
|
+
`;
|
|
64
|
+
export function redisRateLimitStore(client, options = {}) {
|
|
65
|
+
const prefix = options.keyPrefix ?? 'rl:';
|
|
66
|
+
const run = async (script, key, args) => {
|
|
67
|
+
let raw;
|
|
68
|
+
try {
|
|
69
|
+
raw = await client.eval(script, 1, prefix + key, ...args);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
throw new StoreUnavailableError();
|
|
73
|
+
}
|
|
74
|
+
const arr = raw;
|
|
75
|
+
return {
|
|
76
|
+
allowed: Number(arr[0]) === 1,
|
|
77
|
+
remaining: Number(arr[1]),
|
|
78
|
+
resetMs: Number(arr[2]),
|
|
79
|
+
retryAfterMs: Number(arr[3]),
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
consumeTokenBucket: (key, p) => run(TOKEN_BUCKET_LUA, key, [
|
|
84
|
+
p.capacity,
|
|
85
|
+
p.refillPerMs,
|
|
86
|
+
p.cost,
|
|
87
|
+
p.nowMs,
|
|
88
|
+
Math.ceil(p.capacity / p.refillPerMs),
|
|
89
|
+
]),
|
|
90
|
+
consumeSlidingWindow: (key, p) => run(SLIDING_WINDOW_LUA, key, [p.limit, p.windowMs, p.cost, p.nowMs, p.windowMs * 2]),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=redis-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-store.js","sourceRoot":"","sources":["../../../src/rate-limit/adapters/redis-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAa1D,qEAAqE;AACrE,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBxB,CAAC;AAEF,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B1B,CAAC;AAOF,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,UAAsC,EAAE;IAExC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAE1C,MAAM,GAAG,GAAG,KAAK,EAAE,MAAc,EAAE,GAAW,EAAE,IAAc,EAAwB,EAAE;QACtF,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,qBAAqB,EAAE,CAAC;QACpC,CAAC;QACD,MAAM,GAAG,GAAG,GAAuC,CAAC;QACpD,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7B,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC7B,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,kBAAkB,EAAE,CAAC,GAAW,EAAE,CAAoB,EAAE,EAAE,CACxD,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACzB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,KAAK;YACP,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC;SACtC,CAAC;QACJ,oBAAoB,EAAE,CAAC,GAAW,EAAE,CAAsB,EAAE,EAAE,CAC5D,GAAG,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;KACvF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-0604 — Framework-agnostische enforcement-kern. Evalueert een limiter voor een sleutel en levert
|
|
3
|
+
* een beslissing + gestandaardiseerde headers (`X-RateLimit-*`, en bij weigering `Retry-After`).
|
|
4
|
+
* Bij een store-fout volgt het geconfigureerde fail-beleid (fail-open of fail-closed) — nooit
|
|
5
|
+
* onbepaald gedrag, en zonder secret-/connectie-details te lekken.
|
|
6
|
+
*/
|
|
7
|
+
import type { RateLimitResult, RateLimiter } from './ports.js';
|
|
8
|
+
export interface RateLimitDecision {
|
|
9
|
+
allowed: boolean;
|
|
10
|
+
status: number;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
result?: RateLimitResult;
|
|
13
|
+
}
|
|
14
|
+
export interface EnforceOptions {
|
|
15
|
+
limiter: RateLimiter;
|
|
16
|
+
/** `open` laat door bij store-fout, `closed` weigert (503). Default `closed`. */
|
|
17
|
+
failPolicy?: 'open' | 'closed';
|
|
18
|
+
cost?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function enforceRateLimit(key: string, options: EnforceOptions): Promise<RateLimitDecision>;
|
|
21
|
+
/** Bouwt de informatieve `X-RateLimit-*`-headers uit een resultaat. */
|
|
22
|
+
export declare function rateLimitHeaders(result: RateLimitResult): Record<string, string>;
|
|
23
|
+
//# sourceMappingURL=enforcer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforcer.d.ts","sourceRoot":"","sources":["../../../src/rate-limit/core/enforcer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgBvG;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMhF"}
|