@c15t/backend 2.0.0-rc.0 → 2.0.0-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 (336) hide show
  1. package/README.md +3 -3
  2. package/dist/302.js +473 -0
  3. package/dist/583.js +540 -0
  4. package/dist/915.js +1771 -0
  5. package/dist/cache.cjs +5 -5
  6. package/dist/cache.js +4 -415
  7. package/dist/core.cjs +1356 -120
  8. package/dist/core.js +163 -1981
  9. package/dist/db/adapters/drizzle.cjs +1 -1
  10. package/dist/db/adapters/drizzle.js +1 -2
  11. package/dist/db/adapters/kysely.cjs +1 -1
  12. package/dist/db/adapters/kysely.js +1 -2
  13. package/dist/db/adapters/mongo.cjs +1 -1
  14. package/dist/db/adapters/mongo.js +1 -2
  15. package/dist/db/adapters/prisma.cjs +1 -1
  16. package/dist/db/adapters/prisma.js +1 -2
  17. package/dist/db/adapters/typeorm.cjs +1 -1
  18. package/dist/db/adapters/typeorm.js +1 -2
  19. package/dist/db/adapters.cjs +1 -1
  20. package/dist/db/migrator.cjs +1 -1
  21. package/dist/db/schema.cjs +43 -3
  22. package/dist/db/schema.js +35 -4
  23. package/dist/define-config.cjs +1 -1
  24. package/dist/edge.cjs +1106 -0
  25. package/dist/edge.js +190 -0
  26. package/dist/router.cjs +885 -123
  27. package/dist/router.js +1 -1507
  28. package/dist/{types.cjs → types/index.cjs} +1 -1
  29. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  30. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  31. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  32. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  33. package/{dist → dist-types}/cache/gvl-resolver.d.ts +0 -1
  34. package/{dist → dist-types}/cache/index.d.ts +0 -1
  35. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  36. package/{dist → dist-types}/cache/types.d.ts +0 -1
  37. package/{dist → dist-types}/core.d.ts +8 -1
  38. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  39. package/dist-types/db/registry/consent-policy.d.ts +78 -0
  40. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  41. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  42. package/dist-types/db/registry/index.d.ts +118 -0
  43. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  44. package/{dist → dist-types}/db/registry/subject.d.ts +0 -2
  45. package/{dist → dist-types}/db/registry/types.d.ts +1 -1
  46. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  47. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  48. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  49. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  50. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  51. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  52. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  53. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  54. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -32
  55. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -2
  56. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  57. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +3 -3
  58. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  59. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +7 -2
  60. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  61. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +455 -28
  62. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  63. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -3
  64. package/{dist → dist-types}/db/schema/index.d.ts +908 -86
  65. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  66. package/dist-types/define-config.d.ts +17 -0
  67. package/dist-types/edge/index.d.ts +5 -0
  68. package/dist-types/edge/init-handler.d.ts +40 -0
  69. package/dist-types/edge/resolve-consent.d.ts +80 -0
  70. package/dist-types/edge/types.d.ts +13 -0
  71. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  72. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  73. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  74. package/{dist → dist-types}/handlers/init/index.d.ts +2 -3
  75. package/dist-types/handlers/init/policy.d.ts +26 -0
  76. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  77. package/dist-types/handlers/init/translations.d.ts +48 -0
  78. package/dist-types/handlers/legal-document/current.handler.d.ts +11 -0
  79. package/dist-types/handlers/legal-document/snapshot.d.ts +39 -0
  80. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  81. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  82. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  83. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +3 -2
  84. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  85. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +3 -2
  86. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -2
  87. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  88. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +3 -1
  89. package/{dist → dist-types}/init.d.ts +4 -7
  90. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  91. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  92. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  93. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  94. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +0 -1
  95. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  96. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  97. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  98. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  99. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  100. package/dist-types/policies/builder.d.ts +127 -0
  101. package/dist-types/policies/defaults.d.ts +2 -0
  102. package/dist-types/policies/matchers.d.ts +3 -0
  103. package/{dist → dist-types}/router.d.ts +0 -1
  104. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  105. package/{dist → dist-types}/routes/index.d.ts +1 -1
  106. package/{dist → dist-types}/routes/init.d.ts +0 -1
  107. package/dist-types/routes/legal-document.d.ts +7 -0
  108. package/{dist → dist-types}/routes/status.d.ts +0 -1
  109. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  110. package/{dist → dist-types}/types/api.d.ts +0 -1
  111. package/dist-types/types/index.d.ts +464 -0
  112. package/dist-types/utils/background.d.ts +6 -0
  113. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  114. package/{dist → dist-types}/utils/env.d.ts +0 -1
  115. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  116. package/{dist → dist-types}/utils/instrumentation.d.ts +2 -3
  117. package/{dist → dist-types}/utils/logger.d.ts +0 -1
  118. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  119. package/dist-types/version.d.ts +1 -0
  120. package/docs/README.md +49 -0
  121. package/docs/api/configuration.md +208 -0
  122. package/docs/api/endpoints.md +211 -0
  123. package/docs/guides/caching.md +85 -0
  124. package/docs/guides/database-setup.md +128 -0
  125. package/docs/guides/edge-deployment.md +251 -0
  126. package/docs/guides/framework-integration.md +142 -0
  127. package/docs/guides/iab-tcf.md +89 -0
  128. package/docs/guides/observability.md +96 -0
  129. package/docs/guides/policy-packs.md +396 -0
  130. package/docs/quickstart.md +129 -0
  131. package/package.json +53 -39
  132. package/.turbo/turbo-build.log +0 -49
  133. package/CHANGELOG.md +0 -89
  134. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  135. package/dist/cache/adapters/index.d.ts.map +0 -1
  136. package/dist/cache/adapters/memory.d.ts.map +0 -1
  137. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  138. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  139. package/dist/cache/index.d.ts.map +0 -1
  140. package/dist/cache/keys.d.ts.map +0 -1
  141. package/dist/cache/types.d.ts.map +0 -1
  142. package/dist/core.d.ts.map +0 -1
  143. package/dist/db/adapters/drizzle.d.ts +0 -2
  144. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  145. package/dist/db/adapters/index.d.ts +0 -2
  146. package/dist/db/adapters/index.d.ts.map +0 -1
  147. package/dist/db/adapters/kysely.d.ts +0 -2
  148. package/dist/db/adapters/kysely.d.ts.map +0 -1
  149. package/dist/db/adapters/mongo.d.ts +0 -2
  150. package/dist/db/adapters/mongo.d.ts.map +0 -1
  151. package/dist/db/adapters/prisma.d.ts +0 -2
  152. package/dist/db/adapters/prisma.d.ts.map +0 -1
  153. package/dist/db/adapters/typeorm.d.ts +0 -2
  154. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  155. package/dist/db/migrator/index.d.ts.map +0 -1
  156. package/dist/db/registry/consent-policy.d.ts +0 -23
  157. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  158. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  159. package/dist/db/registry/domain.d.ts.map +0 -1
  160. package/dist/db/registry/index.d.ts +0 -57
  161. package/dist/db/registry/index.d.ts.map +0 -1
  162. package/dist/db/registry/subject.d.ts.map +0 -1
  163. package/dist/db/registry/types.d.ts.map +0 -1
  164. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  165. package/dist/db/registry/utils.d.ts.map +0 -1
  166. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  167. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  168. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  169. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  170. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  171. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  172. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  173. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  174. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  175. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  176. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  177. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  178. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  179. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  180. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  181. package/dist/db/schema/index.d.ts.map +0 -1
  182. package/dist/db/tenant-scope.d.ts.map +0 -1
  183. package/dist/define-config.d.ts +0 -5
  184. package/dist/define-config.d.ts.map +0 -1
  185. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  186. package/dist/handlers/consent/index.d.ts +0 -12
  187. package/dist/handlers/consent/index.d.ts.map +0 -1
  188. package/dist/handlers/init/geo.d.ts.map +0 -1
  189. package/dist/handlers/init/index.d.ts.map +0 -1
  190. package/dist/handlers/init/translations.d.ts +0 -28
  191. package/dist/handlers/init/translations.d.ts.map +0 -1
  192. package/dist/handlers/status/index.d.ts +0 -7
  193. package/dist/handlers/status/index.d.ts.map +0 -1
  194. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  195. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  196. package/dist/handlers/subject/index.d.ts +0 -10
  197. package/dist/handlers/subject/index.d.ts.map +0 -1
  198. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  199. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  200. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  201. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  202. package/dist/init.d.ts.map +0 -1
  203. package/dist/middleware/auth/index.d.ts.map +0 -1
  204. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  205. package/dist/middleware/cors/cors.d.ts.map +0 -1
  206. package/dist/middleware/cors/index.d.ts +0 -30
  207. package/dist/middleware/cors/index.d.ts.map +0 -1
  208. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  209. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  210. package/dist/middleware/openapi/config.d.ts.map +0 -1
  211. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  212. package/dist/middleware/openapi/index.d.ts +0 -12
  213. package/dist/middleware/openapi/index.d.ts.map +0 -1
  214. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  215. package/dist/router.d.ts.map +0 -1
  216. package/dist/routes/consent.d.ts.map +0 -1
  217. package/dist/routes/index.d.ts.map +0 -1
  218. package/dist/routes/init.d.ts.map +0 -1
  219. package/dist/routes/status.d.ts.map +0 -1
  220. package/dist/routes/subject.d.ts.map +0 -1
  221. package/dist/types/api.d.ts.map +0 -1
  222. package/dist/types/index.d.ts +0 -255
  223. package/dist/types/index.d.ts.map +0 -1
  224. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  225. package/dist/utils/env.d.ts.map +0 -1
  226. package/dist/utils/extract-error-message.d.ts.map +0 -1
  227. package/dist/utils/index.d.ts +0 -4
  228. package/dist/utils/index.d.ts.map +0 -1
  229. package/dist/utils/instrumentation.d.ts.map +0 -1
  230. package/dist/utils/logger.d.ts.map +0 -1
  231. package/dist/utils/metrics.d.ts.map +0 -1
  232. package/dist/version.d.ts +0 -2
  233. package/dist/version.d.ts.map +0 -1
  234. package/knip.json +0 -31
  235. package/rslib.config.ts +0 -93
  236. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  237. package/src/cache/adapters/index.ts +0 -22
  238. package/src/cache/adapters/memory.ts +0 -111
  239. package/src/cache/adapters/upstash-redis.ts +0 -113
  240. package/src/cache/gvl-resolver.ts +0 -289
  241. package/src/cache/index.ts +0 -34
  242. package/src/cache/keys.ts +0 -68
  243. package/src/cache/types.ts +0 -66
  244. package/src/core.ts +0 -368
  245. package/src/db/migrator/index.ts +0 -80
  246. package/src/db/registry/consent-policy.test.ts +0 -451
  247. package/src/db/registry/consent-policy.ts +0 -82
  248. package/src/db/registry/consent-purpose.test.ts +0 -428
  249. package/src/db/registry/consent-purpose.ts +0 -61
  250. package/src/db/registry/domain.test.ts +0 -445
  251. package/src/db/registry/domain.ts +0 -91
  252. package/src/db/registry/index.ts +0 -14
  253. package/src/db/registry/subject.test.ts +0 -388
  254. package/src/db/registry/subject.ts +0 -129
  255. package/src/db/registry/types.ts +0 -10
  256. package/src/db/registry/utils/generate-id.test.ts +0 -216
  257. package/src/db/registry/utils/generate-id.ts +0 -133
  258. package/src/db/registry/utils.ts +0 -133
  259. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  260. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  261. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  262. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  263. package/src/db/schema/1.0.0/consent.ts +0 -20
  264. package/src/db/schema/1.0.0/domain.ts +0 -12
  265. package/src/db/schema/1.0.0/index.ts +0 -48
  266. package/src/db/schema/1.0.0/subject.ts +0 -12
  267. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  268. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  269. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  270. package/src/db/schema/2.0.0/consent.ts +0 -26
  271. package/src/db/schema/2.0.0/domain.ts +0 -12
  272. package/src/db/schema/2.0.0/index.ts +0 -47
  273. package/src/db/schema/2.0.0/subject.ts +0 -14
  274. package/src/db/schema/index.ts +0 -15
  275. package/src/db/tenant-scope.test.ts +0 -750
  276. package/src/db/tenant-scope.ts +0 -103
  277. package/src/define-config.ts +0 -5
  278. package/src/handlers/consent/check.handler.ts +0 -126
  279. package/src/handlers/init/geo.test.ts +0 -317
  280. package/src/handlers/init/geo.ts +0 -195
  281. package/src/handlers/init/index.test.ts +0 -205
  282. package/src/handlers/init/index.ts +0 -114
  283. package/src/handlers/init/translations.test.ts +0 -121
  284. package/src/handlers/init/translations.ts +0 -72
  285. package/src/handlers/status/status.handler.test.ts +0 -155
  286. package/src/handlers/status/status.handler.ts +0 -51
  287. package/src/handlers/subject/get.handler.ts +0 -93
  288. package/src/handlers/subject/list.handler.ts +0 -93
  289. package/src/handlers/subject/patch.handler.ts +0 -122
  290. package/src/handlers/subject/post.handler.test.ts +0 -294
  291. package/src/handlers/subject/post.handler.ts +0 -254
  292. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  293. package/src/handlers/utils/consent-enrichment.ts +0 -218
  294. package/src/init.test.ts +0 -126
  295. package/src/init.ts +0 -87
  296. package/src/middleware/auth/index.ts +0 -11
  297. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  298. package/src/middleware/auth/validate-api-key.ts +0 -107
  299. package/src/middleware/cors/cors.test.ts +0 -135
  300. package/src/middleware/cors/cors.ts +0 -186
  301. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  302. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  303. package/src/middleware/cors/process-cors.ts +0 -91
  304. package/src/middleware/openapi/config.ts +0 -29
  305. package/src/middleware/openapi/handlers.ts +0 -34
  306. package/src/middleware/process-ip/index.test.ts +0 -195
  307. package/src/middleware/process-ip/index.ts +0 -199
  308. package/src/router.ts +0 -15
  309. package/src/routes/consent.ts +0 -52
  310. package/src/routes/index.ts +0 -10
  311. package/src/routes/init.ts +0 -102
  312. package/src/routes/status.ts +0 -46
  313. package/src/routes/subject.ts +0 -152
  314. package/src/types/api.ts +0 -48
  315. package/src/types/index.ts +0 -288
  316. package/src/utils/create-telemetry-options.test.ts +0 -302
  317. package/src/utils/create-telemetry-options.ts +0 -229
  318. package/src/utils/env.ts +0 -84
  319. package/src/utils/extract-error-message.ts +0 -21
  320. package/src/utils/instrumentation.test.ts +0 -185
  321. package/src/utils/instrumentation.ts +0 -196
  322. package/src/utils/logger.ts +0 -41
  323. package/src/utils/metrics.test.ts +0 -323
  324. package/src/utils/metrics.ts +0 -402
  325. package/src/utils/telemetry-pii.test.ts +0 -325
  326. package/src/version.ts +0 -2
  327. package/tsconfig.json +0 -11
  328. package/vitest.config.ts +0 -28
  329. /package/dist/{types.js → types/index.js} +0 -0
  330. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  331. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  332. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  333. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  334. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  335. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  336. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
