@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.
Files changed (489) hide show
  1. package/.turbo/turbo-build.log +63 -37
  2. package/CHANGELOG.md +4 -209
  3. package/README.md +86 -164
  4. package/dist/contracts/consent/index.d.ts +103 -615
  5. package/dist/contracts/consent/index.d.ts.map +1 -1
  6. package/dist/contracts/consent/post.contract.d.ts +42 -140
  7. package/dist/contracts/consent/post.contract.d.ts.map +1 -1
  8. package/dist/contracts/consent/show-banner.contract.d.ts +28 -376
  9. package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -1
  10. package/dist/contracts/consent/verify.contract.d.ts +33 -99
  11. package/dist/contracts/consent/verify.contract.d.ts.map +1 -1
  12. package/dist/contracts/index.d.ts +222 -1356
  13. package/dist/contracts/index.d.ts.map +1 -1
  14. package/dist/contracts/meta/index.d.ts +8 -63
  15. package/dist/contracts/meta/index.d.ts.map +1 -1
  16. package/dist/contracts/meta/status.contract.d.ts +8 -63
  17. package/dist/contracts/meta/status.contract.d.ts.map +1 -1
  18. package/dist/contracts/shared/jurisdiction.schema.d.ts +21 -9
  19. package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -1
  20. package/dist/contracts.cjs +100 -106
  21. package/dist/contracts.js +100 -106
  22. package/dist/core.cjs +681 -681
  23. package/dist/core.d.ts +118 -678
  24. package/dist/core.d.ts.map +1 -1
  25. package/dist/core.js +634 -637
  26. package/dist/handlers/consent/index.d.ts +103 -615
  27. package/dist/handlers/consent/index.d.ts.map +1 -1
  28. package/dist/handlers/consent/post.handler.d.ts +42 -140
  29. package/dist/handlers/consent/post.handler.d.ts.map +1 -1
  30. package/dist/handlers/consent/show-banner/handler.d.ts +28 -376
  31. package/dist/handlers/consent/show-banner/handler.d.ts.map +1 -1
  32. package/dist/handlers/consent/show-banner/translations.d.ts.map +1 -1
  33. package/dist/handlers/consent/verify.handler.d.ts +33 -99
  34. package/dist/handlers/consent/verify.handler.d.ts.map +1 -1
  35. package/dist/handlers/meta/index.d.ts +8 -63
  36. package/dist/handlers/meta/index.d.ts.map +1 -1
  37. package/dist/handlers/meta/status.handler.d.ts +8 -63
  38. package/dist/handlers/meta/status.handler.d.ts.map +1 -1
  39. package/dist/init.d.ts.map +1 -1
  40. package/dist/middleware/openapi/index.d.ts +2 -2
  41. package/dist/middleware/openapi/index.d.ts.map +1 -1
  42. package/dist/pkgs/data-model/fields/index.cjs +14 -26
  43. package/dist/pkgs/data-model/fields/index.d.ts +4 -4
  44. package/dist/pkgs/data-model/fields/index.d.ts.map +1 -1
  45. package/dist/pkgs/data-model/fields/index.js +14 -26
  46. package/dist/pkgs/data-model/fields/zod-fields.d.ts +195 -871
  47. package/dist/pkgs/data-model/fields/zod-fields.d.ts.map +1 -1
  48. package/dist/pkgs/data-model/hooks/index.d.ts +2 -2
  49. package/dist/pkgs/data-model/hooks/index.d.ts.map +1 -1
  50. package/dist/pkgs/data-model/index.cjs +346 -358
  51. package/dist/pkgs/data-model/index.d.ts +1 -1
  52. package/dist/pkgs/data-model/index.d.ts.map +1 -1
  53. package/dist/pkgs/data-model/index.js +345 -357
  54. package/dist/pkgs/data-model/schema/index.cjs +346 -358
  55. package/dist/pkgs/data-model/schema/index.d.ts +1 -1
  56. package/dist/pkgs/data-model/schema/index.d.ts.map +1 -1
  57. package/dist/pkgs/data-model/schema/index.js +345 -357
  58. package/dist/pkgs/data-model/schema/schemas.d.ts +2 -2
  59. package/dist/pkgs/data-model/schema/schemas.d.ts.map +1 -1
  60. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +3 -0
  61. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts.map +1 -1
  62. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +158 -170
  63. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +157 -169
  64. package/dist/pkgs/db-adapters/adapters/index.d.ts +2 -2
  65. package/dist/pkgs/db-adapters/adapters/index.d.ts.map +1 -1
  66. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +215 -227
  67. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.d.ts +2 -2
  68. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.d.ts.map +1 -1
  69. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +213 -225
  70. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts +2 -0
  71. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts.map +1 -1
  72. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts +1 -1
  73. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
  74. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +158 -170
  75. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +157 -169
  76. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts +3 -0
  77. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts.map +1 -1
  78. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +243 -255
  79. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.d.ts +1 -1
  80. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.d.ts.map +1 -1
  81. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +241 -253
  82. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts +3 -0
  83. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -1
  84. package/dist/pkgs/db-adapters/index.cjs +714 -726
  85. package/dist/pkgs/db-adapters/index.d.ts +6 -6
  86. package/dist/pkgs/db-adapters/index.d.ts.map +1 -1
  87. package/dist/pkgs/db-adapters/index.js +708 -720
  88. package/dist/pkgs/migrations/get-migration.d.ts.map +1 -1
  89. package/dist/pkgs/migrations/get-schema/get-schema.d.ts.map +1 -1
  90. package/dist/pkgs/migrations/get-schema/process-tables.d.ts.map +1 -1
  91. package/dist/pkgs/migrations/index.cjs +236 -248
  92. package/dist/pkgs/migrations/index.d.ts +4 -4
  93. package/dist/pkgs/migrations/index.d.ts.map +1 -1
  94. package/dist/pkgs/migrations/index.js +235 -247
  95. package/dist/pkgs/results/index.cjs +67 -67
  96. package/dist/pkgs/results/index.d.ts +5 -5
  97. package/dist/pkgs/results/index.d.ts.map +1 -1
  98. package/dist/pkgs/results/index.js +67 -67
  99. package/dist/pkgs/results/orpc-error-handler.d.ts +1 -1
  100. package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -1
  101. package/dist/pkgs/types/index.d.ts +1 -2
  102. package/dist/pkgs/types/index.d.ts.map +1 -1
  103. package/dist/pkgs/types/options.d.ts +9 -2
  104. package/dist/pkgs/types/options.d.ts.map +1 -1
  105. package/dist/pkgs/utils/index.d.ts +1 -1
  106. package/dist/pkgs/utils/index.d.ts.map +1 -1
  107. package/dist/pkgs/utils/logger.d.ts +1 -1
  108. package/dist/pkgs/utils/logger.d.ts.map +1 -1
  109. package/dist/router.cjs +114 -117
  110. package/dist/router.d.ts +111 -678
  111. package/dist/router.d.ts.map +1 -1
  112. package/dist/router.js +114 -117
  113. package/dist/schema/audit-log/schema.d.ts +2 -24
  114. package/dist/schema/audit-log/schema.d.ts.map +1 -1
  115. package/dist/schema/audit-log/table.d.ts +2 -24
  116. package/dist/schema/audit-log/table.d.ts.map +1 -1
  117. package/dist/schema/consent/registry.d.ts +8 -8
  118. package/dist/schema/consent/schema.d.ts +9 -33
  119. package/dist/schema/consent/schema.d.ts.map +1 -1
  120. package/dist/schema/consent/table.d.ts +9 -33
  121. package/dist/schema/consent/table.d.ts.map +1 -1
  122. package/dist/schema/consent-policy/registry.d.ts +20 -20
  123. package/dist/schema/consent-policy/schema.d.ts +22 -30
  124. package/dist/schema/consent-policy/schema.d.ts.map +1 -1
  125. package/dist/schema/consent-policy/table.d.ts +13 -29
  126. package/dist/schema/consent-policy/table.d.ts.map +1 -1
  127. package/dist/schema/consent-purpose/registry.d.ts +6 -6
  128. package/dist/schema/consent-purpose/schema.d.ts +5 -27
  129. package/dist/schema/consent-purpose/schema.d.ts.map +1 -1
  130. package/dist/schema/consent-purpose/table.d.ts +5 -27
  131. package/dist/schema/consent-purpose/table.d.ts.map +1 -1
  132. package/dist/schema/consent-record/schema.d.ts +3 -19
  133. package/dist/schema/consent-record/schema.d.ts.map +1 -1
  134. package/dist/schema/consent-record/table.d.ts +3 -19
  135. package/dist/schema/consent-record/table.d.ts.map +1 -1
  136. package/dist/schema/create-registry.d.ts +58 -58
  137. package/dist/schema/definition.d.ts +42 -176
  138. package/dist/schema/definition.d.ts.map +1 -1
  139. package/dist/schema/domain/registry.d.ts +20 -20
  140. package/dist/schema/domain/schema.d.ts +6 -24
  141. package/dist/schema/domain/schema.d.ts.map +1 -1
  142. package/dist/schema/domain/table.d.ts +6 -24
  143. package/dist/schema/domain/table.d.ts.map +1 -1
  144. package/dist/schema/index.cjs +426 -438
  145. package/dist/schema/index.d.ts +12 -12
  146. package/dist/schema/index.d.ts.map +1 -1
  147. package/dist/schema/index.js +426 -438
  148. package/dist/schema/schemas.d.ts +42 -176
  149. package/dist/schema/schemas.d.ts.map +1 -1
  150. package/dist/schema/subject/registry.d.ts +4 -4
  151. package/dist/schema/subject/schema.d.ts +4 -20
  152. package/dist/schema/subject/schema.d.ts.map +1 -1
  153. package/dist/schema/subject/table.d.ts +4 -20
  154. package/dist/schema/subject/table.d.ts.map +1 -1
  155. package/dist/schema/types.d.ts +1 -1
  156. package/dist/schema/types.d.ts.map +1 -1
  157. package/dist/testing/contract-testing.d.ts +3 -2
  158. package/dist/testing/contract-testing.d.ts.map +1 -1
  159. package/dist/types/index.d.ts +5 -4
  160. package/dist/types/index.d.ts.map +1 -1
  161. package/dist/types/options.d.ts +2 -2
  162. package/dist/types/options.d.ts.map +1 -1
  163. package/dist/v2/contracts/consent/index.d.ts +260 -0
  164. package/dist/v2/contracts/consent/index.d.ts.map +1 -0
  165. package/dist/v2/contracts/consent/index.test.d.ts +2 -0
  166. package/dist/v2/contracts/consent/index.test.d.ts.map +1 -0
  167. package/dist/v2/contracts/consent/post.contract.d.ts +114 -0
  168. package/dist/v2/contracts/consent/post.contract.d.ts.map +1 -0
  169. package/dist/v2/contracts/consent/post.contract.test.d.ts +2 -0
  170. package/dist/v2/contracts/consent/post.contract.test.d.ts.map +1 -0
  171. package/dist/v2/contracts/consent/show-banner.contract.d.ts +68 -0
  172. package/dist/v2/contracts/consent/show-banner.contract.d.ts.map +1 -0
  173. package/dist/v2/contracts/consent/show-banner.contract.test.d.ts +2 -0
  174. package/dist/v2/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
  175. package/dist/v2/contracts/consent/verify.contract.d.ts +81 -0
  176. package/dist/v2/contracts/consent/verify.contract.d.ts.map +1 -0
  177. package/dist/v2/contracts/consent/verify.contract.test.d.ts +2 -0
  178. package/dist/v2/contracts/consent/verify.contract.test.d.ts.map +1 -0
  179. package/dist/v2/contracts/index.cjs +644 -0
  180. package/dist/v2/contracts/index.d.ts +563 -0
  181. package/dist/v2/contracts/index.d.ts.map +1 -0
  182. package/dist/v2/contracts/index.js +607 -0
  183. package/dist/v2/contracts/meta/index.d.ts +19 -0
  184. package/dist/v2/contracts/meta/index.d.ts.map +1 -0
  185. package/dist/v2/contracts/meta/index.test.d.ts +2 -0
  186. package/dist/v2/contracts/meta/index.test.d.ts.map +1 -0
  187. package/dist/v2/contracts/meta/status.contract.d.ts +18 -0
  188. package/dist/v2/contracts/meta/status.contract.d.ts.map +1 -0
  189. package/dist/v2/contracts/meta/status.contract.test.d.ts +2 -0
  190. package/dist/v2/contracts/meta/status.contract.test.d.ts.map +1 -0
  191. package/dist/v2/contracts/shared/jurisdiction.schema.d.ts +36 -0
  192. package/dist/v2/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
  193. package/dist/v2/contracts/test.utils.d.ts +38 -0
  194. package/dist/v2/contracts/test.utils.d.ts.map +1 -0
  195. package/dist/v2/core.cjs +2181 -0
  196. package/dist/v2/core.d.ts +364 -0
  197. package/dist/v2/core.d.ts.map +1 -0
  198. package/dist/v2/core.js +2130 -0
  199. package/dist/v2/db/adapters/drizzle.cjs +36 -0
  200. package/dist/v2/db/adapters/drizzle.d.ts +2 -0
  201. package/dist/v2/db/adapters/drizzle.d.ts.map +1 -0
  202. package/dist/v2/db/adapters/drizzle.js +3 -0
  203. package/dist/v2/db/adapters/index.cjs +18 -0
  204. package/dist/v2/db/adapters/index.d.ts +2 -0
  205. package/dist/v2/db/adapters/index.d.ts.map +1 -0
  206. package/dist/v2/db/adapters/index.js +0 -0
  207. package/dist/v2/db/adapters/kysely.cjs +36 -0
  208. package/dist/v2/db/adapters/kysely.d.ts +2 -0
  209. package/dist/v2/db/adapters/kysely.d.ts.map +1 -0
  210. package/dist/v2/db/adapters/kysely.js +3 -0
  211. package/dist/v2/db/adapters/mongo.cjs +36 -0
  212. package/dist/v2/db/adapters/mongo.d.ts +2 -0
  213. package/dist/v2/db/adapters/mongo.d.ts.map +1 -0
  214. package/dist/v2/db/adapters/mongo.js +3 -0
  215. package/dist/v2/db/adapters/prisma.cjs +36 -0
  216. package/dist/v2/db/adapters/prisma.d.ts +2 -0
  217. package/dist/v2/db/adapters/prisma.d.ts.map +1 -0
  218. package/dist/v2/db/adapters/prisma.js +3 -0
  219. package/dist/v2/db/adapters/typeorm.cjs +36 -0
  220. package/dist/v2/db/adapters/typeorm.d.ts +2 -0
  221. package/dist/v2/db/adapters/typeorm.d.ts.map +1 -0
  222. package/dist/v2/db/adapters/typeorm.js +3 -0
  223. package/dist/v2/db/migrator/index.cjs +61 -0
  224. package/dist/v2/db/migrator/index.d.ts +29 -0
  225. package/dist/v2/db/migrator/index.d.ts.map +1 -0
  226. package/dist/v2/db/migrator/index.js +27 -0
  227. package/dist/v2/db/registry/audit-log.d.ts +21 -0
  228. package/dist/v2/db/registry/audit-log.d.ts.map +1 -0
  229. package/dist/v2/db/registry/audit-log.test.d.ts +2 -0
  230. package/dist/v2/db/registry/audit-log.test.d.ts.map +1 -0
  231. package/dist/v2/db/registry/consent-policy.d.ts +29 -0
  232. package/dist/v2/db/registry/consent-policy.d.ts.map +1 -0
  233. package/dist/v2/db/registry/consent-policy.test.d.ts +2 -0
  234. package/dist/v2/db/registry/consent-policy.test.d.ts.map +1 -0
  235. package/dist/v2/db/registry/consent-purpose.d.ts +16 -0
  236. package/dist/v2/db/registry/consent-purpose.d.ts.map +1 -0
  237. package/dist/v2/db/registry/consent-purpose.test.d.ts +2 -0
  238. package/dist/v2/db/registry/consent-purpose.test.d.ts.map +1 -0
  239. package/dist/v2/db/registry/consent.d.ts +20 -0
  240. package/dist/v2/db/registry/consent.d.ts.map +1 -0
  241. package/dist/v2/db/registry/consent.test.d.ts +2 -0
  242. package/dist/v2/db/registry/consent.test.d.ts.map +1 -0
  243. package/dist/v2/db/registry/domain.d.ts +24 -0
  244. package/dist/v2/db/registry/domain.d.ts.map +1 -0
  245. package/dist/v2/db/registry/domain.test.d.ts +2 -0
  246. package/dist/v2/db/registry/domain.test.d.ts.map +1 -0
  247. package/dist/v2/db/registry/index.d.ts +102 -0
  248. package/dist/v2/db/registry/index.d.ts.map +1 -0
  249. package/dist/v2/db/registry/subject.d.ts +18 -0
  250. package/dist/v2/db/registry/subject.d.ts.map +1 -0
  251. package/dist/v2/db/registry/subject.test.d.ts +2 -0
  252. package/dist/v2/db/registry/subject.test.d.ts.map +1 -0
  253. package/dist/v2/db/registry/types.d.ts +10 -0
  254. package/dist/v2/db/registry/types.d.ts.map +1 -0
  255. package/dist/v2/db/registry/utils/generate-id.d.ts +25 -0
  256. package/dist/v2/db/registry/utils/generate-id.d.ts.map +1 -0
  257. package/dist/v2/db/registry/utils/generate-id.test.d.ts +2 -0
  258. package/dist/v2/db/registry/utils/generate-id.test.d.ts.map +1 -0
  259. package/dist/v2/db/registry/utils.d.ts +25 -0
  260. package/dist/v2/db/registry/utils.d.ts.map +1 -0
  261. package/dist/v2/db/schema/1.0.0/audit-log.d.ts +29 -0
  262. package/dist/v2/db/schema/1.0.0/audit-log.d.ts.map +1 -0
  263. package/dist/v2/db/schema/1.0.0/consent-policy.d.ts +45 -0
  264. package/dist/v2/db/schema/1.0.0/consent-policy.d.ts.map +1 -0
  265. package/dist/v2/db/schema/1.0.0/consent-purpose.d.ts +27 -0
  266. package/dist/v2/db/schema/1.0.0/consent-purpose.d.ts.map +1 -0
  267. package/dist/v2/db/schema/1.0.0/consent-record.d.ts +19 -0
  268. package/dist/v2/db/schema/1.0.0/consent-record.d.ts.map +1 -0
  269. package/dist/v2/db/schema/1.0.0/consent.d.ts +42 -0
  270. package/dist/v2/db/schema/1.0.0/consent.d.ts.map +1 -0
  271. package/dist/v2/db/schema/1.0.0/domain.d.ts +23 -0
  272. package/dist/v2/db/schema/1.0.0/domain.d.ts.map +1 -0
  273. package/dist/v2/db/schema/1.0.0/index.d.ts +1513 -0
  274. package/dist/v2/db/schema/1.0.0/index.d.ts.map +1 -0
  275. package/dist/v2/db/schema/1.0.0/subject.d.ts +23 -0
  276. package/dist/v2/db/schema/1.0.0/subject.d.ts.map +1 -0
  277. package/dist/v2/db/schema/index.cjs +326 -0
  278. package/dist/v2/db/schema/index.d.ts +1507 -0
  279. package/dist/v2/db/schema/index.d.ts.map +1 -0
  280. package/dist/v2/db/schema/index.js +241 -0
  281. package/dist/v2/define-config.cjs +36 -0
  282. package/dist/v2/define-config.d.ts +5 -0
  283. package/dist/v2/define-config.d.ts.map +1 -0
  284. package/dist/v2/define-config.js +2 -0
  285. package/dist/v2/handlers/consent/index.d.ts +260 -0
  286. package/dist/v2/handlers/consent/index.d.ts.map +1 -0
  287. package/dist/v2/handlers/consent/post.handler.d.ts +136 -0
  288. package/dist/v2/handlers/consent/post.handler.d.ts.map +1 -0
  289. package/dist/v2/handlers/consent/show-banner/geo.d.ts +10 -0
  290. package/dist/v2/handlers/consent/show-banner/geo.d.ts.map +1 -0
  291. package/dist/v2/handlers/consent/show-banner/geo.test.d.ts +2 -0
  292. package/dist/v2/handlers/consent/show-banner/geo.test.d.ts.map +1 -0
  293. package/dist/v2/handlers/consent/show-banner/handler.d.ts +71 -0
  294. package/dist/v2/handlers/consent/show-banner/handler.d.ts.map +1 -0
  295. package/dist/v2/handlers/consent/show-banner/handler.test.d.ts +2 -0
  296. package/dist/v2/handlers/consent/show-banner/handler.test.d.ts.map +1 -0
  297. package/dist/v2/handlers/consent/show-banner/translations.d.ts +13 -0
  298. package/dist/v2/handlers/consent/show-banner/translations.d.ts.map +1 -0
  299. package/dist/v2/handlers/consent/show-banner/translations.test.d.ts +2 -0
  300. package/dist/v2/handlers/consent/show-banner/translations.test.d.ts.map +1 -0
  301. package/dist/v2/handlers/consent/verify.handler.d.ts +103 -0
  302. package/dist/v2/handlers/consent/verify.handler.d.ts.map +1 -0
  303. package/dist/v2/handlers/meta/index.d.ts +19 -0
  304. package/dist/v2/handlers/meta/index.d.ts.map +1 -0
  305. package/dist/v2/handlers/meta/status.handler.d.ts +17 -0
  306. package/dist/v2/handlers/meta/status.handler.d.ts.map +1 -0
  307. package/dist/v2/init.d.ts +3 -0
  308. package/dist/v2/init.d.ts.map +1 -0
  309. package/dist/v2/init.test.d.ts +2 -0
  310. package/dist/v2/init.test.d.ts.map +1 -0
  311. package/dist/v2/middleware/cors/cors.d.ts +37 -0
  312. package/dist/v2/middleware/cors/cors.d.ts.map +1 -0
  313. package/dist/v2/middleware/cors/cors.test.d.ts +2 -0
  314. package/dist/v2/middleware/cors/cors.test.d.ts.map +1 -0
  315. package/dist/v2/middleware/cors/index.d.ts +30 -0
  316. package/dist/v2/middleware/cors/index.d.ts.map +1 -0
  317. package/dist/v2/middleware/cors/is-origin-trusted.d.ts +49 -0
  318. package/dist/v2/middleware/cors/is-origin-trusted.d.ts.map +1 -0
  319. package/dist/v2/middleware/cors/is-origin-trusted.test.d.ts +2 -0
  320. package/dist/v2/middleware/cors/is-origin-trusted.test.d.ts.map +1 -0
  321. package/dist/v2/middleware/cors/process-cors.d.ts +31 -0
  322. package/dist/v2/middleware/cors/process-cors.d.ts.map +1 -0
  323. package/dist/v2/middleware/openapi/config.d.ts +28 -0
  324. package/dist/v2/middleware/openapi/config.d.ts.map +1 -0
  325. package/dist/v2/middleware/openapi/handlers.d.ts +29 -0
  326. package/dist/v2/middleware/openapi/handlers.d.ts.map +1 -0
  327. package/dist/v2/middleware/openapi/index.d.ts +11 -0
  328. package/dist/v2/middleware/openapi/index.d.ts.map +1 -0
  329. package/dist/v2/middleware/process-ip/index.d.ts +3 -0
  330. package/dist/v2/middleware/process-ip/index.d.ts.map +1 -0
  331. package/dist/v2/router.cjs +1275 -0
  332. package/dist/v2/router.d.ts +280 -0
  333. package/dist/v2/router.d.ts.map +1 -0
  334. package/dist/v2/router.js +1231 -0
  335. package/dist/v2/types/api.d.ts +27 -0
  336. package/dist/v2/types/api.d.ts.map +1 -0
  337. package/dist/v2/types/index.cjs +40 -0
  338. package/dist/v2/types/index.d.ts +104 -0
  339. package/dist/v2/types/index.d.ts.map +1 -0
  340. package/dist/v2/types/index.js +6 -0
  341. package/dist/v2/utils/create-telemetry-options.d.ts +28 -0
  342. package/dist/v2/utils/create-telemetry-options.d.ts.map +1 -0
  343. package/dist/v2/utils/env.d.ts +60 -0
  344. package/dist/v2/utils/env.d.ts.map +1 -0
  345. package/dist/v2/utils/index.d.ts +3 -0
  346. package/dist/v2/utils/index.d.ts.map +1 -0
  347. package/dist/v2/utils/logger.d.ts +16 -0
  348. package/dist/v2/utils/logger.d.ts.map +1 -0
  349. package/dist/version.d.ts +1 -1
  350. package/package.json +106 -15
  351. package/readme.json +30 -0
  352. package/rslib.config.ts +13 -14
  353. package/src/__tests__/server.test.ts +1 -1
  354. package/src/contracts/consent/post.contract.test.ts +3 -8
  355. package/src/contracts/consent/post.contract.ts +13 -13
  356. package/src/contracts/consent/show-banner.contract.test.ts +9 -0
  357. package/src/contracts/consent/show-banner.contract.ts +2 -0
  358. package/src/contracts/consent/verify.contract.ts +19 -23
  359. package/src/core.ts +7 -0
  360. package/src/handlers/consent/show-banner/handler.ts +12 -9
  361. package/src/handlers/consent/show-banner/translations.ts +2 -2
  362. package/src/init.ts +9 -6
  363. package/src/middleware/openapi/index.ts +2 -2
  364. package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +1 -1
  365. package/src/pkgs/data-model/fields/index.ts +17 -22
  366. package/src/pkgs/data-model/fields/zod-fields.ts +14 -26
  367. package/src/pkgs/data-model/hooks/index.ts +3 -2
  368. package/src/pkgs/data-model/index.ts +2 -4
  369. package/src/pkgs/data-model/schema/index.ts +6 -7
  370. package/src/pkgs/data-model/schema/schemas.ts +3 -3
  371. package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +4 -1
  372. package/src/pkgs/db-adapters/adapters/index.ts +2 -2
  373. package/src/pkgs/db-adapters/adapters/kysely-adapter/index.ts +4 -4
  374. package/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts +4 -5
  375. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +2 -4
  376. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +2 -3
  377. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +1 -6
  378. package/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts +4 -1
  379. package/src/pkgs/db-adapters/adapters/prisma-adapter/index.ts +1 -1
  380. package/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts +5 -2
  381. package/src/pkgs/db-adapters/index.ts +12 -13
  382. package/src/pkgs/migrations/get-migration.ts +4 -2
  383. package/src/pkgs/migrations/get-schema/get-schema.ts +0 -1
  384. package/src/pkgs/migrations/get-schema/process-fields.ts +1 -1
  385. package/src/pkgs/migrations/get-schema/process-tables.ts +0 -2
  386. package/src/pkgs/migrations/index.ts +7 -8
  387. package/src/pkgs/results/__tests__/error-codes.test.ts +2 -2
  388. package/src/pkgs/results/index.ts +22 -27
  389. package/src/pkgs/results/orpc-error-handler.ts +1 -1
  390. package/src/pkgs/results/results/result-helpers.ts +1 -1
  391. package/src/pkgs/types/index.ts +4 -4
  392. package/src/pkgs/types/options.ts +10 -3
  393. package/src/pkgs/utils/index.ts +1 -1
  394. package/src/pkgs/utils/logger.ts +1 -1
  395. package/src/schema/audit-log/schema.ts +3 -3
  396. package/src/schema/consent/schema.ts +4 -4
  397. package/src/schema/consent-policy/schema.ts +3 -3
  398. package/src/schema/consent-purpose/schema.ts +4 -4
  399. package/src/schema/consent-record/schema.ts +3 -3
  400. package/src/schema/definition.ts +1 -1
  401. package/src/schema/domain/schema.ts +5 -5
  402. package/src/schema/index.ts +14 -17
  403. package/src/schema/subject/schema.ts +3 -3
  404. package/src/schema/types.ts +1 -1
  405. package/src/testing/contract-testing.ts +15 -52
  406. package/src/types/index.ts +8 -8
  407. package/src/types/options.ts +2 -3
  408. package/src/v2/contracts/consent/index.test.ts +5 -0
  409. package/src/v2/contracts/consent/index.ts +9 -0
  410. package/src/v2/contracts/consent/post.contract.test.ts +521 -0
  411. package/src/v2/contracts/consent/post.contract.ts +155 -0
  412. package/src/v2/contracts/consent/show-banner.contract.test.ts +252 -0
  413. package/src/v2/contracts/consent/show-banner.contract.ts +73 -0
  414. package/src/v2/contracts/consent/verify.contract.test.ts +185 -0
  415. package/src/v2/contracts/consent/verify.contract.ts +122 -0
  416. package/src/v2/contracts/index.ts +20 -0
  417. package/src/v2/contracts/meta/index.test.ts +5 -0
  418. package/src/v2/contracts/meta/index.ts +5 -0
  419. package/src/v2/contracts/meta/status.contract.test.ts +226 -0
  420. package/src/v2/contracts/meta/status.contract.ts +34 -0
  421. package/src/v2/contracts/shared/jurisdiction.schema.ts +30 -0
  422. package/src/v2/contracts/test.utils.ts +400 -0
  423. package/src/v2/core.ts +379 -0
  424. package/src/v2/db/adapters/drizzle.ts +1 -0
  425. package/src/v2/db/adapters/index.ts +1 -0
  426. package/src/v2/db/adapters/kysely.ts +1 -0
  427. package/src/v2/db/adapters/mongo.ts +1 -0
  428. package/src/v2/db/adapters/prisma.ts +1 -0
  429. package/src/v2/db/adapters/typeorm.ts +1 -0
  430. package/src/v2/db/migrator/index.ts +80 -0
  431. package/src/v2/db/registry/audit-log.test.ts +77 -0
  432. package/src/v2/db/registry/audit-log.ts +46 -0
  433. package/src/v2/db/registry/consent-policy.test.ts +778 -0
  434. package/src/v2/db/registry/consent-policy.ts +74 -0
  435. package/src/v2/db/registry/consent-purpose.test.ts +485 -0
  436. package/src/v2/db/registry/consent-purpose.ts +41 -0
  437. package/src/v2/db/registry/consent.test.ts +843 -0
  438. package/src/v2/db/registry/consent.ts +42 -0
  439. package/src/v2/db/registry/domain.test.ts +463 -0
  440. package/src/v2/db/registry/domain.ts +51 -0
  441. package/src/v2/db/registry/index.ts +18 -0
  442. package/src/v2/db/registry/subject.test.ts +497 -0
  443. package/src/v2/db/registry/subject.ts +101 -0
  444. package/src/v2/db/registry/types.ts +10 -0
  445. package/src/v2/db/registry/utils/generate-id.test.ts +217 -0
  446. package/src/v2/db/registry/utils/generate-id.ts +134 -0
  447. package/src/v2/db/registry/utils.ts +134 -0
  448. package/src/v2/db/schema/1.0.0/audit-log.ts +32 -0
  449. package/src/v2/db/schema/1.0.0/consent-policy.ts +41 -0
  450. package/src/v2/db/schema/1.0.0/consent-purpose.ts +30 -0
  451. package/src/v2/db/schema/1.0.0/consent-record.ts +22 -0
  452. package/src/v2/db/schema/1.0.0/consent.ts +38 -0
  453. package/src/v2/db/schema/1.0.0/domain.ts +26 -0
  454. package/src/v2/db/schema/1.0.0/index.ts +56 -0
  455. package/src/v2/db/schema/1.0.0/subject.ts +26 -0
  456. package/src/v2/db/schema/index.ts +9 -0
  457. package/src/v2/define-config.ts +5 -0
  458. package/src/v2/handlers/consent/index.ts +9 -0
  459. package/src/v2/handlers/consent/post.handler.ts +254 -0
  460. package/src/v2/handlers/consent/show-banner/geo.test.ts +281 -0
  461. package/src/v2/handlers/consent/show-banner/geo.ts +96 -0
  462. package/src/v2/handlers/consent/show-banner/handler.test.ts +374 -0
  463. package/src/v2/handlers/consent/show-banner/handler.ts +123 -0
  464. package/src/v2/handlers/consent/show-banner/translations.test.ts +121 -0
  465. package/src/v2/handlers/consent/show-banner/translations.ts +79 -0
  466. package/src/v2/handlers/consent/verify.handler.ts +288 -0
  467. package/src/v2/handlers/meta/index.ts +5 -0
  468. package/src/v2/handlers/meta/status.handler.ts +43 -0
  469. package/src/v2/init.test.ts +114 -0
  470. package/src/v2/init.ts +126 -0
  471. package/src/v2/middleware/cors/cors.test.ts +111 -0
  472. package/src/v2/middleware/cors/cors.ts +192 -0
  473. package/src/v2/middleware/cors/index.ts +30 -0
  474. package/src/v2/middleware/cors/is-origin-trusted.test.ts +104 -0
  475. package/src/v2/middleware/cors/is-origin-trusted.ts +126 -0
  476. package/src/v2/middleware/cors/process-cors.ts +91 -0
  477. package/src/v2/middleware/openapi/config.ts +27 -0
  478. package/src/v2/middleware/openapi/handlers.ts +132 -0
  479. package/src/v2/middleware/openapi/index.ts +11 -0
  480. package/src/v2/middleware/process-ip/index.ts +39 -0
  481. package/src/v2/router.ts +8 -0
  482. package/src/v2/types/api.ts +32 -0
  483. package/src/v2/types/index.ts +121 -0
  484. package/src/v2/utils/create-telemetry-options.ts +115 -0
  485. package/src/v2/utils/env.ts +84 -0
  486. package/src/v2/utils/index.ts +2 -0
  487. package/src/v2/utils/logger.ts +38 -0
  488. package/src/version.ts +1 -1
  489. package/vitest.config.ts +11 -2
