@c15t/backend 0.0.1-rc.10

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 (521) hide show
  1. package/.turbo/turbo-build.log +11 -0
  2. package/.turbo/turbo-check-types.log +5 -0
  3. package/.turbo/turbo-fmt.log +7 -0
  4. package/.turbo/turbo-lint.log +6 -0
  5. package/.turbo/turbo-test.log +26 -0
  6. package/README-next.md +223 -0
  7. package/README.md +164 -0
  8. package/dist/api/call.d.ts +176 -0
  9. package/dist/api/call.d.ts.map +1 -0
  10. package/dist/api/index.d.ts +935 -0
  11. package/dist/api/index.d.ts.map +1 -0
  12. package/dist/api/middlewares/index.d.ts +39 -0
  13. package/dist/api/middlewares/index.d.ts.map +1 -0
  14. package/dist/api/middlewares/origin-check.d.ts +82 -0
  15. package/dist/api/middlewares/origin-check.d.ts.map +1 -0
  16. package/dist/api/middlewares/validate-context.d.ts +38 -0
  17. package/dist/api/middlewares/validate-context.d.ts.map +1 -0
  18. package/dist/api/routes/__tests__/consent.test.d.ts +2 -0
  19. package/dist/api/routes/__tests__/consent.test.d.ts.map +1 -0
  20. package/dist/api/routes/__tests__/status.test.d.ts +2 -0
  21. package/dist/api/routes/__tests__/status.test.d.ts.map +1 -0
  22. package/dist/api/routes/error.d.ts +57 -0
  23. package/dist/api/routes/error.d.ts.map +1 -0
  24. package/dist/api/routes/generate-consent-receipt.d.ts +130 -0
  25. package/dist/api/routes/generate-consent-receipt.d.ts.map +1 -0
  26. package/dist/api/routes/get-consent-history.d.ts +133 -0
  27. package/dist/api/routes/get-consent-history.d.ts.map +1 -0
  28. package/dist/api/routes/get-consent-policy.d.ts +164 -0
  29. package/dist/api/routes/get-consent-policy.d.ts.map +1 -0
  30. package/dist/api/routes/get-consent.d.ts +148 -0
  31. package/dist/api/routes/get-consent.d.ts.map +1 -0
  32. package/dist/api/routes/index.d.ts +339 -0
  33. package/dist/api/routes/index.d.ts.map +1 -0
  34. package/dist/api/routes/ok.d.ts +87 -0
  35. package/dist/api/routes/ok.d.ts.map +1 -0
  36. package/dist/api/routes/set-consent.d.ts +245 -0
  37. package/dist/api/routes/set-consent.d.ts.map +1 -0
  38. package/dist/api/routes/show-consent-banner.d.ts +127 -0
  39. package/dist/api/routes/show-consent-banner.d.ts.map +1 -0
  40. package/dist/api/routes/status.d.ts +61 -0
  41. package/dist/api/routes/status.d.ts.map +1 -0
  42. package/dist/api/routes/verify-consent.d.ts +179 -0
  43. package/dist/api/routes/verify-consent.d.ts.map +1 -0
  44. package/dist/api/routes/withdraw-consent.d.ts +194 -0
  45. package/dist/api/routes/withdraw-consent.d.ts.map +1 -0
  46. package/dist/api/to-endpoints.d.ts +35 -0
  47. package/dist/api/to-endpoints.d.ts.map +1 -0
  48. package/dist/client/index.cjs +139 -0
  49. package/dist/client/index.d.ts +203 -0
  50. package/dist/client/index.d.ts.map +1 -0
  51. package/dist/client/index.js +106 -0
  52. package/dist/client/types.d.ts +431 -0
  53. package/dist/client/types.d.ts.map +1 -0
  54. package/dist/core.d.ts +124 -0
  55. package/dist/core.d.ts.map +1 -0
  56. package/dist/core.test.d.ts +2 -0
  57. package/dist/core.test.d.ts.map +1 -0
  58. package/dist/db/adapters/drizzle-adapter/drizzle-adapter.d.ts +122 -0
  59. package/dist/db/adapters/drizzle-adapter/drizzle-adapter.d.ts.map +1 -0
  60. package/dist/db/adapters/drizzle-adapter/index.d.ts +2 -0
  61. package/dist/db/adapters/drizzle-adapter/index.d.ts.map +1 -0
  62. package/dist/db/adapters/drizzle.cjs +1531 -0
  63. package/dist/db/adapters/drizzle.js +1489 -0
  64. package/dist/db/adapters/kysely-adapter/dialect.d.ts +72 -0
  65. package/dist/db/adapters/kysely-adapter/dialect.d.ts.map +1 -0
  66. package/dist/db/adapters/kysely-adapter/index.d.ts +4 -0
  67. package/dist/db/adapters/kysely-adapter/index.d.ts.map +1 -0
  68. package/dist/db/adapters/kysely-adapter/kysely-adapter.d.ts +98 -0
  69. package/dist/db/adapters/kysely-adapter/kysely-adapter.d.ts.map +1 -0
  70. package/dist/db/adapters/kysely-adapter/types.d.ts +281 -0
  71. package/dist/db/adapters/kysely-adapter/types.d.ts.map +1 -0
  72. package/dist/db/adapters/kysely.cjs +1551 -0
  73. package/dist/db/adapters/kysely.js +1508 -0
  74. package/dist/db/adapters/memory-adapter/index.d.ts +2 -0
  75. package/dist/db/adapters/memory-adapter/index.d.ts.map +1 -0
  76. package/dist/db/adapters/memory-adapter/memory-adapter.d.ts +56 -0
  77. package/dist/db/adapters/memory-adapter/memory-adapter.d.ts.map +1 -0
  78. package/dist/db/adapters/memory.cjs +1391 -0
  79. package/dist/db/adapters/memory.js +1349 -0
  80. package/dist/db/adapters/prisma-adapter/index.d.ts +2 -0
  81. package/dist/db/adapters/prisma-adapter/index.d.ts.map +1 -0
  82. package/dist/db/adapters/prisma-adapter/prisma-adapter.d.ts +143 -0
  83. package/dist/db/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -0
  84. package/dist/db/adapters/prisma.cjs +1503 -0
  85. package/dist/db/adapters/prisma.js +1461 -0
  86. package/dist/db/adapters/types.d.ts +154 -0
  87. package/dist/db/adapters/types.d.ts.map +1 -0
  88. package/dist/db/adapters/utils.d.ts +36 -0
  89. package/dist/db/adapters/utils.d.ts.map +1 -0
  90. package/dist/db/core/fields/field-factory.d.ts +383 -0
  91. package/dist/db/core/fields/field-factory.d.ts.map +1 -0
  92. package/dist/db/core/fields/field-inference.d.ts +218 -0
  93. package/dist/db/core/fields/field-inference.d.ts.map +1 -0
  94. package/dist/db/core/fields/field-options-integration.d.ts +90 -0
  95. package/dist/db/core/fields/field-options-integration.d.ts.map +1 -0
  96. package/dist/db/core/fields/field-types.d.ts +182 -0
  97. package/dist/db/core/fields/field-types.d.ts.map +1 -0
  98. package/dist/db/core/fields/id-generator.d.ts +19 -0
  99. package/dist/db/core/fields/id-generator.d.ts.map +1 -0
  100. package/dist/db/core/fields/index.d.ts +8 -0
  101. package/dist/db/core/fields/index.d.ts.map +1 -0
  102. package/dist/db/core/fields/superjson-utils.d.ts +34 -0
  103. package/dist/db/core/fields/superjson-utils.d.ts.map +1 -0
  104. package/dist/db/core/fields/zod-fields.d.ts +1011 -0
  105. package/dist/db/core/fields/zod-fields.d.ts.map +1 -0
  106. package/dist/db/core/get-schema.d.ts +36 -0
  107. package/dist/db/core/get-schema.d.ts.map +1 -0
  108. package/dist/db/core/types.d.ts +41 -0
  109. package/dist/db/core/types.d.ts.map +1 -0
  110. package/dist/db/create-registry.d.ts +760 -0
  111. package/dist/db/create-registry.d.ts.map +1 -0
  112. package/dist/db/hooks/create-hooks.d.ts +32 -0
  113. package/dist/db/hooks/create-hooks.d.ts.map +1 -0
  114. package/dist/db/hooks/index.d.ts +40 -0
  115. package/dist/db/hooks/index.d.ts.map +1 -0
  116. package/dist/db/hooks/types.d.ts +133 -0
  117. package/dist/db/hooks/types.d.ts.map +1 -0
  118. package/dist/db/hooks/update-hooks.d.ts +33 -0
  119. package/dist/db/hooks/update-hooks.d.ts.map +1 -0
  120. package/dist/db/hooks/update-many-hooks.d.ts +55 -0
  121. package/dist/db/hooks/update-many-hooks.d.ts.map +1 -0
  122. package/dist/db/hooks/utils.d.ts +62 -0
  123. package/dist/db/hooks/utils.d.ts.map +1 -0
  124. package/dist/db/hooks/with-hooks-factory.d.ts +33 -0
  125. package/dist/db/hooks/with-hooks-factory.d.ts.map +1 -0
  126. package/dist/db/index.cjs +2458 -0
  127. package/dist/db/index.d.ts +11 -0
  128. package/dist/db/index.d.ts.map +1 -0
  129. package/dist/db/index.js +2404 -0
  130. package/dist/db/migration/get-migration.d.ts +32 -0
  131. package/dist/db/migration/get-migration.d.ts.map +1 -0
  132. package/dist/db/migration/get-schema/get-schema.d.ts +27 -0
  133. package/dist/db/migration/get-schema/get-schema.d.ts.map +1 -0
  134. package/dist/db/migration/get-schema/index.d.ts +21 -0
  135. package/dist/db/migration/get-schema/index.d.ts.map +1 -0
  136. package/dist/db/migration/get-schema/process-fields.d.ts +16 -0
  137. package/dist/db/migration/get-schema/process-fields.d.ts.map +1 -0
  138. package/dist/db/migration/get-schema/process-tables.d.ts +13 -0
  139. package/dist/db/migration/get-schema/process-tables.d.ts.map +1 -0
  140. package/dist/db/migration/get-schema/types.d.ts +17 -0
  141. package/dist/db/migration/get-schema/types.d.ts.map +1 -0
  142. package/dist/db/migration/index.cjs +1613 -0
  143. package/dist/db/migration/index.d.ts +14 -0
  144. package/dist/db/migration/index.d.ts.map +1 -0
  145. package/dist/db/migration/index.js +1571 -0
  146. package/dist/db/migration/migration-builders.d.ts +28 -0
  147. package/dist/db/migration/migration-builders.d.ts.map +1 -0
  148. package/dist/db/migration/migration-execution.d.ts +12 -0
  149. package/dist/db/migration/migration-execution.d.ts.map +1 -0
  150. package/dist/db/migration/schema-comparison.d.ts +54 -0
  151. package/dist/db/migration/schema-comparison.d.ts.map +1 -0
  152. package/dist/db/migration/type-mapping.d.ts +86 -0
  153. package/dist/db/migration/type-mapping.d.ts.map +1 -0
  154. package/dist/db/migration/types.d.ts +37 -0
  155. package/dist/db/migration/types.d.ts.map +1 -0
  156. package/dist/db/schema/audit-log/index.d.ts +4 -0
  157. package/dist/db/schema/audit-log/index.d.ts.map +1 -0
  158. package/dist/db/schema/audit-log/registry.d.ts +128 -0
  159. package/dist/db/schema/audit-log/registry.d.ts.map +1 -0
  160. package/dist/db/schema/audit-log/schema.d.ts +67 -0
  161. package/dist/db/schema/audit-log/schema.d.ts.map +1 -0
  162. package/dist/db/schema/audit-log/table.d.ts +175 -0
  163. package/dist/db/schema/audit-log/table.d.ts.map +1 -0
  164. package/dist/db/schema/audit-log/types.d.ts +29 -0
  165. package/dist/db/schema/audit-log/types.d.ts.map +1 -0
  166. package/dist/db/schema/consent/index.d.ts +4 -0
  167. package/dist/db/schema/consent/index.d.ts.map +1 -0
  168. package/dist/db/schema/consent/registry.d.ts +318 -0
  169. package/dist/db/schema/consent/registry.d.ts.map +1 -0
  170. package/dist/db/schema/consent/schema.d.ts +135 -0
  171. package/dist/db/schema/consent/schema.d.ts.map +1 -0
  172. package/dist/db/schema/consent/table.d.ts +245 -0
  173. package/dist/db/schema/consent/table.d.ts.map +1 -0
  174. package/dist/db/schema/consent/types.d.ts +37 -0
  175. package/dist/db/schema/consent/types.d.ts.map +1 -0
  176. package/dist/db/schema/consent-geo-location/index.d.ts +4 -0
  177. package/dist/db/schema/consent-geo-location/index.d.ts.map +1 -0
  178. package/dist/db/schema/consent-geo-location/registry.d.ts +96 -0
  179. package/dist/db/schema/consent-geo-location/registry.d.ts.map +1 -0
  180. package/dist/db/schema/consent-geo-location/schema.d.ts +71 -0
  181. package/dist/db/schema/consent-geo-location/schema.d.ts.map +1 -0
  182. package/dist/db/schema/consent-geo-location/table.d.ts +167 -0
  183. package/dist/db/schema/consent-geo-location/table.d.ts.map +1 -0
  184. package/dist/db/schema/consent-geo-location/types.d.ts +21 -0
  185. package/dist/db/schema/consent-geo-location/types.d.ts.map +1 -0
  186. package/dist/db/schema/consent-policy/index.d.ts +4 -0
  187. package/dist/db/schema/consent-policy/index.d.ts.map +1 -0
  188. package/dist/db/schema/consent-policy/registry.d.ts +186 -0
  189. package/dist/db/schema/consent-policy/registry.d.ts.map +1 -0
  190. package/dist/db/schema/consent-policy/schema.d.ts +68 -0
  191. package/dist/db/schema/consent-policy/schema.d.ts.map +1 -0
  192. package/dist/db/schema/consent-policy/table.d.ts +147 -0
  193. package/dist/db/schema/consent-policy/table.d.ts.map +1 -0
  194. package/dist/db/schema/consent-policy/types.d.ts +28 -0
  195. package/dist/db/schema/consent-policy/types.d.ts.map +1 -0
  196. package/dist/db/schema/consent-purpose/index.d.ts +4 -0
  197. package/dist/db/schema/consent-purpose/index.d.ts.map +1 -0
  198. package/dist/db/schema/consent-purpose/registry.d.ts +136 -0
  199. package/dist/db/schema/consent-purpose/registry.d.ts.map +1 -0
  200. package/dist/db/schema/consent-purpose/schema.d.ts +79 -0
  201. package/dist/db/schema/consent-purpose/schema.d.ts.map +1 -0
  202. package/dist/db/schema/consent-purpose/table.d.ts +161 -0
  203. package/dist/db/schema/consent-purpose/table.d.ts.map +1 -0
  204. package/dist/db/schema/consent-purpose/types.d.ts +16 -0
  205. package/dist/db/schema/consent-purpose/types.d.ts.map +1 -0
  206. package/dist/db/schema/consent-purpose-junction/index.d.ts +4 -0
  207. package/dist/db/schema/consent-purpose-junction/index.d.ts.map +1 -0
  208. package/dist/db/schema/consent-purpose-junction/registry.d.ts +109 -0
  209. package/dist/db/schema/consent-purpose-junction/registry.d.ts.map +1 -0
  210. package/dist/db/schema/consent-purpose-junction/schema.d.ts +57 -0
  211. package/dist/db/schema/consent-purpose-junction/schema.d.ts.map +1 -0
  212. package/dist/db/schema/consent-purpose-junction/table.d.ts +138 -0
  213. package/dist/db/schema/consent-purpose-junction/table.d.ts.map +1 -0
  214. package/dist/db/schema/consent-purpose-junction/types.d.ts +14 -0
  215. package/dist/db/schema/consent-purpose-junction/types.d.ts.map +1 -0
  216. package/dist/db/schema/consent-record/index.d.ts +4 -0
  217. package/dist/db/schema/consent-record/index.d.ts.map +1 -0
  218. package/dist/db/schema/consent-record/registry.d.ts +119 -0
  219. package/dist/db/schema/consent-record/registry.d.ts.map +1 -0
  220. package/dist/db/schema/consent-record/schema.d.ts +57 -0
  221. package/dist/db/schema/consent-record/schema.d.ts.map +1 -0
  222. package/dist/db/schema/consent-record/table.d.ts +123 -0
  223. package/dist/db/schema/consent-record/table.d.ts.map +1 -0
  224. package/dist/db/schema/consent-record/types.d.ts +21 -0
  225. package/dist/db/schema/consent-record/types.d.ts.map +1 -0
  226. package/dist/db/schema/consent-withdrawal/index.d.ts +4 -0
  227. package/dist/db/schema/consent-withdrawal/index.d.ts.map +1 -0
  228. package/dist/db/schema/consent-withdrawal/registry.d.ts +134 -0
  229. package/dist/db/schema/consent-withdrawal/registry.d.ts.map +1 -0
  230. package/dist/db/schema/consent-withdrawal/schema.d.ts +67 -0
  231. package/dist/db/schema/consent-withdrawal/schema.d.ts.map +1 -0
  232. package/dist/db/schema/consent-withdrawal/table.d.ts +170 -0
  233. package/dist/db/schema/consent-withdrawal/table.d.ts.map +1 -0
  234. package/dist/db/schema/consent-withdrawal/types.d.ts +28 -0
  235. package/dist/db/schema/consent-withdrawal/types.d.ts.map +1 -0
  236. package/dist/db/schema/definition.d.ts +1100 -0
  237. package/dist/db/schema/definition.d.ts.map +1 -0
  238. package/dist/db/schema/domain/index.d.ts +4 -0
  239. package/dist/db/schema/domain/index.d.ts.map +1 -0
  240. package/dist/db/schema/domain/registry.d.ts +169 -0
  241. package/dist/db/schema/domain/registry.d.ts.map +1 -0
  242. package/dist/db/schema/domain/schema.d.ts +60 -0
  243. package/dist/db/schema/domain/schema.d.ts.map +1 -0
  244. package/dist/db/schema/domain/table.d.ts +140 -0
  245. package/dist/db/schema/domain/table.d.ts.map +1 -0
  246. package/dist/db/schema/domain/types.d.ts +27 -0
  247. package/dist/db/schema/domain/types.d.ts.map +1 -0
  248. package/dist/db/schema/geo-location/index.d.ts +4 -0
  249. package/dist/db/schema/geo-location/index.d.ts.map +1 -0
  250. package/dist/db/schema/geo-location/registry.d.ts +114 -0
  251. package/dist/db/schema/geo-location/registry.d.ts.map +1 -0
  252. package/dist/db/schema/geo-location/schema.d.ts +58 -0
  253. package/dist/db/schema/geo-location/schema.d.ts.map +1 -0
  254. package/dist/db/schema/geo-location/table.d.ts +132 -0
  255. package/dist/db/schema/geo-location/table.d.ts.map +1 -0
  256. package/dist/db/schema/geo-location/types.d.ts +17 -0
  257. package/dist/db/schema/geo-location/types.d.ts.map +1 -0
  258. package/dist/db/schema/index.d.ts +85 -0
  259. package/dist/db/schema/index.d.ts.map +1 -0
  260. package/dist/db/schema/parser.d.ts +183 -0
  261. package/dist/db/schema/parser.d.ts.map +1 -0
  262. package/dist/db/schema/schemas.d.ts +383 -0
  263. package/dist/db/schema/schemas.d.ts.map +1 -0
  264. package/dist/db/schema/subject/index.d.ts +4 -0
  265. package/dist/db/schema/subject/index.d.ts.map +1 -0
  266. package/dist/db/schema/subject/registry.d.ts +141 -0
  267. package/dist/db/schema/subject/registry.d.ts.map +1 -0
  268. package/dist/db/schema/subject/schema.d.ts +56 -0
  269. package/dist/db/schema/subject/schema.d.ts.map +1 -0
  270. package/dist/db/schema/subject/table.d.ts +136 -0
  271. package/dist/db/schema/subject/table.d.ts.map +1 -0
  272. package/dist/db/schema/subject/types.d.ts +22 -0
  273. package/dist/db/schema/subject/types.d.ts.map +1 -0
  274. package/dist/db/schema/types.d.ts +136 -0
  275. package/dist/db/schema/types.d.ts.map +1 -0
  276. package/dist/db/utils/adapter-factory.d.ts +21 -0
  277. package/dist/db/utils/adapter-factory.d.ts.map +1 -0
  278. package/dist/db/utils/index.d.ts +10 -0
  279. package/dist/db/utils/index.d.ts.map +1 -0
  280. package/dist/db/utils.d.ts +4 -0
  281. package/dist/db/utils.d.ts.map +1 -0
  282. package/dist/error/codes.cjs +68 -0
  283. package/dist/error/codes.d.ts +175 -0
  284. package/dist/error/codes.d.ts.map +1 -0
  285. package/dist/error/codes.js +35 -0
  286. package/dist/error/error.d.ts +79 -0
  287. package/dist/error/error.d.ts.map +1 -0
  288. package/dist/error/index.cjs +172 -0
  289. package/dist/error/index.d.ts +9 -0
  290. package/dist/error/index.d.ts.map +1 -0
  291. package/dist/error/index.js +129 -0
  292. package/dist/error/logging.d.ts +25 -0
  293. package/dist/error/logging.d.ts.map +1 -0
  294. package/dist/error/pipeline.d.ts +19 -0
  295. package/dist/error/pipeline.d.ts.map +1 -0
  296. package/dist/error/recovery.d.ts +22 -0
  297. package/dist/error/recovery.d.ts.map +1 -0
  298. package/dist/error/results.d.ts +56 -0
  299. package/dist/error/results.d.ts.map +1 -0
  300. package/dist/index.cjs +4777 -0
  301. package/dist/index.d.ts +46 -0
  302. package/dist/index.d.ts.map +1 -0
  303. package/dist/index.js +4708 -0
  304. package/dist/init.d.ts +52 -0
  305. package/dist/init.d.ts.map +1 -0
  306. package/dist/init.test.d.ts +2 -0
  307. package/dist/init.test.d.ts.map +1 -0
  308. package/dist/integrations/index.cjs +281 -0
  309. package/dist/integrations/index.d.ts +7 -0
  310. package/dist/integrations/index.d.ts.map +1 -0
  311. package/dist/integrations/index.js +248 -0
  312. package/dist/integrations/next.cjs +131 -0
  313. package/dist/integrations/next.d.ts +29 -0
  314. package/dist/integrations/next.d.ts.map +1 -0
  315. package/dist/integrations/next.js +99 -0
  316. package/dist/integrations/react.cjs +182 -0
  317. package/dist/integrations/react.d.ts +257 -0
  318. package/dist/integrations/react.d.ts.map +1 -0
  319. package/dist/integrations/react.js +150 -0
  320. package/dist/plugins/geo/index.d.ts +2 -0
  321. package/dist/plugins/geo/index.d.ts.map +1 -0
  322. package/dist/test/utils.d.ts +65 -0
  323. package/dist/test/utils.d.ts.map +1 -0
  324. package/dist/types/api.d.ts +89 -0
  325. package/dist/types/api.d.ts.map +1 -0
  326. package/dist/types/context.d.ts +205 -0
  327. package/dist/types/context.d.ts.map +1 -0
  328. package/dist/types/helper.d.ts +78 -0
  329. package/dist/types/helper.d.ts.map +1 -0
  330. package/dist/types/index.cjs +19 -0
  331. package/dist/types/index.d.ts +6 -0
  332. package/dist/types/index.d.ts.map +1 -0
  333. package/dist/types/index.js +0 -0
  334. package/dist/types/options.d.ts +172 -0
  335. package/dist/types/options.d.ts.map +1 -0
  336. package/dist/types/plugins.d.ts +442 -0
  337. package/dist/types/plugins.d.ts.map +1 -0
  338. package/dist/utils/env.d.ts +77 -0
  339. package/dist/utils/env.d.ts.map +1 -0
  340. package/dist/utils/hide-metadata.d.ts +22 -0
  341. package/dist/utils/hide-metadata.d.ts.map +1 -0
  342. package/dist/utils/index.cjs +268 -0
  343. package/dist/utils/index.d.ts +18 -0
  344. package/dist/utils/index.d.ts.map +1 -0
  345. package/dist/utils/index.js +210 -0
  346. package/dist/utils/ip.d.ts +10 -0
  347. package/dist/utils/ip.d.ts.map +1 -0
  348. package/dist/utils/json.d.ts +14 -0
  349. package/dist/utils/json.d.ts.map +1 -0
  350. package/dist/utils/logger.d.ts +108 -0
  351. package/dist/utils/logger.d.ts.map +1 -0
  352. package/dist/utils/url.d.ts +87 -0
  353. package/dist/utils/url.d.ts.map +1 -0
  354. package/dist/utils/wildcard.d.ts +46 -0
  355. package/dist/utils/wildcard.d.ts.map +1 -0
  356. package/knip.json +37 -0
  357. package/package.json +146 -0
  358. package/rslib.config.ts +104 -0
  359. package/src/api/call.ts +177 -0
  360. package/src/api/index.ts +303 -0
  361. package/src/api/middlewares/index.ts +38 -0
  362. package/src/api/middlewares/origin-check.ts +260 -0
  363. package/src/api/middlewares/validate-context.ts +175 -0
  364. package/src/api/routes/__tests__/consent.test.ts +270 -0
  365. package/src/api/routes/__tests__/status.test.ts +36 -0
  366. package/src/api/routes/error.ts +130 -0
  367. package/src/api/routes/generate-consent-receipt.ts +244 -0
  368. package/src/api/routes/get-consent-history.ts +128 -0
  369. package/src/api/routes/get-consent-policy.ts +327 -0
  370. package/src/api/routes/get-consent.ts +230 -0
  371. package/src/api/routes/index.ts +12 -0
  372. package/src/api/routes/ok.ts +45 -0
  373. package/src/api/routes/set-consent.ts +328 -0
  374. package/src/api/routes/show-consent-banner.ts +149 -0
  375. package/src/api/routes/status.ts +62 -0
  376. package/src/api/routes/verify-consent.ts +272 -0
  377. package/src/api/routes/withdraw-consent.ts +293 -0
  378. package/src/api/to-endpoints.ts +371 -0
  379. package/src/client/index.ts +471 -0
  380. package/src/client/types.ts +458 -0
  381. package/src/core.test.ts +303 -0
  382. package/src/core.ts +267 -0
  383. package/src/db/adapters/drizzle-adapter/drizzle-adapter.ts +711 -0
  384. package/src/db/adapters/drizzle-adapter/index.ts +1 -0
  385. package/src/db/adapters/kysely-adapter/dialect.ts +192 -0
  386. package/src/db/adapters/kysely-adapter/index.ts +3 -0
  387. package/src/db/adapters/kysely-adapter/kysely-adapter.ts +1168 -0
  388. package/src/db/adapters/kysely-adapter/types.ts +307 -0
  389. package/src/db/adapters/memory-adapter/index.ts +1 -0
  390. package/src/db/adapters/memory-adapter/memory-adapter.ts +648 -0
  391. package/src/db/adapters/prisma-adapter/index.ts +1 -0
  392. package/src/db/adapters/prisma-adapter/prisma-adapter.ts +586 -0
  393. package/src/db/adapters/types.ts +203 -0
  394. package/src/db/adapters/utils.ts +51 -0
  395. package/src/db/core/fields/field-factory.ts +804 -0
  396. package/src/db/core/fields/field-inference.ts +298 -0
  397. package/src/db/core/fields/field-options-integration.ts +135 -0
  398. package/src/db/core/fields/field-types.ts +233 -0
  399. package/src/db/core/fields/id-generator.ts +57 -0
  400. package/src/db/core/fields/index.ts +56 -0
  401. package/src/db/core/fields/superjson-utils.ts +155 -0
  402. package/src/db/core/fields/zod-fields.ts +269 -0
  403. package/src/db/core/get-schema.ts +102 -0
  404. package/src/db/core/types.ts +52 -0
  405. package/src/db/create-registry.ts +31 -0
  406. package/src/db/hooks/create-hooks.ts +88 -0
  407. package/src/db/hooks/index.ts +39 -0
  408. package/src/db/hooks/types.ts +164 -0
  409. package/src/db/hooks/update-hooks.ts +91 -0
  410. package/src/db/hooks/update-many-hooks.ts +176 -0
  411. package/src/db/hooks/utils.ts +151 -0
  412. package/src/db/hooks/with-hooks-factory.ts +68 -0
  413. package/src/db/index.ts +32 -0
  414. package/src/db/migration/get-migration.ts +89 -0
  415. package/src/db/migration/get-schema/get-schema.ts +44 -0
  416. package/src/db/migration/get-schema/index.ts +20 -0
  417. package/src/db/migration/get-schema/process-fields.ts +66 -0
  418. package/src/db/migration/get-schema/process-tables.ts +68 -0
  419. package/src/db/migration/get-schema/types.ts +18 -0
  420. package/src/db/migration/index.ts +18 -0
  421. package/src/db/migration/migration-builders.ts +170 -0
  422. package/src/db/migration/migration-execution.ts +79 -0
  423. package/src/db/migration/schema-comparison.ts +216 -0
  424. package/src/db/migration/type-mapping.ts +255 -0
  425. package/src/db/migration/types.ts +46 -0
  426. package/src/db/schema/audit-log/index.ts +3 -0
  427. package/src/db/schema/audit-log/registry.ts +228 -0
  428. package/src/db/schema/audit-log/schema.ts +46 -0
  429. package/src/db/schema/audit-log/table.ts +185 -0
  430. package/src/db/schema/audit-log/types.ts +29 -0
  431. package/src/db/schema/consent/index.ts +3 -0
  432. package/src/db/schema/consent/registry.ts +381 -0
  433. package/src/db/schema/consent/schema.ts +65 -0
  434. package/src/db/schema/consent/table.ts +220 -0
  435. package/src/db/schema/consent/types.ts +39 -0
  436. package/src/db/schema/consent-geo-location/index.ts +3 -0
  437. package/src/db/schema/consent-geo-location/registry.ts +124 -0
  438. package/src/db/schema/consent-geo-location/schema.ts +51 -0
  439. package/src/db/schema/consent-geo-location/table.ts +169 -0
  440. package/src/db/schema/consent-geo-location/types.ts +21 -0
  441. package/src/db/schema/consent-policy/index.ts +3 -0
  442. package/src/db/schema/consent-policy/registry.ts +313 -0
  443. package/src/db/schema/consent-policy/schema.ts +47 -0
  444. package/src/db/schema/consent-policy/table.ts +141 -0
  445. package/src/db/schema/consent-policy/types.ts +28 -0
  446. package/src/db/schema/consent-purpose/index.ts +3 -0
  447. package/src/db/schema/consent-purpose/registry.ts +188 -0
  448. package/src/db/schema/consent-purpose/schema.ts +58 -0
  449. package/src/db/schema/consent-purpose/table.ts +154 -0
  450. package/src/db/schema/consent-purpose/types.ts +16 -0
  451. package/src/db/schema/consent-purpose-junction/index.ts +3 -0
  452. package/src/db/schema/consent-purpose-junction/registry.ts +189 -0
  453. package/src/db/schema/consent-purpose-junction/schema.ts +49 -0
  454. package/src/db/schema/consent-purpose-junction/table.ts +142 -0
  455. package/src/db/schema/consent-purpose-junction/types.ts +14 -0
  456. package/src/db/schema/consent-record/index.ts +3 -0
  457. package/src/db/schema/consent-record/registry.ts +209 -0
  458. package/src/db/schema/consent-record/schema.ts +42 -0
  459. package/src/db/schema/consent-record/table.ts +124 -0
  460. package/src/db/schema/consent-record/types.ts +21 -0
  461. package/src/db/schema/consent-withdrawal/index.ts +3 -0
  462. package/src/db/schema/consent-withdrawal/registry.ts +219 -0
  463. package/src/db/schema/consent-withdrawal/schema.ts +48 -0
  464. package/src/db/schema/consent-withdrawal/table.ts +181 -0
  465. package/src/db/schema/consent-withdrawal/types.ts +29 -0
  466. package/src/db/schema/definition.ts +196 -0
  467. package/src/db/schema/domain/index.ts +3 -0
  468. package/src/db/schema/domain/registry.ts +272 -0
  469. package/src/db/schema/domain/schema.ts +43 -0
  470. package/src/db/schema/domain/table.ts +137 -0
  471. package/src/db/schema/domain/types.ts +27 -0
  472. package/src/db/schema/geo-location/index.ts +3 -0
  473. package/src/db/schema/geo-location/registry.ts +159 -0
  474. package/src/db/schema/geo-location/schema.ts +45 -0
  475. package/src/db/schema/geo-location/table.ts +148 -0
  476. package/src/db/schema/geo-location/types.ts +18 -0
  477. package/src/db/schema/index.ts +96 -0
  478. package/src/db/schema/parser.ts +417 -0
  479. package/src/db/schema/schemas.ts +35 -0
  480. package/src/db/schema/subject/index.ts +3 -0
  481. package/src/db/schema/subject/registry.ts +371 -0
  482. package/src/db/schema/subject/schema.ts +41 -0
  483. package/src/db/schema/subject/table.ts +139 -0
  484. package/src/db/schema/subject/types.ts +22 -0
  485. package/src/db/schema/types.ts +154 -0
  486. package/src/db/utils/adapter-factory.ts +64 -0
  487. package/src/db/utils/index.ts +10 -0
  488. package/src/db/utils.ts +42 -0
  489. package/src/docs/ADVANCED_JSON_HANDLING.md +99 -0
  490. package/src/docs/neverthrow.md +171 -0
  491. package/src/error/codes.ts +201 -0
  492. package/src/error/error.ts +145 -0
  493. package/src/error/index.ts +23 -0
  494. package/src/error/logging.ts +52 -0
  495. package/src/error/pipeline.ts +57 -0
  496. package/src/error/recovery.ts +45 -0
  497. package/src/error/results.ts +100 -0
  498. package/src/index.ts +79 -0
  499. package/src/init.test.ts +235 -0
  500. package/src/init.ts +261 -0
  501. package/src/integrations/index.ts +10 -0
  502. package/src/integrations/next.ts +136 -0
  503. package/src/integrations/react.ts +567 -0
  504. package/src/plugins/geo/index.ts +563 -0
  505. package/src/test/utils.ts +244 -0
  506. package/src/types/api.ts +101 -0
  507. package/src/types/context.ts +235 -0
  508. package/src/types/helper.ts +87 -0
  509. package/src/types/index.ts +5 -0
  510. package/src/types/options.ts +189 -0
  511. package/src/types/plugins.ts +538 -0
  512. package/src/utils/env.ts +103 -0
  513. package/src/utils/hide-metadata.ts +21 -0
  514. package/src/utils/index.ts +17 -0
  515. package/src/utils/ip.ts +45 -0
  516. package/src/utils/json.ts +19 -0
  517. package/src/utils/logger.ts +252 -0
  518. package/src/utils/url.ts +194 -0
  519. package/src/utils/wildcard.ts +253 -0
  520. package/tsconfig.json +12 -0
  521. package/vitest.config.ts +14 -0