@@ -1,229 +0,0 @@
1
- import {
2
- context,
3
- type Meter,
4
- metrics,
5
- type Span,
6
- SpanStatusCode,
7
- trace,
8
- } from '@opentelemetry/api';
9
- import type { C15TOptions } from '../types';
10
- import { version } from '../version';
11
- import { extractErrorMessage } from './extract-error-message';
12
-
13
- type TelemetryConfig = NonNullable<C15TOptions['advanced']>['telemetry'];
14
-
15
- // ── Cached config (set once during init) ──────────────────────────────
16
- let cachedConfig: TelemetryConfig | null = null;
17
- let cachedDefaultAttributes: Record<string, string | number | boolean> = {};
18
-
19
- /**
20
- * Creates telemetry configuration from provided options
21
- *
22
- * This function merges user-provided telemetry options with sensible defaults,
23
- * ensuring that service name and version are always properly set.
24
- *
25
- * Telemetry is opt-in by default - users must explicitly set enabled: true.
26
- *
27
- * @param appName - The application name to use for service.name attribute
28
- * @param telemetryConfig - Optional user-provided telemetry configuration
29
- * @param tenantId - Optional tenant ID for multi-tenant deployments
30
- * @returns Properly structured telemetry options for the OpenTelemetry SDK
31
- */
32
- export function createTelemetryOptions(
33
- appName = 'c15t',
34
- telemetryConfig?: TelemetryConfig,
35
- tenantId?: string
36
- ): TelemetryConfig {
37
- const defaultAttributes: Record<string, string | number | boolean> = {
38
- ...(telemetryConfig?.defaultAttributes || {}),
39
-
40
- // Always ensure these core attributes are set
41
- 'service.name': String(appName),
42
- 'service.version': version,
43
- };
44
-
45
- if (tenantId) {
46
- defaultAttributes['tenant.id'] = tenantId;
47
- }
48
-
49
- const config: TelemetryConfig = {
50
- // Opt-in: disabled by default, must be explicitly enabled
51
- enabled: telemetryConfig?.enabled ?? false,
52
- tracer: telemetryConfig?.tracer,
53
- meter: telemetryConfig?.meter,
54
- defaultAttributes,
55
- };
56
-
57
- // Cache for use without explicit options
58
- cachedConfig = config;
59
- cachedDefaultAttributes = defaultAttributes;
60
-
61
- return config;
62
- }
63
-
64
- /**
65
- * Checks if telemetry is enabled.
66
- * When called without options, uses the cached config from init.
67
- */
68
- export function isTelemetryEnabled(options?: C15TOptions): boolean {
69
- if (options) {
70
- return options.advanced?.telemetry?.enabled === true;
71
- }
72
- return cachedConfig?.enabled === true;
73
- }
74
-
75
- /**
76
- * Gets the tracer for the c15t backend.
77
- * When called without options, uses the cached config from init.
78
- */
79
- export const getTracer = (options?: C15TOptions) => {
80
- if (!isTelemetryEnabled(options)) {
81
- // Return a no-op tracer when telemetry is disabled
82
- return trace.getTracer('c15t-noop');
83
- }
84
- const tracer = options?.advanced?.telemetry?.tracer ?? cachedConfig?.tracer;
85
- if (tracer) {
86
- return tracer;
87
- }
88
- return trace.getTracer(options?.appName ?? 'c15t');
89
- };
90
-
91
- /**
92
- * Gets the meter for the c15t backend.
93
- * When called without options, uses the cached config from init.
94
- */
95
- export const getMeter = (options?: C15TOptions): Meter => {
96
- if (!isTelemetryEnabled(options)) {
97
- // Return a no-op meter when telemetry is disabled
98
- return metrics.getMeter('c15t-noop');
99
- }
100
- const meter = options?.advanced?.telemetry?.meter ?? cachedConfig?.meter;
101
- if (meter) {
102
- return meter;
103
- }
104
- return metrics.getMeter(options?.appName ?? 'c15t');
105
- };
106
-
107
- /**
108
- * Gets the cached default attributes.
109
- * Used by span wrappers when no explicit options are provided.
110
- */
111
- export function getDefaultAttributes(): Record<
112
- string,
113
- string | number | boolean
114
- > {
115
- return cachedDefaultAttributes;
116
- }
117
-
118
- /**
119
- * Resets the cached telemetry config (for testing).
120
- */
121
- export function resetTelemetryConfig(): void {
122
- cachedConfig = null;
123
- cachedDefaultAttributes = {};
124
- }
125
-
126
- /**
127
- * Creates a span for an API request
128
- */
129
- export const createRequestSpan = (
130
- method: string,
131
- path: string,
132
- options?: C15TOptions
133
- ) => {
134
- if (!isTelemetryEnabled(options)) {
135
- return null;
136
- }
137
-
138
- const tracer = getTracer(options);
139
- const defaultAttrs =
140
- options?.advanced?.telemetry?.defaultAttributes || getDefaultAttributes();
141
-
142
- const span = tracer.startSpan(`${method} ${path}`, {
143
- attributes: {
144
- 'http.method': method,
145
- ...defaultAttrs,
146
- },
147
- });
148
-
149
- return span;
150
- };
151
-
152
- /**
153
- * Wraps an API request handler in a span.
154
- * The span is set as active context so child spans nest correctly.
155
- */
156
- export const withRequestSpan = async <T>(
157
- method: string,
158
- path: string,
159
- operation: () => Promise<T>,
160
- options?: C15TOptions
161
- ): Promise<T> => {
162
- const span = createRequestSpan(method, path, options);
163
-
164
- if (!span) {
165
- return operation();
166
- }
167
-
168
- try {
169
- const result = await withSpanContext(span, operation);
170
- span.setStatus({ code: SpanStatusCode.OK });
171
- return result;
172
- } catch (error) {
173
- handleSpanError(span, error);
174
- throw error;
175
- } finally {
176
- span.end();
177
- }
178
- };
179
-
180
- /**
181
- * Handles errors in spans
182
- */
183
- export const handleSpanError = (span: Span, error: unknown) => {
184
- span.setStatus({
185
- code: SpanStatusCode.ERROR,
186
- message: extractErrorMessage(error),
187
- });
188
-
189
- if (error instanceof Error) {
190
- span.setAttribute('error.type', error.name);
191
- }
192
- };
193
-
194
- /**
195
- * Gets the current trace context for log correlation.
196
- * Returns trace and span IDs from the active span.
197
- *
198
- * @returns Object with traceId and spanId, or null if no active span
199
- */
200
- export function getTraceContext(): {
201
- traceId: string;
202
- spanId: string;
203
- } | null {
204
- const activeSpan = trace.getActiveSpan();
205
- if (!activeSpan) {
206
- return null;
207
- }
208
-
209
- const spanContext = activeSpan.spanContext();
210
- if (!spanContext) {
211
- return null;
212
- }
213
-
214
- return {
215
- traceId: spanContext.traceId,
216
- spanId: spanContext.spanId,
217
- };
218
- }
219
-
220
- /**
221
- * Runs a function within a span context, making the span active.
222
- * This allows nested operations to access the parent span via trace.getActiveSpan().
223
- */
224
- export const withSpanContext = async <T>(
225
- span: Span,
226
- operation: () => Promise<T>
227
- ): Promise<T> => {
228
- return context.with(trace.setSpan(context.active(), span), operation);
229
- };
package/src/utils/env.ts DELETED
@@ -1,84 +0,0 @@
1
- /**
2
- * Environment variables object
3
- *
4
- * Provides access to environment variables in a way that works in both
5
- * browser and Node.js environments. In Node.js, this will be process.env,
6
- * and in browsers, it will be an empty object.
7
- *
8
- * @returns An object containing environment variables accessible in the current runtime
9
- *
10
- * @example
11
- * ```ts
12
- * // Access an environment variable
13
- * const apiKey = env.API_KEY;
14
- * ```
15
- */
16
- export const env = typeof process !== 'undefined' ? process.env : {};
17
-
18
- /**
19
- * Determines if the application is running in production mode
20
- *
21
- * Checks if NODE_ENV is set to 'production'. This is useful for
22
- * conditionally enabling or disabling features based on the environment.
23
- *
24
- * @returns Boolean indicating whether the application is running in production mode
25
- *
26
- * @example
27
- * ```ts
28
- * // Conditionally execute code based on environment
29
- * if (isProduction) {
30
- * // Production-only code
31
- * }
32
- * ```
33
- */
34
- export const isProduction =
35
- typeof process !== 'undefined' && process.env.NODE_ENV === 'production';
36
-
37
- /**
38
- * Converts a string or boolean value to a boolean
39
- *
40
- * @param val - The value to convert to boolean
41
- * @returns `false` if the value is falsy or the string 'false', otherwise `true`
42
- *
43
- * @example
44
- * ```ts
45
- * toBoolean('true'); // true
46
- * toBoolean('false'); // false
47
- * toBoolean(undefined); // false
48
- * toBoolean(true); // true
49
- * ```
50
- *
51
- * @internal Used for environment variable parsing
52
- */
53
- function toBoolean(val: boolean | string | undefined) {
54
- return val ? val !== 'false' : false;
55
- }
56
-
57
- /**
58
- * The current Node.js environment value
59
- *
60
- * Retrieves the NODE_ENV environment variable value if available,
61
- * otherwise returns an empty string.
62
- *
63
- * @returns The current NODE_ENV value or empty string if not set
64
- */
65
- export const nodeENV =
66
- (typeof process !== 'undefined' && process.env && process.env.NODE_ENV) || '';
67
-
68
- /**
69
- * Determines if the application is running in test mode
70
- *
71
- * Checks if NODE_ENV is set to 'test' or if the TEST environment
72
- * variable is truthy and not 'false'.
73
- *
74
- * @returns Boolean indicating whether the application is running in test mode
75
- *
76
- * @example
77
- * ```ts
78
- * // Skip expensive operations in tests
79
- * if (!isTest) {
80
- * runExpensiveOperation();
81
- * }
82
- * ```
83
- */
84
- export const isTest = nodeENV === 'test' || toBoolean(env.TEST);
@@ -1,21 +0,0 @@
1
- /**
2
- * Extracts a useful error message from any error type.
3
- *
4
- * Handles `AggregateError` (e.g. from Node.js `net.connect` failing on both
5
- * IPv4/IPv6) where `error.message` is empty but `error.errors[]` contains the
6
- * real messages.
7
- */
8
- export function extractErrorMessage(error: unknown): string {
9
- if (error instanceof AggregateError && error.errors?.length > 0) {
10
- const inner = error.errors
11
- .map((e: unknown) => (e instanceof Error ? e.message : String(e)))
12
- .join('; ');
13
- return `AggregateError: ${inner}`;
14
- }
15
-
16
- if (error instanceof Error) {
17
- return error.message || error.name;
18
- }
19
-
20
- return String(error);
21
- }
@@ -1,185 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import type { C15TOptions } from '../types';
3
- import {
4
- withCacheSpan,
5
- withDatabaseSpan,
6
- withExternalSpan,
7
- } from './instrumentation';
8
-
9
- // Mock create-telemetry-options
10
- vi.mock('./create-telemetry-options', () => {
11
- const { SpanStatusCode } = require('@opentelemetry/api');
12
-
13
- const mockSpan = () => ({
14
- setStatus: vi.fn(),
15
- setAttribute: vi.fn(),
16
- updateName: vi.fn(),
17
- end: vi.fn(),
18
- });
19
-
20
- return {
21
- isTelemetryEnabled: vi.fn(
22
- (options) => options?.advanced?.telemetry?.enabled === true
23
- ),
24
- getTracer: vi.fn(() => ({
25
- startSpan: vi.fn(() => mockSpan()),
26
- })),
27
- getDefaultAttributes: vi.fn(() => ({
28
- 'service.name': 'test',
29
- 'service.version': '1.0.0',
30
- })),
31
- withSpanContext: vi.fn((_span, operation) => operation()),
32
- handleSpanError: vi.fn((span, error) => {
33
- span.setStatus({
34
- code: SpanStatusCode.ERROR,
35
- message: error instanceof Error ? error.message : String(error),
36
- });
37
- if (error instanceof Error) {
38
- span.setAttribute('error.type', error.name);
39
- }
40
- }),
41
- };
42
- });
43
-
44
- afterEach(() => {
45
- vi.clearAllMocks();
46
- });
47
-
48
- const enabledOptions: C15TOptions = {
49
- trustedOrigins: [],
50
- adapter: {} as C15TOptions['adapter'],
51
- advanced: {
52
- telemetry: {
53
- enabled: true,
54
- },
55
- },
56
- };
57
-
58
- describe('withDatabaseSpan', () => {
59
- it('returns operation result when telemetry is disabled', async () => {
60
- const result = await withDatabaseSpan(
61
- { operation: 'find', entity: 'subject' },
62
- async () => ({ id: '123', name: 'test' })
63
- );
64
-
65
- expect(result).toEqual({ id: '123', name: 'test' });
66
- });
67
-
68
- it('returns operation result when telemetry is enabled', async () => {
69
- const result = await withDatabaseSpan(
70
- { operation: 'find', entity: 'subject' },
71
- async () => ({ id: '123', name: 'test' }),
72
- enabledOptions
73
- );
74
-
75
- expect(result).toEqual({ id: '123', name: 'test' });
76
- });
77
-
78
- it('propagates errors from operation', async () => {
79
- const error = new Error('DB connection failed');
80
-
81
- await expect(
82
- withDatabaseSpan(
83
- { operation: 'find', entity: 'subject' },
84
- async () => {
85
- throw error;
86
- },
87
- enabledOptions
88
- )
89
- ).rejects.toThrow('DB connection failed');
90
- });
91
-
92
- it('executes operation without span when telemetry is disabled', async () => {
93
- const operation = vi.fn().mockResolvedValue('result');
94
-
95
- const result = await withDatabaseSpan(
96
- { operation: 'create', entity: 'consent' },
97
- operation
98
- );
99
-
100
- expect(result).toBe('result');
101
- expect(operation).toHaveBeenCalledTimes(1);
102
- });
103
- });
104
-
105
- describe('withExternalSpan', () => {
106
- it('returns operation result when telemetry is disabled', async () => {
107
- const result = await withExternalSpan(
108
- { url: 'https://example.com/api', method: 'GET' },
109
- async () => ({ status: 200 })
110
- );
111
-
112
- expect(result).toEqual({ status: 200 });
113
- });
114
-
115
- it('returns operation result when telemetry is enabled', async () => {
116
- const result = await withExternalSpan(
117
- { url: 'https://example.com/api', method: 'GET' },
118
- async () => ({ status: 200 }),
119
- enabledOptions
120
- );
121
-
122
- expect(result).toEqual({ status: 200 });
123
- });
124
-
125
- it('propagates errors from operation', async () => {
126
- const error = new Error('Network error');
127
-
128
- await expect(
129
- withExternalSpan(
130
- { url: 'https://example.com/api', method: 'POST' },
131
- async () => {
132
- throw error;
133
- },
134
- enabledOptions
135
- )
136
- ).rejects.toThrow('Network error');
137
- });
138
- });
139
-
140
- describe('withCacheSpan', () => {
141
- it('returns operation result when telemetry is disabled', async () => {
142
- const result = await withCacheSpan('get', 'memory', async () => ({
143
- data: 'cached',
144
- }));
145
-
146
- expect(result).toEqual({ data: 'cached' });
147
- });
148
-
149
- it('returns operation result when telemetry is enabled', async () => {
150
- const result = await withCacheSpan(
151
- 'get',
152
- 'external',
153
- async () => ({ data: 'cached' }),
154
- enabledOptions
155
- );
156
-
157
- expect(result).toEqual({ data: 'cached' });
158
- });
159
-
160
- it('returns null for cache miss', async () => {
161
- const result = await withCacheSpan(
162
- 'get',
163
- 'memory',
164
- async () => null,
165
- enabledOptions
166
- );
167
-
168
- expect(result).toBeNull();
169
- });
170
-
171
- it('propagates errors from operation', async () => {
172
- const error = new Error('Cache connection failed');
173
-
174
- await expect(
175
- withCacheSpan(
176
- 'get',
177
- 'external',
178
- async () => {
179
- throw error;
180
- },
181
- enabledOptions
182
- )
183
- ).rejects.toThrow('Cache connection failed');
184
- });
185
- });
@@ -1,196 +0,0 @@
1
- import type { Span } from '@opentelemetry/api';
2
- import { SpanKind, SpanStatusCode } from '@opentelemetry/api';
3
- import type { C15TOptions } from '../types';
4
- import {
5
- getDefaultAttributes,
6
- getTracer,
7
- handleSpanError,
8
- isTelemetryEnabled,
9
- withSpanContext,
10
- } from './create-telemetry-options';
11
-
12
- /**
13
- * Span attributes for database operations
14
- */
15
- export interface DatabaseSpanAttributes {
16
- /** The database operation type (find, create, update, delete) */
17
- operation: 'find' | 'create' | 'update' | 'delete' | 'findOrCreate';
18
- /** The entity type being operated on */
19
- entity: string;
20
- /** Optional additional attributes */
21
- [key: string]: string | number | boolean | undefined;
22
- }
23
-
24
- /**
25
- * Span attributes for external API calls
26
- */
27
- export interface ExternalSpanAttributes {
28
- /** The URL being called */
29
- url: string;
30
- /** The HTTP method */
31
- method: string;
32
- /** Optional additional attributes */
33
- [key: string]: string | number | boolean | undefined;
34
- }
35
-
36
- /**
37
- * Execute an async operation within a span, handling status and error recording.
38
- *
39
- * Sets SpanStatusCode.OK on success, records error attributes and sets
40
- * SpanStatusCode.ERROR on failure, and always ends the span.
41
- */
42
- async function executeWithSpan<T>(
43
- span: Span,
44
- operation: () => Promise<T>
45
- ): Promise<T> {
46
- try {
47
- const result = await withSpanContext(span, operation);
48
- span.setStatus({ code: SpanStatusCode.OK });
49
- return result;
50
- } catch (error) {
51
- handleSpanError(span, error);
52
- throw error;
53
- } finally {
54
- span.end();
55
- }
56
- }
57
-
58
- /**
59
- * Resolves default attributes from explicit options or the cached config.
60
- */
61
- function resolveDefaultAttributes(
62
- options?: C15TOptions
63
- ): Record<string, string | number | boolean> {
64
- return (
65
- options?.advanced?.telemetry?.defaultAttributes || getDefaultAttributes()
66
- );
67
- }
68
-
69
- /**
70
- * Wraps a database operation in a span for tracing.
71
- *
72
- * @param attributes - Span attributes describing the operation
73
- * @param operation - The async operation to wrap
74
- * @param options - C15T options for telemetry configuration
75
- * @returns The result of the operation
76
- *
77
- * @example
78
- * ```typescript
79
- * const subject = await withDatabaseSpan(
80
- * { operation: 'find', entity: 'subject' },
81
- * async () => db.subject.findUnique({ where: { id } }),
82
- * options
83
- * );
84
- * ```
85
- */
86
- export async function withDatabaseSpan<T>(
87
- attributes: DatabaseSpanAttributes,
88
- operation: () => Promise<T>,
89
- options?: C15TOptions
90
- ): Promise<T> {
91
- if (!isTelemetryEnabled(options)) {
92
- return operation();
93
- }
94
-
95
- const tracer = getTracer(options);
96
- const spanName = `db.${attributes.entity}.${attributes.operation}`;
97
-
98
- const span = tracer.startSpan(spanName, {
99
- kind: SpanKind.CLIENT,
100
- attributes: {
101
- 'db.system': 'c15t',
102
- 'db.operation': attributes.operation,
103
- 'db.entity': attributes.entity,
104
- ...resolveDefaultAttributes(options),
105
- ...Object.fromEntries(
106
- Object.entries(attributes).filter(
107
- ([key]) => !['operation', 'entity'].includes(key)
108
- )
109
- ),
110
- },
111
- });
112
-
113
- return executeWithSpan(span, operation);
114
- }
115
-
116
- /**
117
- * Wraps an external API call in a span for tracing.
118
- *
119
- * @param attributes - Span attributes describing the external call
120
- * @param operation - The async operation to wrap
121
- * @param options - C15T options for telemetry configuration
122
- * @returns The result of the operation
123
- *
124
- * @example
125
- * ```typescript
126
- * const response = await withExternalSpan(
127
- * { url: 'https://api.example.com/data', method: 'GET' },
128
- * async () => fetch('https://api.example.com/data'),
129
- * options
130
- * );
131
- * ```
132
- */
133
- export async function withExternalSpan<T>(
134
- attributes: ExternalSpanAttributes,
135
- operation: () => Promise<T>,
136
- options?: C15TOptions
137
- ): Promise<T> {
138
- if (!isTelemetryEnabled(options)) {
139
- return operation();
140
- }
141
-
142
- const tracer = getTracer(options);
143
- const url = new URL(attributes.url);
144
- const spanName = `HTTP ${attributes.method} ${url.hostname}`;
145
-
146
- const span = tracer.startSpan(spanName, {
147
- kind: SpanKind.CLIENT,
148
- attributes: {
149
- 'http.method': attributes.method,
150
- 'http.url': `${url.origin}${url.pathname}`,
151
- 'http.host': url.hostname,
152
- ...resolveDefaultAttributes(options),
153
- ...Object.fromEntries(
154
- Object.entries(attributes).filter(
155
- ([key]) => !['url', 'method'].includes(key)
156
- )
157
- ),
158
- },
159
- });
160
-
161
- return executeWithSpan(span, operation);
162
- }
163
-
164
- /**
165
- * Wraps a cache operation in a span for tracing.
166
- *
167
- * @param operation - The cache operation type
168
- * @param layer - The cache layer (bundled, memory, external)
169
- * @param fn - The async operation to wrap
170
- * @param options - C15T options for telemetry configuration
171
- * @returns The result of the operation
172
- */
173
- export async function withCacheSpan<T>(
174
- operation: 'get' | 'set' | 'delete',
175
- layer: 'bundled' | 'memory' | 'external',
176
- fn: () => Promise<T>,
177
- options?: C15TOptions
178
- ): Promise<T> {
179
- if (!isTelemetryEnabled(options)) {
180
- return fn();
181
- }
182
-
183
- const tracer = getTracer(options);
184
- const spanName = `cache.${layer}.${operation}`;
185
-
186
- const span = tracer.startSpan(spanName, {
187
- kind: SpanKind.CLIENT,
188
- attributes: {
189
- 'cache.operation': operation,
190
- 'cache.layer': layer,
191
- ...resolveDefaultAttributes(options),
192
- },
193
- });
194
-
195
- return executeWithSpan(span, fn);
196
- }