@@ -0,0 +1,252 @@
1
+ import { baseTranslations } from '@c15t/translations';
2
+ import { describe, expect, it } from 'vitest';
3
+
4
+ import { showConsentBannerContract } from './show-banner.contract';
5
+
6
+ // Add custom tests specific to the show-banner contract
7
+ describe('Show Consent Banner Contract Custom Tests', () => {
8
+ // Helper to access schemas consistently throughout tests
9
+ const schemas = {
10
+ input: showConsentBannerContract['~orpc'].inputSchema,
11
+ output: showConsentBannerContract['~orpc'].outputSchema,
12
+ };
13
+
14
+ const validateOutput = (output: unknown) => {
15
+ return schemas.output?.safeParse(output);
16
+ };
17
+
18
+ describe('Output Validation', () => {
19
+ describe('Required fields', () => {
20
+ it('validates complete output object', () => {
21
+ const validOutput = {
22
+ showConsentBanner: true,
23
+ jurisdiction: {
24
+ code: 'GDPR',
25
+ message: 'GDPR or equivalent regulations require a cookie banner.',
26
+ },
27
+ location: {
28
+ countryCode: 'DE',
29
+ regionCode: null,
30
+ },
31
+ translations: {
32
+ translations: baseTranslations.en,
33
+ language: 'en',
34
+ },
35
+ branding: 'c15t',
36
+ };
37
+
38
+ const result = validateOutput(validOutput);
39
+ expect(result?.success).toBe(true);
40
+ });
41
+
42
+ it('rejects output without required fields', () => {
43
+ const invalidOutput = {
44
+ showConsentBanner: true,
45
+ // Missing jurisdiction and location
46
+ };
47
+
48
+ const result = validateOutput(invalidOutput);
49
+ expect(result?.success).toBe(false);
50
+ });
51
+ });
52
+
53
+ describe('Jurisdiction validation', () => {
54
+ it('validates all supported jurisdiction codes', () => {
55
+ const jurisdictionCodes = [
56
+ 'GDPR',
57
+ 'CH',
58
+ 'BR',
59
+ 'PIPEDA',
60
+ 'AU',
61
+ 'APPI',
62
+ 'PIPA',
63
+ 'NONE',
64
+ ];
65
+
66
+ for (const code of jurisdictionCodes) {
67
+ const output = {
68
+ showConsentBanner: true,
69
+ jurisdiction: {
70
+ code,
71
+ message: 'Test message',
72
+ },
73
+ location: {
74
+ countryCode: 'US',
75
+ regionCode: null,
76
+ },
77
+ translations: {
78
+ translations: baseTranslations.en,
79
+ language: 'en',
80
+ },
81
+ branding: 'c15t',
82
+ };
83
+
84
+ const result = validateOutput(output);
85
+ expect(result?.success).toBe(true);
86
+ }
87
+ });
88
+
89
+ it('rejects invalid jurisdiction codes', () => {
90
+ const output = {
91
+ showConsentBanner: true,
92
+ jurisdiction: {
93
+ code: 'INVALID_CODE', // Invalid code
94
+ message: 'Test message',
95
+ },
96
+ location: {
97
+ countryCode: 'US',
98
+ regionCode: null,
99
+ },
100
+ translations: {
101
+ translations: baseTranslations.en,
102
+ language: 'en',
103
+ },
104
+ branding: 'c15t',
105
+ };
106
+
107
+ const result = validateOutput(output);
108
+ expect(result?.success).toBe(false);
109
+ });
110
+ });
111
+
112
+ describe('Location validation', () => {
113
+ it('accepts null country and region codes', () => {
114
+ const output = {
115
+ showConsentBanner: false,
116
+ jurisdiction: {
117
+ code: 'NONE',
118
+ message: 'No specific requirements',
119
+ },
120
+ location: {
121
+ countryCode: null,
122
+ regionCode: null,
123
+ },
124
+ translations: {
125
+ translations: baseTranslations.en,
126
+ language: 'en',
127
+ },
128
+ branding: 'c15t',
129
+ };
130
+
131
+ const result = validateOutput(output);
132
+ expect(result?.success).toBe(true);
133
+ });
134
+
135
+ it('accepts valid country and region codes', () => {
136
+ const output = {
137
+ showConsentBanner: true,
138
+ jurisdiction: {
139
+ code: 'GDPR',
140
+ message: 'GDPR applies',
141
+ },
142
+ location: {
143
+ countryCode: 'DE',
144
+ regionCode: 'BY',
145
+ },
146
+ translations: {
147
+ translations: baseTranslations.en,
148
+ language: 'en',
149
+ },
150
+ branding: 'c15t',
151
+ };
152
+ const result = validateOutput(output);
153
+ expect(result?.success).toBe(true);
154
+ });
155
+
156
+ it('rejects non-string non-null country codes', () => {
157
+ const output = {
158
+ showConsentBanner: true,
159
+ jurisdiction: {
160
+ code: 'GDPR',
161
+ message: 'GDPR applies',
162
+ },
163
+ location: {
164
+ countryCode: 123, // Invalid type
165
+ regionCode: null,
166
+ },
167
+ translations: {
168
+ translations: baseTranslations.en,
169
+ language: 'en',
170
+ },
171
+ branding: 'c15t',
172
+ };
173
+
174
+ // Need to use type assertion to bypass TypeScript
175
+ const result = validateOutput(output);
176
+ expect(result?.success).toBe(false);
177
+ });
178
+ });
179
+
180
+ describe('ShowConsentBanner flag', () => {
181
+ it('validates boolean value', () => {
182
+ const trueOutput = {
183
+ showConsentBanner: true,
184
+ jurisdiction: {
185
+ code: 'GDPR',
186
+ message: 'GDPR applies',
187
+ },
188
+ location: {
189
+ countryCode: 'DE',
190
+ regionCode: null,
191
+ },
192
+ translations: {
193
+ translations: baseTranslations.en,
194
+ language: 'en',
195
+ },
196
+ branding: 'c15t',
197
+ };
198
+
199
+ const falseOutput = {
200
+ showConsentBanner: false,
201
+ jurisdiction: {
202
+ code: 'NONE',
203
+ message: 'No requirements',
204
+ },
205
+ location: {
206
+ countryCode: 'US',
207
+ regionCode: null,
208
+ },
209
+ translations: {
210
+ translations: baseTranslations.en,
211
+ language: 'en',
212
+ },
213
+ branding: 'c15t',
214
+ };
215
+
216
+ expect(validateOutput(trueOutput)?.success).toBe(true);
217
+ expect(validateOutput(falseOutput)?.success).toBe(true);
218
+ });
219
+
220
+ it('rejects non-boolean values', () => {
221
+ const invalidOutput = {
222
+ showConsentBanner: 'yes', // Invalid type
223
+ jurisdiction: {
224
+ code: 'GDPR',
225
+ message: 'GDPR applies',
226
+ },
227
+ location: {
228
+ countryCode: 'DE',
229
+ regionCode: null,
230
+ },
231
+ translations: {
232
+ translations: baseTranslations.en,
233
+ language: 'en',
234
+ },
235
+ branding: 'c15t',
236
+ };
237
+
238
+ // Need to use type assertion to bypass TypeScript
239
+ const result = validateOutput(invalidOutput);
240
+ expect(result?.success).toBe(false);
241
+ });
242
+ });
243
+ });
244
+ });
245
+
246
+ // // Add required fields testing using the utility
247
+ // // No required fields for input since it's an empty object
248
+ // tester.testRequiredFields('output', [
249
+ // 'showConsentBanner',
250
+ // 'jurisdiction',
251
+ // 'location',
252
+ // ]);
@@ -0,0 +1,73 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+ import { branding } from '~/v2/types';
4
+ import { JurisdictionInfoSchema } from '../shared/jurisdiction.schema';
5
+
6
+ const TitleDescriptionSchema = z.object({
7
+ title: z.string(),
8
+ description: z.string(),
9
+ });
10
+
11
+ const TranslationsSchema = z.object({
12
+ common: z.object({
13
+ acceptAll: z.string(),
14
+ rejectAll: z.string(),
15
+ customize: z.string(),
16
+ save: z.string(),
17
+ }),
18
+ cookieBanner: TitleDescriptionSchema,
19
+ consentManagerDialog: TitleDescriptionSchema,
20
+ consentTypes: z.object({
21
+ experience: TitleDescriptionSchema,
22
+ functionality: TitleDescriptionSchema,
23
+ marketing: TitleDescriptionSchema,
24
+ measurement: TitleDescriptionSchema,
25
+ necessary: TitleDescriptionSchema,
26
+ }),
27
+ });
28
+
29
+ export const showConsentBannerContract = oc
30
+ .route({
31
+ method: 'GET',
32
+ path: '/show-consent-banner',
33
+ description: `Determines if a user should see a consent banner based on their location and applicable privacy regulations.
34
+ This endpoint performs the following checks:
35
+
36
+ 1. Detects the user's location using various header information:
37
+ - Cloudflare country headers
38
+ - Vercel IP country headers
39
+ - AWS CloudFront headers
40
+ - Custom country code headers
41
+
42
+ 2. Determines the applicable jurisdiction based on the location:
43
+ - GDPR (EU/EEA/UK)
44
+ - Swiss Data Protection Act
45
+ - LGPD (Brazil)
46
+ - PIPEDA (Canada)
47
+ - Australian Privacy Principles
48
+ - APPI (Japan)
49
+ - PIPA (South Korea)
50
+
51
+ 3. Returns detailed information about:
52
+ - Whether to show the consent banner
53
+ - The applicable jurisdiction and its requirements
54
+ - The user's detected location (country and region)
55
+
56
+ Use this endpoint to implement geo-targeted consent banners and ensure compliance with regional privacy regulations.`,
57
+ tags: ['cookie-banner'],
58
+ })
59
+ .output(
60
+ z.object({
61
+ showConsentBanner: z.boolean(),
62
+ jurisdiction: JurisdictionInfoSchema,
63
+ location: z.object({
64
+ countryCode: z.string().nullable(),
65
+ regionCode: z.string().nullable(),
66
+ }),
67
+ translations: z.object({
68
+ language: z.string(),
69
+ translations: TranslationsSchema,
70
+ }),
71
+ branding: z.enum(branding),
72
+ })
73
+ );
@@ -0,0 +1,185 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { createContractTests } from '~/v2/contracts/test.utils';
4
+ import { verifyConsentContract } from './verify.contract';
5
+
6
+ // Create base tests for the contract using the utility
7
+ const tester = createContractTests('Verify Consent', verifyConsentContract);
8
+
9
+ // Custom tests specific to verify consent
10
+ describe('Verify Consent Contract Custom Tests', () => {
11
+ // Helper to access schemas consistently throughout tests
12
+ const schemas = {
13
+ input: verifyConsentContract['~orpc'].inputSchema,
14
+ output: verifyConsentContract['~orpc'].outputSchema,
15
+ };
16
+
17
+ // Helper functions for common test patterns
18
+ const validateInput = (input: unknown) => {
19
+ return schemas.input?.safeParse(input);
20
+ };
21
+
22
+ const validateOutput = (output: unknown) => {
23
+ return schemas.output?.safeParse(output);
24
+ };
25
+
26
+ describe('Input Validation', () => {
27
+ it('accepts valid input with minimum required fields', () => {
28
+ const validInput = {
29
+ domain: 'example.com',
30
+ type: 'cookie_banner',
31
+ };
32
+
33
+ const result = validateInput(validInput);
34
+ expect(result?.success).toBe(true);
35
+ });
36
+
37
+ it('accepts valid input with all fields', () => {
38
+ const validInput = {
39
+ subjectId: 'subject-123',
40
+ externalSubjectId: 'ext-123',
41
+ domain: 'example.com',
42
+ type: 'privacy_policy',
43
+ policyId: 'policy-123',
44
+ preferences: ['analytics', 'marketing'],
45
+ };
46
+
47
+ const result = validateInput(validInput);
48
+ expect(result?.success).toBe(true);
49
+ });
50
+
51
+ it('rejects input without required domain', () => {
52
+ const invalidInput = {
53
+ type: 'cookie_banner',
54
+ };
55
+
56
+ const result = validateInput(invalidInput);
57
+ expect(result?.success).toBe(false);
58
+ });
59
+
60
+ it('rejects input without required type', () => {
61
+ const invalidInput = {
62
+ domain: 'example.com',
63
+ };
64
+
65
+ const result = validateInput(invalidInput);
66
+ expect(result?.success).toBe(false);
67
+ });
68
+
69
+ it('rejects input with invalid type', () => {
70
+ const invalidInput = {
71
+ domain: 'example.com',
72
+ type: 'invalid_type', // Not in PolicyTypeSchema
73
+ };
74
+
75
+ const result = validateInput(invalidInput);
76
+ expect(result?.success).toBe(false);
77
+ });
78
+
79
+ it('rejects input with extra properties', () => {
80
+ const invalidInput = {
81
+ domain: 'example.com',
82
+ type: 'cookie_banner',
83
+ extraProperty: 'should not be allowed',
84
+ };
85
+
86
+ const result = validateInput(invalidInput);
87
+ expect(result?.success).toBe(false);
88
+ });
89
+
90
+ it('validates preferences as array of strings', () => {
91
+ const validInput = {
92
+ domain: 'example.com',
93
+ type: 'cookie_banner',
94
+ preferences: ['analytics', 'marketing'],
95
+ };
96
+
97
+ expect(validateInput(validInput)?.success).toBe(true);
98
+
99
+ const invalidInput = {
100
+ domain: 'example.com',
101
+ type: 'cookie_banner',
102
+ preferences: { analytics: true }, // Object instead of array
103
+ };
104
+
105
+ expect(validateInput(invalidInput)?.success).toBe(false);
106
+ });
107
+ });
108
+
109
+ describe('Output Validation', () => {
110
+ it('validates successful consent verification', () => {
111
+ const validOutput = {
112
+ isValid: true,
113
+ consent: {
114
+ id: 'consent-123',
115
+ purposeIds: ['analytics', 'marketing'],
116
+ additionalProperty: 'allowed by passthrough',
117
+ },
118
+ };
119
+
120
+ const result = validateOutput(validOutput);
121
+ expect(result?.success).toBe(true);
122
+ });
123
+
124
+ it('validates unsuccessful consent verification with reasons', () => {
125
+ const validOutput = {
126
+ isValid: false,
127
+ reasons: ['No consent found for the given policy'],
128
+ };
129
+
130
+ const result = validateOutput(validOutput);
131
+ expect(result?.success).toBe(true);
132
+ });
133
+
134
+ it('rejects output without required isValid field', () => {
135
+ const invalidOutput = {
136
+ reasons: ['Some reason'],
137
+ };
138
+
139
+ const result = validateOutput(invalidOutput);
140
+ expect(result?.success).toBe(false);
141
+ });
142
+
143
+ it('validates consent object structure', () => {
144
+ const invalidOutput = {
145
+ isValid: true,
146
+ consent: {
147
+ // Missing required id
148
+ purposeIds: ['analytics'],
149
+ },
150
+ };
151
+
152
+ expect(validateOutput(invalidOutput)?.success).toBe(false);
153
+
154
+ const anotherInvalidOutput = {
155
+ isValid: true,
156
+ consent: {
157
+ id: 'consent-123',
158
+ // Missing required purposeIds
159
+ },
160
+ };
161
+
162
+ expect(validateOutput(anotherInvalidOutput)?.success).toBe(false);
163
+ });
164
+
165
+ it('validates reasons as array of strings', () => {
166
+ const validOutput = {
167
+ isValid: false,
168
+ reasons: ['Reason 1', 'Reason 2'],
169
+ };
170
+
171
+ expect(validateOutput(validOutput)?.success).toBe(true);
172
+
173
+ const invalidOutput = {
174
+ isValid: false,
175
+ reasons: 'Single reason', // String instead of array
176
+ };
177
+
178
+ expect(validateOutput(invalidOutput)?.success).toBe(false);
179
+ });
180
+ });
181
+ });
182
+
183
+ // Add required fields testing
184
+ tester.testRequiredFields('input', ['domain', 'type']);
185
+ tester.testRequiredFields('output', ['isValid']);
@@ -0,0 +1,122 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+ import { PolicyTypeSchema } from '~/v2/db/schema';
4
+
5
+ /**
6
+ * Contract for the verify consent endpoint
7
+ * Verifies if a user has given consent for a specific policy
8
+ */
9
+
10
+ // Input schema based on VerifyConsentRequestBody
11
+ const verifyConsentInputSchema = z.strictObject({
12
+ subjectId: z.string().optional(),
13
+ externalSubjectId: z.string().optional(),
14
+ domain: z.string(),
15
+ type: PolicyTypeSchema,
16
+ policyId: z.string().optional(),
17
+ preferences: z.array(z.string()).optional(),
18
+ });
19
+
20
+ // Minimal consent schema based on the response interface
21
+ const consentSchema = z.looseObject({
22
+ id: z.string(),
23
+ purposeIds: z.array(z.string()),
24
+ }); // Allow additional properties
25
+
26
+ // Output schema based on VerifyConsentResponse
27
+ export const verifyConsentContract = oc
28
+ .route({
29
+ method: 'POST',
30
+ path: '/consent/verify',
31
+ description: `Verifies if a user has given valid consent for a specific policy and domain.
32
+ This endpoint performs comprehensive consent verification by:
33
+
34
+ 1. Validating the subject's identity (using subjectId or externalSubjectId)
35
+ 2. Verifying the domain's existence and validity
36
+ 3. Checking if the specified policy exists and is active
37
+ 4. Validating that all required purposes have been consented to
38
+ 5. Ensuring the consent record is current and valid
39
+
40
+ The endpoint supports different types of consent verification:
41
+ - Cookie banner consent verification
42
+ - Privacy policy consent verification
43
+ - Terms and conditions verification
44
+ - Marketing communications consent verification
45
+ - Age verification
46
+ - Custom consent types
47
+
48
+ Use this endpoint to ensure compliance with privacy regulations and to verify user consent before processing personal data.`,
49
+ tags: ['consent'],
50
+ })
51
+ .errors({
52
+ // Input validation errors
53
+ INPUT_VALIDATION_FAILED: {
54
+ status: 422,
55
+ data: z.object({
56
+ formErrors: z.array(z.string()),
57
+ fieldErrors: z.record(z.string(), z.array(z.string()).optional()),
58
+ }),
59
+ error: 'Invalid input parameters',
60
+ },
61
+ // Subject errors
62
+ SUBJECT_NOT_FOUND: {
63
+ status: 404,
64
+ data: z.object({
65
+ subjectId: z.string().optional(),
66
+ externalSubjectId: z.string().optional(),
67
+ }),
68
+ error: 'Subject not found',
69
+ },
70
+ // Domain errors
71
+ DOMAIN_NOT_FOUND: {
72
+ status: 404,
73
+ data: z.object({
74
+ domain: z.string(),
75
+ }),
76
+ error: 'Domain not found',
77
+ },
78
+ // Policy errors
79
+ POLICY_NOT_FOUND: {
80
+ status: 404,
81
+ data: z.object({
82
+ policyId: z.string(),
83
+ type: z.string(),
84
+ }),
85
+ error: 'Policy not found or invalid',
86
+ },
87
+ // Purpose errors
88
+ PURPOSES_NOT_FOUND: {
89
+ status: 404,
90
+ data: z.object({
91
+ preferences: z.array(z.string()),
92
+ foundPurposes: z.array(z.string()),
93
+ }),
94
+ error: 'Could not find all specified purposes',
95
+ },
96
+ // Cookie banner specific errors
97
+ COOKIE_BANNER_PREFERENCES_REQUIRED: {
98
+ status: 400,
99
+ data: z.object({
100
+ type: z.literal('cookie_banner'),
101
+ }),
102
+ error: 'Preferences are required for cookie banner consent',
103
+ },
104
+ // Consent errors
105
+ NO_CONSENT_FOUND: {
106
+ status: 404,
107
+ data: z.object({
108
+ policyId: z.string(),
109
+ subjectId: z.string(),
110
+ domainId: z.string(),
111
+ }),
112
+ error: 'No consent found for the given policy',
113
+ },
114
+ })
115
+ .input(verifyConsentInputSchema)
116
+ .output(
117
+ z.object({
118
+ isValid: z.boolean(),
119
+ reasons: z.array(z.string()).optional(),
120
+ consent: consentSchema.optional(),
121
+ })
122
+ );
@@ -0,0 +1,20 @@
1
+ import type {
2
+ InferContractRouterInputs,
3
+ InferContractRouterOutputs,
4
+ } from '@orpc/contract';
5
+ import { implement } from '@orpc/server';
6
+
7
+ import { consentContracts } from './consent';
8
+ import { metaContracts } from './meta';
9
+
10
+ const config = {
11
+ consent: consentContracts,
12
+ meta: metaContracts,
13
+ };
14
+
15
+ export { config as contracts };
16
+
17
+ export const os = implement(config);
18
+
19
+ export type ContractsOutputs = InferContractRouterOutputs<typeof config>;
20
+ export type ContractsInputs = InferContractRouterInputs<typeof config>;
@@ -0,0 +1,5 @@
1
+ import { createConsistencyTests } from '~/v2/contracts/test.utils';
2
+ import { metaContracts } from './index';
3
+
4
+ // Add consistency tests across all meta contracts
5
+ createConsistencyTests(metaContracts);
@@ -0,0 +1,5 @@
1
+ import { statusContract } from './status.contract';
2
+
3
+ export const metaContracts = {
4
+ status: statusContract,
5
+ };