@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
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { ORPCError } from '@orpc/server';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import { os } from '~/contracts';
|
|
4
|
+
import type { Consent as DBConsent } from '~/schema/consent';
|
|
5
|
+
import type { PolicyTypeSchema } from '~/schema/consent-policy';
|
|
6
|
+
import type { C15TContext } from '~/types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Type representing a consent record with required fields
|
|
10
|
+
*/
|
|
11
|
+
interface Consent {
|
|
12
|
+
id: string;
|
|
13
|
+
purposeIds: string[];
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Input type for verifying consent
|
|
19
|
+
*/
|
|
20
|
+
type VerifyConsentInput = {
|
|
21
|
+
subjectId?: string;
|
|
22
|
+
externalSubjectId?: string;
|
|
23
|
+
domain: string;
|
|
24
|
+
type: z.infer<typeof PolicyTypeSchema>;
|
|
25
|
+
policyId?: string;
|
|
26
|
+
preferences?: string[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Response type for consent verification
|
|
31
|
+
*/
|
|
32
|
+
type VerifyConsentOutput = {
|
|
33
|
+
isValid: boolean;
|
|
34
|
+
reasons?: string[];
|
|
35
|
+
consent?: Consent;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parameters for checking policy consent
|
|
40
|
+
*/
|
|
41
|
+
interface PolicyConsentCheckParams {
|
|
42
|
+
policyId: string;
|
|
43
|
+
subjectId: string;
|
|
44
|
+
domainId: string;
|
|
45
|
+
purposeIds?: string[];
|
|
46
|
+
type: z.infer<typeof PolicyTypeSchema>;
|
|
47
|
+
context: C15TContext;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handles verification of consent records.
|
|
52
|
+
*
|
|
53
|
+
* This handler checks if a subject has given valid consent for a specific policy
|
|
54
|
+
* and domain, optionally verifying specific purpose preferences.
|
|
55
|
+
*
|
|
56
|
+
* @throws {DoubleTieError} When:
|
|
57
|
+
* - Subject creation fails
|
|
58
|
+
* - Domain is not found
|
|
59
|
+
* - Policy is not found or invalid
|
|
60
|
+
* - Database query fails
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* // Verify cookie banner consent
|
|
65
|
+
* const response = await verifyConsent({
|
|
66
|
+
* type: 'cookie_banner',
|
|
67
|
+
* domain: 'example.com',
|
|
68
|
+
* preferences: ['analytics', 'marketing']
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const verifyConsent = os.consent.verify.handler(
|
|
73
|
+
async ({ input, context }) => {
|
|
74
|
+
const typedContext = context as C15TContext;
|
|
75
|
+
const logger = typedContext.logger;
|
|
76
|
+
logger.info('Handling verify-consent request');
|
|
77
|
+
|
|
78
|
+
const {
|
|
79
|
+
type,
|
|
80
|
+
subjectId,
|
|
81
|
+
externalSubjectId,
|
|
82
|
+
domain,
|
|
83
|
+
policyId,
|
|
84
|
+
preferences,
|
|
85
|
+
} = input as VerifyConsentInput;
|
|
86
|
+
|
|
87
|
+
logger.debug('Request parameters', {
|
|
88
|
+
type,
|
|
89
|
+
subjectId,
|
|
90
|
+
externalSubjectId,
|
|
91
|
+
domain,
|
|
92
|
+
policyId,
|
|
93
|
+
preferences,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
// Find subject
|
|
98
|
+
const subject = await typedContext.registry.findOrCreateSubject({
|
|
99
|
+
subjectId,
|
|
100
|
+
externalSubjectId,
|
|
101
|
+
ipAddress: typedContext.ipAddress || 'unknown',
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (!subject) {
|
|
105
|
+
throw new ORPCError('SUBJECT_NOT_FOUND', {
|
|
106
|
+
data: {
|
|
107
|
+
subjectId,
|
|
108
|
+
externalSubjectId,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Find domain
|
|
114
|
+
const domainRecord = await typedContext.registry.findDomain(domain);
|
|
115
|
+
if (!domainRecord) {
|
|
116
|
+
throw new ORPCError('DOMAIN_NOT_FOUND', {
|
|
117
|
+
data: {
|
|
118
|
+
domain,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Validate preferences for cookie banner
|
|
124
|
+
if (
|
|
125
|
+
type === 'cookie_banner' &&
|
|
126
|
+
(!preferences || preferences.length === 0)
|
|
127
|
+
) {
|
|
128
|
+
throw new ORPCError('COOKIE_BANNER_PREFERENCES_REQUIRED', {
|
|
129
|
+
data: {
|
|
130
|
+
type: 'cookie_banner',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Find purpose IDs if preferences are provided
|
|
136
|
+
const purposePromises = preferences?.map((purpose: string) =>
|
|
137
|
+
typedContext.registry.findConsentPurposeByCode(purpose)
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const rawPurposes = await Promise.all(purposePromises ?? []);
|
|
141
|
+
const purposeIds = rawPurposes
|
|
142
|
+
.filter(
|
|
143
|
+
(purpose): purpose is NonNullable<typeof purpose> => purpose !== null
|
|
144
|
+
)
|
|
145
|
+
.map((purpose) => purpose.id);
|
|
146
|
+
|
|
147
|
+
if (purposeIds.length !== (preferences?.length ?? 0)) {
|
|
148
|
+
throw new ORPCError('PURPOSES_NOT_FOUND', {
|
|
149
|
+
data: {
|
|
150
|
+
preferences: preferences ?? [],
|
|
151
|
+
foundPurposes: rawPurposes
|
|
152
|
+
.filter((p): p is NonNullable<typeof p> => p !== null)
|
|
153
|
+
.map((p) => p.code),
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Check policy consent
|
|
159
|
+
if (policyId) {
|
|
160
|
+
const policy =
|
|
161
|
+
await typedContext.registry.findConsentPolicyById(policyId);
|
|
162
|
+
if (!policy || policy.type !== type) {
|
|
163
|
+
throw new ORPCError('POLICY_NOT_FOUND', {
|
|
164
|
+
data: {
|
|
165
|
+
policyId,
|
|
166
|
+
type,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return await checkPolicyConsent({
|
|
172
|
+
policyId: policy.id,
|
|
173
|
+
subjectId: subject.id,
|
|
174
|
+
domainId: domainRecord.id,
|
|
175
|
+
purposeIds,
|
|
176
|
+
type,
|
|
177
|
+
context: typedContext,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Check latest policy consent
|
|
182
|
+
const latestPolicy = await typedContext.registry.findOrCreatePolicy(type);
|
|
183
|
+
if (!latestPolicy) {
|
|
184
|
+
throw new ORPCError('POLICY_NOT_FOUND', {
|
|
185
|
+
data: {
|
|
186
|
+
policyId: 'latest',
|
|
187
|
+
type,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return await checkPolicyConsent({
|
|
193
|
+
policyId: latestPolicy.id,
|
|
194
|
+
subjectId: subject.id,
|
|
195
|
+
domainId: domainRecord.id,
|
|
196
|
+
purposeIds,
|
|
197
|
+
type,
|
|
198
|
+
context: typedContext,
|
|
199
|
+
});
|
|
200
|
+
} catch (error) {
|
|
201
|
+
logger.error('Error in verify-consent handler', {
|
|
202
|
+
error: error instanceof Error ? error.message : String(error),
|
|
203
|
+
errorType:
|
|
204
|
+
error instanceof Error ? error.constructor.name : typeof error,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Re-throw ORPCError instances
|
|
208
|
+
if (error instanceof ORPCError) {
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Convert other errors to internal server error
|
|
213
|
+
throw new ORPCError('INTERNAL_SERVER_ERROR', {
|
|
214
|
+
message: error instanceof Error ? error.message : String(error),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Checks if consent has been given for a specific policy.
|
|
222
|
+
*
|
|
223
|
+
* @param params - Parameters for checking policy consent
|
|
224
|
+
* @returns Verification result with consent details if valid
|
|
225
|
+
*
|
|
226
|
+
* @throws {DoubleTieError} When database operations fail
|
|
227
|
+
*/
|
|
228
|
+
async function checkPolicyConsent({
|
|
229
|
+
policyId,
|
|
230
|
+
subjectId,
|
|
231
|
+
domainId,
|
|
232
|
+
purposeIds,
|
|
233
|
+
type,
|
|
234
|
+
context,
|
|
235
|
+
}: PolicyConsentCheckParams): Promise<VerifyConsentOutput> {
|
|
236
|
+
const { registry, adapter } = context;
|
|
237
|
+
|
|
238
|
+
// Find all consents for the policy
|
|
239
|
+
const rawConsents = (await adapter.findMany({
|
|
240
|
+
model: 'consent',
|
|
241
|
+
where: [
|
|
242
|
+
{ field: 'subjectId', value: subjectId },
|
|
243
|
+
{ field: 'policyId', value: policyId },
|
|
244
|
+
{ field: 'domainId', value: domainId },
|
|
245
|
+
],
|
|
246
|
+
sortBy: {
|
|
247
|
+
field: 'givenAt',
|
|
248
|
+
direction: 'desc',
|
|
249
|
+
},
|
|
250
|
+
})) as unknown as DBConsent[];
|
|
251
|
+
|
|
252
|
+
// Filter consents by purpose IDs if provided
|
|
253
|
+
const filteredConsents = rawConsents.filter((consent) => {
|
|
254
|
+
if (!purposeIds) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
return purposeIds.every((id) =>
|
|
258
|
+
(consent.purposeIds as string[]).some((purposeId) => purposeId === id)
|
|
259
|
+
);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// Create audit log
|
|
263
|
+
await registry.createAuditLog({
|
|
264
|
+
subjectId,
|
|
265
|
+
entityType: 'consent_policy',
|
|
266
|
+
entityId: policyId,
|
|
267
|
+
actionType: 'verify_consent',
|
|
268
|
+
metadata: {
|
|
269
|
+
type,
|
|
270
|
+
policyId,
|
|
271
|
+
purposeIds,
|
|
272
|
+
success: filteredConsents.length !== 0,
|
|
273
|
+
...(filteredConsents.length > 0
|
|
274
|
+
? {
|
|
275
|
+
consentId: filteredConsents[0]?.id,
|
|
276
|
+
}
|
|
277
|
+
: {}),
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
if (rawConsents.length === 0) {
|
|
282
|
+
throw new ORPCError('NO_CONSENT_FOUND', {
|
|
283
|
+
data: {
|
|
284
|
+
policyId,
|
|
285
|
+
subjectId,
|
|
286
|
+
domainId,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (filteredConsents.length === 0) {
|
|
292
|
+
throw new ORPCError('NO_CONSENT_FOUND', {
|
|
293
|
+
data: {
|
|
294
|
+
policyId,
|
|
295
|
+
subjectId,
|
|
296
|
+
domainId,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
isValid: true,
|
|
303
|
+
consent: filteredConsents[0],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { os } from '~/contracts';
|
|
2
|
+
import type { C15TContext } from '~/types';
|
|
3
|
+
import { version } from '../../../package.json';
|
|
4
|
+
|
|
5
|
+
// Use os.meta.status.handler to connect to the contract
|
|
6
|
+
export const statusHandler = os.meta.status.handler(({ context }) => {
|
|
7
|
+
const typedContext = context as C15TContext;
|
|
8
|
+
|
|
9
|
+
// Extract country and region from request headers
|
|
10
|
+
const headers = typedContext.headers;
|
|
11
|
+
const normalizeHeader = (
|
|
12
|
+
value: string | string[] | null | undefined
|
|
13
|
+
): string | null => {
|
|
14
|
+
if (!value) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return Array.isArray(value) ? (value[0] ?? null) : value;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const countryCode =
|
|
21
|
+
normalizeHeader(headers?.get('cf-ipcountry')) ??
|
|
22
|
+
normalizeHeader(headers?.get('x-vercel-ip-country')) ??
|
|
23
|
+
normalizeHeader(headers?.get('x-amz-cf-ipcountry')) ??
|
|
24
|
+
normalizeHeader(headers?.get('x-country-code'));
|
|
25
|
+
|
|
26
|
+
const regionCode =
|
|
27
|
+
normalizeHeader(headers?.get('x-vercel-ip-country-region')) ??
|
|
28
|
+
normalizeHeader(headers?.get('x-region-code'));
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
status: 'ok' as const,
|
|
32
|
+
version,
|
|
33
|
+
timestamp: new Date(),
|
|
34
|
+
storage: {
|
|
35
|
+
type: typedContext.adapter?.id ?? 'MemoryAdapter',
|
|
36
|
+
available: !!typedContext.adapter,
|
|
37
|
+
},
|
|
38
|
+
client: {
|
|
39
|
+
ip: typedContext.ipAddress ?? null,
|
|
40
|
+
userAgent: typedContext.userAgent ?? null,
|
|
41
|
+
region: {
|
|
42
|
+
countryCode,
|
|
43
|
+
regionCode,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
});
|
package/src/init.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
|
4
4
|
import { defu } from 'defu';
|
|
5
5
|
import type { DatabaseHook } from '~/pkgs/data-model';
|
|
6
6
|
import { getAdapter } from '~/pkgs/db-adapters';
|
|
7
|
-
import { createLogger } from '~/pkgs/logger';
|
|
8
7
|
import type { RegistryContext } from '~/pkgs/types';
|
|
9
|
-
import {
|
|
8
|
+
import { getBaseURL } from '~/pkgs/utils';
|
|
10
9
|
import type { C15TContext, C15TOptions, C15TPlugin } from '~/types';
|
|
10
|
+
import { version } from '../package.json';
|
|
11
11
|
import { generateId } from './pkgs/data-model/fields/id-generator';
|
|
12
12
|
import type { EntityName } from './pkgs/data-model/schema/types';
|
|
13
13
|
import {
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from './pkgs/results';
|
|
23
23
|
|
|
24
24
|
import type { DoubleTieOptions } from './pkgs/types/options';
|
|
25
|
+
import { getLogger, initLogger } from './pkgs/utils/logger';
|
|
25
26
|
import { createRegistry } from './schema/create-registry';
|
|
26
27
|
import { getConsentTables } from './schema/definition';
|
|
27
28
|
|
|
@@ -41,12 +42,6 @@ import { getConsentTables } from './schema/definition';
|
|
|
41
42
|
* This is an internal module typically not used directly by consumers of the c15t library.
|
|
42
43
|
*/
|
|
43
44
|
|
|
44
|
-
/**
|
|
45
|
-
* Default secret used when no secret is provided
|
|
46
|
-
* This should only be used in development environments
|
|
47
|
-
*/
|
|
48
|
-
const DEFAULT_SECRET = 'c15t-default-secret-please-change-in-production';
|
|
49
|
-
|
|
50
45
|
// SDK instance should be at module level for proper lifecycle management
|
|
51
46
|
let telemetrySdk: NodeSDK | undefined;
|
|
52
47
|
|
|
@@ -66,7 +61,6 @@ let telemetrySdk: NodeSDK | undefined;
|
|
|
66
61
|
* @example
|
|
67
62
|
* ```typescript
|
|
68
63
|
* const contextResult = await init({
|
|
69
|
-
* secret: process.env.CONSENT_SECRET,
|
|
70
64
|
* storage: memoryAdapter(),
|
|
71
65
|
* plugins: [geoPlugin()]
|
|
72
66
|
* });
|
|
@@ -95,7 +89,8 @@ export const init = async <P extends C15TPlugin[]>(
|
|
|
95
89
|
const appName = options.appName || 'c15t';
|
|
96
90
|
|
|
97
91
|
// Create a single logger instance early in the initialization process
|
|
98
|
-
|
|
92
|
+
// Initialize the global logger for use throughout the application
|
|
93
|
+
const logger = initLogger({
|
|
99
94
|
...loggerOptions,
|
|
100
95
|
appName: String(appName),
|
|
101
96
|
});
|
|
@@ -120,7 +115,7 @@ export const init = async <P extends C15TPlugin[]>(
|
|
|
120
115
|
// Create a telemetry resource with provided values or safe defaults
|
|
121
116
|
const resource = new Resource({
|
|
122
117
|
'service.name': String(appName),
|
|
123
|
-
'service.version': String(
|
|
118
|
+
'service.version': String(version || '1.0.0'),
|
|
124
119
|
...(telemetryOptions?.defaultAttributes || {}),
|
|
125
120
|
});
|
|
126
121
|
logger.debug('Initializing telemetry with resource attributes', {
|
|
@@ -187,23 +182,10 @@ export const init = async <P extends C15TPlugin[]>(
|
|
|
187
182
|
|
|
188
183
|
return adapterResult.andThen((adapter) => {
|
|
189
184
|
const resolvedBaseURL = getBaseURL(baseUrlStr, basePathStr);
|
|
190
|
-
const secret =
|
|
191
|
-
(options.secret as string) ||
|
|
192
|
-
env.C15T_SECRET ||
|
|
193
|
-
env.CONSENT_SECRET ||
|
|
194
|
-
DEFAULT_SECRET;
|
|
195
|
-
|
|
196
|
-
// Secret warning
|
|
197
|
-
if (secret === DEFAULT_SECRET && isProduction) {
|
|
198
|
-
logger.error(
|
|
199
|
-
'Using default secret in production. Set C15T_SECRET or pass secret in config.'
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
185
|
|
|
203
186
|
// Create normalized options directly with h3 patterns but no version field
|
|
204
187
|
const finalOptions: DoubleTieOptions = {
|
|
205
188
|
...options,
|
|
206
|
-
secret,
|
|
207
189
|
baseURL: resolvedBaseURL ? new URL(resolvedBaseURL).origin : '',
|
|
208
190
|
basePath: basePathStr || '/api/c15t',
|
|
209
191
|
plugins: [...(options.plugins || []), ...getInternalPlugins(options)],
|
|
@@ -236,7 +218,6 @@ export const init = async <P extends C15TPlugin[]>(
|
|
|
236
218
|
options: finalOptions,
|
|
237
219
|
trustedOrigins: options.trustedOrigins || [],
|
|
238
220
|
baseURL: resolvedBaseURL || '',
|
|
239
|
-
secret,
|
|
240
221
|
logger,
|
|
241
222
|
generateId: generateIdFunc,
|
|
242
223
|
adapter,
|
|
@@ -248,7 +229,8 @@ export const init = async <P extends C15TPlugin[]>(
|
|
|
248
229
|
return runPluginInit(ctx);
|
|
249
230
|
});
|
|
250
231
|
} catch (error) {
|
|
251
|
-
|
|
232
|
+
// Use getLogger here since we might be in an error case before logger initialization
|
|
233
|
+
const errorLogger = getLogger(options.logger);
|
|
252
234
|
errorLogger.error('Initialization failed', {
|
|
253
235
|
error: error instanceof Error ? error.message : String(error),
|
|
254
236
|
stack: error instanceof Error ? error.stack : undefined,
|
|
@@ -41,18 +41,21 @@ describe('Hook Processor Module', () => {
|
|
|
41
41
|
|
|
42
42
|
const hooks: Hook[] = [
|
|
43
43
|
{
|
|
44
|
+
//@ts-expect-error
|
|
44
45
|
matcher: (ctx: HookEndpointContext) => ctx.path === '/test',
|
|
45
46
|
handler: vi.fn().mockResolvedValue({
|
|
46
47
|
context: { testKey1: 'value1' },
|
|
47
48
|
}),
|
|
48
49
|
},
|
|
49
50
|
{
|
|
51
|
+
//@ts-expect-error
|
|
50
52
|
matcher: (ctx: HookEndpointContext) => ctx.method === 'GET',
|
|
51
53
|
handler: vi.fn().mockResolvedValue({
|
|
52
54
|
context: { testKey2: 'value2' },
|
|
53
55
|
}),
|
|
54
56
|
},
|
|
55
57
|
{
|
|
58
|
+
//@ts-expect-error
|
|
56
59
|
matcher: (ctx: HookEndpointContext) => ctx.path === '/other',
|
|
57
60
|
handler: vi.fn().mockResolvedValue({
|
|
58
61
|
context: { shouldNotInclude: true },
|
|
@@ -182,16 +185,19 @@ describe('Hook Processor Module', () => {
|
|
|
182
185
|
|
|
183
186
|
const hooks: Hook[] = [
|
|
184
187
|
{
|
|
188
|
+
//@ts-expect-error
|
|
185
189
|
matcher: (ctx: HookEndpointContext) => ctx.path === '/test',
|
|
186
190
|
handler: vi.fn().mockResolvedValue({
|
|
187
191
|
response: modifiedResponse,
|
|
188
192
|
}),
|
|
189
193
|
},
|
|
190
194
|
{
|
|
195
|
+
//@ts-expect-error
|
|
191
196
|
matcher: (ctx: HookEndpointContext) => ctx.method === 'GET',
|
|
192
197
|
handler: vi.fn().mockResolvedValue({}),
|
|
193
198
|
},
|
|
194
199
|
{
|
|
200
|
+
//@ts-expect-error
|
|
195
201
|
matcher: (ctx: HookEndpointContext) => ctx.path === '/other',
|
|
196
202
|
handler: vi.fn().mockResolvedValue({
|
|
197
203
|
response: { shouldNotUse: true },
|
|
@@ -49,6 +49,7 @@ export async function runBeforeHooks(
|
|
|
49
49
|
} = {};
|
|
50
50
|
for (const hook of hooks) {
|
|
51
51
|
if (hook.matcher(context)) {
|
|
52
|
+
//@ts-expect-error
|
|
52
53
|
const result = await hook.handler(context, async () => Promise.resolve());
|
|
53
54
|
if (result && typeof result === 'object') {
|
|
54
55
|
if ('context' in result && typeof result.context === 'object') {
|
|
@@ -123,6 +124,7 @@ export async function runAfterHooks(
|
|
|
123
124
|
let response: unknown = null;
|
|
124
125
|
for (const hook of hooks) {
|
|
125
126
|
if (hook.matcher(context)) {
|
|
127
|
+
//@ts-expect-error
|
|
126
128
|
const result = await hook.handler(context, async () => Promise.resolve());
|
|
127
129
|
if (
|
|
128
130
|
result &&
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Logger } from '@doubletie/logger';
|
|
1
2
|
import type { Adapter } from '~/pkgs/db-adapters/types';
|
|
2
|
-
import type { Logger } from '~/pkgs/logger';
|
|
3
3
|
import type { createRegistry } from '~/schema/create-registry';
|
|
4
4
|
import type { DoubleTieOptions } from '../../types/options';
|
|
5
5
|
|
|
@@ -18,7 +18,7 @@ import type { C15TOptions } from '~/types';
|
|
|
18
18
|
// Create an empty in-memory database
|
|
19
19
|
const db = {};
|
|
20
20
|
|
|
21
|
-
// Configure the adapter in your
|
|
21
|
+
// Configure the adapter in your c15t options
|
|
22
22
|
const options: C15TOptions = {
|
|
23
23
|
// ...other options
|
|
24
24
|
storage: memoryAdapter(db)
|
|
@@ -46,7 +46,7 @@ const db = new Kysely({
|
|
|
46
46
|
dialect: new PostgresDialect({ pool })
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
// Configure the adapter in your
|
|
49
|
+
// Configure the adapter in your c15t options
|
|
50
50
|
const options: C15TOptions = {
|
|
51
51
|
// ...other options
|
|
52
52
|
storage: kyselyAdapter(db, { type: 'postgres' })
|
|
@@ -61,7 +61,7 @@ The package also provides a utility to automatically select the appropriate adap
|
|
|
61
61
|
import { getAdapter } from '~/db/utils/adapter-factory';
|
|
62
62
|
import type { C15TOptions } from '~/types';
|
|
63
63
|
|
|
64
|
-
// Configure
|
|
64
|
+
// Configure c15t with database options
|
|
65
65
|
const options: C15TOptions = {
|
|
66
66
|
// ...other options
|
|
67
67
|
database: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createLogger } from '~/pkgs/logger';
|
|
2
1
|
import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
|
|
2
|
+
import { getLogger } from '~/pkgs/utils/logger';
|
|
3
3
|
import { getConsentTables } from '~/schema';
|
|
4
4
|
import type { C15TOptions } from '~/types';
|
|
5
5
|
import { kyselyAdapter } from './adapters/kysely-adapter';
|
|
@@ -7,14 +7,14 @@ import { createKyselyAdapter } from './adapters/kysely-adapter/dialect';
|
|
|
7
7
|
import { memoryAdapter } from './adapters/memory-adapter';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Creates and configures the appropriate database adapter based on
|
|
10
|
+
* Creates and configures the appropriate database adapter based on c15t options
|
|
11
11
|
*
|
|
12
12
|
* This function handles several scenarios:
|
|
13
13
|
* 1. No database configuration - creates an in-memory adapter (development only)
|
|
14
14
|
* 2. Custom database function - uses the provided function to create an adapter
|
|
15
15
|
* 3. Standard database config - creates a Kysely adapter with the specified database
|
|
16
16
|
*
|
|
17
|
-
* @param options - The
|
|
17
|
+
* @param options - The c15t configuration options
|
|
18
18
|
* @returns A configured database adapter instance
|
|
19
19
|
* @throws {DoubleTieError} If the database adapter initialization fails
|
|
20
20
|
*
|
|
@@ -25,7 +25,11 @@ import { memoryAdapter } from './adapters/memory-adapter';
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export async function getAdapter(options: C15TOptions) {
|
|
28
|
-
|
|
28
|
+
// Use any provided logger options and fall back to the configured appName
|
|
29
|
+
const logger = getLogger({
|
|
30
|
+
appName: options.appName ?? 'c15t',
|
|
31
|
+
...options.logger,
|
|
32
|
+
});
|
|
29
33
|
|
|
30
34
|
// If no database is configured, use an in-memory adapter for development
|
|
31
35
|
if (!options.database) {
|