@c15t/backend 1.0.0 → 1.1.0-canary.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/.turbo/turbo-build.log +33 -39
- package/.turbo/turbo-fmt.log +7 -0
- package/.turbo/turbo-test.log +531 -0
- package/README.md +19 -7
- package/coverage/coverage-final.json +84 -0
- package/coverage/coverage-summary.json +85 -0
- package/coverage/html/backend/index.html +116 -0
- package/coverage/html/backend/rslib.config.ts.html +415 -0
- package/coverage/html/backend/src/contracts/consent/index.html +161 -0
- package/coverage/html/backend/src/contracts/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +559 -0
- package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +220 -0
- package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +463 -0
- package/coverage/html/backend/src/contracts/index.html +116 -0
- package/coverage/html/backend/src/contracts/index.ts.html +139 -0
- package/coverage/html/backend/src/contracts/meta/index.html +131 -0
- package/coverage/html/backend/src/contracts/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +196 -0
- package/coverage/html/backend/src/contracts/shared/index.html +116 -0
- package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +175 -0
- package/coverage/html/backend/src/core.ts.html +1624 -0
- package/coverage/html/backend/src/handlers/consent/index.html +161 -0
- package/coverage/html/backend/src/handlers/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +889 -0
- package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +535 -0
- package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +1000 -0
- package/coverage/html/backend/src/handlers/meta/index.html +131 -0
- package/coverage/html/backend/src/handlers/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +226 -0
- package/coverage/html/backend/src/index.html +161 -0
- package/coverage/html/backend/src/init.ts.html +1018 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +544 -0
- package/coverage/html/backend/src/pkgs/api-router/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +334 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/cors.ts.html +304 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/index.html +131 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +361 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +709 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +256 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/index.html +161 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +136 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +349 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +176 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +358 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +613 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +538 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +2203 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +670 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +3634 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +1417 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +2071 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +1834 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +316 -0
- package/coverage/html/backend/src/pkgs/db-adapters/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +238 -0
- package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +343 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +217 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +146 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/migrations/index.html +176 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +595 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +301 -0
- package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +694 -0
- package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +817 -0
- package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +976 -0
- package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +703 -0
- package/coverage/html/backend/src/pkgs/results/core/index.html +146 -0
- package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +271 -0
- package/coverage/html/backend/src/pkgs/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/results/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +628 -0
- package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +1234 -0
- package/coverage/html/backend/src/pkgs/utils/env.ts.html +337 -0
- package/coverage/html/backend/src/pkgs/utils/index.html +146 -0
- package/coverage/html/backend/src/pkgs/utils/logger.ts.html +199 -0
- package/coverage/html/backend/src/pkgs/utils/url.ts.html +400 -0
- package/coverage/html/backend/src/router.ts.html +109 -0
- package/coverage/html/backend/src/schema/audit-log/index.html +146 -0
- package/coverage/html/backend/src/schema/audit-log/registry.ts.html +436 -0
- package/coverage/html/backend/src/schema/audit-log/schema.ts.html +223 -0
- package/coverage/html/backend/src/schema/audit-log/table.ts.html +640 -0
- package/coverage/html/backend/src/schema/consent/index.html +146 -0
- package/coverage/html/backend/src/schema/consent/registry.ts.html +616 -0
- package/coverage/html/backend/src/schema/consent/schema.ts.html +238 -0
- package/coverage/html/backend/src/schema/consent/table.ts.html +748 -0
- package/coverage/html/backend/src/schema/consent-policy/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +1063 -0
- package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +265 -0
- package/coverage/html/backend/src/schema/consent-policy/table.ts.html +535 -0
- package/coverage/html/backend/src/schema/consent-purpose/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +589 -0
- package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +259 -0
- package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +547 -0
- package/coverage/html/backend/src/schema/consent-record/index.html +131 -0
- package/coverage/html/backend/src/schema/consent-record/schema.ts.html +211 -0
- package/coverage/html/backend/src/schema/consent-record/table.ts.html +457 -0
- package/coverage/html/backend/src/schema/create-registry.ts.html +148 -0
- package/coverage/html/backend/src/schema/definition.ts.html +685 -0
- package/coverage/html/backend/src/schema/domain/index.html +146 -0
- package/coverage/html/backend/src/schema/domain/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/domain/schema.ts.html +214 -0
- package/coverage/html/backend/src/schema/domain/table.ts.html +496 -0
- package/coverage/html/backend/src/schema/index.html +146 -0
- package/coverage/html/backend/src/schema/schemas.ts.html +166 -0
- package/coverage/html/backend/src/schema/subject/index.html +146 -0
- package/coverage/html/backend/src/schema/subject/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/subject/schema.ts.html +208 -0
- package/coverage/html/backend/src/schema/subject/table.ts.html +499 -0
- package/coverage/html/backend/src/server.ts.html +475 -0
- package/coverage/html/backend/src/testing/contract-testing.ts.html +1348 -0
- package/coverage/html/backend/src/testing/index.html +116 -0
- package/coverage/html/base.css +224 -0
- package/coverage/html/block-navigation.js +87 -0
- package/coverage/html/favicon.png +0 -0
- package/coverage/html/index.html +626 -0
- package/coverage/html/prettify.css +1 -0
- package/coverage/html/prettify.js +2 -0
- package/coverage/html/sort-arrow-sprite.png +0 -0
- package/coverage/html/sorter.js +196 -0
- package/dist/contracts/consent/index.d.ts +401 -0
- package/dist/contracts/consent/index.d.ts.map +1 -0
- package/dist/contracts/consent/index.test.d.ts +2 -0
- package/dist/contracts/consent/index.test.d.ts.map +1 -0
- package/dist/contracts/consent/post.contract.d.ts +212 -0
- package/dist/contracts/consent/post.contract.d.ts.map +1 -0
- package/dist/contracts/consent/post.contract.test.d.ts +2 -0
- package/dist/contracts/consent/post.contract.test.d.ts.map +1 -0
- package/dist/contracts/consent/show-banner.contract.d.ts +45 -0
- package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -0
- package/dist/contracts/consent/show-banner.contract.test.d.ts +2 -0
- package/dist/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
- package/dist/contracts/consent/verify.contract.d.ts +147 -0
- package/dist/contracts/consent/verify.contract.d.ts.map +1 -0
- package/dist/contracts/consent/verify.contract.test.d.ts +2 -0
- package/dist/contracts/consent/verify.contract.test.d.ts.map +1 -0
- package/dist/contracts/index.d.ts +963 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/meta/index.d.ts +78 -0
- package/dist/contracts/meta/index.d.ts.map +1 -0
- package/dist/contracts/meta/index.test.d.ts +2 -0
- package/dist/contracts/meta/index.test.d.ts.map +1 -0
- package/dist/contracts/meta/status.contract.d.ts +77 -0
- package/dist/contracts/meta/status.contract.d.ts.map +1 -0
- package/dist/contracts/meta/status.contract.test.d.ts +2 -0
- package/dist/contracts/meta/status.contract.test.d.ts.map +1 -0
- package/dist/contracts/shared/jurisdiction.schema.d.ts +24 -0
- package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
- package/dist/core.cjs +3584 -0
- package/dist/core.d.ts +533 -78
- package/dist/core.d.ts.map +1 -1
- package/dist/{index.js → core.js} +1164 -1292
- package/dist/handlers/consent/index.d.ts +401 -0
- package/dist/handlers/consent/index.d.ts.map +1 -0
- package/dist/handlers/consent/post.handler.d.ts +234 -0
- package/dist/handlers/consent/post.handler.d.ts.map +1 -0
- package/dist/handlers/consent/show-banner.handler.d.ts +57 -0
- package/dist/handlers/consent/show-banner.handler.d.ts.map +1 -0
- package/dist/handlers/consent/show-banner.handler.test.d.ts +2 -0
- package/dist/handlers/consent/show-banner.handler.test.d.ts.map +1 -0
- package/dist/handlers/consent/verify.handler.d.ts +169 -0
- package/dist/handlers/consent/verify.handler.d.ts.map +1 -0
- package/dist/handlers/meta/index.d.ts +78 -0
- package/dist/handlers/meta/index.d.ts.map +1 -0
- package/dist/handlers/meta/status.handler.d.ts +76 -0
- package/dist/handlers/meta/status.handler.d.ts.map +1 -0
- package/dist/init.d.ts +0 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/pkgs/api-router/hooks/processor.d.ts.map +1 -1
- package/dist/pkgs/api-router/types/router-props.d.ts +1 -1
- package/dist/pkgs/api-router/types/router-props.d.ts.map +1 -1
- package/dist/pkgs/api-router/utils/cors.d.ts +1 -1
- package/dist/pkgs/api-router/utils/cors.d.ts.map +1 -1
- package/dist/pkgs/data-model/fields/field-types.d.ts +1 -1
- package/dist/pkgs/data-model/fields/zod-fields.d.ts +32 -32
- package/dist/pkgs/data-model/index.cjs +1433 -1799
- package/dist/pkgs/data-model/index.js +20 -385
- package/dist/pkgs/data-model/schema/index.cjs +1402 -1768
- package/dist/pkgs/data-model/schema/index.js +20 -385
- package/dist/pkgs/db-adapters/adapter-factory.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapter-factory.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +4 -7
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +19 -151
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +19 -151
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts +1 -3
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +17 -149
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +17 -149
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts +0 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts +0 -2
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +17 -149
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +17 -149
- package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts +0 -1
- package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +19 -151
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +19 -151
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts +0 -1
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/index.cjs +31 -153
- package/dist/pkgs/db-adapters/index.js +31 -153
- package/dist/pkgs/migrations/get-schema/get-schema.d.ts +2 -2
- package/dist/pkgs/migrations/get-schema/index.d.ts +1 -1
- package/dist/pkgs/migrations/index.cjs +30 -153
- package/dist/pkgs/migrations/index.js +30 -153
- package/dist/pkgs/migrations/schema-comparison.d.ts.map +1 -1
- package/dist/pkgs/results/core/error-class.d.ts +23 -21
- package/dist/pkgs/results/core/error-class.d.ts.map +1 -1
- package/dist/pkgs/results/index.cjs +17 -150
- package/dist/pkgs/results/index.d.ts +0 -3
- package/dist/pkgs/results/index.d.ts.map +1 -1
- package/dist/pkgs/results/index.js +17 -138
- package/dist/pkgs/results/orpc-error-handler.d.ts +65 -0
- package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -0
- package/dist/pkgs/results/types.d.ts +7 -7
- package/dist/pkgs/results/types.d.ts.map +1 -1
- package/dist/pkgs/types/context.d.ts +15 -8
- package/dist/pkgs/types/context.d.ts.map +1 -1
- package/dist/pkgs/types/endpoints.d.ts +3 -4
- package/dist/pkgs/types/endpoints.d.ts.map +1 -1
- package/dist/pkgs/types/options.d.ts +2 -4
- package/dist/pkgs/types/options.d.ts.map +1 -1
- package/dist/pkgs/types/plugins.d.ts +2 -3
- package/dist/pkgs/types/plugins.d.ts.map +1 -1
- package/dist/pkgs/utils/index.d.ts +1 -0
- package/dist/pkgs/utils/index.d.ts.map +1 -1
- package/dist/pkgs/utils/logger.d.ts +16 -0
- package/dist/pkgs/utils/logger.d.ts.map +1 -0
- package/dist/router.cjs +1213 -0
- package/dist/router.d.ts +480 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +1169 -0
- package/dist/schema/audit-log/table.d.ts +1 -1
- package/dist/schema/consent/table.d.ts +1 -1
- package/dist/schema/consent-policy/registry.d.ts +12 -12
- package/dist/schema/consent-policy/schema.d.ts +6 -6
- package/dist/schema/consent-policy/table.d.ts +7 -7
- package/dist/schema/consent-purpose/registry.d.ts +6 -6
- package/dist/schema/consent-purpose/schema.d.ts +6 -6
- package/dist/schema/consent-purpose/table.d.ts +7 -7
- package/dist/schema/consent-record/table.d.ts +1 -1
- package/dist/schema/create-registry.d.ts +32 -32
- package/dist/schema/definition.d.ts +19 -19
- package/dist/schema/domain/registry.d.ts +10 -10
- package/dist/schema/domain/schema.d.ts +5 -5
- package/dist/schema/domain/table.d.ts +6 -6
- package/dist/schema/index.cjs +1409 -1775
- package/dist/schema/index.js +20 -385
- package/dist/schema/schemas.d.ts +19 -19
- package/dist/schema/subject/registry.d.ts +4 -4
- package/dist/schema/subject/schema.d.ts +2 -2
- package/dist/schema/subject/table.d.ts +3 -3
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/testing/contract-testing.d.ts +37 -0
- package/dist/testing/contract-testing.d.ts.map +1 -0
- package/dist/types/context.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/options.d.ts +33 -3
- package/dist/types/options.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +3 -4
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +20 -28
- package/rslib.config.ts +2 -5
- package/src/contracts/consent/index.test.ts +5 -0
- package/src/contracts/consent/index.ts +9 -0
- package/src/contracts/consent/post.contract.test.ts +526 -0
- package/src/contracts/consent/post.contract.ts +160 -0
- package/src/contracts/consent/show-banner.contract.test.ts +214 -0
- package/src/contracts/consent/show-banner.contract.ts +45 -0
- package/src/contracts/consent/verify.contract.test.ts +185 -0
- package/src/contracts/consent/verify.contract.ts +126 -0
- package/src/contracts/index.ts +18 -0
- package/src/contracts/meta/index.test.ts +5 -0
- package/src/contracts/meta/index.ts +5 -0
- package/src/contracts/meta/status.contract.test.ts +338 -0
- package/src/contracts/meta/status.contract.ts +37 -0
- package/src/contracts/shared/jurisdiction.schema.ts +30 -0
- package/src/core.ts +451 -161
- package/src/handlers/consent/index.ts +9 -0
- package/src/handlers/consent/post.handler.ts +273 -0
- package/src/handlers/consent/show-banner.handler.test.ts +148 -0
- package/src/handlers/consent/show-banner.handler.ts +150 -0
- package/src/handlers/consent/verify.handler.ts +305 -0
- package/src/handlers/meta/index.ts +5 -0
- package/src/handlers/meta/status.handler.ts +47 -0
- package/src/init.ts +8 -26
- package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +6 -0
- package/src/pkgs/api-router/hooks/processor.ts +2 -0
- package/src/pkgs/api-router/types/router-props.ts +1 -1
- package/src/pkgs/api-router/utils/cors.ts +1 -1
- package/src/pkgs/data-model/fields/field-types.ts +1 -1
- package/src/pkgs/data-model/fields/id-generator.ts +1 -1
- package/src/pkgs/db-adapters/README.md +3 -3
- package/src/pkgs/db-adapters/adapter-factory.ts +8 -4
- package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +13 -16
- package/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts +1 -3
- package/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts +0 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +1 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +1 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +2 -2
- package/src/pkgs/db-adapters/adapters/kysely-adapter/types.ts +0 -2
- package/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts +0 -1
- package/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts +0 -1
- package/src/pkgs/migrations/get-migration.ts +3 -3
- package/src/pkgs/migrations/get-schema/get-schema.ts +2 -2
- package/src/pkgs/migrations/get-schema/index.ts +1 -1
- package/src/pkgs/migrations/migration-builders.ts +2 -2
- package/src/pkgs/migrations/migration-execution.ts +2 -2
- package/src/pkgs/migrations/schema-comparison.ts +5 -4
- package/src/pkgs/results/__tests__/error-class.test.ts +8 -7
- package/src/pkgs/results/core/error-class.ts +31 -43
- package/src/pkgs/results/index.ts +0 -10
- package/src/pkgs/results/orpc-error-handler.ts +137 -0
- package/src/pkgs/results/types.ts +8 -7
- package/src/pkgs/types/context.ts +18 -9
- package/src/pkgs/types/endpoints.ts +3 -5
- package/src/pkgs/types/options.ts +2 -4
- package/src/pkgs/types/plugins.ts +2 -3
- package/src/pkgs/utils/index.ts +1 -0
- package/src/pkgs/utils/logger.ts +38 -0
- package/src/router.ts +8 -0
- package/src/schema/audit-log/table.ts +1 -1
- package/src/schema/consent/table.ts +1 -1
- package/src/schema/consent-policy/table.ts +1 -1
- package/src/schema/consent-purpose/table.ts +1 -1
- package/src/schema/consent-record/table.ts +1 -1
- package/src/schema/definition.ts +2 -2
- package/src/schema/domain/table.ts +1 -1
- package/src/schema/subject/table.ts +1 -1
- package/src/server.ts +130 -0
- package/src/testing/contract-testing.ts +437 -0
- package/src/types/context.ts +1 -1
- package/src/types/index.ts +2 -2
- package/src/types/options.ts +38 -3
- package/src/types/plugins.ts +3 -4
- package/dist/index.cjs +0 -3706
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/init.test.d.ts +0 -2
- package/dist/init.test.d.ts.map +0 -1
- package/dist/integrations/cloudflare.cjs +0 -312
- package/dist/integrations/cloudflare.d.ts +0 -32
- package/dist/integrations/cloudflare.d.ts.map +0 -1
- package/dist/integrations/cloudflare.js +0 -278
- package/dist/integrations/next.cjs +0 -276
- package/dist/integrations/next.d.ts +0 -68
- package/dist/integrations/next.d.ts.map +0 -1
- package/dist/integrations/next.js +0 -239
- package/dist/integrations/node.cjs +0 -257
- package/dist/integrations/node.d.ts +0 -29
- package/dist/integrations/node.d.ts.map +0 -1
- package/dist/integrations/node.js +0 -223
- package/dist/pkgs/api-router/index.d.ts +0 -9
- package/dist/pkgs/api-router/index.d.ts.map +0 -1
- package/dist/pkgs/api-router/utils/define-route.d.ts +0 -87
- package/dist/pkgs/api-router/utils/define-route.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/integration.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/integration.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/log-levels.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/log-levels.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/result-logging.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/result-logging.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/types.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/types.test.d.ts.map +0 -1
- package/dist/pkgs/logger/console-formatter.d.ts +0 -56
- package/dist/pkgs/logger/console-formatter.d.ts.map +0 -1
- package/dist/pkgs/logger/index.cjs +0 -240
- package/dist/pkgs/logger/index.d.ts +0 -35
- package/dist/pkgs/logger/index.d.ts.map +0 -1
- package/dist/pkgs/logger/index.js +0 -185
- package/dist/pkgs/logger/log-levels.d.ts +0 -29
- package/dist/pkgs/logger/log-levels.d.ts.map +0 -1
- package/dist/pkgs/logger/logger-factory.d.ts +0 -42
- package/dist/pkgs/logger/logger-factory.d.ts.map +0 -1
- package/dist/pkgs/logger/result-logging.d.ts +0 -71
- package/dist/pkgs/logger/result-logging.d.ts.map +0 -1
- package/dist/pkgs/logger/telemetry.d.ts +0 -14
- package/dist/pkgs/logger/telemetry.d.ts.map +0 -1
- package/dist/pkgs/logger/types.d.ts +0 -121
- package/dist/pkgs/logger/types.d.ts.map +0 -1
- package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts +0 -2
- package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts.map +0 -1
- package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts +0 -2
- package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts.map +0 -1
- package/dist/pkgs/results/h3-integration.d.ts +0 -52
- package/dist/pkgs/results/h3-integration.d.ts.map +0 -1
- package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts +0 -101
- package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts.map +0 -1
- package/dist/pkgs/results/pipeline/validation-pipeline.d.ts +0 -89
- package/dist/pkgs/results/pipeline/validation-pipeline.d.ts.map +0 -1
- package/dist/response-types.d.ts +0 -19
- package/dist/response-types.d.ts.map +0 -1
- package/dist/routes/__test__/index.test.d.ts +0 -17
- package/dist/routes/__test__/index.test.d.ts.map +0 -1
- package/dist/routes/__test__/set-consent.test.d.ts +0 -2
- package/dist/routes/__test__/set-consent.test.d.ts.map +0 -1
- package/dist/routes/__test__/show-consent-banner.test.d.ts +0 -2
- package/dist/routes/__test__/show-consent-banner.test.d.ts.map +0 -1
- package/dist/routes/__test__/status.test.d.ts +0 -2
- package/dist/routes/__test__/status.test.d.ts.map +0 -1
- package/dist/routes/__test__/verify-consent.test.d.ts +0 -2
- package/dist/routes/__test__/verify-consent.test.d.ts.map +0 -1
- package/dist/routes/index.d.ts +0 -3
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/set-consent.d.ts +0 -89
- package/dist/routes/set-consent.d.ts.map +0 -1
- package/dist/routes/show-consent-banner.d.ts +0 -15
- package/dist/routes/show-consent-banner.d.ts.map +0 -1
- package/dist/routes/status.d.ts +0 -44
- package/dist/routes/status.d.ts.map +0 -1
- package/dist/routes/types.d.ts +0 -7
- package/dist/routes/types.d.ts.map +0 -1
- package/dist/routes/verify-consent.d.ts +0 -38
- package/dist/routes/verify-consent.d.ts.map +0 -1
- package/src/docs/ADVANCED_JSON_HANDLING.md +0 -99
- package/src/docs/neverthrow.md +0 -171
- package/src/index.ts +0 -34
- package/src/init.test.ts +0 -236
- package/src/integrations/cloudflare.ts +0 -269
- package/src/integrations/next.ts +0 -204
- package/src/integrations/node.ts +0 -141
- package/src/pkgs/api-router/index.ts +0 -148
- package/src/pkgs/api-router/types/h3.d.ts +0 -42
- package/src/pkgs/api-router/utils/define-route.ts +0 -410
- package/src/pkgs/logger/README.md +0 -213
- package/src/pkgs/logger/__tests__/console-formatter.test.ts +0 -67
- package/src/pkgs/logger/__tests__/integration.test.ts +0 -184
- package/src/pkgs/logger/__tests__/log-levels.test.ts +0 -77
- package/src/pkgs/logger/__tests__/logger-factory.test.ts +0 -156
- package/src/pkgs/logger/__tests__/result-logging.test.ts +0 -209
- package/src/pkgs/logger/__tests__/types.test.ts +0 -94
- package/src/pkgs/logger/console-formatter.ts +0 -75
- package/src/pkgs/logger/doc.md +0 -569
- package/src/pkgs/logger/index.ts +0 -59
- package/src/pkgs/logger/log-levels.ts +0 -46
- package/src/pkgs/logger/logger-factory.ts +0 -121
- package/src/pkgs/logger/result-logging.ts +0 -134
- package/src/pkgs/logger/telemetry.ts +0 -96
- package/src/pkgs/logger/types.ts +0 -138
- package/src/pkgs/results/__tests__/retrieval-pipeline.test.ts +0 -157
- package/src/pkgs/results/__tests__/validation-pipeline.test.ts +0 -151
- package/src/pkgs/results/h3-integration.ts +0 -142
- package/src/pkgs/results/pipeline/retrieval-pipeline.ts +0 -188
- package/src/pkgs/results/pipeline/validation-pipeline.ts +0 -164
- package/src/plugins/.keep +0 -0
- package/src/response-types.ts +0 -29
- package/src/routes/__test__/index.test.ts +0 -112
- package/src/routes/__test__/set-consent.test.ts +0 -242
- package/src/routes/__test__/show-consent-banner.test.ts +0 -98
- package/src/routes/__test__/status.test.ts +0 -64
- package/src/routes/__test__/verify-consent.test.ts +0 -266
- package/src/routes/index.ts +0 -12
- package/src/routes/set-consent.ts +0 -249
- package/src/routes/show-consent-banner.ts +0 -131
- package/src/routes/status.ts +0 -61
- package/src/routes/types.ts +0 -7
- package/src/routes/verify-consent.ts +0 -206
package/dist/router.cjs
ADDED
|
@@ -0,0 +1,1213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
14
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: definition[key]
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
})();
|
|
20
|
+
(()=>{
|
|
21
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
22
|
+
})();
|
|
23
|
+
(()=>{
|
|
24
|
+
__webpack_require__.r = (exports1)=>{
|
|
25
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
26
|
+
value: 'Module'
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
29
|
+
value: true
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
})();
|
|
33
|
+
var __webpack_exports__ = {};
|
|
34
|
+
__webpack_require__.r(__webpack_exports__);
|
|
35
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
+
router: ()=>router
|
|
37
|
+
});
|
|
38
|
+
const server_namespaceObject = require("@orpc/server");
|
|
39
|
+
const contract_namespaceObject = require("@orpc/contract");
|
|
40
|
+
const external_zod_namespaceObject = require("zod");
|
|
41
|
+
const external_base_x_namespaceObject = require("base-x");
|
|
42
|
+
var external_base_x_default = /*#__PURE__*/ __webpack_require__.n(external_base_x_namespaceObject);
|
|
43
|
+
external_base_x_default()('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
|
44
|
+
const fieldConfigSchema = external_zod_namespaceObject.z.object({
|
|
45
|
+
required: external_zod_namespaceObject.z.boolean().default(true),
|
|
46
|
+
returned: external_zod_namespaceObject.z.boolean().default(true),
|
|
47
|
+
input: external_zod_namespaceObject.z.boolean().default(true),
|
|
48
|
+
defaultValue: external_zod_namespaceObject.z.union([
|
|
49
|
+
external_zod_namespaceObject.z.any(),
|
|
50
|
+
external_zod_namespaceObject.z["function"]().returns(external_zod_namespaceObject.z.any())
|
|
51
|
+
]).optional(),
|
|
52
|
+
transform: external_zod_namespaceObject.z.object({
|
|
53
|
+
input: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
|
|
54
|
+
external_zod_namespaceObject.z.any(),
|
|
55
|
+
external_zod_namespaceObject.z.promise(external_zod_namespaceObject.z.any())
|
|
56
|
+
])).optional(),
|
|
57
|
+
output: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
|
|
58
|
+
external_zod_namespaceObject.z.any(),
|
|
59
|
+
external_zod_namespaceObject.z.promise(external_zod_namespaceObject.z.any())
|
|
60
|
+
])).optional()
|
|
61
|
+
}).optional(),
|
|
62
|
+
validator: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
|
|
63
|
+
external_zod_namespaceObject.z.string(),
|
|
64
|
+
external_zod_namespaceObject.z["null"]()
|
|
65
|
+
])).optional(),
|
|
66
|
+
unique: external_zod_namespaceObject.z.boolean().optional(),
|
|
67
|
+
indexed: external_zod_namespaceObject.z.boolean().optional(),
|
|
68
|
+
sortable: external_zod_namespaceObject.z.boolean().default(true),
|
|
69
|
+
fieldName: external_zod_namespaceObject.z.string().optional(),
|
|
70
|
+
bigint: external_zod_namespaceObject.z.boolean().default(false)
|
|
71
|
+
});
|
|
72
|
+
const stringFieldSchema = fieldConfigSchema.extend({
|
|
73
|
+
type: external_zod_namespaceObject.z.literal('string'),
|
|
74
|
+
minLength: external_zod_namespaceObject.z.number().optional(),
|
|
75
|
+
maxLength: external_zod_namespaceObject.z.number().optional(),
|
|
76
|
+
pattern: external_zod_namespaceObject.z.string().optional()
|
|
77
|
+
});
|
|
78
|
+
const numberFieldSchema = fieldConfigSchema.extend({
|
|
79
|
+
type: external_zod_namespaceObject.z.literal('number'),
|
|
80
|
+
min: external_zod_namespaceObject.z.number().optional(),
|
|
81
|
+
max: external_zod_namespaceObject.z.number().optional()
|
|
82
|
+
});
|
|
83
|
+
const booleanFieldSchema = fieldConfigSchema.extend({
|
|
84
|
+
type: external_zod_namespaceObject.z.literal('boolean')
|
|
85
|
+
});
|
|
86
|
+
const dateFieldSchema = fieldConfigSchema.extend({
|
|
87
|
+
type: external_zod_namespaceObject.z.literal('date'),
|
|
88
|
+
minDate: external_zod_namespaceObject.z.date().optional(),
|
|
89
|
+
maxDate: external_zod_namespaceObject.z.date().optional(),
|
|
90
|
+
dateOnly: external_zod_namespaceObject.z.boolean().default(false),
|
|
91
|
+
format: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional()
|
|
92
|
+
});
|
|
93
|
+
const timezoneFieldSchema = fieldConfigSchema.extend({
|
|
94
|
+
type: external_zod_namespaceObject.z.literal('timezone'),
|
|
95
|
+
validateTimezone: external_zod_namespaceObject.z.boolean().default(true),
|
|
96
|
+
suggestedValues: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional(),
|
|
97
|
+
restrictToSuggestedValues: external_zod_namespaceObject.z.boolean().default(false)
|
|
98
|
+
});
|
|
99
|
+
const jsonFieldSchema = fieldConfigSchema.extend({
|
|
100
|
+
type: external_zod_namespaceObject.z.literal('json'),
|
|
101
|
+
validateJson: external_zod_namespaceObject.z.boolean().default(true)
|
|
102
|
+
});
|
|
103
|
+
const stringArrayFieldSchema = fieldConfigSchema.extend({
|
|
104
|
+
type: external_zod_namespaceObject.z.literal('string[]')
|
|
105
|
+
});
|
|
106
|
+
const numberArrayFieldSchema = fieldConfigSchema.extend({
|
|
107
|
+
type: external_zod_namespaceObject.z.literal('number[]')
|
|
108
|
+
});
|
|
109
|
+
external_zod_namespaceObject.z.discriminatedUnion('type', [
|
|
110
|
+
stringFieldSchema,
|
|
111
|
+
numberFieldSchema,
|
|
112
|
+
booleanFieldSchema,
|
|
113
|
+
dateFieldSchema,
|
|
114
|
+
timezoneFieldSchema,
|
|
115
|
+
jsonFieldSchema,
|
|
116
|
+
stringArrayFieldSchema,
|
|
117
|
+
numberArrayFieldSchema
|
|
118
|
+
]);
|
|
119
|
+
require("neverthrow");
|
|
120
|
+
const error_codes_ERROR_CODES = Object.freeze({
|
|
121
|
+
NOT_FOUND: 'Resource not found',
|
|
122
|
+
BAD_REQUEST: 'Bad request',
|
|
123
|
+
CONFLICT: 'Conflict with current state',
|
|
124
|
+
MISSING_REQUIRED_PARAMETER: 'Missing required parameter',
|
|
125
|
+
UNAUTHORIZED: 'Unauthorized',
|
|
126
|
+
FORBIDDEN: 'Forbidden',
|
|
127
|
+
INTERNAL_SERVER_ERROR: 'Internal server error',
|
|
128
|
+
INITIALIZATION_FAILED: 'Initialization failed',
|
|
129
|
+
DATABASE_CONNECTION_ERROR: 'Database connection error',
|
|
130
|
+
DATABASE_QUERY_ERROR: 'Database query error',
|
|
131
|
+
INVALID_CONFIGURATION: 'Invalid configuration',
|
|
132
|
+
REQUEST_HANDLER_ERROR: 'Request handler error',
|
|
133
|
+
INVALID_REQUEST: 'Invalid request',
|
|
134
|
+
UNKNOWN_ERROR: 'Unknown error',
|
|
135
|
+
NETWORK_ERROR: 'Network error',
|
|
136
|
+
PLUGIN_INITIALIZATION_FAILED: 'Plugin initialization failed',
|
|
137
|
+
API_RETRIEVAL_ERROR: 'API retrieval error',
|
|
138
|
+
VALIDATION_ERROR: 'Validation error',
|
|
139
|
+
UNEXPECTED: 'Unexpected error'
|
|
140
|
+
});
|
|
141
|
+
const ERROR_CATEGORIES = Object.freeze({
|
|
142
|
+
VALIDATION: 'validation',
|
|
143
|
+
AUTHORIZATION: 'authorization',
|
|
144
|
+
STORAGE: 'storage',
|
|
145
|
+
NETWORK: 'network',
|
|
146
|
+
PLUGIN: 'plugin',
|
|
147
|
+
CONFIGURATION: 'configuration',
|
|
148
|
+
UNEXPECTED: 'unexpected'
|
|
149
|
+
});
|
|
150
|
+
const api_namespaceObject = require("@opentelemetry/api");
|
|
151
|
+
api_namespaceObject.trace.getTracer('@doubletie/results');
|
|
152
|
+
class error_class_DoubleTieError extends server_namespaceObject.ORPCError {
|
|
153
|
+
category;
|
|
154
|
+
meta;
|
|
155
|
+
statusCode;
|
|
156
|
+
constructor(message, options = {
|
|
157
|
+
code: error_codes_ERROR_CODES.UNKNOWN_ERROR,
|
|
158
|
+
status: 500,
|
|
159
|
+
category: ERROR_CATEGORIES.UNEXPECTED,
|
|
160
|
+
cause: void 0,
|
|
161
|
+
meta: {}
|
|
162
|
+
}){
|
|
163
|
+
super(options.code ?? error_codes_ERROR_CODES.UNKNOWN_ERROR, {
|
|
164
|
+
message,
|
|
165
|
+
cause: options.cause,
|
|
166
|
+
data: options.meta ?? {}
|
|
167
|
+
});
|
|
168
|
+
this.name = 'DoubleTieError';
|
|
169
|
+
this.category = options.category ?? ERROR_CATEGORIES.UNEXPECTED;
|
|
170
|
+
this.meta = options.meta ?? {};
|
|
171
|
+
this.statusCode = options.status ?? 500;
|
|
172
|
+
tracing_withSpan('create_doubletie_error', async (span)=>{
|
|
173
|
+
span.setAttributes({
|
|
174
|
+
'error.name': this.constructor.name,
|
|
175
|
+
'error.message': message,
|
|
176
|
+
'error.code': this.code,
|
|
177
|
+
'error.status': this.statusCode,
|
|
178
|
+
'error.category': this.category,
|
|
179
|
+
'error.has_cause': !!this.cause,
|
|
180
|
+
'error.cause_type': this.cause instanceof Error ? this.cause.constructor.name : typeof this.cause,
|
|
181
|
+
'error.has_meta': !!this.meta
|
|
182
|
+
});
|
|
183
|
+
if (this.cause instanceof Error) span.recordException(this.cause);
|
|
184
|
+
});
|
|
185
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
186
|
+
}
|
|
187
|
+
static isDoubleTieError(error) {
|
|
188
|
+
return error instanceof error_class_DoubleTieError;
|
|
189
|
+
}
|
|
190
|
+
toJSON() {
|
|
191
|
+
const validationErrorMessage = this.meta?.validationErrors ? String(this.meta.validationErrors) : void 0;
|
|
192
|
+
const stackTrace = this.stack ? this.stack.split('\n').map((line)=>line.trim()).filter((line)=>line && !line.includes('Error: ')) : [];
|
|
193
|
+
return {
|
|
194
|
+
code: this.code,
|
|
195
|
+
message: validationErrorMessage || this.message,
|
|
196
|
+
status: this.statusCode,
|
|
197
|
+
defined: true,
|
|
198
|
+
data: {
|
|
199
|
+
category: this.category,
|
|
200
|
+
meta: this.meta,
|
|
201
|
+
...'production' === process.env.NODE_ENV ? {} : {
|
|
202
|
+
stack: stackTrace
|
|
203
|
+
},
|
|
204
|
+
...validationErrorMessage && this.message ? {
|
|
205
|
+
originalMessage: this.message
|
|
206
|
+
} : {},
|
|
207
|
+
...this.cause ? {
|
|
208
|
+
cause: this.cause instanceof Error ? {
|
|
209
|
+
name: this.cause.name,
|
|
210
|
+
message: this.cause.message,
|
|
211
|
+
stack: this.cause.stack ? this.cause.stack.split('\n').map((line)=>line.trim()) : void 0
|
|
212
|
+
} : this.cause
|
|
213
|
+
} : {}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
static fromResponse(response, data) {
|
|
218
|
+
let message = `HTTP error ${response.status}`;
|
|
219
|
+
let errorCode = `HTTP ${response.status}`;
|
|
220
|
+
let errorMeta = {};
|
|
221
|
+
if (data && 'object' == typeof data && null !== data) {
|
|
222
|
+
const errorObj = data;
|
|
223
|
+
if ('string' == typeof errorObj.message) message = errorObj.message;
|
|
224
|
+
if ('string' == typeof errorObj.code) errorCode = errorObj.code;
|
|
225
|
+
if ('object' == typeof errorObj.data && null !== errorObj.data) errorMeta = errorObj.data;
|
|
226
|
+
}
|
|
227
|
+
return new error_class_DoubleTieError(message, {
|
|
228
|
+
code: errorCode,
|
|
229
|
+
status: response.status,
|
|
230
|
+
meta: errorMeta
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
withMeta(additionalMeta) {
|
|
234
|
+
return new error_class_DoubleTieError(this.message, {
|
|
235
|
+
code: this.code,
|
|
236
|
+
status: this.statusCode,
|
|
237
|
+
category: this.category,
|
|
238
|
+
cause: this.cause instanceof Error ? this.cause : void 0,
|
|
239
|
+
meta: {
|
|
240
|
+
...this.meta,
|
|
241
|
+
...additionalMeta
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
static createSubclass(name) {
|
|
246
|
+
const ErrorSubclass = class extends error_class_DoubleTieError {
|
|
247
|
+
constructor(message, options){
|
|
248
|
+
super(message, options);
|
|
249
|
+
Object.defineProperty(this, 'name', {
|
|
250
|
+
value: name
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
Object.defineProperty(ErrorSubclass, 'name', {
|
|
255
|
+
value: name
|
|
256
|
+
});
|
|
257
|
+
return ErrorSubclass;
|
|
258
|
+
}
|
|
259
|
+
static formatValidationError(error) {
|
|
260
|
+
if (!error.meta) return error.message;
|
|
261
|
+
let formattedMessage = `${error.message} (${error.code})`;
|
|
262
|
+
if (error.meta.validationErrors) formattedMessage += `\nValidation Errors: ${JSON.stringify(error.meta.validationErrors, null, 2)}`;
|
|
263
|
+
const otherMeta = Object.fromEntries(Object.entries(error.meta).filter(([key])=>'validationErrors' !== key));
|
|
264
|
+
if (Object.keys(otherMeta).length > 0) formattedMessage += `\nAdditional Context: ${JSON.stringify(otherMeta, null, 2)}`;
|
|
265
|
+
return formattedMessage;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
require("@doubletie/logger");
|
|
269
|
+
external_zod_namespaceObject.z.object({
|
|
270
|
+
id: external_zod_namespaceObject.z.string(),
|
|
271
|
+
entityType: external_zod_namespaceObject.z.string(),
|
|
272
|
+
entityId: external_zod_namespaceObject.z.string(),
|
|
273
|
+
actionType: external_zod_namespaceObject.z.string(),
|
|
274
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
275
|
+
ipAddress: external_zod_namespaceObject.z.string().optional(),
|
|
276
|
+
userAgent: external_zod_namespaceObject.z.string().optional(),
|
|
277
|
+
changes: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
|
|
278
|
+
metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
|
|
279
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
280
|
+
});
|
|
281
|
+
const PolicyTypeSchema = external_zod_namespaceObject.z["enum"]([
|
|
282
|
+
'cookie_banner',
|
|
283
|
+
'privacy_policy',
|
|
284
|
+
'dpa',
|
|
285
|
+
'terms_and_conditions',
|
|
286
|
+
'marketing_communications',
|
|
287
|
+
'age_verification',
|
|
288
|
+
'other'
|
|
289
|
+
]);
|
|
290
|
+
external_zod_namespaceObject.z.object({
|
|
291
|
+
id: external_zod_namespaceObject.z.string(),
|
|
292
|
+
version: external_zod_namespaceObject.z.string(),
|
|
293
|
+
type: PolicyTypeSchema,
|
|
294
|
+
name: external_zod_namespaceObject.z.string(),
|
|
295
|
+
effectiveDate: external_zod_namespaceObject.z.date(),
|
|
296
|
+
expirationDate: external_zod_namespaceObject.z.date().nullable().optional(),
|
|
297
|
+
content: external_zod_namespaceObject.z.string(),
|
|
298
|
+
contentHash: external_zod_namespaceObject.z.string(),
|
|
299
|
+
isActive: external_zod_namespaceObject.z.boolean().default(true),
|
|
300
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
301
|
+
updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
302
|
+
});
|
|
303
|
+
external_zod_namespaceObject.z.object({
|
|
304
|
+
id: external_zod_namespaceObject.z.string(),
|
|
305
|
+
code: external_zod_namespaceObject.z.string(),
|
|
306
|
+
name: external_zod_namespaceObject.z.string(),
|
|
307
|
+
description: external_zod_namespaceObject.z.string(),
|
|
308
|
+
isEssential: external_zod_namespaceObject.z.boolean().default(false),
|
|
309
|
+
dataCategory: external_zod_namespaceObject.z.string().optional(),
|
|
310
|
+
legalBasis: external_zod_namespaceObject.z.string().optional(),
|
|
311
|
+
isActive: external_zod_namespaceObject.z.boolean().default(true),
|
|
312
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
313
|
+
updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
314
|
+
});
|
|
315
|
+
external_zod_namespaceObject.z.object({
|
|
316
|
+
id: external_zod_namespaceObject.z.string(),
|
|
317
|
+
subjectId: external_zod_namespaceObject.z.string(),
|
|
318
|
+
consentId: external_zod_namespaceObject.z.string().optional(),
|
|
319
|
+
actionType: external_zod_namespaceObject.z.string(),
|
|
320
|
+
details: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
|
|
321
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
322
|
+
updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
323
|
+
});
|
|
324
|
+
external_zod_namespaceObject.z.object({
|
|
325
|
+
id: external_zod_namespaceObject.z.string(),
|
|
326
|
+
subjectId: external_zod_namespaceObject.z.string(),
|
|
327
|
+
domainId: external_zod_namespaceObject.z.string(),
|
|
328
|
+
purposeIds: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()),
|
|
329
|
+
metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).nullable().optional(),
|
|
330
|
+
policyId: external_zod_namespaceObject.z.string().optional(),
|
|
331
|
+
ipAddress: external_zod_namespaceObject.z.string().nullable().optional(),
|
|
332
|
+
userAgent: external_zod_namespaceObject.z.string().nullable().optional(),
|
|
333
|
+
status: external_zod_namespaceObject.z["enum"]([
|
|
334
|
+
'active',
|
|
335
|
+
'withdrawn',
|
|
336
|
+
'expired'
|
|
337
|
+
]).default('active'),
|
|
338
|
+
withdrawalReason: external_zod_namespaceObject.z.string().nullable().optional(),
|
|
339
|
+
givenAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
340
|
+
validUntil: external_zod_namespaceObject.z.date().nullable().optional(),
|
|
341
|
+
isActive: external_zod_namespaceObject.z.boolean().default(true)
|
|
342
|
+
});
|
|
343
|
+
external_zod_namespaceObject.z.object({
|
|
344
|
+
id: external_zod_namespaceObject.z.string(),
|
|
345
|
+
name: external_zod_namespaceObject.z.string().min(1),
|
|
346
|
+
description: external_zod_namespaceObject.z.string().optional(),
|
|
347
|
+
allowedOrigins: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional().default([]),
|
|
348
|
+
isVerified: external_zod_namespaceObject.z.boolean().default(true),
|
|
349
|
+
isActive: external_zod_namespaceObject.z.boolean().default(true),
|
|
350
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
351
|
+
updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
352
|
+
});
|
|
353
|
+
external_zod_namespaceObject.z.object({
|
|
354
|
+
id: external_zod_namespaceObject.z.string(),
|
|
355
|
+
isIdentified: external_zod_namespaceObject.z.boolean().default(false),
|
|
356
|
+
externalId: external_zod_namespaceObject.z.string().nullable().optional(),
|
|
357
|
+
identityProvider: external_zod_namespaceObject.z.string().optional(),
|
|
358
|
+
lastIpAddress: external_zod_namespaceObject.z.string().optional(),
|
|
359
|
+
createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
|
|
360
|
+
updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
|
|
361
|
+
});
|
|
362
|
+
require("node:crypto");
|
|
363
|
+
const baseConsentSchema = external_zod_namespaceObject.z.object({
|
|
364
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
365
|
+
externalSubjectId: external_zod_namespaceObject.z.string().optional(),
|
|
366
|
+
domain: external_zod_namespaceObject.z.string().regex(/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i, 'invalid domain'),
|
|
367
|
+
type: PolicyTypeSchema,
|
|
368
|
+
metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional()
|
|
369
|
+
});
|
|
370
|
+
const cookieBannerSchema = baseConsentSchema.extend({
|
|
371
|
+
type: external_zod_namespaceObject.z.literal('cookie_banner'),
|
|
372
|
+
preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean())
|
|
373
|
+
});
|
|
374
|
+
const policyBasedSchema = baseConsentSchema.extend({
|
|
375
|
+
type: external_zod_namespaceObject.z["enum"]([
|
|
376
|
+
'privacy_policy',
|
|
377
|
+
'dpa',
|
|
378
|
+
'terms_and_conditions'
|
|
379
|
+
]),
|
|
380
|
+
policyId: external_zod_namespaceObject.z.string().optional(),
|
|
381
|
+
preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean()).optional()
|
|
382
|
+
});
|
|
383
|
+
const otherConsentSchema = baseConsentSchema.extend({
|
|
384
|
+
type: external_zod_namespaceObject.z["enum"]([
|
|
385
|
+
'marketing_communications',
|
|
386
|
+
'age_verification',
|
|
387
|
+
'other'
|
|
388
|
+
]),
|
|
389
|
+
preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean()).optional()
|
|
390
|
+
});
|
|
391
|
+
const postConsentContract = contract_namespaceObject.oc.route({
|
|
392
|
+
method: 'POST',
|
|
393
|
+
path: '/consent/set',
|
|
394
|
+
description: `Records a user's consent preferences and creates necessary consent records.
|
|
395
|
+
This endpoint handles various types of consent submissions:
|
|
396
|
+
|
|
397
|
+
1. Cookie Banner Consent:
|
|
398
|
+
- Records granular cookie preferences
|
|
399
|
+
- Supports multiple consent purposes
|
|
400
|
+
- Creates audit trail for compliance
|
|
401
|
+
|
|
402
|
+
2. Policy-Based Consent:
|
|
403
|
+
- Privacy Policy acceptance
|
|
404
|
+
- Data Processing Agreement (DPA) consent
|
|
405
|
+
- Terms and Conditions acceptance
|
|
406
|
+
- Links consent to specific policy versions
|
|
407
|
+
|
|
408
|
+
3. Other Consent Types:
|
|
409
|
+
- Marketing communications preferences
|
|
410
|
+
- Age verification consent
|
|
411
|
+
- Custom consent types
|
|
412
|
+
|
|
413
|
+
The endpoint performs the following operations:
|
|
414
|
+
- Creates or retrieves subject records
|
|
415
|
+
- Validates domain and policy information
|
|
416
|
+
- Creates consent records with audit trails
|
|
417
|
+
- Records consent purposes and preferences
|
|
418
|
+
- Generates audit logs for compliance
|
|
419
|
+
|
|
420
|
+
Use this endpoint to record user consent and maintain a compliant consent management system.`,
|
|
421
|
+
tags: [
|
|
422
|
+
'consent',
|
|
423
|
+
'cookie-banner'
|
|
424
|
+
]
|
|
425
|
+
}).errors({
|
|
426
|
+
INPUT_VALIDATION_FAILED: {
|
|
427
|
+
status: 422,
|
|
428
|
+
message: 'Invalid input parameters',
|
|
429
|
+
data: external_zod_namespaceObject.z.object({
|
|
430
|
+
formErrors: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()),
|
|
431
|
+
fieldErrors: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()))
|
|
432
|
+
})
|
|
433
|
+
},
|
|
434
|
+
SUBJECT_CREATION_FAILED: {
|
|
435
|
+
status: 400,
|
|
436
|
+
message: 'Failed to create or find subject',
|
|
437
|
+
data: external_zod_namespaceObject.z.object({
|
|
438
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
439
|
+
externalSubjectId: external_zod_namespaceObject.z.string().optional()
|
|
440
|
+
})
|
|
441
|
+
},
|
|
442
|
+
DOMAIN_CREATION_FAILED: {
|
|
443
|
+
status: 500,
|
|
444
|
+
message: 'Failed to create or find domain',
|
|
445
|
+
data: external_zod_namespaceObject.z.object({
|
|
446
|
+
domain: external_zod_namespaceObject.z.string()
|
|
447
|
+
})
|
|
448
|
+
},
|
|
449
|
+
POLICY_NOT_FOUND: {
|
|
450
|
+
status: 404,
|
|
451
|
+
message: 'Policy not found',
|
|
452
|
+
data: external_zod_namespaceObject.z.object({
|
|
453
|
+
policyId: external_zod_namespaceObject.z.string(),
|
|
454
|
+
type: external_zod_namespaceObject.z.string()
|
|
455
|
+
})
|
|
456
|
+
},
|
|
457
|
+
POLICY_INACTIVE: {
|
|
458
|
+
status: 409,
|
|
459
|
+
message: 'Policy is not active',
|
|
460
|
+
data: external_zod_namespaceObject.z.object({
|
|
461
|
+
policyId: external_zod_namespaceObject.z.string(),
|
|
462
|
+
type: external_zod_namespaceObject.z.string()
|
|
463
|
+
})
|
|
464
|
+
},
|
|
465
|
+
POLICY_CREATION_FAILED: {
|
|
466
|
+
status: 500,
|
|
467
|
+
message: 'Failed to create or find policy',
|
|
468
|
+
data: external_zod_namespaceObject.z.object({
|
|
469
|
+
type: external_zod_namespaceObject.z.string()
|
|
470
|
+
})
|
|
471
|
+
},
|
|
472
|
+
PURPOSE_CREATION_FAILED: {
|
|
473
|
+
status: 500,
|
|
474
|
+
message: 'Failed to create consent purpose',
|
|
475
|
+
data: external_zod_namespaceObject.z.object({
|
|
476
|
+
purposeCode: external_zod_namespaceObject.z.string()
|
|
477
|
+
})
|
|
478
|
+
},
|
|
479
|
+
CONSENT_CREATION_FAILED: {
|
|
480
|
+
status: 500,
|
|
481
|
+
message: 'Failed to create consent record',
|
|
482
|
+
data: external_zod_namespaceObject.z.object({
|
|
483
|
+
subjectId: external_zod_namespaceObject.z.string(),
|
|
484
|
+
domain: external_zod_namespaceObject.z.string()
|
|
485
|
+
})
|
|
486
|
+
}
|
|
487
|
+
}).input(external_zod_namespaceObject.z.discriminatedUnion('type', [
|
|
488
|
+
cookieBannerSchema,
|
|
489
|
+
policyBasedSchema,
|
|
490
|
+
otherConsentSchema
|
|
491
|
+
])).output(external_zod_namespaceObject.z.object({
|
|
492
|
+
id: external_zod_namespaceObject.z.string(),
|
|
493
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
494
|
+
externalSubjectId: external_zod_namespaceObject.z.string().optional(),
|
|
495
|
+
domainId: external_zod_namespaceObject.z.string(),
|
|
496
|
+
domain: external_zod_namespaceObject.z.string(),
|
|
497
|
+
type: PolicyTypeSchema,
|
|
498
|
+
status: external_zod_namespaceObject.z.string(),
|
|
499
|
+
recordId: external_zod_namespaceObject.z.string(),
|
|
500
|
+
metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
|
|
501
|
+
givenAt: external_zod_namespaceObject.z.date()
|
|
502
|
+
}));
|
|
503
|
+
const JurisdictionMessages = {
|
|
504
|
+
GDPR: 'GDPR or equivalent regulations require a cookie banner.',
|
|
505
|
+
CH: 'Switzerland requires similar data protection measures.',
|
|
506
|
+
BR: "Brazil's LGPD requires consent for cookies.",
|
|
507
|
+
PIPEDA: 'PIPEDA requires consent for data collection.',
|
|
508
|
+
AU: "Australia's Privacy Act mandates transparency about data collection.",
|
|
509
|
+
APPI: "Japan's APPI requires consent for data collection.",
|
|
510
|
+
PIPA: "South Korea's PIPA requires consent for data collection.",
|
|
511
|
+
NONE: 'No specific requirements'
|
|
512
|
+
};
|
|
513
|
+
const JurisdictionCodeSchema = external_zod_namespaceObject.z["enum"]([
|
|
514
|
+
'GDPR',
|
|
515
|
+
'CH',
|
|
516
|
+
'BR',
|
|
517
|
+
'PIPEDA',
|
|
518
|
+
'AU',
|
|
519
|
+
'APPI',
|
|
520
|
+
'PIPA',
|
|
521
|
+
'NONE'
|
|
522
|
+
]);
|
|
523
|
+
const JurisdictionInfoSchema = external_zod_namespaceObject.z.object({
|
|
524
|
+
code: JurisdictionCodeSchema,
|
|
525
|
+
message: external_zod_namespaceObject.z.string()
|
|
526
|
+
});
|
|
527
|
+
const showConsentBannerContract = contract_namespaceObject.oc.route({
|
|
528
|
+
method: 'GET',
|
|
529
|
+
path: '/show-consent-banner',
|
|
530
|
+
description: `Determines if a user should see a consent banner based on their location and applicable privacy regulations.
|
|
531
|
+
This endpoint performs the following checks:
|
|
532
|
+
|
|
533
|
+
1. Detects the user's location using various header information:
|
|
534
|
+
- Cloudflare country headers
|
|
535
|
+
- Vercel IP country headers
|
|
536
|
+
- AWS CloudFront headers
|
|
537
|
+
- Custom country code headers
|
|
538
|
+
|
|
539
|
+
2. Determines the applicable jurisdiction based on the location:
|
|
540
|
+
- GDPR (EU/EEA/UK)
|
|
541
|
+
- Swiss Data Protection Act
|
|
542
|
+
- LGPD (Brazil)
|
|
543
|
+
- PIPEDA (Canada)
|
|
544
|
+
- Australian Privacy Principles
|
|
545
|
+
- APPI (Japan)
|
|
546
|
+
- PIPA (South Korea)
|
|
547
|
+
|
|
548
|
+
3. Returns detailed information about:
|
|
549
|
+
- Whether to show the consent banner
|
|
550
|
+
- The applicable jurisdiction and its requirements
|
|
551
|
+
- The user's detected location (country and region)
|
|
552
|
+
|
|
553
|
+
Use this endpoint to implement geo-targeted consent banners and ensure compliance with regional privacy regulations.`,
|
|
554
|
+
tags: [
|
|
555
|
+
'cookie-banner'
|
|
556
|
+
]
|
|
557
|
+
}).output(external_zod_namespaceObject.z.object({
|
|
558
|
+
showConsentBanner: external_zod_namespaceObject.z.boolean(),
|
|
559
|
+
jurisdiction: JurisdictionInfoSchema,
|
|
560
|
+
location: external_zod_namespaceObject.z.object({
|
|
561
|
+
countryCode: external_zod_namespaceObject.z.string().nullable(),
|
|
562
|
+
regionCode: external_zod_namespaceObject.z.string().nullable()
|
|
563
|
+
})
|
|
564
|
+
}));
|
|
565
|
+
const verifyConsentInputSchema = external_zod_namespaceObject.z.object({
|
|
566
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
567
|
+
externalSubjectId: external_zod_namespaceObject.z.string().optional(),
|
|
568
|
+
domain: external_zod_namespaceObject.z.string(),
|
|
569
|
+
type: PolicyTypeSchema,
|
|
570
|
+
policyId: external_zod_namespaceObject.z.string().optional(),
|
|
571
|
+
preferences: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional()
|
|
572
|
+
}).strict();
|
|
573
|
+
const verify_contract_consentSchema = external_zod_namespaceObject.z.object({
|
|
574
|
+
id: external_zod_namespaceObject.z.string(),
|
|
575
|
+
purposeIds: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string())
|
|
576
|
+
}).passthrough();
|
|
577
|
+
const verifyConsentContract = contract_namespaceObject.oc.route({
|
|
578
|
+
method: 'POST',
|
|
579
|
+
path: '/consent/verify',
|
|
580
|
+
description: `Verifies if a user has given valid consent for a specific policy and domain.
|
|
581
|
+
This endpoint performs comprehensive consent verification by:
|
|
582
|
+
|
|
583
|
+
1. Validating the subject's identity (using subjectId or externalSubjectId)
|
|
584
|
+
2. Verifying the domain's existence and validity
|
|
585
|
+
3. Checking if the specified policy exists and is active
|
|
586
|
+
4. Validating that all required purposes have been consented to
|
|
587
|
+
5. Ensuring the consent record is current and valid
|
|
588
|
+
|
|
589
|
+
The endpoint supports different types of consent verification:
|
|
590
|
+
- Cookie banner consent verification
|
|
591
|
+
- Privacy policy consent verification
|
|
592
|
+
- Terms and conditions verification
|
|
593
|
+
- Marketing communications consent verification
|
|
594
|
+
- Age verification
|
|
595
|
+
- Custom consent types
|
|
596
|
+
|
|
597
|
+
Use this endpoint to ensure compliance with privacy regulations and to verify user consent before processing personal data.`,
|
|
598
|
+
tags: [
|
|
599
|
+
'consent'
|
|
600
|
+
]
|
|
601
|
+
}).errors({
|
|
602
|
+
INPUT_VALIDATION_FAILED: {
|
|
603
|
+
status: 422,
|
|
604
|
+
message: 'Invalid input parameters',
|
|
605
|
+
data: external_zod_namespaceObject.z.object({
|
|
606
|
+
formErrors: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()),
|
|
607
|
+
fieldErrors: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional())
|
|
608
|
+
})
|
|
609
|
+
},
|
|
610
|
+
SUBJECT_NOT_FOUND: {
|
|
611
|
+
status: 404,
|
|
612
|
+
message: 'Subject not found',
|
|
613
|
+
data: external_zod_namespaceObject.z.object({
|
|
614
|
+
subjectId: external_zod_namespaceObject.z.string().optional(),
|
|
615
|
+
externalSubjectId: external_zod_namespaceObject.z.string().optional()
|
|
616
|
+
})
|
|
617
|
+
},
|
|
618
|
+
DOMAIN_NOT_FOUND: {
|
|
619
|
+
status: 404,
|
|
620
|
+
message: 'Domain not found',
|
|
621
|
+
data: external_zod_namespaceObject.z.object({
|
|
622
|
+
domain: external_zod_namespaceObject.z.string()
|
|
623
|
+
})
|
|
624
|
+
},
|
|
625
|
+
POLICY_NOT_FOUND: {
|
|
626
|
+
status: 404,
|
|
627
|
+
message: 'Policy not found or invalid',
|
|
628
|
+
data: external_zod_namespaceObject.z.object({
|
|
629
|
+
policyId: external_zod_namespaceObject.z.string(),
|
|
630
|
+
type: external_zod_namespaceObject.z.string()
|
|
631
|
+
})
|
|
632
|
+
},
|
|
633
|
+
PURPOSES_NOT_FOUND: {
|
|
634
|
+
status: 404,
|
|
635
|
+
message: 'Could not find all specified purposes',
|
|
636
|
+
data: external_zod_namespaceObject.z.object({
|
|
637
|
+
preferences: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()),
|
|
638
|
+
foundPurposes: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string())
|
|
639
|
+
})
|
|
640
|
+
},
|
|
641
|
+
COOKIE_BANNER_PREFERENCES_REQUIRED: {
|
|
642
|
+
status: 400,
|
|
643
|
+
message: 'Preferences are required for cookie banner consent',
|
|
644
|
+
data: external_zod_namespaceObject.z.object({
|
|
645
|
+
type: external_zod_namespaceObject.z.literal('cookie_banner')
|
|
646
|
+
})
|
|
647
|
+
},
|
|
648
|
+
NO_CONSENT_FOUND: {
|
|
649
|
+
status: 404,
|
|
650
|
+
message: 'No consent found for the given policy',
|
|
651
|
+
data: external_zod_namespaceObject.z.object({
|
|
652
|
+
policyId: external_zod_namespaceObject.z.string(),
|
|
653
|
+
subjectId: external_zod_namespaceObject.z.string(),
|
|
654
|
+
domainId: external_zod_namespaceObject.z.string()
|
|
655
|
+
})
|
|
656
|
+
}
|
|
657
|
+
}).input(verifyConsentInputSchema).output(external_zod_namespaceObject.z.object({
|
|
658
|
+
isValid: external_zod_namespaceObject.z.boolean(),
|
|
659
|
+
reasons: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional(),
|
|
660
|
+
consent: verify_contract_consentSchema.optional()
|
|
661
|
+
}));
|
|
662
|
+
const consentContracts = {
|
|
663
|
+
post: postConsentContract,
|
|
664
|
+
showBanner: showConsentBannerContract,
|
|
665
|
+
verify: verifyConsentContract
|
|
666
|
+
};
|
|
667
|
+
const statusContract = contract_namespaceObject.oc.route({
|
|
668
|
+
method: 'GET',
|
|
669
|
+
path: '/status',
|
|
670
|
+
description: `Returns the current operational status and health metrics of the service.
|
|
671
|
+
This endpoint provides real-time information about:
|
|
672
|
+
- Overall service status (ok/error)
|
|
673
|
+
- Current API version
|
|
674
|
+
- Server timestamp
|
|
675
|
+
- Storage system status and availability
|
|
676
|
+
- Client information (IP, User Agent, Region)
|
|
677
|
+
|
|
678
|
+
Use this endpoint for health checks, monitoring, and service status verification.`,
|
|
679
|
+
tags: [
|
|
680
|
+
'meta'
|
|
681
|
+
]
|
|
682
|
+
}).output(external_zod_namespaceObject.z.object({
|
|
683
|
+
status: external_zod_namespaceObject.z["enum"]([
|
|
684
|
+
'ok',
|
|
685
|
+
'error'
|
|
686
|
+
]),
|
|
687
|
+
version: external_zod_namespaceObject.z.string(),
|
|
688
|
+
timestamp: external_zod_namespaceObject.z.date(),
|
|
689
|
+
storage: external_zod_namespaceObject.z.object({
|
|
690
|
+
type: external_zod_namespaceObject.z.string(),
|
|
691
|
+
available: external_zod_namespaceObject.z.boolean()
|
|
692
|
+
}),
|
|
693
|
+
client: external_zod_namespaceObject.z.object({
|
|
694
|
+
ip: external_zod_namespaceObject.z.string().nullable(),
|
|
695
|
+
userAgent: external_zod_namespaceObject.z.string().nullable(),
|
|
696
|
+
region: external_zod_namespaceObject.z.object({
|
|
697
|
+
countryCode: external_zod_namespaceObject.z.string().nullable(),
|
|
698
|
+
regionCode: external_zod_namespaceObject.z.string().nullable()
|
|
699
|
+
})
|
|
700
|
+
})
|
|
701
|
+
}));
|
|
702
|
+
const metaContracts = {
|
|
703
|
+
status: statusContract
|
|
704
|
+
};
|
|
705
|
+
const config = {
|
|
706
|
+
consent: consentContracts,
|
|
707
|
+
meta: metaContracts
|
|
708
|
+
};
|
|
709
|
+
const os = (0, server_namespaceObject.implement)(config);
|
|
710
|
+
const postConsent = os.consent.post.handler(async ({ input, context })=>{
|
|
711
|
+
const typedContext = context;
|
|
712
|
+
const logger = typedContext.logger;
|
|
713
|
+
logger.info('Handling post-consent request');
|
|
714
|
+
const { type, subjectId, externalSubjectId, domain, metadata, preferences } = input;
|
|
715
|
+
logger.debug('Request parameters', {
|
|
716
|
+
type,
|
|
717
|
+
subjectId,
|
|
718
|
+
externalSubjectId,
|
|
719
|
+
domain
|
|
720
|
+
});
|
|
721
|
+
try {
|
|
722
|
+
const subject = await typedContext.registry.findOrCreateSubject({
|
|
723
|
+
subjectId,
|
|
724
|
+
externalSubjectId,
|
|
725
|
+
ipAddress: typedContext.ipAddress || 'unknown'
|
|
726
|
+
});
|
|
727
|
+
if (!subject) throw new server_namespaceObject.ORPCError('SUBJECT_CREATION_FAILED', {
|
|
728
|
+
data: {
|
|
729
|
+
subjectId,
|
|
730
|
+
externalSubjectId
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
logger.debug('Subject found/created', {
|
|
734
|
+
subjectId: subject.id
|
|
735
|
+
});
|
|
736
|
+
const domainRecord = await typedContext.registry.findOrCreateDomain(domain);
|
|
737
|
+
if (!domainRecord) throw new server_namespaceObject.ORPCError('DOMAIN_CREATION_FAILED', {
|
|
738
|
+
data: {
|
|
739
|
+
domain
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
const now = new Date();
|
|
743
|
+
let policyId;
|
|
744
|
+
let purposeIds = [];
|
|
745
|
+
if ('policyId' in input && input.policyId) {
|
|
746
|
+
policyId = input.policyId;
|
|
747
|
+
const policy = await typedContext.registry.findConsentPolicyById(policyId);
|
|
748
|
+
if (!policy) throw new server_namespaceObject.ORPCError('POLICY_NOT_FOUND', {
|
|
749
|
+
data: {
|
|
750
|
+
policyId,
|
|
751
|
+
type
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
if (!policy.isActive) throw new server_namespaceObject.ORPCError('POLICY_INACTIVE', {
|
|
755
|
+
data: {
|
|
756
|
+
policyId,
|
|
757
|
+
type
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
} else {
|
|
761
|
+
const policy = await typedContext.registry.findOrCreatePolicy(type);
|
|
762
|
+
if (!policy) throw new server_namespaceObject.ORPCError('POLICY_CREATION_FAILED', {
|
|
763
|
+
data: {
|
|
764
|
+
type
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
policyId = policy.id;
|
|
768
|
+
}
|
|
769
|
+
if (preferences) {
|
|
770
|
+
const consentedPurposes = Object.entries(preferences).filter(([_, isConsented])=>isConsented).map(([purposeCode])=>purposeCode);
|
|
771
|
+
const existingPurposes = await Promise.all(consentedPurposes.map((purposeCode)=>typedContext.registry.findConsentPurposeByCode(purposeCode)));
|
|
772
|
+
const purposesToCreate = consentedPurposes.filter((_purposeCode, index)=>!existingPurposes[index]);
|
|
773
|
+
const createdPurposes = await Promise.all(purposesToCreate.map((purposeCode)=>typedContext.registry.createConsentPurpose({
|
|
774
|
+
code: purposeCode,
|
|
775
|
+
name: purposeCode,
|
|
776
|
+
description: `Auto-created consentPurpose for ${purposeCode}`,
|
|
777
|
+
isActive: true,
|
|
778
|
+
isEssential: false,
|
|
779
|
+
legalBasis: 'consent',
|
|
780
|
+
createdAt: now,
|
|
781
|
+
updatedAt: now
|
|
782
|
+
})));
|
|
783
|
+
purposeIds = [
|
|
784
|
+
...existingPurposes.filter((p)=>null !== p).map((p)=>p.id),
|
|
785
|
+
...createdPurposes.filter((p)=>null !== p).map((p)=>p.id)
|
|
786
|
+
];
|
|
787
|
+
if (purposeIds.length !== consentedPurposes.length) throw new server_namespaceObject.ORPCError('PURPOSE_CREATION_FAILED', {
|
|
788
|
+
data: {
|
|
789
|
+
purposeCode: purposesToCreate[purposeIds.length - consentedPurposes.length]
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
const result = await typedContext.adapter.transaction({
|
|
794
|
+
callback: async (tx)=>{
|
|
795
|
+
const consentRecord = await tx.create({
|
|
796
|
+
model: 'consent',
|
|
797
|
+
data: {
|
|
798
|
+
subjectId: subject.id,
|
|
799
|
+
domainId: domainRecord.id,
|
|
800
|
+
policyId,
|
|
801
|
+
purposeIds,
|
|
802
|
+
status: 'active',
|
|
803
|
+
isActive: true,
|
|
804
|
+
givenAt: now,
|
|
805
|
+
ipAddress: typedContext.ipAddress || 'unknown',
|
|
806
|
+
agent: typedContext.userAgent || 'unknown',
|
|
807
|
+
history: []
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
const record = await tx.create({
|
|
811
|
+
model: 'consentRecord',
|
|
812
|
+
data: {
|
|
813
|
+
subjectId: subject.id,
|
|
814
|
+
consentId: consentRecord.id,
|
|
815
|
+
actionType: 'consent_given',
|
|
816
|
+
details: metadata,
|
|
817
|
+
createdAt: now
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
await tx.create({
|
|
821
|
+
model: 'auditLog',
|
|
822
|
+
data: {
|
|
823
|
+
subjectId: subject.id,
|
|
824
|
+
entityType: 'consent',
|
|
825
|
+
entityId: consentRecord.id,
|
|
826
|
+
actionType: 'consent_given',
|
|
827
|
+
details: {
|
|
828
|
+
consentId: consentRecord.id,
|
|
829
|
+
type
|
|
830
|
+
},
|
|
831
|
+
timestamp: now,
|
|
832
|
+
ipAddress: typedContext.ipAddress || 'unknown',
|
|
833
|
+
agent: typedContext.userAgent || 'unknown'
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
return {
|
|
837
|
+
consent: consentRecord,
|
|
838
|
+
record
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
if (!result || !result.consent || !result.record) throw new server_namespaceObject.ORPCError('CONSENT_CREATION_FAILED', {
|
|
843
|
+
data: {
|
|
844
|
+
subjectId: subject.id,
|
|
845
|
+
domain
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
return {
|
|
849
|
+
id: result.consent.id,
|
|
850
|
+
subjectId: subject.id,
|
|
851
|
+
externalSubjectId: subject.externalId ?? void 0,
|
|
852
|
+
domainId: domainRecord.id,
|
|
853
|
+
domain: domainRecord.name,
|
|
854
|
+
type,
|
|
855
|
+
status: result.consent.status,
|
|
856
|
+
recordId: result.record.id,
|
|
857
|
+
metadata,
|
|
858
|
+
givenAt: result.consent.givenAt
|
|
859
|
+
};
|
|
860
|
+
} catch (error) {
|
|
861
|
+
logger.error('Error in post-consent handler', {
|
|
862
|
+
error: error instanceof Error ? error.message : String(error),
|
|
863
|
+
errorType: error instanceof Error ? error.constructor.name : typeof error
|
|
864
|
+
});
|
|
865
|
+
if (error instanceof server_namespaceObject.ORPCError) throw error;
|
|
866
|
+
throw new server_namespaceObject.ORPCError('INTERNAL_SERVER_ERROR', {
|
|
867
|
+
message: error instanceof Error ? error.message : String(error)
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
const show_banner_handler_showConsentBanner = os.consent.showBanner.handler(({ context })=>{
|
|
872
|
+
const typedContext = context;
|
|
873
|
+
const headers = typedContext.headers;
|
|
874
|
+
if (!headers) throw new server_namespaceObject.ORPCError('LOCATION_DETECTION_FAILED', {
|
|
875
|
+
data: {
|
|
876
|
+
reason: 'No headers found in request context'
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
const normalizeHeader = (value)=>{
|
|
880
|
+
if (!value) return null;
|
|
881
|
+
return Array.isArray(value) ? value[0] ?? null : value;
|
|
882
|
+
};
|
|
883
|
+
const countryCode = normalizeHeader(headers.get('cf-ipcountry')) ?? normalizeHeader(headers.get('x-vercel-ip-country')) ?? normalizeHeader(headers.get('x-amz-cf-ipcountry')) ?? normalizeHeader(headers.get('x-country-code'));
|
|
884
|
+
const regionCode = normalizeHeader(headers.get('x-vercel-ip-country-region')) ?? normalizeHeader(headers.get('x-region-code'));
|
|
885
|
+
const { showConsentBanner, jurisdictionCode, message } = checkJurisdiction(countryCode);
|
|
886
|
+
return {
|
|
887
|
+
showConsentBanner,
|
|
888
|
+
jurisdiction: {
|
|
889
|
+
code: jurisdictionCode,
|
|
890
|
+
message
|
|
891
|
+
},
|
|
892
|
+
location: {
|
|
893
|
+
countryCode,
|
|
894
|
+
regionCode
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
});
|
|
898
|
+
function checkJurisdiction(countryCode) {
|
|
899
|
+
const jurisdictions = {
|
|
900
|
+
EU: new Set([
|
|
901
|
+
'AT',
|
|
902
|
+
'BE',
|
|
903
|
+
'BG',
|
|
904
|
+
'HR',
|
|
905
|
+
'CY',
|
|
906
|
+
'CZ',
|
|
907
|
+
'DK',
|
|
908
|
+
'EE',
|
|
909
|
+
'FI',
|
|
910
|
+
'FR',
|
|
911
|
+
'DE',
|
|
912
|
+
'GR',
|
|
913
|
+
'HU',
|
|
914
|
+
'IE',
|
|
915
|
+
'IT',
|
|
916
|
+
'LV',
|
|
917
|
+
'LT',
|
|
918
|
+
'LU',
|
|
919
|
+
'MT',
|
|
920
|
+
'NL',
|
|
921
|
+
'PL',
|
|
922
|
+
'PT',
|
|
923
|
+
'RO',
|
|
924
|
+
'SK',
|
|
925
|
+
'SI',
|
|
926
|
+
'ES',
|
|
927
|
+
'SE'
|
|
928
|
+
]),
|
|
929
|
+
EEA: new Set([
|
|
930
|
+
'IS',
|
|
931
|
+
'NO',
|
|
932
|
+
'LI'
|
|
933
|
+
]),
|
|
934
|
+
UK: new Set([
|
|
935
|
+
'GB'
|
|
936
|
+
]),
|
|
937
|
+
CH: new Set([
|
|
938
|
+
'CH'
|
|
939
|
+
]),
|
|
940
|
+
BR: new Set([
|
|
941
|
+
'BR'
|
|
942
|
+
]),
|
|
943
|
+
CA: new Set([
|
|
944
|
+
'CA'
|
|
945
|
+
]),
|
|
946
|
+
AU: new Set([
|
|
947
|
+
'AU'
|
|
948
|
+
]),
|
|
949
|
+
JP: new Set([
|
|
950
|
+
'JP'
|
|
951
|
+
]),
|
|
952
|
+
KR: new Set([
|
|
953
|
+
'KR'
|
|
954
|
+
])
|
|
955
|
+
};
|
|
956
|
+
let showConsentBanner = false;
|
|
957
|
+
let jurisdictionCode = 'NONE';
|
|
958
|
+
if (countryCode) {
|
|
959
|
+
const jurisdictionMap = [
|
|
960
|
+
{
|
|
961
|
+
sets: [
|
|
962
|
+
jurisdictions.EU,
|
|
963
|
+
jurisdictions.EEA,
|
|
964
|
+
jurisdictions.UK
|
|
965
|
+
],
|
|
966
|
+
code: 'GDPR'
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
sets: [
|
|
970
|
+
jurisdictions.CH
|
|
971
|
+
],
|
|
972
|
+
code: 'CH'
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
sets: [
|
|
976
|
+
jurisdictions.BR
|
|
977
|
+
],
|
|
978
|
+
code: 'BR'
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
sets: [
|
|
982
|
+
jurisdictions.CA
|
|
983
|
+
],
|
|
984
|
+
code: 'PIPEDA'
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
sets: [
|
|
988
|
+
jurisdictions.AU
|
|
989
|
+
],
|
|
990
|
+
code: 'AU'
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
sets: [
|
|
994
|
+
jurisdictions.JP
|
|
995
|
+
],
|
|
996
|
+
code: 'APPI'
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
sets: [
|
|
1000
|
+
jurisdictions.KR
|
|
1001
|
+
],
|
|
1002
|
+
code: 'PIPA'
|
|
1003
|
+
}
|
|
1004
|
+
];
|
|
1005
|
+
for (const { sets, code } of jurisdictionMap)if (sets.some((set)=>set.has(countryCode))) {
|
|
1006
|
+
showConsentBanner = true;
|
|
1007
|
+
jurisdictionCode = code;
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
const message = JurisdictionMessages[jurisdictionCode];
|
|
1012
|
+
return {
|
|
1013
|
+
showConsentBanner,
|
|
1014
|
+
jurisdictionCode,
|
|
1015
|
+
message
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
const verifyConsent = os.consent.verify.handler(async ({ input, context })=>{
|
|
1019
|
+
const typedContext = context;
|
|
1020
|
+
const logger = typedContext.logger;
|
|
1021
|
+
logger.info('Handling verify-consent request');
|
|
1022
|
+
const { type, subjectId, externalSubjectId, domain, policyId, preferences } = input;
|
|
1023
|
+
logger.debug('Request parameters', {
|
|
1024
|
+
type,
|
|
1025
|
+
subjectId,
|
|
1026
|
+
externalSubjectId,
|
|
1027
|
+
domain,
|
|
1028
|
+
policyId,
|
|
1029
|
+
preferences
|
|
1030
|
+
});
|
|
1031
|
+
try {
|
|
1032
|
+
const subject = await typedContext.registry.findOrCreateSubject({
|
|
1033
|
+
subjectId,
|
|
1034
|
+
externalSubjectId,
|
|
1035
|
+
ipAddress: typedContext.ipAddress || 'unknown'
|
|
1036
|
+
});
|
|
1037
|
+
if (!subject) throw new server_namespaceObject.ORPCError('SUBJECT_NOT_FOUND', {
|
|
1038
|
+
data: {
|
|
1039
|
+
subjectId,
|
|
1040
|
+
externalSubjectId
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
const domainRecord = await typedContext.registry.findDomain(domain);
|
|
1044
|
+
if (!domainRecord) throw new server_namespaceObject.ORPCError('DOMAIN_NOT_FOUND', {
|
|
1045
|
+
data: {
|
|
1046
|
+
domain
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
if ('cookie_banner' === type && (!preferences || 0 === preferences.length)) throw new server_namespaceObject.ORPCError('COOKIE_BANNER_PREFERENCES_REQUIRED', {
|
|
1050
|
+
data: {
|
|
1051
|
+
type: 'cookie_banner'
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
const purposePromises = preferences?.map((purpose)=>typedContext.registry.findConsentPurposeByCode(purpose));
|
|
1055
|
+
const rawPurposes = await Promise.all(purposePromises ?? []);
|
|
1056
|
+
const purposeIds = rawPurposes.filter((purpose)=>null !== purpose).map((purpose)=>purpose.id);
|
|
1057
|
+
if (purposeIds.length !== (preferences?.length ?? 0)) throw new server_namespaceObject.ORPCError('PURPOSES_NOT_FOUND', {
|
|
1058
|
+
data: {
|
|
1059
|
+
preferences: preferences ?? [],
|
|
1060
|
+
foundPurposes: rawPurposes.filter((p)=>null !== p).map((p)=>p.code)
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
if (policyId) {
|
|
1064
|
+
const policy = await typedContext.registry.findConsentPolicyById(policyId);
|
|
1065
|
+
if (!policy || policy.type !== type) throw new server_namespaceObject.ORPCError('POLICY_NOT_FOUND', {
|
|
1066
|
+
data: {
|
|
1067
|
+
policyId,
|
|
1068
|
+
type
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
1071
|
+
return await checkPolicyConsent({
|
|
1072
|
+
policyId: policy.id,
|
|
1073
|
+
subjectId: subject.id,
|
|
1074
|
+
domainId: domainRecord.id,
|
|
1075
|
+
purposeIds,
|
|
1076
|
+
type,
|
|
1077
|
+
context: typedContext
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
const latestPolicy = await typedContext.registry.findOrCreatePolicy(type);
|
|
1081
|
+
if (!latestPolicy) throw new server_namespaceObject.ORPCError('POLICY_NOT_FOUND', {
|
|
1082
|
+
data: {
|
|
1083
|
+
policyId: 'latest',
|
|
1084
|
+
type
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
return await checkPolicyConsent({
|
|
1088
|
+
policyId: latestPolicy.id,
|
|
1089
|
+
subjectId: subject.id,
|
|
1090
|
+
domainId: domainRecord.id,
|
|
1091
|
+
purposeIds,
|
|
1092
|
+
type,
|
|
1093
|
+
context: typedContext
|
|
1094
|
+
});
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
logger.error('Error in verify-consent handler', {
|
|
1097
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1098
|
+
errorType: error instanceof Error ? error.constructor.name : typeof error
|
|
1099
|
+
});
|
|
1100
|
+
if (error instanceof server_namespaceObject.ORPCError) throw error;
|
|
1101
|
+
throw new server_namespaceObject.ORPCError('INTERNAL_SERVER_ERROR', {
|
|
1102
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
async function checkPolicyConsent({ policyId, subjectId, domainId, purposeIds, type, context }) {
|
|
1107
|
+
const { registry, adapter } = context;
|
|
1108
|
+
const rawConsents = await adapter.findMany({
|
|
1109
|
+
model: 'consent',
|
|
1110
|
+
where: [
|
|
1111
|
+
{
|
|
1112
|
+
field: 'subjectId',
|
|
1113
|
+
value: subjectId
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
field: 'policyId',
|
|
1117
|
+
value: policyId
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
field: 'domainId',
|
|
1121
|
+
value: domainId
|
|
1122
|
+
}
|
|
1123
|
+
],
|
|
1124
|
+
sortBy: {
|
|
1125
|
+
field: 'givenAt',
|
|
1126
|
+
direction: 'desc'
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
1129
|
+
const filteredConsents = rawConsents.filter((consent)=>{
|
|
1130
|
+
if (!purposeIds) return true;
|
|
1131
|
+
return purposeIds.every((id)=>consent.purposeIds.some((purposeId)=>purposeId === id));
|
|
1132
|
+
});
|
|
1133
|
+
await registry.createAuditLog({
|
|
1134
|
+
subjectId,
|
|
1135
|
+
entityType: 'consent_policy',
|
|
1136
|
+
entityId: policyId,
|
|
1137
|
+
actionType: 'verify_consent',
|
|
1138
|
+
metadata: {
|
|
1139
|
+
type,
|
|
1140
|
+
policyId,
|
|
1141
|
+
purposeIds,
|
|
1142
|
+
success: 0 !== filteredConsents.length,
|
|
1143
|
+
...filteredConsents.length > 0 ? {
|
|
1144
|
+
consentId: filteredConsents[0]?.id
|
|
1145
|
+
} : {}
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
1148
|
+
if (0 === rawConsents.length) throw new server_namespaceObject.ORPCError('NO_CONSENT_FOUND', {
|
|
1149
|
+
data: {
|
|
1150
|
+
policyId,
|
|
1151
|
+
subjectId,
|
|
1152
|
+
domainId
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
if (0 === filteredConsents.length) throw new server_namespaceObject.ORPCError('NO_CONSENT_FOUND', {
|
|
1156
|
+
data: {
|
|
1157
|
+
policyId,
|
|
1158
|
+
subjectId,
|
|
1159
|
+
domainId
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
return {
|
|
1163
|
+
isValid: true,
|
|
1164
|
+
consent: filteredConsents[0]
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
const consentHandlers = {
|
|
1168
|
+
post: postConsent,
|
|
1169
|
+
showBanner: show_banner_handler_showConsentBanner,
|
|
1170
|
+
verify: verifyConsent
|
|
1171
|
+
};
|
|
1172
|
+
var package_namespaceObject = JSON.parse('{"i8":"1.1.0-canary.0"}');
|
|
1173
|
+
const statusHandler = os.meta.status.handler(({ context })=>{
|
|
1174
|
+
const typedContext = context;
|
|
1175
|
+
const headers = typedContext.headers;
|
|
1176
|
+
const normalizeHeader = (value)=>{
|
|
1177
|
+
if (!value) return null;
|
|
1178
|
+
return Array.isArray(value) ? value[0] ?? null : value;
|
|
1179
|
+
};
|
|
1180
|
+
const countryCode = normalizeHeader(headers?.get('cf-ipcountry')) ?? normalizeHeader(headers?.get('x-vercel-ip-country')) ?? normalizeHeader(headers?.get('x-amz-cf-ipcountry')) ?? normalizeHeader(headers?.get('x-country-code'));
|
|
1181
|
+
const regionCode = normalizeHeader(headers?.get('x-vercel-ip-country-region')) ?? normalizeHeader(headers?.get('x-region-code'));
|
|
1182
|
+
return {
|
|
1183
|
+
status: 'ok',
|
|
1184
|
+
version: package_namespaceObject.i8,
|
|
1185
|
+
timestamp: new Date(),
|
|
1186
|
+
storage: {
|
|
1187
|
+
type: typedContext.adapter?.id ?? 'MemoryAdapter',
|
|
1188
|
+
available: !!typedContext.adapter
|
|
1189
|
+
},
|
|
1190
|
+
client: {
|
|
1191
|
+
ip: typedContext.ipAddress ?? null,
|
|
1192
|
+
userAgent: typedContext.userAgent ?? null,
|
|
1193
|
+
region: {
|
|
1194
|
+
countryCode,
|
|
1195
|
+
regionCode
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
});
|
|
1200
|
+
const metaHandlers = {
|
|
1201
|
+
status: statusHandler
|
|
1202
|
+
};
|
|
1203
|
+
const router = os.router({
|
|
1204
|
+
consent: consentHandlers,
|
|
1205
|
+
meta: metaHandlers
|
|
1206
|
+
});
|
|
1207
|
+
exports.router = __webpack_exports__.router;
|
|
1208
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
1209
|
+
"router"
|
|
1210
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
1211
|
+
Object.defineProperty(exports, '__esModule', {
|
|
1212
|
+
value: true
|
|
1213
|
+
});
|