@c15t/backend 1.5.0 → 1.6.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 +63 -37
- package/CHANGELOG.md +4 -209
- package/README.md +86 -164
- package/dist/contracts/consent/index.d.ts +103 -615
- package/dist/contracts/consent/index.d.ts.map +1 -1
- package/dist/contracts/consent/post.contract.d.ts +42 -140
- package/dist/contracts/consent/post.contract.d.ts.map +1 -1
- package/dist/contracts/consent/show-banner.contract.d.ts +28 -376
- package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -1
- package/dist/contracts/consent/verify.contract.d.ts +33 -99
- package/dist/contracts/consent/verify.contract.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +222 -1356
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/meta/index.d.ts +8 -63
- package/dist/contracts/meta/index.d.ts.map +1 -1
- package/dist/contracts/meta/status.contract.d.ts +8 -63
- package/dist/contracts/meta/status.contract.d.ts.map +1 -1
- package/dist/contracts/shared/jurisdiction.schema.d.ts +21 -9
- package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -1
- package/dist/contracts.cjs +100 -106
- package/dist/contracts.js +100 -106
- package/dist/core.cjs +681 -681
- package/dist/core.d.ts +118 -678
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +634 -637
- package/dist/handlers/consent/index.d.ts +103 -615
- package/dist/handlers/consent/index.d.ts.map +1 -1
- package/dist/handlers/consent/post.handler.d.ts +42 -140
- package/dist/handlers/consent/post.handler.d.ts.map +1 -1
- package/dist/handlers/consent/show-banner/handler.d.ts +28 -376
- package/dist/handlers/consent/show-banner/handler.d.ts.map +1 -1
- package/dist/handlers/consent/show-banner/translations.d.ts.map +1 -1
- package/dist/handlers/consent/verify.handler.d.ts +33 -99
- package/dist/handlers/consent/verify.handler.d.ts.map +1 -1
- package/dist/handlers/meta/index.d.ts +8 -63
- package/dist/handlers/meta/index.d.ts.map +1 -1
- package/dist/handlers/meta/status.handler.d.ts +8 -63
- package/dist/handlers/meta/status.handler.d.ts.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/middleware/openapi/index.d.ts +2 -2
- package/dist/middleware/openapi/index.d.ts.map +1 -1
- package/dist/pkgs/data-model/fields/index.cjs +14 -26
- package/dist/pkgs/data-model/fields/index.d.ts +4 -4
- package/dist/pkgs/data-model/fields/index.d.ts.map +1 -1
- package/dist/pkgs/data-model/fields/index.js +14 -26
- package/dist/pkgs/data-model/fields/zod-fields.d.ts +195 -871
- package/dist/pkgs/data-model/fields/zod-fields.d.ts.map +1 -1
- package/dist/pkgs/data-model/hooks/index.d.ts +2 -2
- package/dist/pkgs/data-model/hooks/index.d.ts.map +1 -1
- package/dist/pkgs/data-model/index.cjs +346 -358
- package/dist/pkgs/data-model/index.d.ts +1 -1
- package/dist/pkgs/data-model/index.d.ts.map +1 -1
- package/dist/pkgs/data-model/index.js +345 -357
- package/dist/pkgs/data-model/schema/index.cjs +346 -358
- package/dist/pkgs/data-model/schema/index.d.ts +1 -1
- package/dist/pkgs/data-model/schema/index.d.ts.map +1 -1
- package/dist/pkgs/data-model/schema/index.js +345 -357
- package/dist/pkgs/data-model/schema/schemas.d.ts +2 -2
- package/dist/pkgs/data-model/schema/schemas.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +3 -0
- 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 +158 -170
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +157 -169
- package/dist/pkgs/db-adapters/adapters/index.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapters/index.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +215 -227
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +213 -225
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts +2 -0
- 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 +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +158 -170
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +157 -169
- package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts +3 -0
- 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 +243 -255
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.d.ts +1 -1
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +241 -253
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts +3 -0
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/index.cjs +714 -726
- package/dist/pkgs/db-adapters/index.d.ts +6 -6
- package/dist/pkgs/db-adapters/index.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/index.js +708 -720
- package/dist/pkgs/migrations/get-migration.d.ts.map +1 -1
- package/dist/pkgs/migrations/get-schema/get-schema.d.ts.map +1 -1
- package/dist/pkgs/migrations/get-schema/process-tables.d.ts.map +1 -1
- package/dist/pkgs/migrations/index.cjs +236 -248
- package/dist/pkgs/migrations/index.d.ts +4 -4
- package/dist/pkgs/migrations/index.d.ts.map +1 -1
- package/dist/pkgs/migrations/index.js +235 -247
- package/dist/pkgs/results/index.cjs +67 -67
- package/dist/pkgs/results/index.d.ts +5 -5
- package/dist/pkgs/results/index.d.ts.map +1 -1
- package/dist/pkgs/results/index.js +67 -67
- package/dist/pkgs/results/orpc-error-handler.d.ts +1 -1
- package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -1
- package/dist/pkgs/types/index.d.ts +1 -2
- package/dist/pkgs/types/index.d.ts.map +1 -1
- package/dist/pkgs/types/options.d.ts +9 -2
- package/dist/pkgs/types/options.d.ts.map +1 -1
- package/dist/pkgs/utils/index.d.ts +1 -1
- package/dist/pkgs/utils/index.d.ts.map +1 -1
- package/dist/pkgs/utils/logger.d.ts +1 -1
- package/dist/pkgs/utils/logger.d.ts.map +1 -1
- package/dist/router.cjs +114 -117
- package/dist/router.d.ts +111 -678
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +114 -117
- package/dist/schema/audit-log/schema.d.ts +2 -24
- package/dist/schema/audit-log/schema.d.ts.map +1 -1
- package/dist/schema/audit-log/table.d.ts +2 -24
- package/dist/schema/audit-log/table.d.ts.map +1 -1
- package/dist/schema/consent/registry.d.ts +8 -8
- package/dist/schema/consent/schema.d.ts +9 -33
- package/dist/schema/consent/schema.d.ts.map +1 -1
- package/dist/schema/consent/table.d.ts +9 -33
- package/dist/schema/consent/table.d.ts.map +1 -1
- package/dist/schema/consent-policy/registry.d.ts +20 -20
- package/dist/schema/consent-policy/schema.d.ts +22 -30
- package/dist/schema/consent-policy/schema.d.ts.map +1 -1
- package/dist/schema/consent-policy/table.d.ts +13 -29
- package/dist/schema/consent-policy/table.d.ts.map +1 -1
- package/dist/schema/consent-purpose/registry.d.ts +6 -6
- package/dist/schema/consent-purpose/schema.d.ts +5 -27
- package/dist/schema/consent-purpose/schema.d.ts.map +1 -1
- package/dist/schema/consent-purpose/table.d.ts +5 -27
- package/dist/schema/consent-purpose/table.d.ts.map +1 -1
- package/dist/schema/consent-record/schema.d.ts +3 -19
- package/dist/schema/consent-record/schema.d.ts.map +1 -1
- package/dist/schema/consent-record/table.d.ts +3 -19
- package/dist/schema/consent-record/table.d.ts.map +1 -1
- package/dist/schema/create-registry.d.ts +58 -58
- package/dist/schema/definition.d.ts +42 -176
- package/dist/schema/definition.d.ts.map +1 -1
- package/dist/schema/domain/registry.d.ts +20 -20
- package/dist/schema/domain/schema.d.ts +6 -24
- package/dist/schema/domain/schema.d.ts.map +1 -1
- package/dist/schema/domain/table.d.ts +6 -24
- package/dist/schema/domain/table.d.ts.map +1 -1
- package/dist/schema/index.cjs +426 -438
- package/dist/schema/index.d.ts +12 -12
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +426 -438
- package/dist/schema/schemas.d.ts +42 -176
- package/dist/schema/schemas.d.ts.map +1 -1
- package/dist/schema/subject/registry.d.ts +4 -4
- package/dist/schema/subject/schema.d.ts +4 -20
- package/dist/schema/subject/schema.d.ts.map +1 -1
- package/dist/schema/subject/table.d.ts +4 -20
- package/dist/schema/subject/table.d.ts.map +1 -1
- package/dist/schema/types.d.ts +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/testing/contract-testing.d.ts +3 -2
- package/dist/testing/contract-testing.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/options.d.ts +2 -2
- package/dist/types/options.d.ts.map +1 -1
- package/dist/v2/contracts/consent/index.d.ts +260 -0
- package/dist/v2/contracts/consent/index.d.ts.map +1 -0
- package/dist/v2/contracts/consent/index.test.d.ts +2 -0
- package/dist/v2/contracts/consent/index.test.d.ts.map +1 -0
- package/dist/v2/contracts/consent/post.contract.d.ts +114 -0
- package/dist/v2/contracts/consent/post.contract.d.ts.map +1 -0
- package/dist/v2/contracts/consent/post.contract.test.d.ts +2 -0
- package/dist/v2/contracts/consent/post.contract.test.d.ts.map +1 -0
- package/dist/v2/contracts/consent/show-banner.contract.d.ts +68 -0
- package/dist/v2/contracts/consent/show-banner.contract.d.ts.map +1 -0
- package/dist/v2/contracts/consent/show-banner.contract.test.d.ts +2 -0
- package/dist/v2/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
- package/dist/v2/contracts/consent/verify.contract.d.ts +81 -0
- package/dist/v2/contracts/consent/verify.contract.d.ts.map +1 -0
- package/dist/v2/contracts/consent/verify.contract.test.d.ts +2 -0
- package/dist/v2/contracts/consent/verify.contract.test.d.ts.map +1 -0
- package/dist/v2/contracts/index.cjs +644 -0
- package/dist/v2/contracts/index.d.ts +563 -0
- package/dist/v2/contracts/index.d.ts.map +1 -0
- package/dist/v2/contracts/index.js +607 -0
- package/dist/v2/contracts/meta/index.d.ts +19 -0
- package/dist/v2/contracts/meta/index.d.ts.map +1 -0
- package/dist/v2/contracts/meta/index.test.d.ts +2 -0
- package/dist/v2/contracts/meta/index.test.d.ts.map +1 -0
- package/dist/v2/contracts/meta/status.contract.d.ts +18 -0
- package/dist/v2/contracts/meta/status.contract.d.ts.map +1 -0
- package/dist/v2/contracts/meta/status.contract.test.d.ts +2 -0
- package/dist/v2/contracts/meta/status.contract.test.d.ts.map +1 -0
- package/dist/v2/contracts/shared/jurisdiction.schema.d.ts +36 -0
- package/dist/v2/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
- package/dist/v2/contracts/test.utils.d.ts +38 -0
- package/dist/v2/contracts/test.utils.d.ts.map +1 -0
- package/dist/v2/core.cjs +2181 -0
- package/dist/v2/core.d.ts +364 -0
- package/dist/v2/core.d.ts.map +1 -0
- package/dist/v2/core.js +2130 -0
- package/dist/v2/db/adapters/drizzle.cjs +36 -0
- package/dist/v2/db/adapters/drizzle.d.ts +2 -0
- package/dist/v2/db/adapters/drizzle.d.ts.map +1 -0
- package/dist/v2/db/adapters/drizzle.js +3 -0
- package/dist/v2/db/adapters/index.cjs +18 -0
- package/dist/v2/db/adapters/index.d.ts +2 -0
- package/dist/v2/db/adapters/index.d.ts.map +1 -0
- package/dist/v2/db/adapters/index.js +0 -0
- package/dist/v2/db/adapters/kysely.cjs +36 -0
- package/dist/v2/db/adapters/kysely.d.ts +2 -0
- package/dist/v2/db/adapters/kysely.d.ts.map +1 -0
- package/dist/v2/db/adapters/kysely.js +3 -0
- package/dist/v2/db/adapters/mongo.cjs +36 -0
- package/dist/v2/db/adapters/mongo.d.ts +2 -0
- package/dist/v2/db/adapters/mongo.d.ts.map +1 -0
- package/dist/v2/db/adapters/mongo.js +3 -0
- package/dist/v2/db/adapters/prisma.cjs +36 -0
- package/dist/v2/db/adapters/prisma.d.ts +2 -0
- package/dist/v2/db/adapters/prisma.d.ts.map +1 -0
- package/dist/v2/db/adapters/prisma.js +3 -0
- package/dist/v2/db/adapters/typeorm.cjs +36 -0
- package/dist/v2/db/adapters/typeorm.d.ts +2 -0
- package/dist/v2/db/adapters/typeorm.d.ts.map +1 -0
- package/dist/v2/db/adapters/typeorm.js +3 -0
- package/dist/v2/db/migrator/index.cjs +61 -0
- package/dist/v2/db/migrator/index.d.ts +29 -0
- package/dist/v2/db/migrator/index.d.ts.map +1 -0
- package/dist/v2/db/migrator/index.js +27 -0
- package/dist/v2/db/registry/audit-log.d.ts +21 -0
- package/dist/v2/db/registry/audit-log.d.ts.map +1 -0
- package/dist/v2/db/registry/audit-log.test.d.ts +2 -0
- package/dist/v2/db/registry/audit-log.test.d.ts.map +1 -0
- package/dist/v2/db/registry/consent-policy.d.ts +29 -0
- package/dist/v2/db/registry/consent-policy.d.ts.map +1 -0
- package/dist/v2/db/registry/consent-policy.test.d.ts +2 -0
- package/dist/v2/db/registry/consent-policy.test.d.ts.map +1 -0
- package/dist/v2/db/registry/consent-purpose.d.ts +16 -0
- package/dist/v2/db/registry/consent-purpose.d.ts.map +1 -0
- package/dist/v2/db/registry/consent-purpose.test.d.ts +2 -0
- package/dist/v2/db/registry/consent-purpose.test.d.ts.map +1 -0
- package/dist/v2/db/registry/consent.d.ts +20 -0
- package/dist/v2/db/registry/consent.d.ts.map +1 -0
- package/dist/v2/db/registry/consent.test.d.ts +2 -0
- package/dist/v2/db/registry/consent.test.d.ts.map +1 -0
- package/dist/v2/db/registry/domain.d.ts +24 -0
- package/dist/v2/db/registry/domain.d.ts.map +1 -0
- package/dist/v2/db/registry/domain.test.d.ts +2 -0
- package/dist/v2/db/registry/domain.test.d.ts.map +1 -0
- package/dist/v2/db/registry/index.d.ts +102 -0
- package/dist/v2/db/registry/index.d.ts.map +1 -0
- package/dist/v2/db/registry/subject.d.ts +18 -0
- package/dist/v2/db/registry/subject.d.ts.map +1 -0
- package/dist/v2/db/registry/subject.test.d.ts +2 -0
- package/dist/v2/db/registry/subject.test.d.ts.map +1 -0
- package/dist/v2/db/registry/types.d.ts +10 -0
- package/dist/v2/db/registry/types.d.ts.map +1 -0
- package/dist/v2/db/registry/utils/generate-id.d.ts +25 -0
- package/dist/v2/db/registry/utils/generate-id.d.ts.map +1 -0
- package/dist/v2/db/registry/utils/generate-id.test.d.ts +2 -0
- package/dist/v2/db/registry/utils/generate-id.test.d.ts.map +1 -0
- package/dist/v2/db/registry/utils.d.ts +25 -0
- package/dist/v2/db/registry/utils.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/audit-log.d.ts +29 -0
- package/dist/v2/db/schema/1.0.0/audit-log.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/consent-policy.d.ts +45 -0
- package/dist/v2/db/schema/1.0.0/consent-policy.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/consent-purpose.d.ts +27 -0
- package/dist/v2/db/schema/1.0.0/consent-purpose.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/consent-record.d.ts +19 -0
- package/dist/v2/db/schema/1.0.0/consent-record.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/consent.d.ts +42 -0
- package/dist/v2/db/schema/1.0.0/consent.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/domain.d.ts +23 -0
- package/dist/v2/db/schema/1.0.0/domain.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/index.d.ts +1513 -0
- package/dist/v2/db/schema/1.0.0/index.d.ts.map +1 -0
- package/dist/v2/db/schema/1.0.0/subject.d.ts +23 -0
- package/dist/v2/db/schema/1.0.0/subject.d.ts.map +1 -0
- package/dist/v2/db/schema/index.cjs +326 -0
- package/dist/v2/db/schema/index.d.ts +1507 -0
- package/dist/v2/db/schema/index.d.ts.map +1 -0
- package/dist/v2/db/schema/index.js +241 -0
- package/dist/v2/define-config.cjs +36 -0
- package/dist/v2/define-config.d.ts +5 -0
- package/dist/v2/define-config.d.ts.map +1 -0
- package/dist/v2/define-config.js +2 -0
- package/dist/v2/handlers/consent/index.d.ts +260 -0
- package/dist/v2/handlers/consent/index.d.ts.map +1 -0
- package/dist/v2/handlers/consent/post.handler.d.ts +136 -0
- package/dist/v2/handlers/consent/post.handler.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/geo.d.ts +10 -0
- package/dist/v2/handlers/consent/show-banner/geo.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/geo.test.d.ts +2 -0
- package/dist/v2/handlers/consent/show-banner/geo.test.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/handler.d.ts +71 -0
- package/dist/v2/handlers/consent/show-banner/handler.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/handler.test.d.ts +2 -0
- package/dist/v2/handlers/consent/show-banner/handler.test.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/translations.d.ts +13 -0
- package/dist/v2/handlers/consent/show-banner/translations.d.ts.map +1 -0
- package/dist/v2/handlers/consent/show-banner/translations.test.d.ts +2 -0
- package/dist/v2/handlers/consent/show-banner/translations.test.d.ts.map +1 -0
- package/dist/v2/handlers/consent/verify.handler.d.ts +103 -0
- package/dist/v2/handlers/consent/verify.handler.d.ts.map +1 -0
- package/dist/v2/handlers/meta/index.d.ts +19 -0
- package/dist/v2/handlers/meta/index.d.ts.map +1 -0
- package/dist/v2/handlers/meta/status.handler.d.ts +17 -0
- package/dist/v2/handlers/meta/status.handler.d.ts.map +1 -0
- package/dist/v2/init.d.ts +3 -0
- package/dist/v2/init.d.ts.map +1 -0
- package/dist/v2/init.test.d.ts +2 -0
- package/dist/v2/init.test.d.ts.map +1 -0
- package/dist/v2/middleware/cors/cors.d.ts +37 -0
- package/dist/v2/middleware/cors/cors.d.ts.map +1 -0
- package/dist/v2/middleware/cors/cors.test.d.ts +2 -0
- package/dist/v2/middleware/cors/cors.test.d.ts.map +1 -0
- package/dist/v2/middleware/cors/index.d.ts +30 -0
- package/dist/v2/middleware/cors/index.d.ts.map +1 -0
- package/dist/v2/middleware/cors/is-origin-trusted.d.ts +49 -0
- package/dist/v2/middleware/cors/is-origin-trusted.d.ts.map +1 -0
- package/dist/v2/middleware/cors/is-origin-trusted.test.d.ts +2 -0
- package/dist/v2/middleware/cors/is-origin-trusted.test.d.ts.map +1 -0
- package/dist/v2/middleware/cors/process-cors.d.ts +31 -0
- package/dist/v2/middleware/cors/process-cors.d.ts.map +1 -0
- package/dist/v2/middleware/openapi/config.d.ts +28 -0
- package/dist/v2/middleware/openapi/config.d.ts.map +1 -0
- package/dist/v2/middleware/openapi/handlers.d.ts +29 -0
- package/dist/v2/middleware/openapi/handlers.d.ts.map +1 -0
- package/dist/v2/middleware/openapi/index.d.ts +11 -0
- package/dist/v2/middleware/openapi/index.d.ts.map +1 -0
- package/dist/v2/middleware/process-ip/index.d.ts +3 -0
- package/dist/v2/middleware/process-ip/index.d.ts.map +1 -0
- package/dist/v2/router.cjs +1275 -0
- package/dist/v2/router.d.ts +280 -0
- package/dist/v2/router.d.ts.map +1 -0
- package/dist/v2/router.js +1231 -0
- package/dist/v2/types/api.d.ts +27 -0
- package/dist/v2/types/api.d.ts.map +1 -0
- package/dist/v2/types/index.cjs +40 -0
- package/dist/v2/types/index.d.ts +104 -0
- package/dist/v2/types/index.d.ts.map +1 -0
- package/dist/v2/types/index.js +6 -0
- package/dist/v2/utils/create-telemetry-options.d.ts +28 -0
- package/dist/v2/utils/create-telemetry-options.d.ts.map +1 -0
- package/dist/v2/utils/env.d.ts +60 -0
- package/dist/v2/utils/env.d.ts.map +1 -0
- package/dist/v2/utils/index.d.ts +3 -0
- package/dist/v2/utils/index.d.ts.map +1 -0
- package/dist/v2/utils/logger.d.ts +16 -0
- package/dist/v2/utils/logger.d.ts.map +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +106 -15
- package/readme.json +30 -0
- package/rslib.config.ts +13 -14
- package/src/__tests__/server.test.ts +1 -1
- package/src/contracts/consent/post.contract.test.ts +3 -8
- package/src/contracts/consent/post.contract.ts +13 -13
- package/src/contracts/consent/show-banner.contract.test.ts +9 -0
- package/src/contracts/consent/show-banner.contract.ts +2 -0
- package/src/contracts/consent/verify.contract.ts +19 -23
- package/src/core.ts +7 -0
- package/src/handlers/consent/show-banner/handler.ts +12 -9
- package/src/handlers/consent/show-banner/translations.ts +2 -2
- package/src/init.ts +9 -6
- package/src/middleware/openapi/index.ts +2 -2
- package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +1 -1
- package/src/pkgs/data-model/fields/index.ts +17 -22
- package/src/pkgs/data-model/fields/zod-fields.ts +14 -26
- package/src/pkgs/data-model/hooks/index.ts +3 -2
- package/src/pkgs/data-model/index.ts +2 -4
- package/src/pkgs/data-model/schema/index.ts +6 -7
- package/src/pkgs/data-model/schema/schemas.ts +3 -3
- package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +4 -1
- package/src/pkgs/db-adapters/adapters/index.ts +2 -2
- package/src/pkgs/db-adapters/adapters/kysely-adapter/index.ts +4 -4
- package/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts +4 -5
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +2 -4
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +2 -3
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +1 -6
- package/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts +4 -1
- package/src/pkgs/db-adapters/adapters/prisma-adapter/index.ts +1 -1
- package/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts +5 -2
- package/src/pkgs/db-adapters/index.ts +12 -13
- package/src/pkgs/migrations/get-migration.ts +4 -2
- package/src/pkgs/migrations/get-schema/get-schema.ts +0 -1
- package/src/pkgs/migrations/get-schema/process-fields.ts +1 -1
- package/src/pkgs/migrations/get-schema/process-tables.ts +0 -2
- package/src/pkgs/migrations/index.ts +7 -8
- package/src/pkgs/results/__tests__/error-codes.test.ts +2 -2
- package/src/pkgs/results/index.ts +22 -27
- package/src/pkgs/results/orpc-error-handler.ts +1 -1
- package/src/pkgs/results/results/result-helpers.ts +1 -1
- package/src/pkgs/types/index.ts +4 -4
- package/src/pkgs/types/options.ts +10 -3
- package/src/pkgs/utils/index.ts +1 -1
- package/src/pkgs/utils/logger.ts +1 -1
- package/src/schema/audit-log/schema.ts +3 -3
- package/src/schema/consent/schema.ts +4 -4
- package/src/schema/consent-policy/schema.ts +3 -3
- package/src/schema/consent-purpose/schema.ts +4 -4
- package/src/schema/consent-record/schema.ts +3 -3
- package/src/schema/definition.ts +1 -1
- package/src/schema/domain/schema.ts +5 -5
- package/src/schema/index.ts +14 -17
- package/src/schema/subject/schema.ts +3 -3
- package/src/schema/types.ts +1 -1
- package/src/testing/contract-testing.ts +15 -52
- package/src/types/index.ts +8 -8
- package/src/types/options.ts +2 -3
- package/src/v2/contracts/consent/index.test.ts +5 -0
- package/src/v2/contracts/consent/index.ts +9 -0
- package/src/v2/contracts/consent/post.contract.test.ts +521 -0
- package/src/v2/contracts/consent/post.contract.ts +155 -0
- package/src/v2/contracts/consent/show-banner.contract.test.ts +252 -0
- package/src/v2/contracts/consent/show-banner.contract.ts +73 -0
- package/src/v2/contracts/consent/verify.contract.test.ts +185 -0
- package/src/v2/contracts/consent/verify.contract.ts +122 -0
- package/src/v2/contracts/index.ts +20 -0
- package/src/v2/contracts/meta/index.test.ts +5 -0
- package/src/v2/contracts/meta/index.ts +5 -0
- package/src/v2/contracts/meta/status.contract.test.ts +226 -0
- package/src/v2/contracts/meta/status.contract.ts +34 -0
- package/src/v2/contracts/shared/jurisdiction.schema.ts +30 -0
- package/src/v2/contracts/test.utils.ts +400 -0
- package/src/v2/core.ts +379 -0
- package/src/v2/db/adapters/drizzle.ts +1 -0
- package/src/v2/db/adapters/index.ts +1 -0
- package/src/v2/db/adapters/kysely.ts +1 -0
- package/src/v2/db/adapters/mongo.ts +1 -0
- package/src/v2/db/adapters/prisma.ts +1 -0
- package/src/v2/db/adapters/typeorm.ts +1 -0
- package/src/v2/db/migrator/index.ts +80 -0
- package/src/v2/db/registry/audit-log.test.ts +77 -0
- package/src/v2/db/registry/audit-log.ts +46 -0
- package/src/v2/db/registry/consent-policy.test.ts +778 -0
- package/src/v2/db/registry/consent-policy.ts +74 -0
- package/src/v2/db/registry/consent-purpose.test.ts +485 -0
- package/src/v2/db/registry/consent-purpose.ts +41 -0
- package/src/v2/db/registry/consent.test.ts +843 -0
- package/src/v2/db/registry/consent.ts +42 -0
- package/src/v2/db/registry/domain.test.ts +463 -0
- package/src/v2/db/registry/domain.ts +51 -0
- package/src/v2/db/registry/index.ts +18 -0
- package/src/v2/db/registry/subject.test.ts +497 -0
- package/src/v2/db/registry/subject.ts +101 -0
- package/src/v2/db/registry/types.ts +10 -0
- package/src/v2/db/registry/utils/generate-id.test.ts +217 -0
- package/src/v2/db/registry/utils/generate-id.ts +134 -0
- package/src/v2/db/registry/utils.ts +134 -0
- package/src/v2/db/schema/1.0.0/audit-log.ts +32 -0
- package/src/v2/db/schema/1.0.0/consent-policy.ts +41 -0
- package/src/v2/db/schema/1.0.0/consent-purpose.ts +30 -0
- package/src/v2/db/schema/1.0.0/consent-record.ts +22 -0
- package/src/v2/db/schema/1.0.0/consent.ts +38 -0
- package/src/v2/db/schema/1.0.0/domain.ts +26 -0
- package/src/v2/db/schema/1.0.0/index.ts +56 -0
- package/src/v2/db/schema/1.0.0/subject.ts +26 -0
- package/src/v2/db/schema/index.ts +9 -0
- package/src/v2/define-config.ts +5 -0
- package/src/v2/handlers/consent/index.ts +9 -0
- package/src/v2/handlers/consent/post.handler.ts +254 -0
- package/src/v2/handlers/consent/show-banner/geo.test.ts +281 -0
- package/src/v2/handlers/consent/show-banner/geo.ts +96 -0
- package/src/v2/handlers/consent/show-banner/handler.test.ts +374 -0
- package/src/v2/handlers/consent/show-banner/handler.ts +123 -0
- package/src/v2/handlers/consent/show-banner/translations.test.ts +121 -0
- package/src/v2/handlers/consent/show-banner/translations.ts +79 -0
- package/src/v2/handlers/consent/verify.handler.ts +288 -0
- package/src/v2/handlers/meta/index.ts +5 -0
- package/src/v2/handlers/meta/status.handler.ts +43 -0
- package/src/v2/init.test.ts +114 -0
- package/src/v2/init.ts +126 -0
- package/src/v2/middleware/cors/cors.test.ts +111 -0
- package/src/v2/middleware/cors/cors.ts +192 -0
- package/src/v2/middleware/cors/index.ts +30 -0
- package/src/v2/middleware/cors/is-origin-trusted.test.ts +104 -0
- package/src/v2/middleware/cors/is-origin-trusted.ts +126 -0
- package/src/v2/middleware/cors/process-cors.ts +91 -0
- package/src/v2/middleware/openapi/config.ts +27 -0
- package/src/v2/middleware/openapi/handlers.ts +132 -0
- package/src/v2/middleware/openapi/index.ts +11 -0
- package/src/v2/middleware/process-ip/index.ts +39 -0
- package/src/v2/router.ts +8 -0
- package/src/v2/types/api.ts +32 -0
- package/src/v2/types/index.ts +121 -0
- package/src/v2/utils/create-telemetry-options.ts +115 -0
- package/src/v2/utils/env.ts +84 -0
- package/src/v2/utils/index.ts +2 -0
- package/src/v2/utils/logger.ts +38 -0
- package/src/version.ts +1 -1
- package/vitest.config.ts +11 -2
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { createContractTests } from '~/v2/contracts/test.utils';
|
|
4
|
+
import { statusContract } from './status.contract';
|
|
5
|
+
|
|
6
|
+
// Create base tests for the contract using the utility
|
|
7
|
+
const tester = createContractTests('Status', statusContract);
|
|
8
|
+
|
|
9
|
+
// Add custom tests specific to the status contract
|
|
10
|
+
describe('Status Contract Custom Tests', () => {
|
|
11
|
+
// Helper to access schemas consistently throughout tests
|
|
12
|
+
const schemas = {
|
|
13
|
+
input: statusContract['~orpc'].inputSchema,
|
|
14
|
+
output: statusContract['~orpc'].outputSchema,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Helper functions for common test patterns
|
|
18
|
+
const validateInput = (input: unknown) => {
|
|
19
|
+
//@ts-expect-error
|
|
20
|
+
return schemas.input?.safeParse(input);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const validateOutput = (output: unknown) => {
|
|
24
|
+
return schemas.output?.safeParse(output);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
describe('Schema Structure', () => {
|
|
28
|
+
it('input schema is an undefined', () => {
|
|
29
|
+
const result = validateInput(undefined);
|
|
30
|
+
expect(result?.success).toBe(undefined);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('rejects input with extra properties', () => {
|
|
34
|
+
const result = validateInput({ extraProp: 'value' });
|
|
35
|
+
expect(result?.success).toBe(undefined);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('Output Validation', () => {
|
|
40
|
+
describe('Required fields', () => {
|
|
41
|
+
it('validates complete output object', () => {
|
|
42
|
+
const validOutput = {
|
|
43
|
+
status: 'ok',
|
|
44
|
+
version: '1.0.0',
|
|
45
|
+
timestamp: new Date(),
|
|
46
|
+
client: {
|
|
47
|
+
ip: '127.0.0.1',
|
|
48
|
+
userAgent: 'Mozilla/5.0',
|
|
49
|
+
region: {
|
|
50
|
+
countryCode: 'US',
|
|
51
|
+
regionCode: 'CA',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const result = validateOutput(validOutput);
|
|
57
|
+
expect(result?.success).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('rejects output without required fields', () => {
|
|
61
|
+
const invalidOutput = {
|
|
62
|
+
status: 'ok',
|
|
63
|
+
// Missing version, timestamp, and client
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const result = validateOutput(invalidOutput);
|
|
67
|
+
expect(result?.success).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('Status field validation', () => {
|
|
72
|
+
it('accepts valid status values', () => {
|
|
73
|
+
for (const statusValue of ['ok', 'error']) {
|
|
74
|
+
const output = {
|
|
75
|
+
status: statusValue,
|
|
76
|
+
version: '1.0.0',
|
|
77
|
+
timestamp: new Date(),
|
|
78
|
+
client: {
|
|
79
|
+
ip: '127.0.0.1',
|
|
80
|
+
userAgent: 'Mozilla/5.0',
|
|
81
|
+
region: {
|
|
82
|
+
countryCode: 'US',
|
|
83
|
+
regionCode: 'CA',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
const result = validateOutput(output);
|
|
88
|
+
expect(result?.success).toBe(true);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('rejects invalid status values', () => {
|
|
93
|
+
const output = {
|
|
94
|
+
status: 'unknown', // Invalid status
|
|
95
|
+
version: '1.0.0',
|
|
96
|
+
timestamp: new Date(),
|
|
97
|
+
client: {
|
|
98
|
+
ip: '127.0.0.1',
|
|
99
|
+
userAgent: 'Mozilla/5.0',
|
|
100
|
+
region: {
|
|
101
|
+
countryCode: 'US',
|
|
102
|
+
regionCode: 'CA',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
// Need to use type assertion to bypass TypeScript
|
|
107
|
+
const result = validateOutput(output);
|
|
108
|
+
expect(result?.success).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('Timestamp validation', () => {
|
|
113
|
+
it('accepts Date objects', () => {
|
|
114
|
+
const output = {
|
|
115
|
+
status: 'ok',
|
|
116
|
+
version: '1.0.0',
|
|
117
|
+
timestamp: new Date(),
|
|
118
|
+
client: {
|
|
119
|
+
ip: '127.0.0.1',
|
|
120
|
+
userAgent: 'Mozilla/5.0',
|
|
121
|
+
region: {
|
|
122
|
+
countryCode: 'US',
|
|
123
|
+
regionCode: 'CA',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const result = validateOutput(output);
|
|
128
|
+
expect(result?.success).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('rejects string timestamps', () => {
|
|
132
|
+
const output = {
|
|
133
|
+
status: 'ok',
|
|
134
|
+
version: '1.0.0',
|
|
135
|
+
timestamp: new Date().toISOString(), // String instead of Date
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Need to use type assertion to bypass TypeScript
|
|
139
|
+
const result = validateOutput(output);
|
|
140
|
+
expect(result?.success).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('Client information validation', () => {
|
|
145
|
+
it('accepts null values for client fields', () => {
|
|
146
|
+
const output = {
|
|
147
|
+
status: 'ok',
|
|
148
|
+
version: '1.0.0',
|
|
149
|
+
timestamp: new Date(),
|
|
150
|
+
client: {
|
|
151
|
+
ip: null,
|
|
152
|
+
userAgent: null,
|
|
153
|
+
region: {
|
|
154
|
+
countryCode: null,
|
|
155
|
+
regionCode: null,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const result = validateOutput(output);
|
|
161
|
+
expect(result?.success).toBe(true);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('validates client object structure', () => {
|
|
165
|
+
const output = {
|
|
166
|
+
status: 'ok',
|
|
167
|
+
version: '1.0.0',
|
|
168
|
+
timestamp: new Date(),
|
|
169
|
+
client: {
|
|
170
|
+
ip: '127.0.0.1',
|
|
171
|
+
userAgent: 'Mozilla/5.0',
|
|
172
|
+
region: {
|
|
173
|
+
countryCode: 'US',
|
|
174
|
+
regionCode: 'CA',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const result = validateOutput(output);
|
|
180
|
+
expect(result?.success).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('rejects invalid client IP format', () => {
|
|
184
|
+
const output = {
|
|
185
|
+
status: 'ok',
|
|
186
|
+
version: '1.0.0',
|
|
187
|
+
timestamp: new Date(),
|
|
188
|
+
client: {
|
|
189
|
+
ip: 123, // Number instead of string
|
|
190
|
+
userAgent: 'Mozilla/5.0',
|
|
191
|
+
region: {
|
|
192
|
+
countryCode: 'US',
|
|
193
|
+
regionCode: 'CA',
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const result = validateOutput(output);
|
|
199
|
+
expect(result?.success).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('rejects invalid region structure', () => {
|
|
203
|
+
const output = {
|
|
204
|
+
status: 'ok',
|
|
205
|
+
version: '1.0.0',
|
|
206
|
+
timestamp: new Date(),
|
|
207
|
+
client: {
|
|
208
|
+
ip: '127.0.0.1',
|
|
209
|
+
userAgent: 'Mozilla/5.0',
|
|
210
|
+
region: {
|
|
211
|
+
countryCode: 123, // Number instead of string
|
|
212
|
+
regionCode: 'CA',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const result = validateOutput(output);
|
|
218
|
+
expect(result?.success).toBe(false);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Add required fields testing using the utility
|
|
225
|
+
// No required fields for input since it's an empty object
|
|
226
|
+
tester.testRequiredFields('output', ['status', 'version', 'timestamp']);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { oc } from '@orpc/contract';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const statusContract = oc
|
|
5
|
+
.route({
|
|
6
|
+
method: 'GET',
|
|
7
|
+
path: '/status',
|
|
8
|
+
description: `Returns the current operational status and health metrics of the service.
|
|
9
|
+
This endpoint provides real-time information about:
|
|
10
|
+
- Overall service status (ok/error)
|
|
11
|
+
- Current API version
|
|
12
|
+
- Server timestamp
|
|
13
|
+
- Storage system status and availability
|
|
14
|
+
- Client information (IP, User Agent, Region)
|
|
15
|
+
|
|
16
|
+
Use this endpoint for health checks, monitoring, and service status verification.`,
|
|
17
|
+
tags: ['meta'],
|
|
18
|
+
})
|
|
19
|
+
.output(
|
|
20
|
+
z.object({
|
|
21
|
+
status: z.enum(['ok', 'error']),
|
|
22
|
+
version: z.string(),
|
|
23
|
+
timestamp: z.date(),
|
|
24
|
+
|
|
25
|
+
client: z.object({
|
|
26
|
+
ip: z.string().nullable(),
|
|
27
|
+
userAgent: z.string().nullable(),
|
|
28
|
+
region: z.object({
|
|
29
|
+
countryCode: z.string().nullable(),
|
|
30
|
+
regionCode: z.string().nullable(),
|
|
31
|
+
}),
|
|
32
|
+
}),
|
|
33
|
+
})
|
|
34
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
export const JurisdictionMessages = {
|
|
4
|
+
GDPR: 'GDPR or equivalent regulations require a cookie banner.',
|
|
5
|
+
CH: 'Switzerland requires similar data protection measures.',
|
|
6
|
+
BR: "Brazil's LGPD requires consent for cookies.",
|
|
7
|
+
PIPEDA: 'PIPEDA requires consent for data collection.',
|
|
8
|
+
AU: "Australia's Privacy Act mandates transparency about data collection.",
|
|
9
|
+
APPI: "Japan's APPI requires consent for data collection.",
|
|
10
|
+
PIPA: "South Korea's PIPA requires consent for data collection.",
|
|
11
|
+
NONE: 'No specific requirements',
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export type JurisdictionCode = keyof typeof JurisdictionMessages;
|
|
15
|
+
|
|
16
|
+
export const JurisdictionCodeSchema = z.enum([
|
|
17
|
+
'GDPR',
|
|
18
|
+
'CH',
|
|
19
|
+
'BR',
|
|
20
|
+
'PIPEDA',
|
|
21
|
+
'AU',
|
|
22
|
+
'APPI',
|
|
23
|
+
'PIPA',
|
|
24
|
+
'NONE',
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
export const JurisdictionInfoSchema = z.object({
|
|
28
|
+
code: JurisdictionCodeSchema,
|
|
29
|
+
message: z.string(),
|
|
30
|
+
});
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import type { Schema as ORPCSchema } from '@orpc/contract';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import type { ZodIssue, z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Contract test utilities for creating reusable test patterns
|
|
7
|
+
* across multiple contracts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
type SafeParseResult = ReturnType<z.ZodTypeAny['safeParse']>;
|
|
11
|
+
|
|
12
|
+
type ContractTestHelpers = {
|
|
13
|
+
validateInput?: (input: unknown) => SafeParseResult | undefined;
|
|
14
|
+
validateOutput: (output: unknown) => SafeParseResult | undefined;
|
|
15
|
+
testInput: (testName: string, input: unknown, shouldBeValid: boolean) => void;
|
|
16
|
+
testOutput: (
|
|
17
|
+
testName: string,
|
|
18
|
+
output: unknown,
|
|
19
|
+
shouldBeValid: boolean
|
|
20
|
+
) => void;
|
|
21
|
+
testDiscriminatedUnion: (
|
|
22
|
+
discriminator: string,
|
|
23
|
+
validValues: string[]
|
|
24
|
+
) => void;
|
|
25
|
+
testRequiredFields: (schema: 'input' | 'output', fields: string[]) => void;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type ContractSchema = z.ZodType | ORPCSchema<unknown, unknown>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a test suite for basic contract validation
|
|
32
|
+
* @param contractName Display name for the contract
|
|
33
|
+
* @param contract The contract to test
|
|
34
|
+
*/
|
|
35
|
+
export function createContractTests(
|
|
36
|
+
contractName: string,
|
|
37
|
+
contract: {
|
|
38
|
+
'~orpc'?: { inputSchema?: ContractSchema; outputSchema?: ContractSchema };
|
|
39
|
+
}
|
|
40
|
+
): ContractTestHelpers {
|
|
41
|
+
const schemas = {
|
|
42
|
+
input: contract['~orpc']?.inputSchema,
|
|
43
|
+
output: contract['~orpc']?.outputSchema,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Helper functions
|
|
47
|
+
const validateInput = (input: unknown): SafeParseResult | undefined => {
|
|
48
|
+
const schema = schemas.input;
|
|
49
|
+
if (!schema) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Handle both Zod and oRPC schemas
|
|
54
|
+
if ('safeParse' in schema) {
|
|
55
|
+
return schema.safeParse(input);
|
|
56
|
+
}
|
|
57
|
+
// For oRPC schemas, we'll need to implement validation
|
|
58
|
+
// This is a placeholder - you may need to implement actual validation
|
|
59
|
+
return { success: true, data: input } as SafeParseResult;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const validateOutput = (output: unknown): SafeParseResult | undefined => {
|
|
63
|
+
const schema = schemas.output;
|
|
64
|
+
if (!schema) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Handle both Zod and oRPC schemas
|
|
69
|
+
if ('safeParse' in schema) {
|
|
70
|
+
return schema.safeParse(output);
|
|
71
|
+
}
|
|
72
|
+
// For oRPC schemas, we'll need to implement validation
|
|
73
|
+
// This is a placeholder - you may need to implement actual validation
|
|
74
|
+
return { success: true, data: output } as SafeParseResult;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Create base test suite
|
|
78
|
+
describe(`${contractName} Contract`, () => {
|
|
79
|
+
describe('Schema Structure', () => {
|
|
80
|
+
it('has properly defined schemas', () => {
|
|
81
|
+
// Only require output schema
|
|
82
|
+
expect(schemas.output).toBeDefined();
|
|
83
|
+
|
|
84
|
+
// Input schema is optional
|
|
85
|
+
if (schemas.input) {
|
|
86
|
+
expect(schemas.input).toBeDefined();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('schemas are serializable', () => {
|
|
91
|
+
// Test serialization for output schema
|
|
92
|
+
if (schemas.output) {
|
|
93
|
+
const serialized = JSON.stringify(schemas.output);
|
|
94
|
+
expect(serialized).toBeDefined();
|
|
95
|
+
expect(typeof serialized).toBe('string');
|
|
96
|
+
expect(() => JSON.parse(serialized)).not.toThrow();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Test serialization for input schema if it exists
|
|
100
|
+
if (schemas.input) {
|
|
101
|
+
const serialized = JSON.stringify(schemas.input);
|
|
102
|
+
expect(serialized).toBeDefined();
|
|
103
|
+
expect(typeof serialized).toBe('string');
|
|
104
|
+
expect(() => JSON.parse(serialized)).not.toThrow();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Define test helpers
|
|
111
|
+
const testInput = (
|
|
112
|
+
testName: string,
|
|
113
|
+
input: unknown,
|
|
114
|
+
shouldBeValid: boolean
|
|
115
|
+
) => {
|
|
116
|
+
it(`${testName}`, () => {
|
|
117
|
+
const result = validateInput(input);
|
|
118
|
+
if (!result) {
|
|
119
|
+
throw new Error('Validation result is undefined');
|
|
120
|
+
}
|
|
121
|
+
expect(result.success).toBe(shouldBeValid);
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const testOutput = (
|
|
126
|
+
testName: string,
|
|
127
|
+
output: unknown,
|
|
128
|
+
shouldBeValid: boolean
|
|
129
|
+
) => {
|
|
130
|
+
it(`${testName}`, () => {
|
|
131
|
+
const result = validateOutput(output);
|
|
132
|
+
if (!result) {
|
|
133
|
+
throw new Error('Validation result is undefined');
|
|
134
|
+
}
|
|
135
|
+
expect(result.success).toBe(shouldBeValid);
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const testDiscriminatedUnion = (
|
|
140
|
+
discriminator: string,
|
|
141
|
+
validValues: string[]
|
|
142
|
+
) => {
|
|
143
|
+
describe('Discriminated Union validation', () => {
|
|
144
|
+
it(`requires '${discriminator}' discriminator`, () => {
|
|
145
|
+
if (!schemas.input) return;
|
|
146
|
+
const result = validateInput({});
|
|
147
|
+
expect(result?.success).toBe(false);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('validates all defined discriminator values', () => {
|
|
151
|
+
if (!schemas.input) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
for (const value of validValues) {
|
|
155
|
+
const input = {
|
|
156
|
+
[discriminator]: value,
|
|
157
|
+
// Add minimum required fields based on your contract
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// This test assumes minimal input - you may need to add required fields
|
|
161
|
+
// based on the specific contract being tested
|
|
162
|
+
const result = validateInput(input);
|
|
163
|
+
// Specifically assert that it fails due to missing required fields
|
|
164
|
+
expect(result?.success).toBe(false);
|
|
165
|
+
// We no longer assert on internal issue codes; presence of failure is enough
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const testRequiredFields = (schema: 'input' | 'output', fields: string[]) => {
|
|
172
|
+
describe(`Required ${schema} fields`, () => {
|
|
173
|
+
// Skip if testing input fields but no input schema exists
|
|
174
|
+
if (schema === 'input' && !schemas.input) {
|
|
175
|
+
it('skips input field tests as no input schema exists', () => {
|
|
176
|
+
expect(true).toBe(true);
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Create a sample of valid data to test against
|
|
182
|
+
let sampleValid: Record<string, unknown>;
|
|
183
|
+
|
|
184
|
+
if (schema === 'input') {
|
|
185
|
+
// For input schema, we need a valid input based on the contract type
|
|
186
|
+
sampleValid = {
|
|
187
|
+
type: 'marketing_communications', // A common type that most contracts would have
|
|
188
|
+
domain: 'example.com',
|
|
189
|
+
// Add other fields that might be required by your contracts
|
|
190
|
+
subjectId: 'test-123',
|
|
191
|
+
metadata: {},
|
|
192
|
+
};
|
|
193
|
+
} else {
|
|
194
|
+
// For output schema, create a generic valid output
|
|
195
|
+
sampleValid = {
|
|
196
|
+
id: 'test-123',
|
|
197
|
+
domainId: 'domain-123',
|
|
198
|
+
domain: 'example.com',
|
|
199
|
+
type: 'marketing_communications',
|
|
200
|
+
status: 'granted',
|
|
201
|
+
recordId: 'record-123',
|
|
202
|
+
givenAt: new Date().toISOString(),
|
|
203
|
+
metadata: {},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
for (const field of fields) {
|
|
208
|
+
it(`requires '${field}' field`, () => {
|
|
209
|
+
// Create a copy of the valid data without the tested field
|
|
210
|
+
const invalidData = { ...sampleValid };
|
|
211
|
+
delete invalidData[field];
|
|
212
|
+
|
|
213
|
+
const validator = schema === 'input' ? validateInput : validateOutput;
|
|
214
|
+
const result = validator(invalidData);
|
|
215
|
+
|
|
216
|
+
if (!result) {
|
|
217
|
+
throw new Error('Validation result is undefined');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
expect(result.success).toBe(false);
|
|
221
|
+
if (!result.success) {
|
|
222
|
+
expect(
|
|
223
|
+
result.error.issues.some(
|
|
224
|
+
(issue: ZodIssue) =>
|
|
225
|
+
issue.path.some((p) => String(p).includes(field)) ||
|
|
226
|
+
issue.message.includes('required')
|
|
227
|
+
)
|
|
228
|
+
).toBe(true);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// Return the test helpers for re-use
|
|
236
|
+
return {
|
|
237
|
+
validateInput,
|
|
238
|
+
validateOutput,
|
|
239
|
+
testInput,
|
|
240
|
+
testOutput,
|
|
241
|
+
testDiscriminatedUnion,
|
|
242
|
+
testRequiredFields,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Creates consistency tests for multiple related contracts
|
|
248
|
+
*/
|
|
249
|
+
export function createConsistencyTests(
|
|
250
|
+
contracts: Record<
|
|
251
|
+
string,
|
|
252
|
+
{
|
|
253
|
+
'~orpc'?: {
|
|
254
|
+
inputSchema?: ContractSchema;
|
|
255
|
+
outputSchema?: ContractSchema;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
>
|
|
259
|
+
) {
|
|
260
|
+
describe('Contract Consistency', () => {
|
|
261
|
+
it('all contracts have output schemas', () => {
|
|
262
|
+
for (const [_name, contract] of Object.entries(contracts)) {
|
|
263
|
+
expect(contract['~orpc']?.outputSchema).toBeDefined();
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Field type consistency - ensure common fields use same types across contracts
|
|
268
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: excessive cognitive complexity is acceptable here
|
|
269
|
+
it('common fields have consistent types across contracts', () => {
|
|
270
|
+
const commonFields = ['id', 'domainId', 'type', 'status'];
|
|
271
|
+
const contractEntries = Object.entries(contracts);
|
|
272
|
+
|
|
273
|
+
for (const field of commonFields) {
|
|
274
|
+
const fieldTypes = new Set();
|
|
275
|
+
|
|
276
|
+
for (const [_name, contract] of contractEntries) {
|
|
277
|
+
const schema = contract['~orpc']?.outputSchema;
|
|
278
|
+
if (!schema || !('shape' in schema)) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const shape = schema.shape as Record<string, z.ZodTypeAny>;
|
|
283
|
+
if (field in shape) {
|
|
284
|
+
const fieldDef = shape[field];
|
|
285
|
+
if (fieldDef) {
|
|
286
|
+
fieldTypes.add(fieldDef.constructor.name);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// If the field exists in multiple contracts, they should all use the same type
|
|
292
|
+
if (fieldTypes.size > 0) {
|
|
293
|
+
expect(
|
|
294
|
+
fieldTypes.size,
|
|
295
|
+
`Field '${field}' has inconsistent types across contracts`
|
|
296
|
+
).toBe(1);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Validate enum value consistency across contracts
|
|
302
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: excessive cognitive complexity is acceptable here
|
|
303
|
+
it('enum values are consistent across contracts', () => {
|
|
304
|
+
// Example: status field should have the same allowed values in all contracts
|
|
305
|
+
const statusValues = new Map<string, string[]>();
|
|
306
|
+
|
|
307
|
+
for (const [name, contract] of Object.entries(contracts)) {
|
|
308
|
+
const schema = contract['~orpc']?.outputSchema;
|
|
309
|
+
if (!schema || !('shape' in schema)) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const shape = schema.shape as Record<string, z.ZodTypeAny>;
|
|
314
|
+
if (!shape.status) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const statusField = shape.status;
|
|
319
|
+
if ('_def' in statusField && 'values' in statusField._def) {
|
|
320
|
+
statusValues.set(name, statusField._def.values as string[]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// All status enums should have the same values
|
|
325
|
+
const allValues = Array.from(statusValues.values());
|
|
326
|
+
if (allValues.length > 1) {
|
|
327
|
+
for (let i = 1; i < allValues.length; i++) {
|
|
328
|
+
expect(allValues[i]).toEqual(allValues[0]);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Validation rule consistency for common fields
|
|
334
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: excessive cognitive complexity is acceptable here
|
|
335
|
+
it('validation rules for common fields are consistent', () => {
|
|
336
|
+
const contractEntries = Object.entries(contracts);
|
|
337
|
+
const commonStringFields = ['domain', 'subjectId', 'externalSubjectId'];
|
|
338
|
+
|
|
339
|
+
for (const field of commonStringFields) {
|
|
340
|
+
const minLengths = new Set();
|
|
341
|
+
const maxLengths = new Set();
|
|
342
|
+
|
|
343
|
+
for (const [_name, contract] of contractEntries) {
|
|
344
|
+
const schema = contract['~orpc']?.inputSchema;
|
|
345
|
+
if (!schema || !('shape' in schema)) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const shape = schema.shape as Record<string, z.ZodTypeAny>;
|
|
350
|
+
if (!shape[field]) {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const _fieldSchema = shape[field];
|
|
355
|
+
// Skip introspecting Zod internals in v4; cannot reliably extract checks
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// All contracts should use the same min/max for common string fields
|
|
359
|
+
expect(
|
|
360
|
+
minLengths.size,
|
|
361
|
+
`Inconsistent min length for field '${field}'`
|
|
362
|
+
).toBeLessThanOrEqual(1);
|
|
363
|
+
expect(
|
|
364
|
+
maxLengths.size,
|
|
365
|
+
`Inconsistent max length for field '${field}'`
|
|
366
|
+
).toBeLessThanOrEqual(1);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Discriminated union consistency
|
|
371
|
+
it('discriminated unions use consistent discriminator across contracts', () => {
|
|
372
|
+
const discriminators = new Set();
|
|
373
|
+
|
|
374
|
+
for (const [_name, contract] of Object.entries(contracts)) {
|
|
375
|
+
const schema = contract['~orpc']?.inputSchema;
|
|
376
|
+
if (!schema || !('_def' in schema)) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Check if schema is a discriminated union
|
|
381
|
+
if (
|
|
382
|
+
'typeName' in schema._def &&
|
|
383
|
+
schema._def.typeName === 'ZodDiscriminatedUnion' &&
|
|
384
|
+
'discriminator' in schema._def
|
|
385
|
+
) {
|
|
386
|
+
// Safe assertion since we've checked the property exists
|
|
387
|
+
discriminators.add(
|
|
388
|
+
(schema._def as { discriminator: string }).discriminator
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// All contracts should use the same discriminator (e.g., 'type')
|
|
394
|
+
expect(
|
|
395
|
+
discriminators.size,
|
|
396
|
+
'Inconsistent discriminator fields used across contracts'
|
|
397
|
+
).toBeLessThanOrEqual(1);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
}
|