@c15t/backend 2.0.0-rc.4 → 2.0.0-rc.6

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 (327) hide show
  1. package/dist/302.js +473 -0
  2. package/dist/364.js +1140 -0
  3. package/dist/583.js +540 -0
  4. package/dist/cache.cjs +1 -1
  5. package/dist/cache.js +4 -415
  6. package/dist/core.cjs +849 -96
  7. package/dist/core.js +147 -1817
  8. package/dist/db/adapters/drizzle.cjs +1 -1
  9. package/dist/db/adapters/drizzle.js +1 -2
  10. package/dist/db/adapters/kysely.cjs +1 -1
  11. package/dist/db/adapters/kysely.js +1 -2
  12. package/dist/db/adapters/mongo.cjs +1 -1
  13. package/dist/db/adapters/mongo.js +1 -2
  14. package/dist/db/adapters/prisma.cjs +1 -1
  15. package/dist/db/adapters/prisma.js +1 -2
  16. package/dist/db/adapters/typeorm.cjs +1 -1
  17. package/dist/db/adapters/typeorm.js +1 -2
  18. package/dist/db/adapters.cjs +1 -1
  19. package/dist/db/migrator.cjs +1 -1
  20. package/dist/db/schema.cjs +38 -1
  21. package/dist/db/schema.js +33 -2
  22. package/dist/define-config.cjs +1 -1
  23. package/dist/edge.cjs +1106 -0
  24. package/dist/edge.js +190 -0
  25. package/dist/router.cjs +629 -81
  26. package/dist/router.js +1 -1509
  27. package/dist/types/index.cjs +1 -1
  28. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  29. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  30. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  31. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  32. package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
  33. package/{dist → dist-types}/cache/index.d.ts +0 -1
  34. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  35. package/{dist → dist-types}/cache/types.d.ts +0 -1
  36. package/{dist → dist-types}/core.d.ts +8 -1
  37. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  38. package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
  39. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  40. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  41. package/{dist → dist-types}/db/registry/index.d.ts +22 -2
  42. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  43. package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
  44. package/{dist → dist-types}/db/registry/types.d.ts +1 -2
  45. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  46. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  47. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  48. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  49. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  50. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  51. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +2 -3
  52. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  53. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
  54. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
  55. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +2 -3
  56. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +2 -3
  57. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +2 -3
  58. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +6 -3
  59. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +2 -3
  60. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
  61. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  62. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +2 -3
  63. package/{dist → dist-types}/db/schema/index.d.ts +862 -33
  64. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  65. package/{dist → dist-types}/define-config.d.ts +0 -1
  66. package/dist-types/edge/index.d.ts +5 -0
  67. package/dist-types/edge/init-handler.d.ts +38 -0
  68. package/dist-types/edge/resolve-consent.d.ts +80 -0
  69. package/dist-types/edge/types.d.ts +13 -0
  70. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  71. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  72. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  73. package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
  74. package/dist-types/handlers/init/policy.d.ts +26 -0
  75. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  76. package/dist-types/handlers/init/translations.d.ts +48 -0
  77. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  78. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  79. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  80. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
  81. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  82. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
  83. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
  84. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  85. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
  86. package/{dist → dist-types}/init.d.ts +0 -1
  87. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  88. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  89. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  90. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  91. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
  92. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  93. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  94. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  95. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  96. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  97. package/dist-types/policies/builder.d.ts +127 -0
  98. package/dist-types/policies/defaults.d.ts +2 -0
  99. package/dist-types/policies/matchers.d.ts +3 -0
  100. package/{dist → dist-types}/router.d.ts +0 -1
  101. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  102. package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
  103. package/{dist → dist-types}/routes/init.d.ts +0 -1
  104. package/{dist → dist-types}/routes/status.d.ts +0 -1
  105. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  106. package/{dist → dist-types}/types/api.d.ts +0 -1
  107. package/{dist → dist-types}/types/index.d.ts +110 -6
  108. package/dist-types/utils/background.d.ts +6 -0
  109. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +0 -1
  110. package/{dist → dist-types}/utils/env.d.ts +0 -1
  111. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  112. package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
  113. package/{dist → dist-types}/utils/logger.d.ts +1 -2
  114. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  115. package/dist-types/version.d.ts +1 -0
  116. package/docs/README.md +49 -0
  117. package/docs/api/configuration.md +197 -0
  118. package/docs/api/endpoints.md +211 -0
  119. package/docs/guides/caching.md +85 -0
  120. package/docs/guides/database-setup.md +128 -0
  121. package/docs/guides/edge-deployment.md +248 -0
  122. package/docs/guides/framework-integration.md +142 -0
  123. package/docs/guides/iab-tcf.md +89 -0
  124. package/docs/guides/observability.md +96 -0
  125. package/docs/guides/policy-packs.md +396 -0
  126. package/docs/quickstart.md +129 -0
  127. package/package.json +45 -31
  128. package/.turbo/turbo-build.log +0 -49
  129. package/CHANGELOG.md +0 -123
  130. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  131. package/dist/cache/adapters/index.d.ts.map +0 -1
  132. package/dist/cache/adapters/memory.d.ts.map +0 -1
  133. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  134. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  135. package/dist/cache/index.d.ts.map +0 -1
  136. package/dist/cache/keys.d.ts.map +0 -1
  137. package/dist/cache/types.d.ts.map +0 -1
  138. package/dist/core.d.ts.map +0 -1
  139. package/dist/db/adapters/drizzle.d.ts +0 -2
  140. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  141. package/dist/db/adapters/index.d.ts +0 -2
  142. package/dist/db/adapters/index.d.ts.map +0 -1
  143. package/dist/db/adapters/kysely.d.ts +0 -2
  144. package/dist/db/adapters/kysely.d.ts.map +0 -1
  145. package/dist/db/adapters/mongo.d.ts +0 -2
  146. package/dist/db/adapters/mongo.d.ts.map +0 -1
  147. package/dist/db/adapters/prisma.d.ts +0 -2
  148. package/dist/db/adapters/prisma.d.ts.map +0 -1
  149. package/dist/db/adapters/typeorm.d.ts +0 -2
  150. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  151. package/dist/db/migrator/index.d.ts.map +0 -1
  152. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  153. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  154. package/dist/db/registry/domain.d.ts.map +0 -1
  155. package/dist/db/registry/index.d.ts.map +0 -1
  156. package/dist/db/registry/subject.d.ts.map +0 -1
  157. package/dist/db/registry/types.d.ts.map +0 -1
  158. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  159. package/dist/db/registry/utils.d.ts.map +0 -1
  160. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  161. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  162. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  163. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  164. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  165. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  166. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  167. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  168. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  169. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  170. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  171. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  172. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  173. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  174. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  175. package/dist/db/schema/index.d.ts.map +0 -1
  176. package/dist/db/tenant-scope.d.ts.map +0 -1
  177. package/dist/define-config.d.ts.map +0 -1
  178. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  179. package/dist/handlers/consent/index.d.ts +0 -12
  180. package/dist/handlers/consent/index.d.ts.map +0 -1
  181. package/dist/handlers/init/geo.d.ts.map +0 -1
  182. package/dist/handlers/init/index.d.ts.map +0 -1
  183. package/dist/handlers/init/translations.d.ts +0 -26
  184. package/dist/handlers/init/translations.d.ts.map +0 -1
  185. package/dist/handlers/status/index.d.ts +0 -7
  186. package/dist/handlers/status/index.d.ts.map +0 -1
  187. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  188. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  189. package/dist/handlers/subject/index.d.ts +0 -10
  190. package/dist/handlers/subject/index.d.ts.map +0 -1
  191. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  192. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  193. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  194. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  195. package/dist/init.d.ts.map +0 -1
  196. package/dist/middleware/auth/index.d.ts.map +0 -1
  197. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  198. package/dist/middleware/cors/cors.d.ts.map +0 -1
  199. package/dist/middleware/cors/index.d.ts +0 -30
  200. package/dist/middleware/cors/index.d.ts.map +0 -1
  201. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  202. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  203. package/dist/middleware/openapi/config.d.ts.map +0 -1
  204. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  205. package/dist/middleware/openapi/index.d.ts +0 -12
  206. package/dist/middleware/openapi/index.d.ts.map +0 -1
  207. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  208. package/dist/router.d.ts.map +0 -1
  209. package/dist/routes/consent.d.ts.map +0 -1
  210. package/dist/routes/index.d.ts +0 -10
  211. package/dist/routes/index.d.ts.map +0 -1
  212. package/dist/routes/init.d.ts.map +0 -1
  213. package/dist/routes/status.d.ts.map +0 -1
  214. package/dist/routes/subject.d.ts.map +0 -1
  215. package/dist/types/api.d.ts.map +0 -1
  216. package/dist/types/index.d.ts.map +0 -1
  217. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  218. package/dist/utils/env.d.ts.map +0 -1
  219. package/dist/utils/extract-error-message.d.ts.map +0 -1
  220. package/dist/utils/index.d.ts +0 -4
  221. package/dist/utils/index.d.ts.map +0 -1
  222. package/dist/utils/instrumentation.d.ts.map +0 -1
  223. package/dist/utils/logger.d.ts.map +0 -1
  224. package/dist/utils/metrics.d.ts.map +0 -1
  225. package/dist/version.d.ts +0 -2
  226. package/dist/version.d.ts.map +0 -1
  227. package/knip.json +0 -31
  228. package/rslib.config.ts +0 -93
  229. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  230. package/src/cache/adapters/index.ts +0 -22
  231. package/src/cache/adapters/memory.ts +0 -111
  232. package/src/cache/adapters/upstash-redis.ts +0 -113
  233. package/src/cache/gvl-resolver.ts +0 -289
  234. package/src/cache/index.ts +0 -34
  235. package/src/cache/keys.ts +0 -68
  236. package/src/cache/types.ts +0 -66
  237. package/src/core.ts +0 -369
  238. package/src/db/migrator/index.ts +0 -80
  239. package/src/db/registry/consent-policy.test.ts +0 -451
  240. package/src/db/registry/consent-policy.ts +0 -82
  241. package/src/db/registry/consent-purpose.test.ts +0 -428
  242. package/src/db/registry/consent-purpose.ts +0 -61
  243. package/src/db/registry/domain.test.ts +0 -445
  244. package/src/db/registry/domain.ts +0 -91
  245. package/src/db/registry/index.ts +0 -14
  246. package/src/db/registry/subject.test.ts +0 -371
  247. package/src/db/registry/subject.ts +0 -126
  248. package/src/db/registry/types.ts +0 -10
  249. package/src/db/registry/utils/generate-id.test.ts +0 -216
  250. package/src/db/registry/utils/generate-id.ts +0 -133
  251. package/src/db/registry/utils.ts +0 -133
  252. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  253. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  254. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  255. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  256. package/src/db/schema/1.0.0/consent.ts +0 -20
  257. package/src/db/schema/1.0.0/domain.ts +0 -12
  258. package/src/db/schema/1.0.0/index.ts +0 -48
  259. package/src/db/schema/1.0.0/subject.ts +0 -11
  260. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  261. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  262. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  263. package/src/db/schema/2.0.0/consent.ts +0 -28
  264. package/src/db/schema/2.0.0/domain.ts +0 -12
  265. package/src/db/schema/2.0.0/index.ts +0 -47
  266. package/src/db/schema/2.0.0/subject.ts +0 -13
  267. package/src/db/schema/index.ts +0 -15
  268. package/src/db/tenant-scope.test.ts +0 -747
  269. package/src/db/tenant-scope.ts +0 -103
  270. package/src/define-config.ts +0 -19
  271. package/src/handlers/consent/check.handler.ts +0 -126
  272. package/src/handlers/init/geo.test.ts +0 -317
  273. package/src/handlers/init/geo.ts +0 -195
  274. package/src/handlers/init/index.test.ts +0 -205
  275. package/src/handlers/init/index.ts +0 -114
  276. package/src/handlers/init/translations.test.ts +0 -121
  277. package/src/handlers/init/translations.ts +0 -69
  278. package/src/handlers/status/status.handler.test.ts +0 -155
  279. package/src/handlers/status/status.handler.ts +0 -51
  280. package/src/handlers/subject/get.handler.ts +0 -92
  281. package/src/handlers/subject/list.handler.ts +0 -92
  282. package/src/handlers/subject/patch.handler.ts +0 -119
  283. package/src/handlers/subject/post.handler.test.ts +0 -294
  284. package/src/handlers/subject/post.handler.ts +0 -268
  285. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  286. package/src/handlers/utils/consent-enrichment.ts +0 -218
  287. package/src/init.test.ts +0 -122
  288. package/src/init.ts +0 -88
  289. package/src/middleware/auth/index.ts +0 -11
  290. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  291. package/src/middleware/auth/validate-api-key.ts +0 -107
  292. package/src/middleware/cors/cors.test.ts +0 -135
  293. package/src/middleware/cors/cors.ts +0 -186
  294. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  295. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  296. package/src/middleware/cors/process-cors.ts +0 -91
  297. package/src/middleware/openapi/config.ts +0 -29
  298. package/src/middleware/openapi/handlers.ts +0 -34
  299. package/src/middleware/process-ip/index.test.ts +0 -193
  300. package/src/middleware/process-ip/index.ts +0 -199
  301. package/src/router.ts +0 -15
  302. package/src/routes/consent.ts +0 -52
  303. package/src/routes/init.ts +0 -105
  304. package/src/routes/status.ts +0 -46
  305. package/src/routes/subject.ts +0 -152
  306. package/src/types/api.ts +0 -48
  307. package/src/types/index.ts +0 -391
  308. package/src/utils/create-telemetry-options.test.ts +0 -286
  309. package/src/utils/create-telemetry-options.ts +0 -229
  310. package/src/utils/env.ts +0 -84
  311. package/src/utils/extract-error-message.ts +0 -21
  312. package/src/utils/instrumentation.test.ts +0 -183
  313. package/src/utils/instrumentation.ts +0 -194
  314. package/src/utils/logger.ts +0 -41
  315. package/src/utils/metrics.test.ts +0 -311
  316. package/src/utils/metrics.ts +0 -402
  317. package/src/utils/telemetry-pii.test.ts +0 -323
  318. package/src/version.ts +0 -2
  319. package/tsconfig.json +0 -11
  320. package/vitest.config.ts +0 -28
  321. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  322. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  323. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  324. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  325. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  326. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  327. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
