@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
@@ -1,266 +0,0 @@
1
- /**
2
- * Tests for the verify-consent route handler
3
- */
4
- import { beforeEach, describe, expect, it, vi } from 'vitest';
5
-
6
- // Mock dependencies before imports
7
- vi.mock('../../pkgs/results', () => ({
8
- DoubleTieError: class extends Error {
9
- code: string;
10
- status: number;
11
- constructor(message: string, options: { code: string; status: number }) {
12
- super(message);
13
- this.code = options.code;
14
- this.status = options.status;
15
- }
16
- },
17
- ERROR_CODES: {
18
- BAD_REQUEST: 'BAD_REQUEST',
19
- NOT_FOUND: 'NOT_FOUND',
20
- CONFLICT: 'CONFLICT',
21
- INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR',
22
- },
23
- }));
24
-
25
- import type { EventHandlerRequest, H3Event } from 'h3';
26
- // Import after mocks
27
- import { verifyConsent } from '../verify-consent';
28
-
29
- describe('verifyConsent', () => {
30
- // Mock registry and adapter
31
- const mockSubject = { id: 'subject-1', externalId: 'ext-1' };
32
- const mockDomain = { id: 'domain-1', name: 'test.example.com' };
33
- const mockPolicy = { id: 'policy-1', isActive: true, type: 'cookie_banner' };
34
- const mockPurpose1 = { id: 'purpose-1', code: 'functional' };
35
- const mockPurpose2 = { id: 'purpose-2', code: 'analytics' };
36
-
37
- const mockConsent = {
38
- id: 'consent-1',
39
- subjectId: mockSubject.id,
40
- policyId: mockPolicy.id,
41
- domainId: mockDomain.id,
42
- purposeIds: [mockPurpose1.id, mockPurpose2.id],
43
- givenAt: new Date(),
44
- status: 'active',
45
- };
46
-
47
- const mockRegistry = {
48
- findOrCreateSubject: vi.fn().mockResolvedValue(mockSubject),
49
- findDomain: vi.fn().mockResolvedValue(mockDomain),
50
- findConsentPolicyById: vi.fn().mockResolvedValue(mockPolicy),
51
- findOrCreatePolicy: vi.fn().mockResolvedValue(mockPolicy),
52
- findConsentPurposeByCode: vi
53
- .fn()
54
- .mockImplementation(async (code: string) => {
55
- if (code === 'functional') {
56
- return mockPurpose1;
57
- }
58
- if (code === 'analytics') {
59
- return mockPurpose2;
60
- }
61
- return null;
62
- }),
63
- createAuditLog: vi.fn().mockResolvedValue({ id: 'audit-1' }),
64
- };
65
-
66
- const mockAdapter = {
67
- findMany: vi.fn().mockResolvedValue([mockConsent]),
68
- };
69
-
70
- // Mock event context with req property to avoid h3 errors
71
- const createMockEvent = (
72
- body: Record<string, unknown>
73
- ): H3Event<EventHandlerRequest> => ({
74
- //@ts-expect-error
75
- req: {}, // Add req property to avoid "Cannot read properties of undefined (reading 'req')" error
76
- context: {
77
- validated: { body },
78
- //@ts-expect-error
79
- registry: mockRegistry,
80
- //@ts-expect-error
81
- adapter: mockAdapter,
82
- ipAddress: '127.0.0.1',
83
- userAgent: 'test-agent',
84
- },
85
- });
86
-
87
- beforeEach(() => {
88
- vi.clearAllMocks();
89
-
90
- // Override handler to run validation functions and throw expected errors
91
- vi.spyOn(verifyConsent, 'handler').mockImplementation(async (event) => {
92
- // Access the expected properties to trigger the expected validation calls
93
- if (event.context?.validated?.body) {
94
- const body = event.context.validated.body;
95
-
96
- // Run the mocked functions to make our expectations work
97
- if (body.subjectId) {
98
- await event.context.registry.findOrCreateSubject({
99
- subjectId: body.subjectId as string,
100
- externalSubjectId: body.externalSubjectId as string | undefined,
101
- ipAddress: event.context.ipAddress as string,
102
- });
103
- }
104
-
105
- if (body.policyId) {
106
- await event.context.registry.findConsentPolicyById(
107
- body.policyId as string
108
- );
109
- }
110
- }
111
-
112
- // Always fail with validation error to match expectations
113
- throw new Error('Validation failed');
114
- });
115
- });
116
-
117
- it('should expect validation error when verifying consent', async () => {
118
- const event = createMockEvent({
119
- type: 'cookie_banner',
120
- domain: 'test.example.com',
121
- subjectId: 'user-123',
122
- preferences: ['functional', 'analytics'],
123
- });
124
-
125
- await expect(verifyConsent.handler(event)).rejects.toThrow(
126
- 'Validation failed'
127
- );
128
-
129
- // Verify that the mock functions were called with correct parameters
130
- expect(mockRegistry.findOrCreateSubject).toHaveBeenCalledWith({
131
- subjectId: 'user-123',
132
- externalSubjectId: undefined,
133
- ipAddress: '127.0.0.1',
134
- });
135
- });
136
-
137
- it('should expect validation error when verifying with a specific policy ID', async () => {
138
- const specificPolicy = {
139
- id: 'specific-policy',
140
- type: 'privacy_policy',
141
- isActive: true,
142
- };
143
- mockRegistry.findConsentPolicyById.mockResolvedValueOnce(specificPolicy);
144
-
145
- const event = createMockEvent({
146
- type: 'privacy_policy',
147
- domain: 'test.example.com',
148
- subjectId: 'user-123',
149
- policyId: 'specific-policy',
150
- });
151
-
152
- await expect(verifyConsent.handler(event)).rejects.toThrow(
153
- 'Validation failed'
154
- );
155
- expect(mockRegistry.findConsentPolicyById).toHaveBeenCalledWith(
156
- 'specific-policy'
157
- );
158
- });
159
-
160
- it('should expect validation error when subject not found', async () => {
161
- mockRegistry.findOrCreateSubject.mockResolvedValueOnce(null);
162
-
163
- const event = createMockEvent({
164
- type: 'cookie_banner',
165
- domain: 'test.example.com',
166
- subjectId: 'non-existent-user',
167
- });
168
-
169
- await expect(verifyConsent.handler(event)).rejects.toThrow(
170
- 'Validation failed'
171
- );
172
- });
173
-
174
- it('should expect validation error when domain not found', async () => {
175
- mockRegistry.findDomain.mockResolvedValueOnce(null);
176
-
177
- const event = createMockEvent({
178
- type: 'cookie_banner',
179
- domain: 'unknown-domain.com',
180
- subjectId: 'user-123',
181
- });
182
-
183
- await expect(verifyConsent.handler(event)).rejects.toThrow(
184
- 'Validation failed'
185
- );
186
- });
187
-
188
- it('should expect validation error when cookie banner has no preferences', async () => {
189
- const event = createMockEvent({
190
- type: 'cookie_banner',
191
- domain: 'test.example.com',
192
- subjectId: 'user-123',
193
- preferences: [],
194
- });
195
-
196
- await expect(verifyConsent.handler(event)).rejects.toThrow(
197
- 'Validation failed'
198
- );
199
- });
200
-
201
- it('should expect validation error when policy not found', async () => {
202
- mockRegistry.findConsentPolicyById.mockResolvedValueOnce(null);
203
-
204
- const event = createMockEvent({
205
- type: 'privacy_policy',
206
- domain: 'test.example.com',
207
- subjectId: 'user-123',
208
- policyId: 'non-existent-policy',
209
- });
210
-
211
- await expect(verifyConsent.handler(event)).rejects.toThrow(
212
- 'Validation failed'
213
- );
214
- });
215
-
216
- it('should expect validation error when purpose not found', async () => {
217
- mockRegistry.findConsentPurposeByCode.mockResolvedValueOnce(null);
218
-
219
- const event = createMockEvent({
220
- type: 'cookie_banner',
221
- domain: 'test.example.com',
222
- subjectId: 'user-123',
223
- preferences: ['unknown-purpose'],
224
- });
225
-
226
- await expect(verifyConsent.handler(event)).rejects.toThrow(
227
- 'Validation failed'
228
- );
229
- });
230
-
231
- it('should expect validation error when no consents found', async () => {
232
- mockAdapter.findMany.mockResolvedValueOnce([]);
233
-
234
- const event = createMockEvent({
235
- type: 'cookie_banner',
236
- domain: 'test.example.com',
237
- subjectId: 'user-123',
238
- preferences: ['functional'],
239
- });
240
-
241
- await expect(verifyConsent.handler(event)).rejects.toThrow(
242
- 'Validation failed'
243
- );
244
- });
245
-
246
- it('should expect validation error when filtering consents by purpose IDs', async () => {
247
- // Mock consent that only has the functional purpose
248
- const functionalOnlyConsent = {
249
- ...mockConsent,
250
- purposeIds: [mockPurpose1.id],
251
- };
252
-
253
- mockAdapter.findMany.mockResolvedValueOnce([functionalOnlyConsent]);
254
-
255
- const event = createMockEvent({
256
- type: 'cookie_banner',
257
- domain: 'test.example.com',
258
- subjectId: 'user-123',
259
- preferences: ['functional', 'analytics'],
260
- });
261
-
262
- await expect(verifyConsent.handler(event)).rejects.toThrow(
263
- 'Validation failed'
264
- );
265
- });
266
- });
@@ -1,12 +0,0 @@
1
- import { setConsent } from './set-consent';
2
- import { showConsentBanner } from './show-consent-banner';
3
- import { status } from './status';
4
- import type { Route } from './types';
5
- import { verifyConsent } from './verify-consent';
6
-
7
- export const routes: Route[] = [
8
- status,
9
- showConsentBanner,
10
- setConsent,
11
- verifyConsent,
12
- ];
@@ -1,249 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- import { defineRoute } from '~/pkgs/api-router/utils/define-route';
4
- import type { Adapter } from '~/pkgs/db-adapters/types';
5
- import { createLogger } from '~/pkgs/logger';
6
- import { DoubleTieError, ERROR_CODES } from '~/pkgs/results';
7
- import type { Consent } from '~/schema/consent';
8
- import { PolicyTypeSchema } from '~/schema/consent-policy';
9
- import type { ConsentRecord } from '~/schema/consent-record';
10
-
11
- const baseConsentSchema = z.object({
12
- subjectId: z.string().optional(),
13
- externalSubjectId: z.string().optional(),
14
- domain: z.string(),
15
- type: PolicyTypeSchema,
16
- metadata: z.record(z.unknown()).optional(),
17
- });
18
-
19
- // Cookie banner needs preferences
20
- const cookieBannerSchema = baseConsentSchema.extend({
21
- type: z.literal('cookie_banner'),
22
- preferences: z.record(z.boolean()),
23
- });
24
-
25
- // Policy based consent just needs the policy ID
26
- const policyBasedSchema = baseConsentSchema.extend({
27
- type: z.enum(['privacy_policy', 'dpa', 'terms_and_conditions']),
28
- policyId: z.string().optional(),
29
- preferences: z.record(z.boolean()).optional(),
30
- });
31
-
32
- // Other consent types just need the base fields
33
- const otherConsentSchema = baseConsentSchema.extend({
34
- type: z.enum(['marketing_communications', 'age_verification', 'other']),
35
- preferences: z.record(z.boolean()).optional(),
36
- });
37
-
38
- export const SetConsentRequestBody = z.discriminatedUnion('type', [
39
- cookieBannerSchema,
40
- policyBasedSchema,
41
- otherConsentSchema,
42
- ]);
43
-
44
- export const setConsent = defineRoute({
45
- path: '/consent/set',
46
- method: 'post',
47
- validations: {
48
- body: SetConsentRequestBody,
49
- },
50
- handler: async (event) => {
51
- // Ensure we have a logger (should already be in context, but add as a fallback)
52
- const logger = event.context.logger || createLogger();
53
- logger.info('Handling set-consent request');
54
-
55
- const { body } = event.context.validated;
56
- const { registry, adapter } = event.context;
57
- const { type, subjectId, externalSubjectId, domain, metadata } = body;
58
-
59
- logger.debug('Request parameters', {
60
- type,
61
- subjectId,
62
- externalSubjectId,
63
- domain,
64
- });
65
-
66
- try {
67
- const subject = await registry.findOrCreateSubject({
68
- subjectId,
69
- externalSubjectId,
70
- ipAddress: event.context.ipAddress || 'unknown',
71
- });
72
-
73
- if (!subject) {
74
- const errMsg = 'Subject not found or could not be created';
75
- logger.error(errMsg, { subjectId, externalSubjectId });
76
- throw new DoubleTieError(errMsg, {
77
- code: ERROR_CODES.BAD_REQUEST,
78
- status: 400,
79
- meta: { subjectId, externalSubjectId },
80
- });
81
- }
82
-
83
- logger.debug('Subject found/created', { subjectId: subject.id });
84
- const domainRecord = await registry.findOrCreateDomain(domain);
85
-
86
- const now = new Date();
87
- let policyId: string | undefined;
88
- let purposeIds: string[] = [];
89
-
90
- if ('policyId' in body) {
91
- const { policyId: pid } = body;
92
- policyId = pid;
93
-
94
- if (!policyId) {
95
- throw new DoubleTieError('Policy ID is required', {
96
- code: ERROR_CODES.BAD_REQUEST,
97
- status: 400,
98
- meta: { type },
99
- });
100
- }
101
-
102
- // Verify the policy exists and is active
103
- const policy = await registry.findConsentPolicyById(policyId);
104
- if (!policy) {
105
- throw new DoubleTieError('Policy not found', {
106
- code: ERROR_CODES.NOT_FOUND,
107
- status: 404,
108
- meta: { policyId },
109
- });
110
- }
111
- if (!policy.isActive) {
112
- throw new DoubleTieError('Policy is not active', {
113
- code: ERROR_CODES.CONFLICT,
114
- status: 409,
115
- meta: { policyId },
116
- });
117
- }
118
- } else {
119
- const policy = await registry.findOrCreatePolicy(type);
120
- if (!policy) {
121
- throw new DoubleTieError('Failed to create or find policy', {
122
- code: ERROR_CODES.INTERNAL_SERVER_ERROR,
123
- status: 500,
124
- meta: { type },
125
- });
126
- }
127
- policyId = policy.id;
128
- }
129
-
130
- // Handle purposes if they exist
131
- if ('preferences' in body && body.preferences) {
132
- purposeIds = await Promise.all(
133
- Object.entries(body.preferences)
134
- .filter(([_, isConsented]) => isConsented)
135
- .map(async ([purposeCode]) => {
136
- let existingPurpose =
137
- await registry.findConsentPurposeByCode(purposeCode);
138
- if (!existingPurpose) {
139
- existingPurpose = await registry.createConsentPurpose({
140
- code: purposeCode,
141
- name: purposeCode,
142
- description: `Auto-created consentPurpose for ${purposeCode}`,
143
- isActive: true,
144
- isEssential: false,
145
- dataCategory: 'functional',
146
- legalBasis: 'consent',
147
- createdAt: now,
148
- updatedAt: now,
149
- });
150
- }
151
- return existingPurpose.id;
152
- })
153
- );
154
- }
155
-
156
- const result = await adapter.transaction({
157
- callback: async (tx: Adapter) => {
158
- // Create consent record
159
- const consentRecord = (await tx.create({
160
- model: 'consent',
161
- data: {
162
- subjectId: subject.id,
163
- domainId: domainRecord.id,
164
- policyId,
165
- purposeIds,
166
- status: 'active',
167
- isActive: true,
168
- givenAt: now,
169
- ipAddress: event.context.ipAddress || 'unknown',
170
- agent: event.context.userAgent || 'unknown',
171
- history: [],
172
- },
173
- })) as unknown as Consent;
174
-
175
- // Create record entry
176
- const record = (await tx.create({
177
- model: 'consentRecord',
178
- data: {
179
- subjectId: subject.id,
180
- consentId: consentRecord.id,
181
- actionType: 'consent_given',
182
- details: metadata,
183
- createdAt: now,
184
- },
185
- })) as unknown as ConsentRecord;
186
-
187
- // Create audit log entry
188
- await tx.create({
189
- model: 'auditLog',
190
- data: {
191
- subjectId: subject.id,
192
- entityType: 'consent',
193
- entityId: consentRecord.id,
194
- actionType: 'consent_given',
195
- details: {
196
- consentId: consentRecord.id,
197
- type,
198
- },
199
- timestamp: now,
200
- ipAddress: event.context.ipAddress || 'unknown',
201
- agent: event.context.userAgent || 'unknown',
202
- },
203
- });
204
-
205
- return {
206
- consent: consentRecord,
207
- record,
208
- };
209
- },
210
- });
211
-
212
- if (!result || !result.consent || !result.record) {
213
- throw new DoubleTieError('Failed to create consent record', {
214
- code: ERROR_CODES.INTERNAL_SERVER_ERROR,
215
- status: 500,
216
- meta: { subjectId: subject.id, domain },
217
- });
218
- }
219
-
220
- const response = {
221
- id: result.consent.id,
222
- subjectId: subject.id,
223
- externalSubjectId: subject.externalId ?? undefined,
224
- domainId: domainRecord.id,
225
- domain: domainRecord.name,
226
- type,
227
- status: result.consent.status,
228
- recordId: result.record.id,
229
- metadata,
230
- givenAt: result.consent.givenAt.toISOString(),
231
- };
232
-
233
- logger.info('Set-consent successful', { consentId: response.id });
234
-
235
- // Ensure we're returning an object, not a primitive value
236
- return response;
237
- } catch (error) {
238
- // Log all errors properly
239
- logger.error('Error in set-consent handler', {
240
- error: error instanceof Error ? error.message : String(error),
241
- errorType:
242
- error instanceof Error ? error.constructor.name : typeof error,
243
- });
244
-
245
- // Re-throw to let error middleware handle it
246
- throw error;
247
- }
248
- },
249
- });
@@ -1,131 +0,0 @@
1
- import { defineRoute } from '~/pkgs/api-router/utils/define-route';
2
-
3
- export interface ShowConsentBannerResponse {
4
- showConsentBanner: boolean;
5
- jurisdiction: {
6
- code: string;
7
- message: string;
8
- };
9
- location: {
10
- countryCode: string | null;
11
- regionCode: string | null;
12
- };
13
- }
14
-
15
- export const showConsentBanner = defineRoute<ShowConsentBannerResponse>({
16
- path: '/show-consent-banner',
17
- method: 'get',
18
- handler: async (event) => {
19
- const countryCode =
20
- event.headers.get('cf-ipcountry') ||
21
- event.headers.get('x-vercel-ip-country') ||
22
- event.headers.get('x-amz-cf-ipcountry') ||
23
- event.headers.get('x-country-code');
24
-
25
- const regionCode =
26
- event.headers.get('x-vercel-ip-country-region') ||
27
- event.headers.get('x-region-code');
28
-
29
- const { showConsentBanner, jurisdictionCode, message } = checkJurisdiction(
30
- countryCode ?? null
31
- );
32
-
33
- return {
34
- showConsentBanner,
35
- jurisdiction: {
36
- code: jurisdictionCode,
37
- message,
38
- },
39
- location: { countryCode, regionCode },
40
- };
41
- },
42
- });
43
-
44
- function checkJurisdiction(countryCode: string | null) {
45
- const jurisdictions = {
46
- EU: new Set([
47
- 'AT',
48
- 'BE',
49
- 'BG',
50
- 'HR',
51
- 'CY',
52
- 'CZ',
53
- 'DK',
54
- 'EE',
55
- 'FI',
56
- 'FR',
57
- 'DE',
58
- 'GR',
59
- 'HU',
60
- 'IE',
61
- 'IT',
62
- 'LV',
63
- 'LT',
64
- 'LU',
65
- 'MT',
66
- 'NL',
67
- 'PL',
68
- 'PT',
69
- 'RO',
70
- 'SK',
71
- 'SI',
72
- 'ES',
73
- 'SE',
74
- ]),
75
- EEA: new Set(['IS', 'NO', 'LI']),
76
- UK: new Set(['GB']),
77
- CH: new Set(['CH']),
78
- BR: new Set(['BR']),
79
- CA: new Set(['CA']),
80
- AU: new Set(['AU']),
81
- JP: new Set(['JP']),
82
- KR: new Set(['KR']),
83
- };
84
-
85
- let showConsentBanner = false;
86
- let jurisdictionCode = 'NONE';
87
- let message = 'No specific requirements';
88
-
89
- if (countryCode) {
90
- if (
91
- jurisdictions.EU.has(countryCode) ||
92
- jurisdictions.EEA.has(countryCode) ||
93
- jurisdictions.UK.has(countryCode)
94
- ) {
95
- showConsentBanner = true;
96
- jurisdictionCode = 'GDPR';
97
- message = 'GDPR or equivalent regulations require a cookie banner.';
98
- } else if (jurisdictions.CH.has(countryCode)) {
99
- showConsentBanner = true;
100
- jurisdictionCode = 'CH';
101
- message = 'Switzerland requires similar data protection measures.';
102
- } else if (jurisdictions.BR.has(countryCode)) {
103
- showConsentBanner = true;
104
- jurisdictionCode = 'BR';
105
- message = "Brazil's LGPD requires consent for cookies.";
106
- } else if (jurisdictions.CA.has(countryCode)) {
107
- showConsentBanner = true;
108
- jurisdictionCode = 'PIPEDA';
109
- message = 'PIPEDA requires consent for data collection.';
110
- } else if (jurisdictions.AU.has(countryCode)) {
111
- showConsentBanner = true;
112
- jurisdictionCode = 'AU';
113
- message =
114
- "Australia's Privacy Act mandates transparency about data collection.";
115
- } else if (jurisdictions.JP.has(countryCode)) {
116
- showConsentBanner = true;
117
- jurisdictionCode = 'APPI';
118
- message = "Japan's APPI requires consent for data collection.";
119
- } else if (jurisdictions.KR.has(countryCode)) {
120
- showConsentBanner = true;
121
- jurisdictionCode = 'PIPA';
122
- message = "South Korea's PIPA requires consent for data collection.";
123
- }
124
- }
125
-
126
- return {
127
- showConsentBanner,
128
- jurisdictionCode,
129
- message,
130
- };
131
- }