@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,521 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import type { z } from 'zod';
3
+
4
+ import { createContractTests } from '~/v2/contracts/test.utils';
5
+ import { PolicyTypeSchema } from '~/v2/db/schema';
6
+
7
+ import { postConsentContract } from './post.contract';
8
+
9
+ // Create base tests for the contract using the utility
10
+ const tester = createContractTests('Post Consent', postConsentContract);
11
+
12
+ // Keep the detailed custom tests to maintain existing coverage
13
+ describe('Post Consent Contract Custom Tests', () => {
14
+ // Helper to access schemas consistently throughout tests
15
+ const schemas = {
16
+ input: postConsentContract['~orpc'].inputSchema,
17
+ output: postConsentContract['~orpc'].outputSchema,
18
+ };
19
+
20
+ // Helper functions for common test patterns
21
+ const validateInput = (input: unknown) => {
22
+ return schemas.input?.safeParse(input);
23
+ };
24
+
25
+ const validateOutput = (output: unknown) => {
26
+ return schemas.output?.safeParse(output);
27
+ };
28
+
29
+ describe('Schema Structure', () => {
30
+ it('input schema requires a type discriminator', () => {
31
+ const result = validateInput({ domain: 'example.com' });
32
+ expect(result?.success).toBe(false);
33
+ });
34
+
35
+ it('supports all defined policy types', () => {
36
+ const policyTypes = PolicyTypeSchema.options;
37
+
38
+ for (const type of policyTypes) {
39
+ const input = {
40
+ type,
41
+ domain: 'example.com',
42
+ ...(type === 'cookie_banner' ? { preferences: { test: true } } : {}),
43
+ };
44
+
45
+ const result = validateInput(input);
46
+ expect(result?.success).toBe(true);
47
+ }
48
+ });
49
+ });
50
+
51
+ describe('Input Validation', () => {
52
+ describe('cookie_banner type', () => {
53
+ it('accepts valid input with preferences', () => {
54
+ const validInput = {
55
+ type: 'cookie_banner',
56
+ domain: 'example.com',
57
+ preferences: { analytics: true, marketing: false },
58
+ } as const;
59
+
60
+ const result = validateInput(validInput);
61
+ expect(result?.success).toBe(true);
62
+ });
63
+
64
+ it('rejects input without required preferences', () => {
65
+ const invalidInput = {
66
+ type: 'cookie_banner',
67
+ domain: 'example.com',
68
+ } as const;
69
+
70
+ const result = validateInput(invalidInput);
71
+ if (!result) {
72
+ throw new Error('Result is undefined');
73
+ }
74
+
75
+ expect(result.success).toBe(false);
76
+ if (!result.success) {
77
+ // Use optional chaining to safely access potentially undefined properties
78
+ expect(result.error.issues?.[0]?.path).toContain('preferences');
79
+ }
80
+ });
81
+
82
+ it('verifies boolean values in preferences', () => {
83
+ const invalidPreferences = {
84
+ type: 'cookie_banner',
85
+ domain: 'example.com',
86
+ preferences: { analytics: 'yes' }, // Should be boolean
87
+ };
88
+
89
+ const result = validateInput(invalidPreferences);
90
+ if (!result) {
91
+ throw new Error('Result is undefined');
92
+ }
93
+
94
+ expect(result.success).toBe(false);
95
+ if (!result.success) {
96
+ expect(result.error.issues?.[0]?.path).toContain('preferences');
97
+ }
98
+ });
99
+ });
100
+
101
+ describe('policy-based types', () => {
102
+ it('validates privacy_policy input', () => {
103
+ const validInput = {
104
+ type: 'privacy_policy',
105
+ domain: 'example.com',
106
+ policyId: 'policy-123',
107
+ } as const;
108
+
109
+ const result = validateInput(validInput);
110
+ expect(result?.success).toBe(true);
111
+ });
112
+
113
+ it('validates dpa input', () => {
114
+ const validInput = {
115
+ type: 'dpa',
116
+ domain: 'example.com',
117
+ policyId: 'dpa-123',
118
+ };
119
+
120
+ const result = validateInput(validInput);
121
+ expect(result?.success).toBe(true);
122
+ });
123
+
124
+ it('validates terms_and_conditions input', () => {
125
+ const validInput = {
126
+ type: 'terms_and_conditions',
127
+ domain: 'example.com',
128
+ policyId: 'terms-123',
129
+ };
130
+
131
+ const result = validateInput(validInput);
132
+ expect(result?.success).toBe(true);
133
+ });
134
+
135
+ it('accepts optional preferences for policy-based consents', () => {
136
+ const validInput = {
137
+ type: 'privacy_policy',
138
+ domain: 'example.com',
139
+ policyId: 'policy-123',
140
+ preferences: { acceptAll: true, marketing: false },
141
+ };
142
+
143
+ const result = validateInput(validInput);
144
+ expect(result?.success).toBe(true);
145
+ });
146
+ });
147
+
148
+ describe('other consent types', () => {
149
+ it('validates marketing_communications input', () => {
150
+ const validInput = {
151
+ type: 'marketing_communications',
152
+ domain: 'example.com',
153
+ subjectId: 'user-123',
154
+ } as const;
155
+
156
+ const result = validateInput(validInput);
157
+ if (!result) {
158
+ throw new Error('Result is undefined');
159
+ }
160
+
161
+ expect(result.success).toBe(true);
162
+ });
163
+
164
+ it('validates age_verification input', () => {
165
+ const validInput = {
166
+ type: 'age_verification',
167
+ domain: 'example.com',
168
+ };
169
+
170
+ const result = validateInput(validInput);
171
+ expect(result?.success).toBe(true);
172
+ });
173
+
174
+ it('validates other type input', () => {
175
+ const validInput = {
176
+ type: 'other',
177
+ domain: 'example.com',
178
+ metadata: { customField: 'value' },
179
+ };
180
+
181
+ const result = validateInput(validInput);
182
+ expect(result?.success).toBe(true);
183
+ });
184
+ });
185
+
186
+ describe('common requirements', () => {
187
+ it('rejects input with invalid type', () => {
188
+ const invalidInput = {
189
+ // Type cast to bypass TS errors for testing
190
+ type: 'invalid_type' as unknown as z.infer<typeof PolicyTypeSchema>,
191
+ domain: 'example.com',
192
+ };
193
+
194
+ const result = validateInput(invalidInput);
195
+
196
+ if (!result) {
197
+ throw new Error('Result is undefined');
198
+ }
199
+
200
+ expect(result.success).toBe(false);
201
+ if (!result.success) {
202
+ expect(result.error.issues?.[0]?.path).toContain('type');
203
+ }
204
+ });
205
+
206
+ it('requires domain field', () => {
207
+ const invalidInput = {
208
+ type: 'marketing_communications' as z.infer<typeof PolicyTypeSchema>,
209
+ };
210
+
211
+ const result = validateInput(invalidInput);
212
+ if (!result) {
213
+ throw new Error('Result is undefined');
214
+ }
215
+
216
+ expect(result.success).toBe(false);
217
+ if (!result.success) {
218
+ expect(result.error.issues?.[0]?.path).toContain('domain');
219
+ }
220
+ });
221
+
222
+ it('accepts additional metadata', () => {
223
+ const validInput = {
224
+ type: 'marketing_communications',
225
+ domain: 'example.com',
226
+ metadata: {
227
+ source: 'web',
228
+ campaign: 'summer2023',
229
+ customData: { nested: true },
230
+ },
231
+ };
232
+
233
+ const result = validateInput(validInput);
234
+ expect(result?.success).toBe(true);
235
+ });
236
+
237
+ it('accepts optional subjectId', () => {
238
+ const validInput = {
239
+ type: 'privacy_policy',
240
+ domain: 'example.com',
241
+ subjectId: 'user-abc-123',
242
+ };
243
+
244
+ const result = validateInput(validInput);
245
+ expect(result?.success).toBe(true);
246
+ });
247
+
248
+ it('accepts optional externalSubjectId', () => {
249
+ const validInput = {
250
+ type: 'privacy_policy',
251
+ domain: 'example.com',
252
+ externalSubjectId: 'external-user-123',
253
+ };
254
+
255
+ const result = validateInput(validInput);
256
+ expect(result?.success).toBe(true);
257
+ });
258
+ });
259
+ });
260
+
261
+ describe('Output Validation', () => {
262
+ it('validates complete output object', () => {
263
+ const validOutput = {
264
+ id: '123',
265
+ domainId: '456',
266
+ domain: 'example.com',
267
+ type: 'marketing_communications',
268
+ status: 'granted',
269
+ recordId: '789',
270
+ givenAt: new Date(),
271
+ metadata: { source: 'web' },
272
+ } as const;
273
+
274
+ const result = validateOutput(validOutput);
275
+ if (!result) {
276
+ throw new Error('Result is undefined');
277
+ }
278
+
279
+ expect(result.success).toBe(true);
280
+ });
281
+
282
+ it('rejects output without required fields', () => {
283
+ const invalidOutput = {
284
+ id: '123',
285
+ domain: 'example.com',
286
+ type: 'marketing_communications',
287
+ // Missing required fields: domainId, status, recordId, givenAt
288
+ } as const;
289
+
290
+ const result = validateOutput(invalidOutput);
291
+ if (!result) {
292
+ throw new Error('Result is undefined');
293
+ }
294
+
295
+ expect(result.success).toBe(false);
296
+ });
297
+
298
+ it('validates output with all possible status values', () => {
299
+ const statusValues = ['granted', 'denied', 'pending', 'withdrawn'];
300
+
301
+ for (const status of statusValues) {
302
+ const output = {
303
+ id: '123',
304
+ domainId: '456',
305
+ domain: 'example.com',
306
+ type: 'marketing_communications',
307
+ status,
308
+ recordId: '789',
309
+ givenAt: new Date(),
310
+ };
311
+
312
+ const result = validateOutput(output);
313
+ expect(result?.success).toBe(true);
314
+ }
315
+ });
316
+
317
+ it('validates output with different policy types', () => {
318
+ const policyTypes = PolicyTypeSchema.options;
319
+
320
+ for (const type of policyTypes) {
321
+ const output = {
322
+ id: '123',
323
+ domainId: '456',
324
+ domain: 'example.com',
325
+ type,
326
+ status: 'granted',
327
+ recordId: '789',
328
+ givenAt: new Date(),
329
+ };
330
+
331
+ const result = validateOutput(output);
332
+ expect(result?.success).toBe(true);
333
+ }
334
+ });
335
+
336
+ describe('givenAt field', () => {
337
+ it('rejects string values', () => {
338
+ const invalidOutput = {
339
+ id: '123',
340
+ domainId: '456',
341
+ domain: 'example.com',
342
+ type: 'marketing_communications',
343
+ status: 'granted',
344
+ recordId: '789',
345
+ givenAt: 'not-a-date', // This should now fail with z.date()
346
+ metadata: {},
347
+ } as const;
348
+
349
+ const result = validateOutput(invalidOutput);
350
+ if (!result) {
351
+ throw new Error('Result is undefined');
352
+ }
353
+
354
+ expect(result.success).toBe(false);
355
+ });
356
+
357
+ it('accepts Date objects', () => {
358
+ const validOutput = {
359
+ id: '123',
360
+ domainId: '456',
361
+ domain: 'example.com',
362
+ type: 'marketing_communications',
363
+ status: 'granted',
364
+ recordId: '789',
365
+ givenAt: new Date(),
366
+ metadata: {},
367
+ };
368
+
369
+ const result = validateOutput(validOutput);
370
+ expect(result?.success).toBe(true);
371
+ });
372
+
373
+ it('rejects non-date values', () => {
374
+ const invalidOutput = {
375
+ id: '123',
376
+ domainId: '456',
377
+ domain: 'example.com',
378
+ type: 'marketing_communications',
379
+ status: 'granted',
380
+ recordId: '789',
381
+ givenAt: 123, // Number instead of Date
382
+ metadata: {},
383
+ };
384
+
385
+ const result = validateOutput(invalidOutput);
386
+ expect(result?.success).toBe(false);
387
+ });
388
+
389
+ it('accepts ISO date strings', () => {
390
+ const validOutput = {
391
+ id: '123',
392
+ domainId: '456',
393
+ domain: 'example.com',
394
+ type: 'marketing_communications',
395
+ status: 'granted',
396
+ recordId: '789',
397
+ givenAt: new Date(),
398
+ metadata: {},
399
+ };
400
+
401
+ const result = validateOutput(validOutput);
402
+ expect(result?.success).toBe(true);
403
+ });
404
+
405
+ it('rejects non-string values', () => {
406
+ // Create an object with a number for givenAt (should fail validation)
407
+ const invalidOutput = {
408
+ id: '123',
409
+ domainId: '456',
410
+ domain: 'example.com',
411
+ type: 'marketing_communications',
412
+ status: 'granted',
413
+ recordId: '789',
414
+ givenAt: 123, // Number instead of string (intentionally invalid)
415
+ metadata: {},
416
+ };
417
+
418
+ // We need to cast here because TypeScript wouldn't allow this invalid type normally
419
+ const result = validateOutput(invalidOutput);
420
+ if (!result) {
421
+ throw new Error('Result is undefined');
422
+ }
423
+
424
+ expect(result.success).toBe(false);
425
+ if (!result.success) {
426
+ expect(result.error.issues?.[0]?.path).toContain('givenAt');
427
+ }
428
+ });
429
+ });
430
+
431
+ describe('Optional fields validation', () => {
432
+ it('accepts output without optional fields', () => {
433
+ const validOutput = {
434
+ id: '123',
435
+ domainId: '456',
436
+ domain: 'example.com',
437
+ type: 'marketing_communications',
438
+ status: 'granted',
439
+ recordId: '789',
440
+ givenAt: new Date(),
441
+ // No metadata, subjectId or externalSubjectId
442
+ };
443
+
444
+ const result = validateOutput(validOutput);
445
+ expect(result?.success).toBe(true);
446
+ });
447
+
448
+ it('accepts output with optional subjectId', () => {
449
+ const validOutput = {
450
+ id: '123',
451
+ domainId: '456',
452
+ domain: 'example.com',
453
+ type: 'marketing_communications',
454
+ status: 'granted',
455
+ recordId: '789',
456
+ givenAt: new Date(),
457
+ subjectId: 'user-123',
458
+ };
459
+
460
+ const result = validateOutput(validOutput);
461
+ expect(result?.success).toBe(true);
462
+ });
463
+
464
+ it('accepts output with optional externalSubjectId', () => {
465
+ const validOutput = {
466
+ id: '123',
467
+ domainId: '456',
468
+ domain: 'example.com',
469
+ type: 'marketing_communications',
470
+ status: 'granted',
471
+ recordId: '789',
472
+ givenAt: new Date(),
473
+ externalSubjectId: 'external-user-123',
474
+ };
475
+
476
+ const result = validateOutput(validOutput);
477
+ expect(result?.success).toBe(true);
478
+ });
479
+
480
+ it('accepts output with complex metadata', () => {
481
+ const validOutput = {
482
+ id: '123',
483
+ domainId: '456',
484
+ domain: 'example.com',
485
+ type: 'marketing_communications',
486
+ status: 'granted',
487
+ recordId: '789',
488
+ givenAt: new Date(),
489
+ metadata: {
490
+ source: 'web',
491
+ platform: 'mobile',
492
+ browser: { name: 'Chrome', version: '115' },
493
+ consentMethod: 'explicit',
494
+ nestedData: {
495
+ level1: {
496
+ level2: {
497
+ level3: true,
498
+ },
499
+ },
500
+ },
501
+ },
502
+ };
503
+
504
+ const result = validateOutput(validOutput);
505
+ expect(result?.success).toBe(true);
506
+ });
507
+ });
508
+ });
509
+ });
510
+
511
+ // Add required fields testing using the utility
512
+ tester.testRequiredFields('input', ['domain', 'type']);
513
+ tester.testRequiredFields('output', [
514
+ 'id',
515
+ 'domainId',
516
+ 'domain',
517
+ 'type',
518
+ 'status',
519
+ 'recordId',
520
+ 'givenAt',
521
+ ]);
@@ -0,0 +1,155 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+
4
+ import { PolicyTypeSchema } from '~/v2/db/schema';
5
+
6
+ const baseConsentSchema = z.object({
7
+ subjectId: z.string().optional(),
8
+ externalSubjectId: z.string().optional(),
9
+ domain: z.string(),
10
+ type: PolicyTypeSchema,
11
+ metadata: z.record(z.string(), z.unknown()).optional(),
12
+ });
13
+
14
+ // Cookie banner needs preferences
15
+ const cookieBannerSchema = baseConsentSchema.extend({
16
+ type: z.literal('cookie_banner'),
17
+ preferences: z.record(z.string(), z.boolean()),
18
+ });
19
+
20
+ // Policy based consent just needs the policy ID
21
+ const policyBasedSchema = baseConsentSchema.extend({
22
+ type: z.enum(['privacy_policy', 'dpa', 'terms_and_conditions']),
23
+ policyId: z.string().optional(),
24
+ preferences: z.record(z.string(), z.boolean()).optional(),
25
+ });
26
+
27
+ // Other consent types just need the base fields
28
+ const otherConsentSchema = baseConsentSchema.extend({
29
+ type: z.enum(['marketing_communications', 'age_verification', 'other']),
30
+ preferences: z.record(z.string(), z.boolean()).optional(),
31
+ });
32
+
33
+ export const postConsentContract = oc
34
+ .route({
35
+ method: 'POST',
36
+ path: '/consent/set',
37
+ description: `Records a user's consent preferences and creates necessary consent records.
38
+ This endpoint handles various types of consent submissions:
39
+
40
+ 1. Cookie Banner Consent:
41
+ - Records granular cookie preferences
42
+ - Supports multiple consent purposes
43
+ - Creates audit trail for compliance
44
+
45
+ 2. Policy-Based Consent:
46
+ - Privacy Policy acceptance
47
+ - Data Processing Agreement (DPA) consent
48
+ - Terms and Conditions acceptance
49
+ - Links consent to specific policy versions
50
+
51
+ 3. Other Consent Types:
52
+ - Marketing communications preferences
53
+ - Age verification consent
54
+ - Custom consent types
55
+
56
+ The endpoint performs the following operations:
57
+ - Creates or retrieves subject records
58
+ - Validates domain and policy information
59
+ - Creates consent records with audit trails
60
+ - Records consent purposes and preferences
61
+ - Generates audit logs for compliance
62
+
63
+ Use this endpoint to record user consent and maintain a compliant consent management system.`,
64
+ tags: ['consent', 'cookie-banner'],
65
+ })
66
+ .errors({
67
+ // Input validation errors
68
+ INPUT_VALIDATION_FAILED: {
69
+ status: 422,
70
+ data: z.object({
71
+ formErrors: z.array(z.string()),
72
+ fieldErrors: z.record(z.string(), z.array(z.string())),
73
+ }),
74
+ error: 'Invalid input parameters',
75
+ },
76
+ // Subject errors
77
+ SUBJECT_CREATION_FAILED: {
78
+ status: 400,
79
+ data: z.object({
80
+ subjectId: z.string().optional(),
81
+ externalSubjectId: z.string().optional(),
82
+ }),
83
+ error: 'Failed to create or find subject',
84
+ },
85
+ // Domain errors
86
+ DOMAIN_CREATION_FAILED: {
87
+ status: 500,
88
+ data: z.object({
89
+ domain: z.string(),
90
+ }),
91
+ error: 'Failed to create or find domain',
92
+ },
93
+ // Policy errors
94
+ POLICY_NOT_FOUND: {
95
+ status: 404,
96
+ data: z.object({
97
+ policyId: z.string(),
98
+ type: z.string(),
99
+ }),
100
+ error: 'Policy not found',
101
+ },
102
+ POLICY_INACTIVE: {
103
+ status: 409,
104
+ data: z.object({
105
+ policyId: z.string(),
106
+ type: z.string(),
107
+ }),
108
+ error: 'Policy is not active',
109
+ },
110
+ POLICY_CREATION_FAILED: {
111
+ status: 500,
112
+ data: z.object({
113
+ type: z.string(),
114
+ }),
115
+ error: 'Failed to create or find policy',
116
+ },
117
+ // Purpose errors
118
+ PURPOSE_CREATION_FAILED: {
119
+ status: 500,
120
+ data: z.object({
121
+ purposeCode: z.string(),
122
+ }),
123
+ error: 'Failed to create consent purpose',
124
+ },
125
+ // Transaction errors
126
+ CONSENT_CREATION_FAILED: {
127
+ status: 500,
128
+ data: z.object({
129
+ subjectId: z.string(),
130
+ domain: z.string(),
131
+ }),
132
+ error: 'Failed to create consent record',
133
+ },
134
+ })
135
+ .input(
136
+ z.discriminatedUnion('type', [
137
+ cookieBannerSchema,
138
+ policyBasedSchema,
139
+ otherConsentSchema,
140
+ ])
141
+ )
142
+ .output(
143
+ z.object({
144
+ id: z.string(),
145
+ subjectId: z.string().optional(),
146
+ externalSubjectId: z.string().optional(),
147
+ domainId: z.string(),
148
+ domain: z.string(),
149
+ type: PolicyTypeSchema,
150
+ status: z.string(),
151
+ recordId: z.string(),
152
+ metadata: z.record(z.string(), z.unknown()).optional(),
153
+ givenAt: z.date(),
154
+ })
155
+ );