@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
package/dist/302.js ADDED
@@ -0,0 +1,473 @@
1
+ import { SpanKind, SpanStatusCode as api_SpanStatusCode, context, metrics, trace } from "@opentelemetry/api";
2
+ const version = '2.0.0-rc.6';
3
+ function extractErrorMessage(error) {
4
+ if (error instanceof AggregateError && error.errors?.length > 0) {
5
+ const inner = error.errors.map((e)=>e instanceof Error ? e.message : String(e)).join('; ');
6
+ return `AggregateError: ${inner}`;
7
+ }
8
+ if (error instanceof Error) return error.message || error.name;
9
+ return String(error);
10
+ }
11
+ let cachedConfig = null;
12
+ let cachedDefaultAttributes = {};
13
+ function createTelemetryOptions(appName = 'c15t', telemetryConfig, tenantId) {
14
+ const defaultAttributes = {
15
+ ...telemetryConfig?.defaultAttributes || {},
16
+ 'service.name': String(appName),
17
+ 'service.version': version
18
+ };
19
+ if (tenantId) defaultAttributes['tenant.id'] = tenantId;
20
+ const config = {
21
+ enabled: telemetryConfig?.enabled ?? false,
22
+ tracer: telemetryConfig?.tracer,
23
+ meter: telemetryConfig?.meter,
24
+ defaultAttributes
25
+ };
26
+ cachedConfig = config;
27
+ cachedDefaultAttributes = defaultAttributes;
28
+ return config;
29
+ }
30
+ function isTelemetryEnabled(options) {
31
+ if (options) return options.telemetry?.enabled === true;
32
+ return cachedConfig?.enabled === true;
33
+ }
34
+ const getTracer = (options)=>{
35
+ if (!isTelemetryEnabled(options)) return trace.getTracer('c15t-noop');
36
+ const tracer = options?.telemetry?.tracer ?? cachedConfig?.tracer;
37
+ if (tracer) return tracer;
38
+ return trace.getTracer(options?.appName ?? 'c15t');
39
+ };
40
+ const getMeter = (options)=>{
41
+ if (!isTelemetryEnabled(options)) return metrics.getMeter('c15t-noop');
42
+ const meter = options?.telemetry?.meter ?? cachedConfig?.meter;
43
+ if (meter) return meter;
44
+ return metrics.getMeter(options?.appName ?? 'c15t');
45
+ };
46
+ function getDefaultAttributes() {
47
+ return cachedDefaultAttributes;
48
+ }
49
+ const createRequestSpan = (method, path, options)=>{
50
+ if (!isTelemetryEnabled(options)) return null;
51
+ const tracer = getTracer(options);
52
+ const defaultAttrs = options?.telemetry?.defaultAttributes || getDefaultAttributes();
53
+ const span = tracer.startSpan(`${method} ${path}`, {
54
+ attributes: {
55
+ 'http.method': method,
56
+ ...defaultAttrs
57
+ }
58
+ });
59
+ return span;
60
+ };
61
+ const handleSpanError = (span, error)=>{
62
+ span.setStatus({
63
+ code: api_SpanStatusCode.ERROR,
64
+ message: extractErrorMessage(error)
65
+ });
66
+ if (error instanceof Error) span.setAttribute('error.type', error.name);
67
+ };
68
+ function getTraceContext() {
69
+ const activeSpan = trace.getActiveSpan();
70
+ if (!activeSpan) return null;
71
+ const spanContext = activeSpan.spanContext();
72
+ if (!spanContext) return null;
73
+ return {
74
+ traceId: spanContext.traceId,
75
+ spanId: spanContext.spanId
76
+ };
77
+ }
78
+ const withSpanContext = async (span, operation)=>context["with"](trace.setSpan(context.active(), span), operation);
79
+ async function executeWithSpan(span, operation) {
80
+ try {
81
+ const result = await withSpanContext(span, operation);
82
+ span.setStatus({
83
+ code: api_SpanStatusCode.OK
84
+ });
85
+ return result;
86
+ } catch (error) {
87
+ handleSpanError(span, error);
88
+ throw error;
89
+ } finally{
90
+ span.end();
91
+ }
92
+ }
93
+ function resolveDefaultAttributes(options) {
94
+ return options?.telemetry?.defaultAttributes || getDefaultAttributes();
95
+ }
96
+ async function withDatabaseSpan(attributes, operation, options) {
97
+ if (!isTelemetryEnabled(options)) return operation();
98
+ const tracer = getTracer(options);
99
+ const spanName = `db.${attributes.entity}.${attributes.operation}`;
100
+ const span = tracer.startSpan(spanName, {
101
+ kind: SpanKind.CLIENT,
102
+ attributes: {
103
+ 'db.system': 'c15t',
104
+ 'db.operation': attributes.operation,
105
+ 'db.entity': attributes.entity,
106
+ ...resolveDefaultAttributes(options),
107
+ ...Object.fromEntries(Object.entries(attributes).filter(([key])=>![
108
+ 'operation',
109
+ 'entity'
110
+ ].includes(key)))
111
+ }
112
+ });
113
+ return executeWithSpan(span, operation);
114
+ }
115
+ async function withExternalSpan(attributes, operation, options) {
116
+ if (!isTelemetryEnabled(options)) return operation();
117
+ const tracer = getTracer(options);
118
+ const url = new URL(attributes.url);
119
+ const spanName = `HTTP ${attributes.method} ${url.hostname}`;
120
+ const span = tracer.startSpan(spanName, {
121
+ kind: SpanKind.CLIENT,
122
+ attributes: {
123
+ 'http.method': attributes.method,
124
+ 'http.url': `${url.origin}${url.pathname}`,
125
+ 'http.host': url.hostname,
126
+ ...resolveDefaultAttributes(options),
127
+ ...Object.fromEntries(Object.entries(attributes).filter(([key])=>![
128
+ 'url',
129
+ 'method'
130
+ ].includes(key)))
131
+ }
132
+ });
133
+ return executeWithSpan(span, operation);
134
+ }
135
+ async function withCacheSpan(operation, layer, fn, options) {
136
+ if (!isTelemetryEnabled(options)) return fn();
137
+ const tracer = getTracer(options);
138
+ const spanName = `cache.${layer}.${operation}`;
139
+ const span = tracer.startSpan(spanName, {
140
+ kind: SpanKind.CLIENT,
141
+ attributes: {
142
+ 'cache.operation': operation,
143
+ 'cache.layer': layer,
144
+ ...resolveDefaultAttributes(options)
145
+ }
146
+ });
147
+ return executeWithSpan(span, fn);
148
+ }
149
+ function sanitizeAttributes(attrs) {
150
+ return Object.fromEntries(Object.entries(attrs).filter(([_, v])=>null != v));
151
+ }
152
+ function createMetrics(meter) {
153
+ const consentCreated = meter.createCounter('c15t.consent.created', {
154
+ description: 'Number of consent submissions',
155
+ unit: '1'
156
+ });
157
+ const consentAccepted = meter.createCounter('c15t.consent.accepted', {
158
+ description: 'Number of consents accepted',
159
+ unit: '1'
160
+ });
161
+ const consentRejected = meter.createCounter('c15t.consent.rejected', {
162
+ description: 'Number of consents rejected',
163
+ unit: '1'
164
+ });
165
+ const subjectCreated = meter.createCounter('c15t.subject.created', {
166
+ description: 'Number of new subjects created',
167
+ unit: '1'
168
+ });
169
+ const subjectLinked = meter.createCounter('c15t.subject.linked', {
170
+ description: 'Number of subjects linked to external ID',
171
+ unit: '1'
172
+ });
173
+ const consentCheckCount = meter.createCounter('c15t.consent_check.count', {
174
+ description: 'Number of cross-device consent checks',
175
+ unit: '1'
176
+ });
177
+ const initCount = meter.createCounter('c15t.init.count', {
178
+ description: 'Number of init endpoint calls',
179
+ unit: '1'
180
+ });
181
+ const httpRequestDuration = meter.createHistogram('c15t.http.request.duration', {
182
+ description: 'HTTP request latency',
183
+ unit: 'ms'
184
+ });
185
+ const httpRequestCount = meter.createCounter('c15t.http.request.count', {
186
+ description: 'Number of HTTP requests',
187
+ unit: '1'
188
+ });
189
+ const httpErrorCount = meter.createCounter('c15t.http.error.count', {
190
+ description: 'Number of HTTP errors',
191
+ unit: '1'
192
+ });
193
+ const dbQueryDuration = meter.createHistogram('c15t.db.query.duration', {
194
+ description: 'Database query latency',
195
+ unit: 'ms'
196
+ });
197
+ const dbQueryCount = meter.createCounter('c15t.db.query.count', {
198
+ description: 'Number of database queries',
199
+ unit: '1'
200
+ });
201
+ const dbErrorCount = meter.createCounter('c15t.db.error.count', {
202
+ description: 'Number of database errors',
203
+ unit: '1'
204
+ });
205
+ const cacheHit = meter.createCounter('c15t.cache.hit', {
206
+ description: 'Number of cache hits',
207
+ unit: '1'
208
+ });
209
+ const cacheMiss = meter.createCounter('c15t.cache.miss', {
210
+ description: 'Number of cache misses',
211
+ unit: '1'
212
+ });
213
+ const cacheLatency = meter.createHistogram('c15t.cache.latency', {
214
+ description: 'Cache operation latency',
215
+ unit: 'ms'
216
+ });
217
+ const gvlFetchDuration = meter.createHistogram('c15t.gvl.fetch.duration', {
218
+ description: 'GVL fetch latency',
219
+ unit: 'ms'
220
+ });
221
+ const gvlFetchCount = meter.createCounter('c15t.gvl.fetch.count', {
222
+ description: 'Number of GVL fetches',
223
+ unit: '1'
224
+ });
225
+ const gvlFetchError = meter.createCounter('c15t.gvl.fetch.error', {
226
+ description: 'Number of GVL fetch errors',
227
+ unit: '1'
228
+ });
229
+ return {
230
+ consentCreated,
231
+ consentAccepted,
232
+ consentRejected,
233
+ subjectCreated,
234
+ subjectLinked,
235
+ consentCheckCount,
236
+ initCount,
237
+ httpRequestDuration,
238
+ httpRequestCount,
239
+ httpErrorCount,
240
+ dbQueryDuration,
241
+ dbQueryCount,
242
+ dbErrorCount,
243
+ cacheHit,
244
+ cacheMiss,
245
+ cacheLatency,
246
+ gvlFetchDuration,
247
+ gvlFetchCount,
248
+ gvlFetchError,
249
+ recordConsentCreated (attributes) {
250
+ consentCreated.add(1, sanitizeAttributes(attributes));
251
+ },
252
+ recordConsentAccepted (attributes) {
253
+ consentAccepted.add(1, sanitizeAttributes(attributes));
254
+ },
255
+ recordConsentRejected (attributes) {
256
+ consentRejected.add(1, sanitizeAttributes(attributes));
257
+ },
258
+ recordSubjectCreated (attributes) {
259
+ subjectCreated.add(1, sanitizeAttributes(attributes));
260
+ },
261
+ recordSubjectLinked (identityProvider) {
262
+ subjectLinked.add(1, {
263
+ identityProvider: identityProvider || 'unknown'
264
+ });
265
+ },
266
+ recordConsentCheck (type, found) {
267
+ consentCheckCount.add(1, {
268
+ type,
269
+ found: String(found)
270
+ });
271
+ },
272
+ recordInit (attributes) {
273
+ initCount.add(1, sanitizeAttributes(attributes));
274
+ },
275
+ recordHttpRequest (attributes, durationMs) {
276
+ const attrs = sanitizeAttributes(attributes);
277
+ httpRequestCount.add(1, attrs);
278
+ httpRequestDuration.record(durationMs, attrs);
279
+ if (attributes.status >= 400) httpErrorCount.add(1, attrs);
280
+ },
281
+ recordDbQuery (attributes, durationMs) {
282
+ const attrs = sanitizeAttributes(attributes);
283
+ dbQueryCount.add(1, attrs);
284
+ dbQueryDuration.record(durationMs, attrs);
285
+ },
286
+ recordDbError (attributes) {
287
+ dbErrorCount.add(1, sanitizeAttributes(attributes));
288
+ },
289
+ recordCacheHit (layer) {
290
+ cacheHit.add(1, {
291
+ layer
292
+ });
293
+ },
294
+ recordCacheMiss (layer) {
295
+ cacheMiss.add(1, {
296
+ layer
297
+ });
298
+ },
299
+ recordCacheLatency (attributes, durationMs) {
300
+ cacheLatency.record(durationMs, sanitizeAttributes(attributes));
301
+ },
302
+ recordGvlFetch (attributes, durationMs) {
303
+ const attrs = sanitizeAttributes(attributes);
304
+ gvlFetchCount.add(1, attrs);
305
+ gvlFetchDuration.record(durationMs, attrs);
306
+ },
307
+ recordGvlError (attributes) {
308
+ gvlFetchError.add(1, sanitizeAttributes(attributes));
309
+ }
310
+ };
311
+ }
312
+ let metricsInstance = null;
313
+ function getMetrics(options) {
314
+ if (metricsInstance) return metricsInstance;
315
+ if (!isTelemetryEnabled(options)) return null;
316
+ metricsInstance = createMetrics(getMeter(options));
317
+ return metricsInstance;
318
+ }
319
+ const GVL_TTL_MS = 259200000;
320
+ const memory_memoryCache = new Map();
321
+ function createMemoryCacheAdapter() {
322
+ return {
323
+ async get (key) {
324
+ const entry = memory_memoryCache.get(key);
325
+ if (!entry) return null;
326
+ if (Date.now() > entry.expiresAt) {
327
+ memory_memoryCache.delete(key);
328
+ return null;
329
+ }
330
+ return entry.value;
331
+ },
332
+ async set (key, value, ttlMs = 300000) {
333
+ memory_memoryCache.set(key, {
334
+ value,
335
+ expiresAt: Date.now() + ttlMs
336
+ });
337
+ },
338
+ async delete (key) {
339
+ memory_memoryCache.delete(key);
340
+ },
341
+ async has (key) {
342
+ const entry = memory_memoryCache.get(key);
343
+ if (!entry) return false;
344
+ if (Date.now() > entry.expiresAt) {
345
+ memory_memoryCache.delete(key);
346
+ return false;
347
+ }
348
+ return true;
349
+ }
350
+ };
351
+ }
352
+ function clearMemoryCache() {
353
+ memory_memoryCache.clear();
354
+ }
355
+ function getMemoryCacheSize() {
356
+ return memory_memoryCache.size;
357
+ }
358
+ function createGVLCacheKey(appName, language, vendorIds) {
359
+ const sortedIds = vendorIds ? [
360
+ ...vendorIds
361
+ ].sort((a, b)=>a - b).join(',') : 'all';
362
+ return `${appName}:gvl:${language}:${sortedIds}`;
363
+ }
364
+ function createCacheKey(appName, namespace, ...parts) {
365
+ const allParts = [
366
+ appName,
367
+ namespace,
368
+ ...parts
369
+ ];
370
+ return allParts.join(':');
371
+ }
372
+ const GVL_ENDPOINT = 'https://gvl.consent.io';
373
+ const inflightRequests = new Map();
374
+ async function fetchGVLWithLanguage(language, vendorIds, endpoint = GVL_ENDPOINT) {
375
+ const sortedVendorIds = vendorIds ? [
376
+ ...vendorIds
377
+ ].sort((a, b)=>a - b) : [];
378
+ const dedupeKey = `${endpoint}|${language}|${sortedVendorIds.join(',')}`;
379
+ const existingRequest = inflightRequests.get(dedupeKey);
380
+ if (existingRequest) return existingRequest;
381
+ const url = new URL(endpoint);
382
+ if (sortedVendorIds.length > 0) url.searchParams.set('vendorIds', sortedVendorIds.join(','));
383
+ const promise = (async ()=>{
384
+ const fetchStart = Date.now();
385
+ try {
386
+ const gvl = await withExternalSpan({
387
+ url: url.toString(),
388
+ method: 'GET'
389
+ }, async ()=>{
390
+ const response = await fetch(url.toString(), {
391
+ headers: {
392
+ 'Accept-Language': language
393
+ }
394
+ });
395
+ if (204 === response.status) return null;
396
+ if (!response.ok) throw new Error(`Failed to fetch GVL: ${response.status} ${response.statusText}`);
397
+ const text = await response.text();
398
+ const trimmed = text.trim().replace(/^\uFEFF/, '');
399
+ let parsed;
400
+ try {
401
+ parsed = JSON.parse(trimmed);
402
+ } catch {
403
+ let depth = 0;
404
+ let end = -1;
405
+ const start = trimmed.indexOf('{');
406
+ if (start >= 0) for(let i = start; i < trimmed.length; i++){
407
+ const c = trimmed[i];
408
+ if ('{' === c) depth++;
409
+ else if ('}' === c) {
410
+ depth--;
411
+ if (0 === depth) {
412
+ end = i + 1;
413
+ break;
414
+ }
415
+ }
416
+ }
417
+ if (end > 0) parsed = JSON.parse(trimmed.slice(0, end));
418
+ else throw new SyntaxError('Invalid GVL response: not valid JSON');
419
+ }
420
+ if (!parsed.vendorListVersion || !parsed.purposes || !parsed.vendors) throw new Error('Invalid GVL response: missing required fields');
421
+ return parsed;
422
+ });
423
+ getMetrics()?.recordGvlFetch({
424
+ language,
425
+ source: 'fetch',
426
+ status: 200
427
+ }, Date.now() - fetchStart);
428
+ return gvl;
429
+ } catch (error) {
430
+ getMetrics()?.recordGvlError({
431
+ language,
432
+ errorType: error instanceof Error ? error.name : 'UnknownError'
433
+ });
434
+ throw error;
435
+ } finally{
436
+ inflightRequests.delete(dedupeKey);
437
+ }
438
+ })();
439
+ inflightRequests.set(dedupeKey, promise);
440
+ return promise;
441
+ }
442
+ function createGVLResolver(options) {
443
+ const { appName, bundled, cacheAdapter, vendorIds, endpoint } = options;
444
+ const memoryCache = createMemoryCacheAdapter();
445
+ return {
446
+ async get (language) {
447
+ const cacheKey = createGVLCacheKey(appName, language, vendorIds);
448
+ if (bundled?.[language]) return bundled[language];
449
+ const memoryHit = await withCacheSpan('get', 'memory', ()=>memoryCache.get(cacheKey));
450
+ if (memoryHit) {
451
+ getMetrics()?.recordCacheHit('memory');
452
+ return memoryHit;
453
+ }
454
+ getMetrics()?.recordCacheMiss('memory');
455
+ if (cacheAdapter) {
456
+ const externalHit = await withCacheSpan('get', 'external', ()=>cacheAdapter.get(cacheKey));
457
+ if (externalHit) {
458
+ getMetrics()?.recordCacheHit('external');
459
+ await withCacheSpan('set', 'memory', ()=>memoryCache.set(cacheKey, externalHit, 300000));
460
+ return externalHit;
461
+ }
462
+ getMetrics()?.recordCacheMiss('external');
463
+ }
464
+ const gvl = await fetchGVLWithLanguage(language, vendorIds, endpoint);
465
+ if (gvl) {
466
+ await withCacheSpan('set', 'memory', ()=>memoryCache.set(cacheKey, gvl, 300000));
467
+ if (cacheAdapter) await withCacheSpan('set', 'external', ()=>cacheAdapter.set(cacheKey, gvl, GVL_TTL_MS));
468
+ }
469
+ return gvl;
470
+ }
471
+ };
472
+ }
473
+ export { GVL_TTL_MS, clearMemoryCache, createCacheKey, createGVLCacheKey, createGVLResolver, createMemoryCacheAdapter, createRequestSpan, createTelemetryOptions, extractErrorMessage, getMemoryCacheSize, getMetrics, getTraceContext, handleSpanError, isTelemetryEnabled, version, withDatabaseSpan, withSpanContext };