@c15t/backend 1.0.0 → 1.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/.turbo/turbo-build.log +33 -39
  2. package/.turbo/turbo-fmt.log +7 -0
  3. package/.turbo/turbo-test.log +531 -0
  4. package/README.md +19 -7
  5. package/coverage/coverage-final.json +84 -0
  6. package/coverage/coverage-summary.json +85 -0
  7. package/coverage/html/backend/index.html +116 -0
  8. package/coverage/html/backend/rslib.config.ts.html +415 -0
  9. package/coverage/html/backend/src/contracts/consent/index.html +161 -0
  10. package/coverage/html/backend/src/contracts/consent/index.ts.html +112 -0
  11. package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +559 -0
  12. package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +220 -0
  13. package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +463 -0
  14. package/coverage/html/backend/src/contracts/index.html +116 -0
  15. package/coverage/html/backend/src/contracts/index.ts.html +139 -0
  16. package/coverage/html/backend/src/contracts/meta/index.html +131 -0
  17. package/coverage/html/backend/src/contracts/meta/index.ts.html +100 -0
  18. package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +196 -0
  19. package/coverage/html/backend/src/contracts/shared/index.html +116 -0
  20. package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +175 -0
  21. package/coverage/html/backend/src/core.ts.html +1624 -0
  22. package/coverage/html/backend/src/handlers/consent/index.html +161 -0
  23. package/coverage/html/backend/src/handlers/consent/index.ts.html +112 -0
  24. package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +889 -0
  25. package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +535 -0
  26. package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +1000 -0
  27. package/coverage/html/backend/src/handlers/meta/index.html +131 -0
  28. package/coverage/html/backend/src/handlers/meta/index.ts.html +100 -0
  29. package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +226 -0
  30. package/coverage/html/backend/src/index.html +161 -0
  31. package/coverage/html/backend/src/init.ts.html +1018 -0
  32. package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +116 -0
  33. package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +544 -0
  34. package/coverage/html/backend/src/pkgs/api-router/index.html +116 -0
  35. package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +334 -0
  36. package/coverage/html/backend/src/pkgs/api-router/utils/cors.ts.html +304 -0
  37. package/coverage/html/backend/src/pkgs/api-router/utils/index.html +131 -0
  38. package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +361 -0
  39. package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +709 -0
  40. package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +256 -0
  41. package/coverage/html/backend/src/pkgs/data-model/fields/index.html +161 -0
  42. package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +136 -0
  43. package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +496 -0
  44. package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +349 -0
  45. package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +176 -0
  46. package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +358 -0
  47. package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +613 -0
  48. package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +538 -0
  49. package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +289 -0
  50. package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +289 -0
  51. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +2203 -0
  52. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +116 -0
  53. package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +116 -0
  54. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +670 -0
  55. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +131 -0
  56. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +3634 -0
  57. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +116 -0
  58. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +1417 -0
  59. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +116 -0
  60. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +2071 -0
  61. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +116 -0
  62. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +1834 -0
  63. package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +316 -0
  64. package/coverage/html/backend/src/pkgs/db-adapters/index.html +131 -0
  65. package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +238 -0
  66. package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +343 -0
  67. package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +217 -0
  68. package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +146 -0
  69. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +280 -0
  70. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +289 -0
  71. package/coverage/html/backend/src/pkgs/migrations/index.html +176 -0
  72. package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +595 -0
  73. package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +301 -0
  74. package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +694 -0
  75. package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +817 -0
  76. package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +976 -0
  77. package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +703 -0
  78. package/coverage/html/backend/src/pkgs/results/core/index.html +146 -0
  79. package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +280 -0
  80. package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +271 -0
  81. package/coverage/html/backend/src/pkgs/results/index.html +131 -0
  82. package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +496 -0
  83. package/coverage/html/backend/src/pkgs/results/results/index.html +131 -0
  84. package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +628 -0
  85. package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +1234 -0
  86. package/coverage/html/backend/src/pkgs/utils/env.ts.html +337 -0
  87. package/coverage/html/backend/src/pkgs/utils/index.html +146 -0
  88. package/coverage/html/backend/src/pkgs/utils/logger.ts.html +199 -0
  89. package/coverage/html/backend/src/pkgs/utils/url.ts.html +400 -0
  90. package/coverage/html/backend/src/router.ts.html +109 -0
  91. package/coverage/html/backend/src/schema/audit-log/index.html +146 -0
  92. package/coverage/html/backend/src/schema/audit-log/registry.ts.html +436 -0
  93. package/coverage/html/backend/src/schema/audit-log/schema.ts.html +223 -0
  94. package/coverage/html/backend/src/schema/audit-log/table.ts.html +640 -0
  95. package/coverage/html/backend/src/schema/consent/index.html +146 -0
  96. package/coverage/html/backend/src/schema/consent/registry.ts.html +616 -0
  97. package/coverage/html/backend/src/schema/consent/schema.ts.html +238 -0
  98. package/coverage/html/backend/src/schema/consent/table.ts.html +748 -0
  99. package/coverage/html/backend/src/schema/consent-policy/index.html +146 -0
  100. package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +1063 -0
  101. package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +265 -0
  102. package/coverage/html/backend/src/schema/consent-policy/table.ts.html +535 -0
  103. package/coverage/html/backend/src/schema/consent-purpose/index.html +146 -0
  104. package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +589 -0
  105. package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +259 -0
  106. package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +547 -0
  107. package/coverage/html/backend/src/schema/consent-record/index.html +131 -0
  108. package/coverage/html/backend/src/schema/consent-record/schema.ts.html +211 -0
  109. package/coverage/html/backend/src/schema/consent-record/table.ts.html +457 -0
  110. package/coverage/html/backend/src/schema/create-registry.ts.html +148 -0
  111. package/coverage/html/backend/src/schema/definition.ts.html +685 -0
  112. package/coverage/html/backend/src/schema/domain/index.html +146 -0
  113. package/coverage/html/backend/src/schema/domain/registry.ts.html +973 -0
  114. package/coverage/html/backend/src/schema/domain/schema.ts.html +214 -0
  115. package/coverage/html/backend/src/schema/domain/table.ts.html +496 -0
  116. package/coverage/html/backend/src/schema/index.html +146 -0
  117. package/coverage/html/backend/src/schema/schemas.ts.html +166 -0
  118. package/coverage/html/backend/src/schema/subject/index.html +146 -0
  119. package/coverage/html/backend/src/schema/subject/registry.ts.html +973 -0
  120. package/coverage/html/backend/src/schema/subject/schema.ts.html +208 -0
  121. package/coverage/html/backend/src/schema/subject/table.ts.html +499 -0
  122. package/coverage/html/backend/src/server.ts.html +475 -0
  123. package/coverage/html/backend/src/testing/contract-testing.ts.html +1348 -0
  124. package/coverage/html/backend/src/testing/index.html +116 -0
  125. package/coverage/html/base.css +224 -0
  126. package/coverage/html/block-navigation.js +87 -0
  127. package/coverage/html/favicon.png +0 -0
  128. package/coverage/html/index.html +626 -0
  129. package/coverage/html/prettify.css +1 -0
  130. package/coverage/html/prettify.js +2 -0
  131. package/coverage/html/sort-arrow-sprite.png +0 -0
  132. package/coverage/html/sorter.js +196 -0
  133. package/dist/contracts/consent/index.d.ts +401 -0
  134. package/dist/contracts/consent/index.d.ts.map +1 -0
  135. package/dist/contracts/consent/index.test.d.ts +2 -0
  136. package/dist/contracts/consent/index.test.d.ts.map +1 -0
  137. package/dist/contracts/consent/post.contract.d.ts +212 -0
  138. package/dist/contracts/consent/post.contract.d.ts.map +1 -0
  139. package/dist/contracts/consent/post.contract.test.d.ts +2 -0
  140. package/dist/contracts/consent/post.contract.test.d.ts.map +1 -0
  141. package/dist/contracts/consent/show-banner.contract.d.ts +45 -0
  142. package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -0
  143. package/dist/contracts/consent/show-banner.contract.test.d.ts +2 -0
  144. package/dist/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
  145. package/dist/contracts/consent/verify.contract.d.ts +147 -0
  146. package/dist/contracts/consent/verify.contract.d.ts.map +1 -0
  147. package/dist/contracts/consent/verify.contract.test.d.ts +2 -0
  148. package/dist/contracts/consent/verify.contract.test.d.ts.map +1 -0
  149. package/dist/contracts/index.d.ts +963 -0
  150. package/dist/contracts/index.d.ts.map +1 -0
  151. package/dist/contracts/meta/index.d.ts +78 -0
  152. package/dist/contracts/meta/index.d.ts.map +1 -0
  153. package/dist/contracts/meta/index.test.d.ts +2 -0
  154. package/dist/contracts/meta/index.test.d.ts.map +1 -0
  155. package/dist/contracts/meta/status.contract.d.ts +77 -0
  156. package/dist/contracts/meta/status.contract.d.ts.map +1 -0
  157. package/dist/contracts/meta/status.contract.test.d.ts +2 -0
  158. package/dist/contracts/meta/status.contract.test.d.ts.map +1 -0
  159. package/dist/contracts/shared/jurisdiction.schema.d.ts +24 -0
  160. package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
  161. package/dist/core.cjs +3584 -0
  162. package/dist/core.d.ts +533 -78
  163. package/dist/core.d.ts.map +1 -1
  164. package/dist/{index.js → core.js} +1164 -1292
  165. package/dist/handlers/consent/index.d.ts +401 -0
  166. package/dist/handlers/consent/index.d.ts.map +1 -0
  167. package/dist/handlers/consent/post.handler.d.ts +234 -0
  168. package/dist/handlers/consent/post.handler.d.ts.map +1 -0
  169. package/dist/handlers/consent/show-banner.handler.d.ts +57 -0
  170. package/dist/handlers/consent/show-banner.handler.d.ts.map +1 -0
  171. package/dist/handlers/consent/show-banner.handler.test.d.ts +2 -0
  172. package/dist/handlers/consent/show-banner.handler.test.d.ts.map +1 -0
  173. package/dist/handlers/consent/verify.handler.d.ts +169 -0
  174. package/dist/handlers/consent/verify.handler.d.ts.map +1 -0
  175. package/dist/handlers/meta/index.d.ts +78 -0
  176. package/dist/handlers/meta/index.d.ts.map +1 -0
  177. package/dist/handlers/meta/status.handler.d.ts +76 -0
  178. package/dist/handlers/meta/status.handler.d.ts.map +1 -0
  179. package/dist/init.d.ts +0 -1
  180. package/dist/init.d.ts.map +1 -1
  181. package/dist/pkgs/api-router/hooks/processor.d.ts.map +1 -1
  182. package/dist/pkgs/api-router/types/router-props.d.ts +1 -1
  183. package/dist/pkgs/api-router/types/router-props.d.ts.map +1 -1
  184. package/dist/pkgs/api-router/utils/cors.d.ts +1 -1
  185. package/dist/pkgs/api-router/utils/cors.d.ts.map +1 -1
  186. package/dist/pkgs/data-model/fields/field-types.d.ts +1 -1
  187. package/dist/pkgs/data-model/fields/zod-fields.d.ts +32 -32
  188. package/dist/pkgs/data-model/index.cjs +1433 -1799
  189. package/dist/pkgs/data-model/index.js +20 -385
  190. package/dist/pkgs/data-model/schema/index.cjs +1402 -1768
  191. package/dist/pkgs/data-model/schema/index.js +20 -385
  192. package/dist/pkgs/db-adapters/adapter-factory.d.ts +2 -2
  193. package/dist/pkgs/db-adapters/adapter-factory.d.ts.map +1 -1
  194. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +4 -7
  195. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts.map +1 -1
  196. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +19 -151
  197. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +19 -151
  198. package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts +1 -3
  199. package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts.map +1 -1
  200. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +17 -149
  201. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +17 -149
  202. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts +0 -1
  203. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts.map +1 -1
  204. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts +2 -2
  205. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
  206. package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts +0 -2
  207. package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts.map +1 -1
  208. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +17 -149
  209. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +17 -149
  210. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts +0 -1
  211. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts.map +1 -1
  212. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +19 -151
  213. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +19 -151
  214. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts +0 -1
  215. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -1
  216. package/dist/pkgs/db-adapters/index.cjs +31 -153
  217. package/dist/pkgs/db-adapters/index.js +31 -153
  218. package/dist/pkgs/migrations/get-schema/get-schema.d.ts +2 -2
  219. package/dist/pkgs/migrations/get-schema/index.d.ts +1 -1
  220. package/dist/pkgs/migrations/index.cjs +30 -153
  221. package/dist/pkgs/migrations/index.js +30 -153
  222. package/dist/pkgs/migrations/schema-comparison.d.ts.map +1 -1
  223. package/dist/pkgs/results/core/error-class.d.ts +23 -21
  224. package/dist/pkgs/results/core/error-class.d.ts.map +1 -1
  225. package/dist/pkgs/results/index.cjs +17 -150
  226. package/dist/pkgs/results/index.d.ts +0 -3
  227. package/dist/pkgs/results/index.d.ts.map +1 -1
  228. package/dist/pkgs/results/index.js +17 -138
  229. package/dist/pkgs/results/orpc-error-handler.d.ts +65 -0
  230. package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -0
  231. package/dist/pkgs/results/types.d.ts +7 -7
  232. package/dist/pkgs/results/types.d.ts.map +1 -1
  233. package/dist/pkgs/types/context.d.ts +15 -8
  234. package/dist/pkgs/types/context.d.ts.map +1 -1
  235. package/dist/pkgs/types/endpoints.d.ts +3 -4
  236. package/dist/pkgs/types/endpoints.d.ts.map +1 -1
  237. package/dist/pkgs/types/options.d.ts +2 -4
  238. package/dist/pkgs/types/options.d.ts.map +1 -1
  239. package/dist/pkgs/types/plugins.d.ts +2 -3
  240. package/dist/pkgs/types/plugins.d.ts.map +1 -1
  241. package/dist/pkgs/utils/index.d.ts +1 -0
  242. package/dist/pkgs/utils/index.d.ts.map +1 -1
  243. package/dist/pkgs/utils/logger.d.ts +16 -0
  244. package/dist/pkgs/utils/logger.d.ts.map +1 -0
  245. package/dist/router.cjs +1213 -0
  246. package/dist/router.d.ts +480 -0
  247. package/dist/router.d.ts.map +1 -0
  248. package/dist/router.js +1169 -0
  249. package/dist/schema/audit-log/table.d.ts +1 -1
  250. package/dist/schema/consent/table.d.ts +1 -1
  251. package/dist/schema/consent-policy/registry.d.ts +12 -12
  252. package/dist/schema/consent-policy/schema.d.ts +6 -6
  253. package/dist/schema/consent-policy/table.d.ts +7 -7
  254. package/dist/schema/consent-purpose/registry.d.ts +6 -6
  255. package/dist/schema/consent-purpose/schema.d.ts +6 -6
  256. package/dist/schema/consent-purpose/table.d.ts +7 -7
  257. package/dist/schema/consent-record/table.d.ts +1 -1
  258. package/dist/schema/create-registry.d.ts +32 -32
  259. package/dist/schema/definition.d.ts +19 -19
  260. package/dist/schema/domain/registry.d.ts +10 -10
  261. package/dist/schema/domain/schema.d.ts +5 -5
  262. package/dist/schema/domain/table.d.ts +6 -6
  263. package/dist/schema/index.cjs +1409 -1775
  264. package/dist/schema/index.js +20 -385
  265. package/dist/schema/schemas.d.ts +19 -19
  266. package/dist/schema/subject/registry.d.ts +4 -4
  267. package/dist/schema/subject/schema.d.ts +2 -2
  268. package/dist/schema/subject/table.d.ts +3 -3
  269. package/dist/server.d.ts +2 -0
  270. package/dist/server.d.ts.map +1 -0
  271. package/dist/testing/contract-testing.d.ts +37 -0
  272. package/dist/testing/contract-testing.d.ts.map +1 -0
  273. package/dist/types/context.d.ts +1 -1
  274. package/dist/types/index.d.ts +2 -2
  275. package/dist/types/options.d.ts +33 -3
  276. package/dist/types/options.d.ts.map +1 -1
  277. package/dist/types/plugins.d.ts +3 -4
  278. package/dist/types/plugins.d.ts.map +1 -1
  279. package/package.json +20 -28
  280. package/rslib.config.ts +2 -5
  281. package/src/contracts/consent/index.test.ts +5 -0
  282. package/src/contracts/consent/index.ts +9 -0
  283. package/src/contracts/consent/post.contract.test.ts +526 -0
  284. package/src/contracts/consent/post.contract.ts +160 -0
  285. package/src/contracts/consent/show-banner.contract.test.ts +214 -0
  286. package/src/contracts/consent/show-banner.contract.ts +45 -0
  287. package/src/contracts/consent/verify.contract.test.ts +185 -0
  288. package/src/contracts/consent/verify.contract.ts +126 -0
  289. package/src/contracts/index.ts +18 -0
  290. package/src/contracts/meta/index.test.ts +5 -0
  291. package/src/contracts/meta/index.ts +5 -0
  292. package/src/contracts/meta/status.contract.test.ts +338 -0
  293. package/src/contracts/meta/status.contract.ts +37 -0
  294. package/src/contracts/shared/jurisdiction.schema.ts +30 -0
  295. package/src/core.ts +451 -161
  296. package/src/handlers/consent/index.ts +9 -0
  297. package/src/handlers/consent/post.handler.ts +273 -0
  298. package/src/handlers/consent/show-banner.handler.test.ts +148 -0
  299. package/src/handlers/consent/show-banner.handler.ts +150 -0
  300. package/src/handlers/consent/verify.handler.ts +305 -0
  301. package/src/handlers/meta/index.ts +5 -0
  302. package/src/handlers/meta/status.handler.ts +47 -0
  303. package/src/init.ts +8 -26
  304. package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +6 -0
  305. package/src/pkgs/api-router/hooks/processor.ts +2 -0
  306. package/src/pkgs/api-router/types/router-props.ts +1 -1
  307. package/src/pkgs/api-router/utils/cors.ts +1 -1
  308. package/src/pkgs/data-model/fields/field-types.ts +1 -1
  309. package/src/pkgs/data-model/fields/id-generator.ts +1 -1
  310. package/src/pkgs/db-adapters/README.md +3 -3
  311. package/src/pkgs/db-adapters/adapter-factory.ts +8 -4
  312. package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +13 -16
  313. package/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts +1 -3
  314. package/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts +0 -1
  315. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +1 -1
  316. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +1 -1
  317. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +2 -2
  318. package/src/pkgs/db-adapters/adapters/kysely-adapter/types.ts +0 -2
  319. package/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts +0 -1
  320. package/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts +0 -1
  321. package/src/pkgs/migrations/get-migration.ts +3 -3
  322. package/src/pkgs/migrations/get-schema/get-schema.ts +2 -2
  323. package/src/pkgs/migrations/get-schema/index.ts +1 -1
  324. package/src/pkgs/migrations/migration-builders.ts +2 -2
  325. package/src/pkgs/migrations/migration-execution.ts +2 -2
  326. package/src/pkgs/migrations/schema-comparison.ts +5 -4
  327. package/src/pkgs/results/__tests__/error-class.test.ts +8 -7
  328. package/src/pkgs/results/core/error-class.ts +31 -43
  329. package/src/pkgs/results/index.ts +0 -10
  330. package/src/pkgs/results/orpc-error-handler.ts +137 -0
  331. package/src/pkgs/results/types.ts +8 -7
  332. package/src/pkgs/types/context.ts +18 -9
  333. package/src/pkgs/types/endpoints.ts +3 -5
  334. package/src/pkgs/types/options.ts +2 -4
  335. package/src/pkgs/types/plugins.ts +2 -3
  336. package/src/pkgs/utils/index.ts +1 -0
  337. package/src/pkgs/utils/logger.ts +38 -0
  338. package/src/router.ts +8 -0
  339. package/src/schema/audit-log/table.ts +1 -1
  340. package/src/schema/consent/table.ts +1 -1
  341. package/src/schema/consent-policy/table.ts +1 -1
  342. package/src/schema/consent-purpose/table.ts +1 -1
  343. package/src/schema/consent-record/table.ts +1 -1
  344. package/src/schema/definition.ts +2 -2
  345. package/src/schema/domain/table.ts +1 -1
  346. package/src/schema/subject/table.ts +1 -1
  347. package/src/server.ts +130 -0
  348. package/src/testing/contract-testing.ts +437 -0
  349. package/src/types/context.ts +1 -1
  350. package/src/types/index.ts +2 -2
  351. package/src/types/options.ts +38 -3
  352. package/src/types/plugins.ts +3 -4
  353. package/dist/index.cjs +0 -3706
  354. package/dist/index.d.ts +0 -11
  355. package/dist/index.d.ts.map +0 -1
  356. package/dist/init.test.d.ts +0 -2
  357. package/dist/init.test.d.ts.map +0 -1
  358. package/dist/integrations/cloudflare.cjs +0 -312
  359. package/dist/integrations/cloudflare.d.ts +0 -32
  360. package/dist/integrations/cloudflare.d.ts.map +0 -1
  361. package/dist/integrations/cloudflare.js +0 -278
  362. package/dist/integrations/next.cjs +0 -276
  363. package/dist/integrations/next.d.ts +0 -68
  364. package/dist/integrations/next.d.ts.map +0 -1
  365. package/dist/integrations/next.js +0 -239
  366. package/dist/integrations/node.cjs +0 -257
  367. package/dist/integrations/node.d.ts +0 -29
  368. package/dist/integrations/node.d.ts.map +0 -1
  369. package/dist/integrations/node.js +0 -223
  370. package/dist/pkgs/api-router/index.d.ts +0 -9
  371. package/dist/pkgs/api-router/index.d.ts.map +0 -1
  372. package/dist/pkgs/api-router/utils/define-route.d.ts +0 -87
  373. package/dist/pkgs/api-router/utils/define-route.d.ts.map +0 -1
  374. package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts +0 -2
  375. package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts.map +0 -1
  376. package/dist/pkgs/logger/__tests__/integration.test.d.ts +0 -2
  377. package/dist/pkgs/logger/__tests__/integration.test.d.ts.map +0 -1
  378. package/dist/pkgs/logger/__tests__/log-levels.test.d.ts +0 -2
  379. package/dist/pkgs/logger/__tests__/log-levels.test.d.ts.map +0 -1
  380. package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts +0 -2
  381. package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts.map +0 -1
  382. package/dist/pkgs/logger/__tests__/result-logging.test.d.ts +0 -2
  383. package/dist/pkgs/logger/__tests__/result-logging.test.d.ts.map +0 -1
  384. package/dist/pkgs/logger/__tests__/types.test.d.ts +0 -2
  385. package/dist/pkgs/logger/__tests__/types.test.d.ts.map +0 -1
  386. package/dist/pkgs/logger/console-formatter.d.ts +0 -56
  387. package/dist/pkgs/logger/console-formatter.d.ts.map +0 -1
  388. package/dist/pkgs/logger/index.cjs +0 -240
  389. package/dist/pkgs/logger/index.d.ts +0 -35
  390. package/dist/pkgs/logger/index.d.ts.map +0 -1
  391. package/dist/pkgs/logger/index.js +0 -185
  392. package/dist/pkgs/logger/log-levels.d.ts +0 -29
  393. package/dist/pkgs/logger/log-levels.d.ts.map +0 -1
  394. package/dist/pkgs/logger/logger-factory.d.ts +0 -42
  395. package/dist/pkgs/logger/logger-factory.d.ts.map +0 -1
  396. package/dist/pkgs/logger/result-logging.d.ts +0 -71
  397. package/dist/pkgs/logger/result-logging.d.ts.map +0 -1
  398. package/dist/pkgs/logger/telemetry.d.ts +0 -14
  399. package/dist/pkgs/logger/telemetry.d.ts.map +0 -1
  400. package/dist/pkgs/logger/types.d.ts +0 -121
  401. package/dist/pkgs/logger/types.d.ts.map +0 -1
  402. package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts +0 -2
  403. package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts.map +0 -1
  404. package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts +0 -2
  405. package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts.map +0 -1
  406. package/dist/pkgs/results/h3-integration.d.ts +0 -52
  407. package/dist/pkgs/results/h3-integration.d.ts.map +0 -1
  408. package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts +0 -101
  409. package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts.map +0 -1
  410. package/dist/pkgs/results/pipeline/validation-pipeline.d.ts +0 -89
  411. package/dist/pkgs/results/pipeline/validation-pipeline.d.ts.map +0 -1
  412. package/dist/response-types.d.ts +0 -19
  413. package/dist/response-types.d.ts.map +0 -1
  414. package/dist/routes/__test__/index.test.d.ts +0 -17
  415. package/dist/routes/__test__/index.test.d.ts.map +0 -1
  416. package/dist/routes/__test__/set-consent.test.d.ts +0 -2
  417. package/dist/routes/__test__/set-consent.test.d.ts.map +0 -1
  418. package/dist/routes/__test__/show-consent-banner.test.d.ts +0 -2
  419. package/dist/routes/__test__/show-consent-banner.test.d.ts.map +0 -1
  420. package/dist/routes/__test__/status.test.d.ts +0 -2
  421. package/dist/routes/__test__/status.test.d.ts.map +0 -1
  422. package/dist/routes/__test__/verify-consent.test.d.ts +0 -2
  423. package/dist/routes/__test__/verify-consent.test.d.ts.map +0 -1
  424. package/dist/routes/index.d.ts +0 -3
  425. package/dist/routes/index.d.ts.map +0 -1
  426. package/dist/routes/set-consent.d.ts +0 -89
  427. package/dist/routes/set-consent.d.ts.map +0 -1
  428. package/dist/routes/show-consent-banner.d.ts +0 -15
  429. package/dist/routes/show-consent-banner.d.ts.map +0 -1
  430. package/dist/routes/status.d.ts +0 -44
  431. package/dist/routes/status.d.ts.map +0 -1
  432. package/dist/routes/types.d.ts +0 -7
  433. package/dist/routes/types.d.ts.map +0 -1
  434. package/dist/routes/verify-consent.d.ts +0 -38
  435. package/dist/routes/verify-consent.d.ts.map +0 -1
  436. package/src/docs/ADVANCED_JSON_HANDLING.md +0 -99
  437. package/src/docs/neverthrow.md +0 -171
  438. package/src/index.ts +0 -34
  439. package/src/init.test.ts +0 -236
  440. package/src/integrations/cloudflare.ts +0 -269
  441. package/src/integrations/next.ts +0 -204
  442. package/src/integrations/node.ts +0 -141
  443. package/src/pkgs/api-router/index.ts +0 -148
  444. package/src/pkgs/api-router/types/h3.d.ts +0 -42
  445. package/src/pkgs/api-router/utils/define-route.ts +0 -410
  446. package/src/pkgs/logger/README.md +0 -213
  447. package/src/pkgs/logger/__tests__/console-formatter.test.ts +0 -67
  448. package/src/pkgs/logger/__tests__/integration.test.ts +0 -184
  449. package/src/pkgs/logger/__tests__/log-levels.test.ts +0 -77
  450. package/src/pkgs/logger/__tests__/logger-factory.test.ts +0 -156
  451. package/src/pkgs/logger/__tests__/result-logging.test.ts +0 -209
  452. package/src/pkgs/logger/__tests__/types.test.ts +0 -94
  453. package/src/pkgs/logger/console-formatter.ts +0 -75
  454. package/src/pkgs/logger/doc.md +0 -569
  455. package/src/pkgs/logger/index.ts +0 -59
  456. package/src/pkgs/logger/log-levels.ts +0 -46
  457. package/src/pkgs/logger/logger-factory.ts +0 -121
  458. package/src/pkgs/logger/result-logging.ts +0 -134
  459. package/src/pkgs/logger/telemetry.ts +0 -96
  460. package/src/pkgs/logger/types.ts +0 -138
  461. package/src/pkgs/results/__tests__/retrieval-pipeline.test.ts +0 -157
  462. package/src/pkgs/results/__tests__/validation-pipeline.test.ts +0 -151
  463. package/src/pkgs/results/h3-integration.ts +0 -142
  464. package/src/pkgs/results/pipeline/retrieval-pipeline.ts +0 -188
  465. package/src/pkgs/results/pipeline/validation-pipeline.ts +0 -164
  466. package/src/plugins/.keep +0 -0
  467. package/src/response-types.ts +0 -29
  468. package/src/routes/__test__/index.test.ts +0 -112
  469. package/src/routes/__test__/set-consent.test.ts +0 -242
  470. package/src/routes/__test__/show-consent-banner.test.ts +0 -98
  471. package/src/routes/__test__/status.test.ts +0 -64
  472. package/src/routes/__test__/verify-consent.test.ts +0 -266
  473. package/src/routes/index.ts +0 -12
  474. package/src/routes/set-consent.ts +0 -249
  475. package/src/routes/show-consent-banner.ts +0 -131
  476. package/src/routes/status.ts +0 -61
  477. package/src/routes/types.ts +0 -7
  478. package/src/routes/verify-consent.ts +0 -206