@@ -1,391 +0,0 @@
1
- import type { createLogger, LoggerOptions } from '@c15t/logger';
2
- import {
3
- type Branding,
4
- brandingValues,
5
- type GlobalVendorList,
6
- type NonIABVendor,
7
- } from '@c15t/schema/types';
8
- import type { Translations } from '@c15t/translations';
9
- import type { Meter, Tracer } from '@opentelemetry/api';
10
- import type { FumaDB, InferFumaDB } from 'fumadb';
11
- import type { CacheAdapter } from '../cache/types';
12
- import type { createRegistry } from '../db/registry';
13
- import type { DB, LatestDB } from '../db/schema';
14
-
15
- export * from './api';
16
-
17
- // Re-export from @c15t/schema for backward compatibility
18
- export const branding = brandingValues;
19
- export type { Branding };
20
-
21
- export interface DatabaseOptions {
22
- /**
23
- * The database adapter to use.
24
- *
25
- * @see {@link https://v2.c15t.com/docs/self-host/guides/database-setup}
26
- */
27
- adapter: FumaDB<FumaDBSchema>['adapter'];
28
-
29
- /**
30
- * Tenant ID for multi-tenant deployments.
31
- * When set, all database queries are automatically scoped to this tenant.
32
- */
33
- tenantId?: string;
34
-
35
- /**
36
- * Optional prefix for all database table names.
37
- * Useful when sharing a database with other applications to avoid naming conflicts.
38
- *
39
- * @example 'c15t_' // tables become: c15t_subject, c15t_consent, etc.
40
- * @see {@link https://v2.c15t.com/docs/self-host/guides/database-setup}
41
- */
42
- tablePrefix?: string;
43
- }
44
-
45
- /**
46
- * OpenAPI spec generation and documentation UI options.
47
- */
48
- export interface OpenAPIOptions {
49
- /**
50
- * Enable/disable OpenAPI spec generation
51
- * @default true
52
- */
53
- enabled?: boolean;
54
-
55
- /**
56
- * Path to serve the OpenAPI JSON spec
57
- * @default "/spec.json"
58
- */
59
- specPath?: string;
60
-
61
- /**
62
- * Path to serve the API documentation UI
63
- * @default "/docs"
64
- */
65
- docsPath?: string;
66
-
67
- /**
68
- * OpenAPI specification options
69
- */
70
- options?: {
71
- info?: {
72
- title?: string;
73
- version?: string;
74
- description?: string;
75
- };
76
- servers?: Array<{ url: string; description?: string }>;
77
- security?: Array<Record<string, string[]>>;
78
- };
79
-
80
- /**
81
- * Custom template for rendering the API documentation UI
82
- * If provided, this will be used instead of the default Scalar UI
83
- */
84
- customUiTemplate?: string;
85
- }
86
-
87
- /**
88
- * OpenTelemetry configuration for tracing and metrics.
89
- * Telemetry is opt-in and disabled by default.
90
- * Users must provide their own SDK setup (Node, Bun, edge, etc.).
91
- */
92
- export interface TelemetryOptions {
93
- /**
94
- * Enable telemetry (tracing and metrics).
95
- * Must be explicitly set to true to activate.
96
- * @default false
97
- */
98
- enabled?: boolean;
99
- /**
100
- * User-provided tracer instance.
101
- * Users should set up their own OpenTelemetry SDK and pass the tracer here.
102
- * @example trace.getTracer('my-app')
103
- */
104
- tracer?: Tracer;
105
- /**
106
- * User-provided meter instance for metrics.
107
- * Users should set up their own OpenTelemetry SDK and pass the meter here.
108
- * @example metrics.getMeter('my-app')
109
- */
110
- meter?: Meter;
111
- /**
112
- * Default attributes to include on all spans and metrics.
113
- */
114
- defaultAttributes?: Record<string, string | number | boolean>;
115
- }
116
-
117
- /**
118
- * IP address tracking and masking options.
119
- */
120
- export interface IPAddressOptions {
121
- /**
122
- * Enable/disable IP address tracking.
123
- * When disabled, all IP addresses will be stored as null.
124
- * @default true
125
- */
126
- tracking?: boolean;
127
-
128
- /**
129
- * Enable/disable IP address masking to reduce PII collection.
130
- * - IPv4: Last octet is replaced with 0 (e.g., 192.168.1.100 -> 192.168.1.0)
131
- * - IPv6: Last 80 bits are masked (e.g., 2001:db8:85a3::1 -> 2001:db8:85a3::)
132
- * @default true
133
- */
134
- masking?: boolean;
135
-
136
- /**
137
- * Override the default IP address headers used to extract client IP.
138
- * Headers are checked in order, first match wins.
139
- */
140
- ipAddressHeaders?: string[];
141
- }
142
-
143
- /**
144
- * Cache configuration for external persistent storage.
145
- * Used for caching GVL and other data.
146
- */
147
- export interface CacheOptions {
148
- /**
149
- * External cache adapter (Redis, KV, etc.).
150
- * If not provided, only in-memory cache is used.
151
- */
152
- adapter?: CacheAdapter;
153
- }
154
-
155
- /**
156
- * IAB TCF configuration including GVL, CMP registration, and custom vendors.
157
- * Disabled by default - most users don't need IAB TCF.
158
- * Set enabled: true to activate IAB support.
159
- */
160
- export interface IABOptions {
161
- /**
162
- * Enable IAB TCF support.
163
- * When false or not provided, /init returns gvl: null.
164
- */
165
- enabled: true;
166
-
167
- /**
168
- * CMP ID registered with IAB Europe.
169
- * This is returned to clients via the /init endpoint so they
170
- * can use the correct CMP identity in TC Strings.
171
- *
172
- * @see https://iabeurope.eu/cmp-list/ - List of registered CMPs
173
- */
174
- cmpId?: number;
175
-
176
- /**
177
- * Bundled GVL translations by language code.
178
- * These are checked first before any cache or fetch.
179
- *
180
- * @example
181
- * ```ts
182
- * import enGVL from './gvl/en.json';
183
- * import deGVL from './gvl/de.json';
184
- *
185
- * iab: {
186
- * enabled: true,
187
- * bundled: { en: enGVL, de: deGVL }
188
- * }
189
- * ```
190
- */
191
- bundled?: Record<string, GlobalVendorList>;
192
-
193
- /**
194
- * Vendor IDs to filter when fetching non-bundled languages.
195
- * Reduces payload size.
196
- */
197
- vendorIds?: number[];
198
-
199
- /**
200
- * Override the default GVL endpoint.
201
- * @default 'https://gvl.consent.io'
202
- */
203
- endpoint?: string;
204
-
205
- /**
206
- * Custom vendors not registered with IAB.
207
- * These are synced to the frontend via the /init endpoint.
208
- *
209
- * @example
210
- * ```ts
211
- * customVendors: [
212
- * {
213
- * id: 'internal-analytics',
214
- * name: 'Our Analytics',
215
- * privacyPolicyUrl: 'https://example.com/privacy',
216
- * purposes: [1, 8],
217
- * }
218
- * ]
219
- * ```
220
- */
221
- customVendors?: NonIABVendor[];
222
- }
223
-
224
- type FumaDBSchema = InferFumaDB<typeof DB>['schemas'];
225
-
226
- export interface C15TOptions {
227
- /**
228
- * The database adapter to use.
229
- *
230
- * @see {@link https://v2.c15t.com/docs/self-host/guides/database-setup}
231
- */
232
- adapter: FumaDB<FumaDBSchema>['adapter'];
233
-
234
- /**
235
- * Tenant ID for multi-tenant deployments.
236
- * When set, all database queries are automatically scoped to this tenant.
237
- */
238
- tenantId?: string;
239
-
240
- /**
241
- * Optional prefix for all database table names.
242
- * Useful when sharing a database with other applications to avoid naming conflicts.
243
- *
244
- * @example 'c15t_' // tables become: c15t_subject, c15t_consent, etc.
245
- * @see {@link https://v2.c15t.com/docs/self-host/guides/database-setup}
246
- */
247
- tablePrefix?: string;
248
-
249
- /**
250
- * Application name used as backend metadata and identity.
251
- * Returned by `/init` (`appName`), used in logs, telemetry defaults (`service.name`),
252
- * and cache key prefixing.
253
- *
254
- * @default "c15t"
255
- * @see {@link https://v2.c15t.com/docs/self-host/api/configuration}
256
- */
257
- appName?: string;
258
-
259
- /**
260
- * Base path prefix for all API routes (e.g. `/api/self-host`).
261
- *
262
- * @see {@link https://v2.c15t.com/docs/self-host/api/endpoints}
263
- */
264
- basePath?: string;
265
-
266
- /**
267
- * Allowed origins for CORS. Required for browser-based consent collection.
268
- * Protocol is optional; matching is protocol-agnostic and normalized.
269
- *
270
- * @example ['example.com', 'app.example.com', 'localhost:3000']
271
- * @see {@link https://v2.c15t.com/docs/self-host/api/configuration}
272
- */
273
- trustedOrigins: string[];
274
-
275
- /** Logger configuration. */
276
- logger?: LoggerOptions;
277
-
278
- /**
279
- * Disables the use of Geo Location to determine the jurisdiction.
280
- *
281
- * When enabled, the jurisdiction will be set to "GDPR" to show the strictest
282
- * version of the banner as we don't know the jurisdiction in this case.
283
- *
284
- * @default false
285
- */
286
- disableGeoLocation?: boolean;
287
-
288
- /**
289
- * Override base translations.
290
- *
291
- * @example
292
- * ```ts
293
- * {
294
- * en: enTranslations,
295
- * de: deTranslations,
296
- * }
297
- * ```
298
- */
299
- customTranslations?: Record<string, Partial<Translations>>;
300
-
301
- /**
302
- * Select which branding to show in the consent banner.
303
- * Use "none" to hide branding.
304
- * @default "c15t"
305
- */
306
- branding?: Branding;
307
-
308
- /**
309
- * OpenAPI spec generation and documentation UI options.
310
- *
311
- * @see {@link https://v2.c15t.com/docs/self-host/api/endpoints}
312
- */
313
- openapi?: OpenAPIOptions;
314
-
315
- /**
316
- * OpenTelemetry configuration for tracing and metrics.
317
- * Telemetry is opt-in and disabled by default.
318
- * Users must provide their own SDK setup (Node, Bun, edge, etc.).
319
- *
320
- * @see {@link https://v2.c15t.com/docs/self-host/guides/observability}
321
- */
322
- telemetry?: TelemetryOptions;
323
-
324
- /**
325
- * IP address tracking and masking options.
326
- *
327
- * @see {@link https://v2.c15t.com/docs/self-host/api/configuration}
328
- */
329
- ipAddress?: IPAddressOptions;
330
-
331
- /**
332
- * Cache configuration for external persistent storage.
333
- * Used for caching GVL and other data.
334
- *
335
- * @see {@link https://v2.c15t.com/docs/self-host/guides/caching}
336
- */
337
- cache?: CacheOptions;
338
-
339
- /**
340
- * API keys for authenticated endpoints.
341
- * Used for server-side endpoints like GET /subjects.
342
- *
343
- * @example
344
- * ```ts
345
- * apiKeys: ['sk_live_abc123', 'sk_live_def456']
346
- * ```
347
- */
348
- apiKeys?: string[];
349
-
350
- /**
351
- * IAB TCF configuration including GVL, CMP registration, and custom vendors.
352
- * Disabled by default - most users don't need IAB TCF.
353
- * Set enabled: true to activate IAB support.
354
- *
355
- * @see {@link https://v2.c15t.com/docs/self-host/guides/iab-tcf}
356
- */
357
- iab?: IABOptions;
358
- }
359
-
360
- export interface C15TContext
361
- extends Omit<
362
- C15TOptions,
363
- 'ipAddress' | 'adapter' | 'logger' | 'tablePrefix' | 'tenantId'
364
- > {
365
- appName: string;
366
- logger: ReturnType<typeof createLogger>;
367
- registry: ReturnType<typeof createRegistry>;
368
- db: ReturnType<InferFumaDB<typeof LatestDB>['orm']>;
369
-
370
- // Resolved from request
371
- ipAddress?: string | null;
372
- userAgent?: string;
373
- origin?: string;
374
- trustedOrigin?: boolean;
375
- path?: string;
376
- method?: string;
377
- headers?: Headers;
378
-
379
- // Authentication state
380
- /**
381
- * Whether the request was authenticated with a valid API key.
382
- * Set to true when a valid Bearer token is provided in the Authorization header.
383
- */
384
- apiKeyAuthenticated?: boolean;
385
- }
386
-
387
- export type DeepPartial<T> = T extends (...args: unknown[]) => unknown
388
- ? T
389
- : T extends object
390
- ? { [K in keyof T]?: DeepPartial<T[K]> }
391
- : T;
@@ -1,286 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import type { C15TOptions } from '../types';
3
- import {
4
- createRequestSpan,
5
- createTelemetryOptions,
6
- getDefaultAttributes,
7
- getMeter,
8
- getTraceContext,
9
- getTracer,
10
- isTelemetryEnabled,
11
- resetTelemetryConfig,
12
- withRequestSpan,
13
- } from './create-telemetry-options';
14
-
15
- afterEach(() => {
16
- resetTelemetryConfig();
17
- });
18
-
19
- describe('createTelemetryOptions', () => {
20
- it('returns disabled by default (opt-in)', () => {
21
- const options = createTelemetryOptions('test-app');
22
-
23
- expect(options?.enabled).toBe(false);
24
- });
25
-
26
- it('sets enabled when explicitly configured', () => {
27
- const options = createTelemetryOptions('test-app', { enabled: true });
28
-
29
- expect(options?.enabled).toBe(true);
30
- });
31
-
32
- it('includes default attributes with service name and version', () => {
33
- const options = createTelemetryOptions('my-app');
34
-
35
- expect(options?.defaultAttributes).toMatchObject({
36
- 'service.name': 'my-app',
37
- });
38
- expect(options?.defaultAttributes?.['service.version']).toBeDefined();
39
- });
40
-
41
- it('merges user-provided default attributes', () => {
42
- const options = createTelemetryOptions('my-app', {
43
- defaultAttributes: {
44
- environment: 'production',
45
- region: 'us-east-1',
46
- },
47
- });
48
-
49
- expect(options?.defaultAttributes).toMatchObject({
50
- 'service.name': 'my-app',
51
- environment: 'production',
52
- region: 'us-east-1',
53
- });
54
- });
55
-
56
- it('preserves user-provided tracer', () => {
57
- const mockTracer = { startSpan: vi.fn() };
58
- type TelemetryConfig = NonNullable<C15TOptions['telemetry']>;
59
- const options = createTelemetryOptions('my-app', {
60
- tracer: mockTracer as unknown as TelemetryConfig['tracer'],
61
- });
62
-
63
- expect(options?.tracer).toBe(mockTracer);
64
- });
65
- });
66
-
67
- describe('isTelemetryEnabled', () => {
68
- it('returns false when no options provided', () => {
69
- expect(isTelemetryEnabled()).toBe(false);
70
- });
71
-
72
- it('returns false when telemetry is not configured', () => {
73
- const options: C15TOptions = {
74
- trustedOrigins: [],
75
- adapter: {} as C15TOptions['adapter'],
76
- };
77
-
78
- expect(isTelemetryEnabled(options)).toBe(false);
79
- });
80
-
81
- it('returns false when enabled is not set', () => {
82
- const options: C15TOptions = {
83
- trustedOrigins: [],
84
- adapter: {} as C15TOptions['adapter'],
85
- telemetry: {},
86
- };
87
-
88
- expect(isTelemetryEnabled(options)).toBe(false);
89
- });
90
-
91
- it('returns true when enabled is true', () => {
92
- const options: C15TOptions = {
93
- trustedOrigins: [],
94
- adapter: {} as C15TOptions['adapter'],
95
- telemetry: {
96
- enabled: true,
97
- },
98
- };
99
-
100
- expect(isTelemetryEnabled(options)).toBe(true);
101
- });
102
- });
103
-
104
- describe('getTracer', () => {
105
- it('returns a tracer even when telemetry is disabled', () => {
106
- const tracer = getTracer();
107
-
108
- expect(tracer).toBeDefined();
109
- expect(tracer.startSpan).toBeDefined();
110
- });
111
-
112
- it('uses user-provided tracer when available', () => {
113
- const mockTracer = { startSpan: vi.fn() };
114
- type TelemetryConfig = NonNullable<C15TOptions['telemetry']>;
115
- const options: C15TOptions = {
116
- trustedOrigins: [],
117
- adapter: {} as C15TOptions['adapter'],
118
- telemetry: {
119
- enabled: true,
120
- tracer: mockTracer as unknown as TelemetryConfig['tracer'],
121
- },
122
- };
123
-
124
- const tracer = getTracer(options);
125
- expect(tracer).toBe(mockTracer);
126
- });
127
- });
128
-
129
- describe('getMeter', () => {
130
- it('returns a meter even when telemetry is disabled', () => {
131
- const meter = getMeter();
132
-
133
- expect(meter).toBeDefined();
134
- expect(meter.createCounter).toBeDefined();
135
- });
136
-
137
- it('returns meter with expected interface when telemetry is enabled', () => {
138
- const options: C15TOptions = {
139
- trustedOrigins: [],
140
- adapter: {} as C15TOptions['adapter'],
141
- telemetry: {
142
- enabled: true,
143
- },
144
- };
145
-
146
- const meter = getMeter(options);
147
- // Verify the meter has the expected interface
148
- expect(meter.createCounter).toBeDefined();
149
- expect(meter.createHistogram).toBeDefined();
150
- });
151
- });
152
-
153
- describe('createRequestSpan', () => {
154
- it('returns null when telemetry is disabled', () => {
155
- const span = createRequestSpan('GET', '/test');
156
-
157
- expect(span).toBeNull();
158
- });
159
-
160
- it('creates span when telemetry is enabled', () => {
161
- const options: C15TOptions = {
162
- trustedOrigins: [],
163
- adapter: {} as C15TOptions['adapter'],
164
- telemetry: {
165
- enabled: true,
166
- },
167
- };
168
-
169
- const span = createRequestSpan('GET', '/test', options);
170
-
171
- expect(span).toBeDefined();
172
- // Clean up
173
- span?.end();
174
- });
175
- });
176
-
177
- describe('withRequestSpan', () => {
178
- it('executes operation without span when telemetry is disabled', async () => {
179
- const operation = vi.fn().mockResolvedValue('result');
180
-
181
- const result = await withRequestSpan('GET', '/test', operation);
182
-
183
- expect(result).toBe('result');
184
- expect(operation).toHaveBeenCalledTimes(1);
185
- });
186
-
187
- it('wraps operation in span when telemetry is enabled', async () => {
188
- const options: C15TOptions = {
189
- trustedOrigins: [],
190
- adapter: {} as C15TOptions['adapter'],
191
- telemetry: {
192
- enabled: true,
193
- },
194
- };
195
- const operation = vi.fn().mockResolvedValue('result');
196
-
197
- const result = await withRequestSpan('GET', '/test', operation, options);
198
-
199
- expect(result).toBe('result');
200
- expect(operation).toHaveBeenCalledTimes(1);
201
- });
202
-
203
- it('propagates errors from operation', async () => {
204
- const error = new Error('Test error');
205
- const operation = vi.fn().mockRejectedValue(error);
206
-
207
- await expect(withRequestSpan('GET', '/test', operation)).rejects.toThrow(
208
- 'Test error'
209
- );
210
- });
211
- });
212
-
213
- describe('getTraceContext', () => {
214
- it('returns null when no active span', () => {
215
- const context = getTraceContext();
216
-
217
- expect(context).toBeNull();
218
- });
219
- });
220
-
221
- describe('cached telemetry config', () => {
222
- it('isTelemetryEnabled returns false before init', () => {
223
- expect(isTelemetryEnabled()).toBe(false);
224
- });
225
-
226
- it('isTelemetryEnabled returns cached value after init', () => {
227
- createTelemetryOptions('test-app', { enabled: true });
228
-
229
- expect(isTelemetryEnabled()).toBe(true);
230
- });
231
-
232
- it('getDefaultAttributes returns empty before init', () => {
233
- const attrs = getDefaultAttributes();
234
-
235
- expect(Object.keys(attrs)).toHaveLength(0);
236
- });
237
-
238
- it('getDefaultAttributes returns cached attributes after init', () => {
239
- createTelemetryOptions('test-app', {
240
- defaultAttributes: { environment: 'test' },
241
- });
242
-
243
- const attrs = getDefaultAttributes();
244
- expect(attrs['service.name']).toBe('test-app');
245
- expect(attrs['environment']).toBe('test');
246
- });
247
-
248
- it('includes tenantId in default attributes when provided', () => {
249
- createTelemetryOptions('test-app', {}, 'tenant-123');
250
-
251
- const attrs = getDefaultAttributes();
252
- expect(attrs['tenant.id']).toBe('tenant-123');
253
- });
254
-
255
- it('does not include tenant.id when tenantId is undefined', () => {
256
- createTelemetryOptions('test-app');
257
-
258
- const attrs = getDefaultAttributes();
259
- expect(attrs['tenant.id']).toBeUndefined();
260
- });
261
-
262
- it('resetTelemetryConfig clears the cache', () => {
263
- createTelemetryOptions('test-app', { enabled: true });
264
- expect(isTelemetryEnabled()).toBe(true);
265
-
266
- resetTelemetryConfig();
267
- expect(isTelemetryEnabled()).toBe(false);
268
- expect(Object.keys(getDefaultAttributes())).toHaveLength(0);
269
- });
270
-
271
- it('getTracer returns a tracer without explicit options after init', () => {
272
- createTelemetryOptions('test-app', { enabled: true });
273
-
274
- const tracer = getTracer();
275
- expect(tracer).toBeDefined();
276
- expect(tracer.startSpan).toBeDefined();
277
- });
278
-
279
- it('getMeter returns a meter without explicit options after init', () => {
280
- createTelemetryOptions('test-app', { enabled: true });
281
-
282
- const meter = getMeter();
283
- expect(meter).toBeDefined();
284
- expect(meter.createCounter).toBeDefined();
285
- });
286
- });