@@ -0,0 +1,260 @@
1
+ import { BASE_ERROR_CODES, C15TError } from '~/error';
2
+ import type { GenericEndpointContext } from '~/types';
3
+ import { getHost, getOrigin, getProtocol } from '~/utils/url';
4
+ import { wildcardMatch } from '~/utils/wildcard';
5
+ import { createAuthMiddleware } from '../call';
6
+
7
+ /**
8
+ * Regular expression for validating relative URLs
9
+ * Ensures URLs don't contain path traversal attacks and have a valid structure
10
+ *
11
+ * @internal
12
+ */
13
+ const VALID_RELATIVE_URL_REGEX =
14
+ /^\/(?!\/|\\|%2f|%5c)[\w\-./]*(?:\?[\w\-./=&%]*)?$/;
15
+
16
+ /**
17
+ * Middleware that validates request origins and callback URLs against trusted origins
18
+ *
19
+ * This middleware performs security checks to prevent cross-site request forgery (CSRF)
20
+ * and open redirect vulnerabilities by validating various URLs in the request against
21
+ * a list of trusted origins configured in the C15T context.
22
+ *
23
+ * @remarks
24
+ * The middleware checks the following URLs from request body and headers:
25
+ * - Origin/Referer header (when cookies are used and CSRF checks are enabled)
26
+ * - callbackURL
27
+ * - redirectTo
28
+ * - errorCallbackURL
29
+ * - newSubjectCallbackURL
30
+ *
31
+ * URLs are validated using exact matching for origins and wildcard pattern matching
32
+ * for hostnames. Relative URLs are allowed for callback URLs but must match a safe
33
+ * URL pattern.
34
+ *
35
+ * @throws {C15TError} Throws a FORBIDDEN error if any URL fails validation
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { c15tInstance } from '@c15t/backend';
40
+ * // This middleware is typically used in router configuration
41
+ * const router = createRouter(endpoints, {
42
+ * routerMiddleware: [
43
+ * {
44
+ * path: '/**',
45
+ * middleware: originCheckMiddleware
46
+ * }
47
+ * ]
48
+ * });
49
+ *
50
+ * // To configure trusted origins in your C15T options:
51
+ * const c15t = c15tInstance({
52
+ * // Static list of trusted origins
53
+ * trustedOrigins: [
54
+ * 'https://example.com',
55
+ * 'https://*.example.org'
56
+ * ]
57
+ *
58
+ * // Or a function to dynamically determine trusted origins
59
+ * trustedOrigins: (request) => {
60
+ * const host = new URL(request.url).host;
61
+ * return [`https://${host}`, `http://${host}`];
62
+ * }
63
+ * });
64
+ * ```
65
+ */
66
+ export const originCheckMiddleware = createAuthMiddleware(async (ctx) => {
67
+ if (ctx.request?.method !== 'POST' || !ctx.request) {
68
+ return;
69
+ }
70
+ const { body, query, context } = ctx;
71
+ const originHeader =
72
+ ctx.headers?.get('origin') || ctx.headers?.get('referer') || '';
73
+ const callbackURL = body?.callbackURL || query?.callbackURL;
74
+ const redirectURL = body?.redirectTo;
75
+ const errorCallbackURL = body?.errorCallbackURL;
76
+ const newSubjectCallbackURL = body?.newSubjectCallbackURL;
77
+ const trustedOrigins: string[] = Array.isArray(context.options.trustedOrigins)
78
+ ? context.trustedOrigins
79
+ : [
80
+ ...context.trustedOrigins,
81
+ ...(context.options.trustedOrigins?.(ctx.request) || []),
82
+ ];
83
+ const usesCookies = ctx.headers?.has('cookie');
84
+
85
+ /**
86
+ * Determines if a URL matches a trusted origin pattern
87
+ *
88
+ * @internal
89
+ * @param url - The URL to check
90
+ * @param pattern - The trusted origin pattern to match against
91
+ * @returns Whether the URL matches the pattern
92
+ */
93
+ const matchesPattern = (url: string, pattern: string): boolean => {
94
+ if (url.startsWith('/')) {
95
+ return false;
96
+ }
97
+ if (pattern.includes('*')) {
98
+ return wildcardMatch(pattern)(getHost(url));
99
+ }
100
+
101
+ const protocol = getProtocol(url);
102
+ return protocol === 'http:' || protocol === 'https:' || !protocol
103
+ ? pattern === getOrigin(url)
104
+ : url.startsWith(pattern);
105
+ };
106
+
107
+ /**
108
+ * Validates a URL against trusted origins
109
+ *
110
+ * @internal
111
+ * @param url - The URL to validate
112
+ * @param label - A label describing what type of URL is being validated
113
+ * @throws {C15TError} If the URL is not from a trusted origin
114
+ */
115
+ const validateURL = (url: string | undefined, label: string) => {
116
+ if (!url) {
117
+ return;
118
+ }
119
+ const isTrustedOrigin = trustedOrigins.some(
120
+ (origin) =>
121
+ matchesPattern(url, origin) ||
122
+ (url?.startsWith('/') &&
123
+ label !== 'origin' &&
124
+ VALID_RELATIVE_URL_REGEX.test(url))
125
+ );
126
+ if (!isTrustedOrigin) {
127
+ ctx.context.logger.error(`Invalid ${label}: ${url}`);
128
+ ctx.context.logger.info(
129
+ `If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`,
130
+ `Current list of trustedOrigins: ${trustedOrigins}`
131
+ );
132
+ throw new C15TError(
133
+ 'The URL provided is not from a trusted origin. Please ensure the URL is correctly configured in the trusted origins list.',
134
+ {
135
+ code: BASE_ERROR_CODES.FORBIDDEN,
136
+ status: 403,
137
+ data: {
138
+ url,
139
+ label,
140
+ trustedOrigins,
141
+ },
142
+ }
143
+ );
144
+ }
145
+ };
146
+ if (usesCookies && !ctx.context.options.advanced?.disableCSRFCheck) {
147
+ validateURL(originHeader, 'origin');
148
+ }
149
+ callbackURL && validateURL(callbackURL, 'callbackURL');
150
+ redirectURL && validateURL(redirectURL, 'redirectURL');
151
+ errorCallbackURL && validateURL(errorCallbackURL, 'errorCallbackURL');
152
+ newSubjectCallbackURL &&
153
+ validateURL(newSubjectCallbackURL, 'newSubjectCallbackURL');
154
+ });
155
+
156
+ /**
157
+ * Creates a middleware that validates a specific URL against trusted origins
158
+ *
159
+ * This factory function creates a middleware for validating a single URL extracted
160
+ * from the request context against the list of trusted origins.
161
+ *
162
+ * @param getValue - A function that extracts the URL to validate from the endpoint context
163
+ * @returns A middleware that validates the extracted URL
164
+ * @throws {C15TError} Throws a FORBIDDEN error if the URL fails validation
165
+ *
166
+ * @remarks
167
+ * Unlike the more comprehensive originCheckMiddleware, this factory allows creating
168
+ * targeted middleware for specific URL fields or custom extraction logic.
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * // Create a middleware that validates the 'returnUrl' from request body
173
+ * const validateReturnUrl = originCheck(ctx => ctx.body?.returnUrl);
174
+ *
175
+ * // Use the middleware in a specific route
176
+ * router.post('/api/subscribe', validateReturnUrl, subscribeHandler);
177
+ *
178
+ * // Create a middleware that validates a URL from a custom header
179
+ * const validateHeaderUrl = originCheck(ctx =>
180
+ * ctx.headers?.get('x-callback-url')
181
+ * );
182
+ * ```
183
+ */
184
+ export const originCheck = (
185
+ getValue: (ctx: GenericEndpointContext) => string
186
+ ) =>
187
+ createAuthMiddleware(async (ctx) => {
188
+ if (!ctx.request) {
189
+ return;
190
+ }
191
+ const { context } = ctx;
192
+ const callbackURL = getValue(ctx);
193
+ const trustedOrigins: string[] = Array.isArray(
194
+ context.options.trustedOrigins
195
+ )
196
+ ? context.trustedOrigins
197
+ : [
198
+ ...context.trustedOrigins,
199
+ ...(context.options.trustedOrigins?.(ctx.request) || []),
200
+ ];
201
+
202
+ /**
203
+ * Determines if a URL matches a trusted origin pattern
204
+ *
205
+ * @internal
206
+ * @param url - The URL to check
207
+ * @param pattern - The trusted origin pattern to match against
208
+ * @returns Whether the URL matches the pattern
209
+ */
210
+ const matchesPattern = (url: string, pattern: string): boolean => {
211
+ if (url.startsWith('/')) {
212
+ return false;
213
+ }
214
+ if (pattern.includes('*')) {
215
+ return wildcardMatch(pattern)(getHost(url));
216
+ }
217
+ return url.startsWith(pattern);
218
+ };
219
+
220
+ /**
221
+ * Validates a URL against trusted origins
222
+ *
223
+ * @internal
224
+ * @param url - The URL to validate
225
+ * @param label - A label describing what type of URL is being validated
226
+ * @throws {C15TError} If the URL is not from a trusted origin
227
+ */
228
+ const validateURL = (url: string | undefined, label: string) => {
229
+ if (!url) {
230
+ return;
231
+ }
232
+ const isTrustedOrigin = trustedOrigins.some(
233
+ (origin) =>
234
+ matchesPattern(url, origin) ||
235
+ (url?.startsWith('/') &&
236
+ label !== 'origin' &&
237
+ VALID_RELATIVE_URL_REGEX.test(url))
238
+ );
239
+ if (!isTrustedOrigin) {
240
+ ctx.context.logger.error(`Invalid ${label}: ${url}`);
241
+ ctx.context.logger.info(
242
+ `If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`,
243
+ `Current list of trustedOrigins: ${trustedOrigins}`
244
+ );
245
+ throw new C15TError(
246
+ 'The URL provided is not from a trusted origin. Please ensure the URL is correctly configured in the trusted origins list.',
247
+ {
248
+ code: BASE_ERROR_CODES.FORBIDDEN,
249
+ status: 403,
250
+ data: {
251
+ url,
252
+ label,
253
+ trustedOrigins,
254
+ },
255
+ }
256
+ );
257
+ }
258
+ };
259
+ callbackURL && validateURL(callbackURL, 'callbackURL');
260
+ });
@@ -0,0 +1,175 @@
1
+ import { BASE_ERROR_CODES, C15TError } from '~/error';
2
+ import type { C15TContext, C15TPlugin } from '~/types';
3
+ import { createAuthMiddleware } from '../call';
4
+
5
+ import type { Adapter } from '~/db/adapters/types';
6
+
7
+ /**
8
+ * Redacts sensitive information from context for error reporting
9
+ *
10
+ * @param context - The context object to redact
11
+ * @returns A sanitized version of the context
12
+ */
13
+ function redactContext(context: unknown): Record<string, unknown> {
14
+ if (!context || typeof context !== 'object') {
15
+ return { type: typeof context };
16
+ }
17
+
18
+ const typedContext = context as C15TContext;
19
+ return {
20
+ baseURL: typedContext.baseURL,
21
+ storageType: typedContext.storage?.constructor.name,
22
+ pluginsCount: Array.isArray(typedContext.plugins)
23
+ ? typedContext.plugins.length
24
+ : 0,
25
+ hasOptions: !!typedContext.options,
26
+ hasLogger: !!typedContext.logger,
27
+ hasPlugins: !!typedContext.plugins,
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Validates plugin initialization status
33
+ *
34
+ * @param plugins - Array of configured plugins
35
+ * @param initializedPlugins - Array of successfully initialized plugins
36
+ * @returns Array of failed plugin names, or null if all plugins initialized
37
+ */
38
+ function validatePlugins(
39
+ plugins: C15TPlugin[] | undefined,
40
+ initializedPlugins: C15TPlugin[] | undefined
41
+ ): string[] | null {
42
+ if (!plugins?.length) {
43
+ return null;
44
+ }
45
+
46
+ const initializedNames = new Set(initializedPlugins?.map((p) => p.id) ?? []);
47
+
48
+ const failedPlugins = plugins
49
+ .filter((p) => !initializedNames.has(p.id))
50
+ .map((p) => p.id);
51
+
52
+ return failedPlugins.length > 0 ? failedPlugins : null;
53
+ }
54
+
55
+ /**
56
+ * Middleware that validates the context for all routes
57
+ *
58
+ * This middleware ensures that the context object is properly structured and
59
+ * contains all required properties and services before allowing the request to proceed.
60
+ *
61
+ * @remarks
62
+ * The middleware performs comprehensive validation of:
63
+ * - Basic context structure
64
+ * - Required configuration options
65
+ * - Storage adapter availability
66
+ * - Logger availability
67
+ * - Plugin initialization status
68
+ * - Required services and dependencies
69
+ *
70
+ * @throws {C15TError} Throws appropriate errors for:
71
+ * - INVALID_CONFIGURATION: When context or options are invalid
72
+ * - STORAGE_ERROR: When storage adapter is not available
73
+ * - INITIALIZATION_FAILED: When required services failed to initialize
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * // Using with memory adapter
78
+ * const router = createRouter(endpoints, {
79
+ * routerMiddleware: [
80
+ * {
81
+ * path: '/**',
82
+ * middleware: validateContextMiddleware
83
+ * }
84
+ * ]
85
+ * });
86
+ * ```
87
+ */
88
+ export const validateContextMiddleware = createAuthMiddleware(async (ctx) => {
89
+ const { context } = ctx;
90
+
91
+ // Basic context validation
92
+ if (!context || typeof context !== 'object') {
93
+ throw new C15TError(
94
+ 'The context configuration is incomplete. Please ensure all required configuration options are provided and properly formatted.',
95
+ {
96
+ code: BASE_ERROR_CODES.INVALID_CONFIGURATION,
97
+ status: 500,
98
+ data: redactContext(context),
99
+ }
100
+ );
101
+ }
102
+
103
+ // Ensure the context is properly typed
104
+ const typedContext = context as C15TContext;
105
+
106
+ // Validate required configuration
107
+ if (!typedContext.options) {
108
+ throw new C15TError(
109
+ 'The context configuration is missing required options. Please ensure the options object is properly configured.',
110
+ {
111
+ code: BASE_ERROR_CODES.INVALID_CONFIGURATION,
112
+ status: 500,
113
+ }
114
+ );
115
+ }
116
+
117
+ // Optional storage adapter validation
118
+ if (typedContext.storage) {
119
+ const storage = typedContext.storage as Adapter;
120
+ const requiredMethods = ['subjects', 'records', 'policies'];
121
+ const missingMethods = requiredMethods.filter(
122
+ (method) => !(method in storage)
123
+ );
124
+
125
+ if (missingMethods.length > 0) {
126
+ typedContext.logger?.warn?.('Storage adapter missing methods', {
127
+ missingMethods,
128
+ storageType: storage.constructor.name,
129
+ });
130
+ }
131
+ }
132
+
133
+ // Validate logger (make it optional for memory adapter in development)
134
+ if (!typedContext.logger && process.env.NODE_ENV === 'production') {
135
+ throw new C15TError(
136
+ 'Logger is required in production environment. Please configure a logger for your application.',
137
+ {
138
+ code: BASE_ERROR_CODES.INVALID_CONFIGURATION,
139
+ status: 500,
140
+ data: {
141
+ environment: process.env.NODE_ENV,
142
+ },
143
+ }
144
+ );
145
+ }
146
+
147
+ // Validate plugins if any are configured
148
+ const failedPlugins = validatePlugins(
149
+ typedContext.options.plugins,
150
+ typedContext.plugins as C15TPlugin[] | undefined
151
+ );
152
+ if (failedPlugins) {
153
+ throw new C15TError(
154
+ 'Plugin initialization failed. Some plugins could not be initialized properly. Please check your plugin configuration.',
155
+ {
156
+ code: BASE_ERROR_CODES.PLUGIN_INITIALIZATION_FAILED,
157
+ status: 500,
158
+ data: {
159
+ failedPlugins,
160
+ },
161
+ }
162
+ );
163
+ }
164
+
165
+ // Log successful validation if logger exists
166
+ typedContext.logger?.debug?.('Context validation successful', {
167
+ baseURL: typedContext.baseURL,
168
+ storageType: typedContext.storage?.constructor.name,
169
+ pluginsCount: Array.isArray(typedContext.plugins)
170
+ ? typedContext.plugins.length
171
+ : 0,
172
+ });
173
+
174
+ return { context: typedContext };
175
+ });
@@ -0,0 +1,270 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { c15tInstance } from '~/core';
3
+ import { memoryAdapter } from '~/db/adapters/memory-adapter';
4
+ import type { ConsentPolicy } from '~/db/schema';
5
+ import { BASE_ERROR_CODES } from '~/error';
6
+ import type { C15TContext } from '~/types';
7
+ import { setConsent } from '../set-consent';
8
+
9
+ describe('Consent Endpoints', () => {
10
+ let context: C15TContext;
11
+
12
+ beforeEach(async () => {
13
+ const instance = await c15tInstance({
14
+ baseURL: 'http://localhost:3000',
15
+ database: memoryAdapter({}),
16
+ trustedOrigins: ['http://localhost:3000'],
17
+ secret: 'test-secret',
18
+ });
19
+
20
+ const contextResult = await instance.$context;
21
+ if (!contextResult.isOk()) {
22
+ throw new Error('Failed to initialize context');
23
+ }
24
+ context = contextResult.value;
25
+ });
26
+
27
+ describe('setConsent', () => {
28
+ // Helper function for common consent data
29
+ const createConsentData = (
30
+ type: 'cookie_banner' | 'privacy_policy',
31
+ overrides = {}
32
+ ) => ({
33
+ type,
34
+ domain: 'example.com',
35
+ preferences: {
36
+ marketing: true,
37
+ analytics: true,
38
+ },
39
+ ...overrides,
40
+ });
41
+
42
+ // Helper function for common response checks
43
+ const expectValidConsentResponse = (
44
+ response: {
45
+ id: string;
46
+ givenAt: string;
47
+ subjectId: string;
48
+ domainId: string;
49
+ type: string;
50
+ status: string;
51
+ domain: string;
52
+ metadata?: unknown;
53
+ },
54
+ type: string,
55
+ extraChecks = {}
56
+ ) => {
57
+ // biome-ignore lint/suspicious/noMisplacedAssertion: its okay
58
+ expect(response).toMatchObject({
59
+ type,
60
+ status: 'active',
61
+ domain: 'example.com',
62
+ metadata: undefined,
63
+ ...extraChecks,
64
+ });
65
+ // biome-ignore lint/suspicious/noMisplacedAssertion: its okay
66
+ expect(typeof response.id).toBe('string');
67
+ // biome-ignore lint/suspicious/noMisplacedAssertion: its okay
68
+ expect(response.givenAt).toBeDefined();
69
+ // biome-ignore lint/suspicious/noMisplacedAssertion: its okay
70
+ expect(response.subjectId).toBeDefined();
71
+ // biome-ignore lint/suspicious/noMisplacedAssertion: its okay
72
+ expect(response.domainId).toBeDefined();
73
+ };
74
+
75
+ it('should set cookie banner consent successfully', async () => {
76
+ const response = await setConsent({
77
+ context,
78
+ params: undefined,
79
+ query: undefined,
80
+ body: createConsentData('cookie_banner'),
81
+ });
82
+ expectValidConsentResponse(response, 'cookie_banner');
83
+ });
84
+
85
+ it('should set privacy policy consent successfully with external subject', async () => {
86
+ await context.registry.createSubject({
87
+ externalId: 'test-subject',
88
+ isIdentified: true,
89
+ identityProvider: 'test',
90
+ });
91
+
92
+ const response = await setConsent({
93
+ context,
94
+ params: undefined,
95
+ query: undefined,
96
+ body: createConsentData('privacy_policy', {
97
+ externalSubjectId: 'test-subject',
98
+ }),
99
+ });
100
+
101
+ expectValidConsentResponse(response, 'privacy_policy', {
102
+ externalSubjectId: 'test-subject',
103
+ });
104
+ });
105
+
106
+ describe('Policy ID handling', () => {
107
+ let policy: ConsentPolicy;
108
+
109
+ beforeEach(async () => {
110
+ policy = await context.registry.createConsentPolicy({
111
+ name: 'Test Privacy Policy',
112
+ version: '1.0',
113
+ content: 'Test content',
114
+ contentHash: 'test-hash',
115
+ effectiveDate: new Date(),
116
+ updatedAt: new Date(),
117
+ isActive: true,
118
+ });
119
+ });
120
+
121
+ it('should set consent with explicit policy ID', async () => {
122
+ const response = await setConsent({
123
+ context,
124
+ params: undefined,
125
+ query: undefined,
126
+ body: createConsentData('privacy_policy', { policyId: policy.id }),
127
+ });
128
+
129
+ expectValidConsentResponse(response, 'privacy_policy');
130
+ });
131
+
132
+ it('should find latest policy when policy ID is not provided', async () => {
133
+ const response = await setConsent({
134
+ context,
135
+ params: undefined,
136
+ query: undefined,
137
+ body: createConsentData('privacy_policy'),
138
+ });
139
+
140
+ expectValidConsentResponse(response, 'privacy_policy');
141
+ });
142
+
143
+ it('should error with invalid policy ID', async () => {
144
+ await expect(
145
+ setConsent({
146
+ context,
147
+ params: undefined,
148
+ query: undefined,
149
+ body: createConsentData('privacy_policy', {
150
+ policyId: 'invalid-id',
151
+ }),
152
+ })
153
+ ).rejects.toMatchObject({
154
+ name: 'C15TError',
155
+ code: BASE_ERROR_CODES.NOT_FOUND,
156
+ status: 404,
157
+ });
158
+ });
159
+ });
160
+
161
+ describe('Subject mapping validation', () => {
162
+ it('should validate that subjectId and externalSubjectId map to the same subject', async () => {
163
+ // Create a subject with external ID
164
+ const subject = await context.registry.createSubject({
165
+ externalId: 'test-subject',
166
+ isIdentified: true,
167
+ identityProvider: 'test',
168
+ });
169
+
170
+ if (!subject) {
171
+ throw new Error('Failed to create test subject');
172
+ }
173
+
174
+ // Test with matching IDs
175
+ const response = await setConsent({
176
+ context,
177
+ params: undefined,
178
+ query: undefined,
179
+ body: createConsentData('privacy_policy', {
180
+ subjectId: subject.id,
181
+ externalSubjectId: 'test-subject',
182
+ }),
183
+ });
184
+
185
+ expectValidConsentResponse(response, 'privacy_policy', {
186
+ subjectId: subject.id,
187
+ externalSubjectId: 'test-subject',
188
+ });
189
+
190
+ // Create another subject with different external ID
191
+ const otherSubject = await context.registry.createSubject({
192
+ externalId: 'other-subject',
193
+ isIdentified: true,
194
+ identityProvider: 'test',
195
+ });
196
+
197
+ if (!otherSubject) {
198
+ throw new Error('Failed to create other test subject');
199
+ }
200
+
201
+ // Test with mismatched IDs
202
+ await expect(
203
+ setConsent({
204
+ context,
205
+ params: undefined,
206
+ query: undefined,
207
+ body: createConsentData('privacy_policy', {
208
+ subjectId: subject.id,
209
+ externalSubjectId: 'other-subject',
210
+ }),
211
+ })
212
+ ).rejects.toMatchObject({
213
+ name: 'C15TError',
214
+ code: BASE_ERROR_CODES.BAD_REQUEST,
215
+ status: 400,
216
+ });
217
+ });
218
+ });
219
+
220
+ describe('Error cases', () => {
221
+ it('should create anonymous subject when external subject is not found', async () => {
222
+ const response = await setConsent({
223
+ context,
224
+ params: undefined,
225
+ query: undefined,
226
+ body: createConsentData('privacy_policy', {
227
+ externalSubjectId: 'non-existent',
228
+ }),
229
+ });
230
+
231
+ expectValidConsentResponse(response, 'privacy_policy', {
232
+ externalSubjectId: 'non-existent',
233
+ });
234
+ });
235
+
236
+ it('should error if subject ID is not found', async () => {
237
+ await expect(
238
+ setConsent({
239
+ context,
240
+ params: undefined,
241
+ query: undefined,
242
+ body: createConsentData('privacy_policy', {
243
+ subjectId: 'non-existent',
244
+ }),
245
+ })
246
+ ).rejects.toMatchObject({
247
+ name: 'C15TError',
248
+ code: BASE_ERROR_CODES.NOT_FOUND,
249
+ status: 404,
250
+ });
251
+ });
252
+
253
+ it('should handle invalid consent data', async () => {
254
+ await expect(
255
+ setConsent({
256
+ context,
257
+ params: undefined,
258
+ query: undefined,
259
+ body: createConsentData('cookie_banner', {
260
+ preferences: {
261
+ marketing: 'invalid' as unknown as boolean,
262
+ analytics: 'invalid' as unknown as boolean,
263
+ },
264
+ }),
265
+ })
266
+ ).rejects.toThrow('Invalid body parameters');
267
+ });
268
+ });
269
+ });
270
+ });