@@ -0,0 +1,214 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ // import { createContractTests } from '~/testing/contract-testing';
4
+ import { showConsentBannerContract } from './show-banner.contract';
5
+
6
+ // // Create base tests for the contract using the utility
7
+ // const tester = createContractTests(
8
+ // 'Show Consent Banner',
9
+ // showConsentBannerContract
10
+ // );
11
+
12
+ // Add custom tests specific to the show-banner contract
13
+ describe('Show Consent Banner Contract Custom Tests', () => {
14
+ // Helper to access schemas consistently throughout tests
15
+ const schemas = {
16
+ input: showConsentBannerContract['~orpc'].inputSchema,
17
+ output: showConsentBannerContract['~orpc'].outputSchema,
18
+ };
19
+
20
+ const validateOutput = (output: unknown) => {
21
+ return schemas.output?.safeParse(output);
22
+ };
23
+
24
+ describe('Output Validation', () => {
25
+ describe('Required fields', () => {
26
+ it('validates complete output object', () => {
27
+ const validOutput = {
28
+ showConsentBanner: true,
29
+ jurisdiction: {
30
+ code: 'GDPR',
31
+ message: 'GDPR or equivalent regulations require a cookie banner.',
32
+ },
33
+ location: {
34
+ countryCode: 'DE',
35
+ regionCode: null,
36
+ },
37
+ };
38
+
39
+ const result = validateOutput(validOutput);
40
+ expect(result?.success).toBe(true);
41
+ });
42
+
43
+ it('rejects output without required fields', () => {
44
+ const invalidOutput = {
45
+ showConsentBanner: true,
46
+ // Missing jurisdiction and location
47
+ };
48
+
49
+ const result = validateOutput(invalidOutput);
50
+ expect(result?.success).toBe(false);
51
+ });
52
+ });
53
+
54
+ describe('Jurisdiction validation', () => {
55
+ it('validates all supported jurisdiction codes', () => {
56
+ const jurisdictionCodes = [
57
+ 'GDPR',
58
+ 'CH',
59
+ 'BR',
60
+ 'PIPEDA',
61
+ 'AU',
62
+ 'APPI',
63
+ 'PIPA',
64
+ 'NONE',
65
+ ];
66
+
67
+ for (const code of jurisdictionCodes) {
68
+ const output = {
69
+ showConsentBanner: true,
70
+ jurisdiction: {
71
+ code,
72
+ message: 'Test message',
73
+ },
74
+ location: {
75
+ countryCode: 'US',
76
+ regionCode: null,
77
+ },
78
+ };
79
+
80
+ const result = validateOutput(output);
81
+ expect(result?.success).toBe(true);
82
+ }
83
+ });
84
+
85
+ it('rejects invalid jurisdiction codes', () => {
86
+ const output = {
87
+ showConsentBanner: true,
88
+ jurisdiction: {
89
+ code: 'INVALID_CODE', // Invalid code
90
+ message: 'Test message',
91
+ },
92
+ location: {
93
+ countryCode: 'US',
94
+ regionCode: null,
95
+ },
96
+ };
97
+
98
+ const result = validateOutput(output);
99
+ expect(result?.success).toBe(false);
100
+ });
101
+ });
102
+
103
+ describe('Location validation', () => {
104
+ it('accepts null country and region codes', () => {
105
+ const output = {
106
+ showConsentBanner: false,
107
+ jurisdiction: {
108
+ code: 'NONE',
109
+ message: 'No specific requirements',
110
+ },
111
+ location: {
112
+ countryCode: null,
113
+ regionCode: null,
114
+ },
115
+ };
116
+
117
+ const result = validateOutput(output);
118
+ expect(result?.success).toBe(true);
119
+ });
120
+
121
+ it('accepts valid country and region codes', () => {
122
+ const output = {
123
+ showConsentBanner: true,
124
+ jurisdiction: {
125
+ code: 'GDPR',
126
+ message: 'GDPR applies',
127
+ },
128
+ location: {
129
+ countryCode: 'DE',
130
+ regionCode: 'BY',
131
+ },
132
+ };
133
+
134
+ const result = validateOutput(output);
135
+ expect(result?.success).toBe(true);
136
+ });
137
+
138
+ it('rejects non-string non-null country codes', () => {
139
+ const output = {
140
+ showConsentBanner: true,
141
+ jurisdiction: {
142
+ code: 'GDPR',
143
+ message: 'GDPR applies',
144
+ },
145
+ location: {
146
+ countryCode: 123, // Invalid type
147
+ regionCode: null,
148
+ },
149
+ };
150
+
151
+ // Need to use type assertion to bypass TypeScript
152
+ const result = validateOutput(output);
153
+ expect(result?.success).toBe(false);
154
+ });
155
+ });
156
+
157
+ describe('ShowConsentBanner flag', () => {
158
+ it('validates boolean value', () => {
159
+ const trueOutput = {
160
+ showConsentBanner: true,
161
+ jurisdiction: {
162
+ code: 'GDPR',
163
+ message: 'GDPR applies',
164
+ },
165
+ location: {
166
+ countryCode: 'DE',
167
+ regionCode: null,
168
+ },
169
+ };
170
+
171
+ const falseOutput = {
172
+ showConsentBanner: false,
173
+ jurisdiction: {
174
+ code: 'NONE',
175
+ message: 'No requirements',
176
+ },
177
+ location: {
178
+ countryCode: 'US',
179
+ regionCode: null,
180
+ },
181
+ };
182
+
183
+ expect(validateOutput(trueOutput)?.success).toBe(true);
184
+ expect(validateOutput(falseOutput)?.success).toBe(true);
185
+ });
186
+
187
+ it('rejects non-boolean values', () => {
188
+ const invalidOutput = {
189
+ showConsentBanner: 'yes', // Invalid type
190
+ jurisdiction: {
191
+ code: 'GDPR',
192
+ message: 'GDPR applies',
193
+ },
194
+ location: {
195
+ countryCode: 'DE',
196
+ regionCode: null,
197
+ },
198
+ };
199
+
200
+ // Need to use type assertion to bypass TypeScript
201
+ const result = validateOutput(invalidOutput);
202
+ expect(result?.success).toBe(false);
203
+ });
204
+ });
205
+ });
206
+ });
207
+
208
+ // // Add required fields testing using the utility
209
+ // // No required fields for input since it's an empty object
210
+ // tester.testRequiredFields('output', [
211
+ // 'showConsentBanner',
212
+ // 'jurisdiction',
213
+ // 'location',
214
+ // ]);
@@ -0,0 +1,45 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+
4
+ import { JurisdictionInfoSchema } from '../shared/jurisdiction.schema';
5
+
6
+ export const showConsentBannerContract = oc
7
+ .route({
8
+ method: 'GET',
9
+ path: '/show-consent-banner',
10
+ description: `Determines if a user should see a consent banner based on their location and applicable privacy regulations.
11
+ This endpoint performs the following checks:
12
+
13
+ 1. Detects the user's location using various header information:
14
+ - Cloudflare country headers
15
+ - Vercel IP country headers
16
+ - AWS CloudFront headers
17
+ - Custom country code headers
18
+
19
+ 2. Determines the applicable jurisdiction based on the location:
20
+ - GDPR (EU/EEA/UK)
21
+ - Swiss Data Protection Act
22
+ - LGPD (Brazil)
23
+ - PIPEDA (Canada)
24
+ - Australian Privacy Principles
25
+ - APPI (Japan)
26
+ - PIPA (South Korea)
27
+
28
+ 3. Returns detailed information about:
29
+ - Whether to show the consent banner
30
+ - The applicable jurisdiction and its requirements
31
+ - The user's detected location (country and region)
32
+
33
+ Use this endpoint to implement geo-targeted consent banners and ensure compliance with regional privacy regulations.`,
34
+ tags: ['cookie-banner'],
35
+ })
36
+ .output(
37
+ z.object({
38
+ showConsentBanner: z.boolean(),
39
+ jurisdiction: JurisdictionInfoSchema,
40
+ location: z.object({
41
+ countryCode: z.string().nullable(),
42
+ regionCode: z.string().nullable(),
43
+ }),
44
+ })
45
+ );
@@ -0,0 +1,185 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { createContractTests } from '~/testing/contract-testing';
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,126 @@
1
+ import { oc } from '@orpc/contract';
2
+ import { z } from 'zod';
3
+ import { PolicyTypeSchema } from '~/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
12
+ .object({
13
+ subjectId: z.string().optional(),
14
+ externalSubjectId: z.string().optional(),
15
+ domain: z.string(),
16
+ type: PolicyTypeSchema,
17
+ policyId: z.string().optional(),
18
+ preferences: z.array(z.string()).optional(),
19
+ })
20
+ .strict();
21
+
22
+ // Minimal consent schema based on the response interface
23
+ const consentSchema = z
24
+ .object({
25
+ id: z.string(),
26
+ purposeIds: z.array(z.string()),
27
+ })
28
+ .passthrough(); // Allow additional properties
29
+
30
+ // Output schema based on VerifyConsentResponse
31
+ export const verifyConsentContract = oc
32
+ .route({
33
+ method: 'POST',
34
+ path: '/consent/verify',
35
+ description: `Verifies if a user has given valid consent for a specific policy and domain.
36
+ This endpoint performs comprehensive consent verification by:
37
+
38
+ 1. Validating the subject's identity (using subjectId or externalSubjectId)
39
+ 2. Verifying the domain's existence and validity
40
+ 3. Checking if the specified policy exists and is active
41
+ 4. Validating that all required purposes have been consented to
42
+ 5. Ensuring the consent record is current and valid
43
+
44
+ The endpoint supports different types of consent verification:
45
+ - Cookie banner consent verification
46
+ - Privacy policy consent verification
47
+ - Terms and conditions verification
48
+ - Marketing communications consent verification
49
+ - Age verification
50
+ - Custom consent types
51
+
52
+ Use this endpoint to ensure compliance with privacy regulations and to verify user consent before processing personal data.`,
53
+ tags: ['consent'],
54
+ })
55
+ .errors({
56
+ // Input validation errors
57
+ INPUT_VALIDATION_FAILED: {
58
+ status: 422,
59
+ message: 'Invalid input parameters',
60
+ data: z.object({
61
+ formErrors: z.array(z.string()),
62
+ fieldErrors: z.record(z.string(), z.array(z.string()).optional()),
63
+ }),
64
+ },
65
+ // Subject errors
66
+ SUBJECT_NOT_FOUND: {
67
+ status: 404,
68
+ message: 'Subject not found',
69
+ data: z.object({
70
+ subjectId: z.string().optional(),
71
+ externalSubjectId: z.string().optional(),
72
+ }),
73
+ },
74
+ // Domain errors
75
+ DOMAIN_NOT_FOUND: {
76
+ status: 404,
77
+ message: 'Domain not found',
78
+ data: z.object({
79
+ domain: z.string(),
80
+ }),
81
+ },
82
+ // Policy errors
83
+ POLICY_NOT_FOUND: {
84
+ status: 404,
85
+ message: 'Policy not found or invalid',
86
+ data: z.object({
87
+ policyId: z.string(),
88
+ type: z.string(),
89
+ }),
90
+ },
91
+ // Purpose errors
92
+ PURPOSES_NOT_FOUND: {
93
+ status: 404,
94
+ message: 'Could not find all specified purposes',
95
+ data: z.object({
96
+ preferences: z.array(z.string()),
97
+ foundPurposes: z.array(z.string()),
98
+ }),
99
+ },
100
+ // Cookie banner specific errors
101
+ COOKIE_BANNER_PREFERENCES_REQUIRED: {
102
+ status: 400,
103
+ message: 'Preferences are required for cookie banner consent',
104
+ data: z.object({
105
+ type: z.literal('cookie_banner'),
106
+ }),
107
+ },
108
+ // Consent errors
109
+ NO_CONSENT_FOUND: {
110
+ status: 404,
111
+ message: 'No consent found for the given policy',
112
+ data: z.object({
113
+ policyId: z.string(),
114
+ subjectId: z.string(),
115
+ domainId: z.string(),
116
+ }),
117
+ },
118
+ })
119
+ .input(verifyConsentInputSchema)
120
+ .output(
121
+ z.object({
122
+ isValid: z.boolean(),
123
+ reasons: z.array(z.string()).optional(),
124
+ consent: consentSchema.optional(),
125
+ })
126
+ );
@@ -0,0 +1,18 @@
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 const os = implement(config);
16
+
17
+ export type ContractsOutputs = InferContractRouterOutputs<typeof config>;
18
+ export type ContractsInputs = InferContractRouterInputs<typeof config>;
@@ -0,0 +1,5 @@
1
+ import { createConsistencyTests } from '~/testing/contract-testing';
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
+ };