@c15t/backend 2.0.0-rc.3 → 2.0.0-rc.5

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 (314) hide show
  1. package/dist/cache.cjs +4 -4
  2. package/dist/cache.js +4 -4
  3. package/dist/core.cjs +845 -87
  4. package/dist/core.js +821 -87
  5. package/dist/db/schema.cjs +37 -0
  6. package/dist/db/schema.js +33 -2
  7. package/dist/edge.cjs +1106 -0
  8. package/dist/edge.js +1069 -0
  9. package/dist/router.cjs +621 -71
  10. package/dist/router.js +621 -71
  11. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  12. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  13. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  14. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  15. package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
  16. package/{dist → dist-types}/cache/index.d.ts +0 -1
  17. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  18. package/{dist → dist-types}/cache/types.d.ts +0 -1
  19. package/{dist → dist-types}/core.d.ts +8 -1
  20. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  21. package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
  22. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  23. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  24. package/{dist → dist-types}/db/registry/index.d.ts +22 -2
  25. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  26. package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
  27. package/{dist → dist-types}/db/registry/types.d.ts +1 -2
  28. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  29. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  30. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  31. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  32. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  33. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  34. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  35. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  36. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
  37. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
  38. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  39. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +1 -2
  40. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  41. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +5 -2
  42. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  43. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
  44. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  45. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -2
  46. package/{dist → dist-types}/db/schema/index.d.ts +862 -33
  47. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  48. package/dist-types/define-config.d.ts +17 -0
  49. package/dist-types/edge/index.d.ts +5 -0
  50. package/dist-types/edge/init-handler.d.ts +38 -0
  51. package/dist-types/edge/resolve-consent.d.ts +80 -0
  52. package/dist-types/edge/types.d.ts +13 -0
  53. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  54. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  55. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  56. package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
  57. package/dist-types/handlers/init/policy.d.ts +26 -0
  58. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  59. package/dist-types/handlers/init/translations.d.ts +48 -0
  60. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  61. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  62. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  63. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
  64. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  65. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
  66. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
  67. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  68. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
  69. package/{dist → dist-types}/init.d.ts +4 -7
  70. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  71. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  72. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  73. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  74. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
  75. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  76. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  77. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  78. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  79. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  80. package/dist-types/policies/builder.d.ts +127 -0
  81. package/dist-types/policies/defaults.d.ts +2 -0
  82. package/dist-types/policies/matchers.d.ts +3 -0
  83. package/{dist → dist-types}/router.d.ts +0 -1
  84. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  85. package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
  86. package/{dist → dist-types}/routes/init.d.ts +0 -1
  87. package/{dist → dist-types}/routes/status.d.ts +0 -1
  88. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  89. package/{dist → dist-types}/types/api.d.ts +0 -1
  90. package/dist-types/types/index.d.ts +443 -0
  91. package/dist-types/utils/background.d.ts +6 -0
  92. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  93. package/{dist → dist-types}/utils/env.d.ts +0 -1
  94. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  95. package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
  96. package/{dist → dist-types}/utils/logger.d.ts +1 -2
  97. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  98. package/dist-types/version.d.ts +1 -0
  99. package/docs/README.md +49 -0
  100. package/docs/api/configuration.md +197 -0
  101. package/docs/api/endpoints.md +211 -0
  102. package/docs/guides/caching.md +85 -0
  103. package/docs/guides/database-setup.md +128 -0
  104. package/docs/guides/edge-deployment.md +248 -0
  105. package/docs/guides/framework-integration.md +142 -0
  106. package/docs/guides/iab-tcf.md +89 -0
  107. package/docs/guides/observability.md +96 -0
  108. package/docs/guides/policy-packs.md +396 -0
  109. package/docs/quickstart.md +129 -0
  110. package/package.json +37 -23
  111. package/.turbo/turbo-build.log +0 -49
  112. package/CHANGELOG.md +0 -115
  113. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  114. package/dist/cache/adapters/index.d.ts.map +0 -1
  115. package/dist/cache/adapters/memory.d.ts.map +0 -1
  116. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  117. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  118. package/dist/cache/index.d.ts.map +0 -1
  119. package/dist/cache/keys.d.ts.map +0 -1
  120. package/dist/cache/types.d.ts.map +0 -1
  121. package/dist/core.d.ts.map +0 -1
  122. package/dist/db/adapters/drizzle.d.ts +0 -2
  123. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  124. package/dist/db/adapters/index.d.ts +0 -2
  125. package/dist/db/adapters/index.d.ts.map +0 -1
  126. package/dist/db/adapters/kysely.d.ts +0 -2
  127. package/dist/db/adapters/kysely.d.ts.map +0 -1
  128. package/dist/db/adapters/mongo.d.ts +0 -2
  129. package/dist/db/adapters/mongo.d.ts.map +0 -1
  130. package/dist/db/adapters/prisma.d.ts +0 -2
  131. package/dist/db/adapters/prisma.d.ts.map +0 -1
  132. package/dist/db/adapters/typeorm.d.ts +0 -2
  133. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  134. package/dist/db/migrator/index.d.ts.map +0 -1
  135. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  136. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  137. package/dist/db/registry/domain.d.ts.map +0 -1
  138. package/dist/db/registry/index.d.ts.map +0 -1
  139. package/dist/db/registry/subject.d.ts.map +0 -1
  140. package/dist/db/registry/types.d.ts.map +0 -1
  141. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  142. package/dist/db/registry/utils.d.ts.map +0 -1
  143. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  144. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  145. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  146. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  147. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  148. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  149. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  150. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  151. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  152. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  153. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  154. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  155. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  156. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  157. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  158. package/dist/db/schema/index.d.ts.map +0 -1
  159. package/dist/db/tenant-scope.d.ts.map +0 -1
  160. package/dist/define-config.d.ts +0 -5
  161. package/dist/define-config.d.ts.map +0 -1
  162. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  163. package/dist/handlers/consent/index.d.ts +0 -12
  164. package/dist/handlers/consent/index.d.ts.map +0 -1
  165. package/dist/handlers/init/geo.d.ts.map +0 -1
  166. package/dist/handlers/init/index.d.ts.map +0 -1
  167. package/dist/handlers/init/translations.d.ts +0 -28
  168. package/dist/handlers/init/translations.d.ts.map +0 -1
  169. package/dist/handlers/status/index.d.ts +0 -7
  170. package/dist/handlers/status/index.d.ts.map +0 -1
  171. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  172. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  173. package/dist/handlers/subject/index.d.ts +0 -10
  174. package/dist/handlers/subject/index.d.ts.map +0 -1
  175. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  176. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  177. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  178. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  179. package/dist/init.d.ts.map +0 -1
  180. package/dist/middleware/auth/index.d.ts.map +0 -1
  181. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  182. package/dist/middleware/cors/cors.d.ts.map +0 -1
  183. package/dist/middleware/cors/index.d.ts +0 -30
  184. package/dist/middleware/cors/index.d.ts.map +0 -1
  185. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  186. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  187. package/dist/middleware/openapi/config.d.ts.map +0 -1
  188. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  189. package/dist/middleware/openapi/index.d.ts +0 -12
  190. package/dist/middleware/openapi/index.d.ts.map +0 -1
  191. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  192. package/dist/router.d.ts.map +0 -1
  193. package/dist/routes/consent.d.ts.map +0 -1
  194. package/dist/routes/index.d.ts +0 -10
  195. package/dist/routes/index.d.ts.map +0 -1
  196. package/dist/routes/init.d.ts.map +0 -1
  197. package/dist/routes/status.d.ts.map +0 -1
  198. package/dist/routes/subject.d.ts.map +0 -1
  199. package/dist/types/api.d.ts.map +0 -1
  200. package/dist/types/index.d.ts +0 -263
  201. package/dist/types/index.d.ts.map +0 -1
  202. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  203. package/dist/utils/env.d.ts.map +0 -1
  204. package/dist/utils/extract-error-message.d.ts.map +0 -1
  205. package/dist/utils/index.d.ts +0 -4
  206. package/dist/utils/index.d.ts.map +0 -1
  207. package/dist/utils/instrumentation.d.ts.map +0 -1
  208. package/dist/utils/logger.d.ts.map +0 -1
  209. package/dist/utils/metrics.d.ts.map +0 -1
  210. package/dist/version.d.ts +0 -2
  211. package/dist/version.d.ts.map +0 -1
  212. package/knip.json +0 -31
  213. package/rslib.config.ts +0 -93
  214. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  215. package/src/cache/adapters/index.ts +0 -22
  216. package/src/cache/adapters/memory.ts +0 -111
  217. package/src/cache/adapters/upstash-redis.ts +0 -113
  218. package/src/cache/gvl-resolver.ts +0 -289
  219. package/src/cache/index.ts +0 -34
  220. package/src/cache/keys.ts +0 -68
  221. package/src/cache/types.ts +0 -66
  222. package/src/core.ts +0 -369
  223. package/src/db/migrator/index.ts +0 -80
  224. package/src/db/registry/consent-policy.test.ts +0 -451
  225. package/src/db/registry/consent-policy.ts +0 -82
  226. package/src/db/registry/consent-purpose.test.ts +0 -428
  227. package/src/db/registry/consent-purpose.ts +0 -61
  228. package/src/db/registry/domain.test.ts +0 -445
  229. package/src/db/registry/domain.ts +0 -91
  230. package/src/db/registry/index.ts +0 -14
  231. package/src/db/registry/subject.test.ts +0 -371
  232. package/src/db/registry/subject.ts +0 -126
  233. package/src/db/registry/types.ts +0 -10
  234. package/src/db/registry/utils/generate-id.test.ts +0 -216
  235. package/src/db/registry/utils/generate-id.ts +0 -133
  236. package/src/db/registry/utils.ts +0 -133
  237. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  238. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  239. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  240. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  241. package/src/db/schema/1.0.0/consent.ts +0 -20
  242. package/src/db/schema/1.0.0/domain.ts +0 -12
  243. package/src/db/schema/1.0.0/index.ts +0 -48
  244. package/src/db/schema/1.0.0/subject.ts +0 -11
  245. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  246. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  247. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  248. package/src/db/schema/2.0.0/consent.ts +0 -28
  249. package/src/db/schema/2.0.0/domain.ts +0 -12
  250. package/src/db/schema/2.0.0/index.ts +0 -47
  251. package/src/db/schema/2.0.0/subject.ts +0 -13
  252. package/src/db/schema/index.ts +0 -15
  253. package/src/db/tenant-scope.test.ts +0 -747
  254. package/src/db/tenant-scope.ts +0 -103
  255. package/src/define-config.ts +0 -5
  256. package/src/handlers/consent/check.handler.ts +0 -126
  257. package/src/handlers/init/geo.test.ts +0 -317
  258. package/src/handlers/init/geo.ts +0 -195
  259. package/src/handlers/init/index.test.ts +0 -205
  260. package/src/handlers/init/index.ts +0 -114
  261. package/src/handlers/init/translations.test.ts +0 -121
  262. package/src/handlers/init/translations.ts +0 -72
  263. package/src/handlers/status/status.handler.test.ts +0 -155
  264. package/src/handlers/status/status.handler.ts +0 -51
  265. package/src/handlers/subject/get.handler.ts +0 -92
  266. package/src/handlers/subject/list.handler.ts +0 -92
  267. package/src/handlers/subject/patch.handler.ts +0 -119
  268. package/src/handlers/subject/post.handler.test.ts +0 -294
  269. package/src/handlers/subject/post.handler.ts +0 -268
  270. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  271. package/src/handlers/utils/consent-enrichment.ts +0 -218
  272. package/src/init.test.ts +0 -126
  273. package/src/init.ts +0 -87
  274. package/src/middleware/auth/index.ts +0 -11
  275. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  276. package/src/middleware/auth/validate-api-key.ts +0 -107
  277. package/src/middleware/cors/cors.test.ts +0 -135
  278. package/src/middleware/cors/cors.ts +0 -186
  279. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  280. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  281. package/src/middleware/cors/process-cors.ts +0 -91
  282. package/src/middleware/openapi/config.ts +0 -29
  283. package/src/middleware/openapi/handlers.ts +0 -34
  284. package/src/middleware/process-ip/index.test.ts +0 -195
  285. package/src/middleware/process-ip/index.ts +0 -199
  286. package/src/router.ts +0 -15
  287. package/src/routes/consent.ts +0 -52
  288. package/src/routes/init.ts +0 -105
  289. package/src/routes/status.ts +0 -46
  290. package/src/routes/subject.ts +0 -152
  291. package/src/types/api.ts +0 -48
  292. package/src/types/index.ts +0 -297
  293. package/src/utils/create-telemetry-options.test.ts +0 -302
  294. package/src/utils/create-telemetry-options.ts +0 -229
  295. package/src/utils/env.ts +0 -84
  296. package/src/utils/extract-error-message.ts +0 -21
  297. package/src/utils/instrumentation.test.ts +0 -185
  298. package/src/utils/instrumentation.ts +0 -196
  299. package/src/utils/logger.ts +0 -41
  300. package/src/utils/metrics.test.ts +0 -323
  301. package/src/utils/metrics.ts +0 -402
  302. package/src/utils/telemetry-pii.test.ts +0 -325
  303. package/src/version.ts +0 -2
  304. package/tsconfig.json +0 -11
  305. package/vitest.config.ts +0 -28
  306. /package/dist/{types.cjs → types/index.cjs} +0 -0
  307. /package/dist/{types.js → types/index.js} +0 -0
  308. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  309. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  310. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  311. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  312. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  313. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  314. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
package/dist/edge.cjs ADDED
@@ -0,0 +1,1106 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ resolveConsent: ()=>resolveConsent,
28
+ c15tEdgeInit: ()=>c15tEdgeInit
29
+ });
30
+ const logger_namespaceObject = require("@c15t/logger");
31
+ const types_namespaceObject = require("@c15t/schema/types");
32
+ function inspectPolicies(policies, options) {
33
+ return (0, types_namespaceObject.inspectPolicies)(policies, options);
34
+ }
35
+ async function resolvePolicyDecision(params) {
36
+ return (0, types_namespaceObject.resolvePolicyDecision)({
37
+ policies: params.policies,
38
+ countryCode: params.countryCode,
39
+ regionCode: params.regionCode,
40
+ jurisdiction: params.jurisdiction,
41
+ iabEnabled: params.iabEnabled
42
+ });
43
+ }
44
+ function resolvePolicySync(params) {
45
+ return (0, types_namespaceObject.resolvePolicySync)({
46
+ policies: params.policies,
47
+ countryCode: params.countryCode,
48
+ regionCode: params.regionCode,
49
+ jurisdiction: params.jurisdiction,
50
+ iabEnabled: params.iabEnabled
51
+ });
52
+ }
53
+ const api_namespaceObject = require("@opentelemetry/api");
54
+ function extractErrorMessage(error) {
55
+ if (error instanceof AggregateError && error.errors?.length > 0) {
56
+ const inner = error.errors.map((e)=>e instanceof Error ? e.message : String(e)).join('; ');
57
+ return `AggregateError: ${inner}`;
58
+ }
59
+ if (error instanceof Error) return error.message || error.name;
60
+ return String(error);
61
+ }
62
+ let cachedConfig = null;
63
+ let cachedDefaultAttributes = {};
64
+ function create_telemetry_options_isTelemetryEnabled(options) {
65
+ if (options) return options.telemetry?.enabled === true;
66
+ return cachedConfig?.enabled === true;
67
+ }
68
+ const create_telemetry_options_getTracer = (options)=>{
69
+ if (!create_telemetry_options_isTelemetryEnabled(options)) return api_namespaceObject.trace.getTracer('c15t-noop');
70
+ const tracer = options?.telemetry?.tracer ?? cachedConfig?.tracer;
71
+ if (tracer) return tracer;
72
+ return api_namespaceObject.trace.getTracer(options?.appName ?? 'c15t');
73
+ };
74
+ const getMeter = (options)=>{
75
+ if (!create_telemetry_options_isTelemetryEnabled(options)) return api_namespaceObject.metrics.getMeter('c15t-noop');
76
+ const meter = options?.telemetry?.meter ?? cachedConfig?.meter;
77
+ if (meter) return meter;
78
+ return api_namespaceObject.metrics.getMeter(options?.appName ?? 'c15t');
79
+ };
80
+ function getDefaultAttributes() {
81
+ return cachedDefaultAttributes;
82
+ }
83
+ const handleSpanError = (span, error)=>{
84
+ span.setStatus({
85
+ code: api_namespaceObject.SpanStatusCode.ERROR,
86
+ message: extractErrorMessage(error)
87
+ });
88
+ if (error instanceof Error) span.setAttribute('error.type', error.name);
89
+ };
90
+ const withSpanContext = async (span, operation)=>api_namespaceObject.context["with"](api_namespaceObject.trace.setSpan(api_namespaceObject.context.active(), span), operation);
91
+ async function executeWithSpan(span, operation) {
92
+ try {
93
+ const result = await withSpanContext(span, operation);
94
+ span.setStatus({
95
+ code: api_namespaceObject.SpanStatusCode.OK
96
+ });
97
+ return result;
98
+ } catch (error) {
99
+ handleSpanError(span, error);
100
+ throw error;
101
+ } finally{
102
+ span.end();
103
+ }
104
+ }
105
+ function resolveDefaultAttributes(options) {
106
+ return options?.telemetry?.defaultAttributes || getDefaultAttributes();
107
+ }
108
+ async function withExternalSpan(attributes, operation, options) {
109
+ if (!create_telemetry_options_isTelemetryEnabled(options)) return operation();
110
+ const tracer = create_telemetry_options_getTracer(options);
111
+ const url = new URL(attributes.url);
112
+ const spanName = `HTTP ${attributes.method} ${url.hostname}`;
113
+ const span = tracer.startSpan(spanName, {
114
+ kind: api_namespaceObject.SpanKind.CLIENT,
115
+ attributes: {
116
+ 'http.method': attributes.method,
117
+ 'http.url': `${url.origin}${url.pathname}`,
118
+ 'http.host': url.hostname,
119
+ ...resolveDefaultAttributes(options),
120
+ ...Object.fromEntries(Object.entries(attributes).filter(([key])=>![
121
+ 'url',
122
+ 'method'
123
+ ].includes(key)))
124
+ }
125
+ });
126
+ return executeWithSpan(span, operation);
127
+ }
128
+ async function withCacheSpan(operation, layer, fn, options) {
129
+ if (!create_telemetry_options_isTelemetryEnabled(options)) return fn();
130
+ const tracer = create_telemetry_options_getTracer(options);
131
+ const spanName = `cache.${layer}.${operation}`;
132
+ const span = tracer.startSpan(spanName, {
133
+ kind: api_namespaceObject.SpanKind.CLIENT,
134
+ attributes: {
135
+ 'cache.operation': operation,
136
+ 'cache.layer': layer,
137
+ ...resolveDefaultAttributes(options)
138
+ }
139
+ });
140
+ return executeWithSpan(span, fn);
141
+ }
142
+ function sanitizeAttributes(attrs) {
143
+ return Object.fromEntries(Object.entries(attrs).filter(([_, v])=>null != v));
144
+ }
145
+ function createMetrics(meter) {
146
+ const consentCreated = meter.createCounter('c15t.consent.created', {
147
+ description: 'Number of consent submissions',
148
+ unit: '1'
149
+ });
150
+ const consentAccepted = meter.createCounter('c15t.consent.accepted', {
151
+ description: 'Number of consents accepted',
152
+ unit: '1'
153
+ });
154
+ const consentRejected = meter.createCounter('c15t.consent.rejected', {
155
+ description: 'Number of consents rejected',
156
+ unit: '1'
157
+ });
158
+ const subjectCreated = meter.createCounter('c15t.subject.created', {
159
+ description: 'Number of new subjects created',
160
+ unit: '1'
161
+ });
162
+ const subjectLinked = meter.createCounter('c15t.subject.linked', {
163
+ description: 'Number of subjects linked to external ID',
164
+ unit: '1'
165
+ });
166
+ const consentCheckCount = meter.createCounter('c15t.consent_check.count', {
167
+ description: 'Number of cross-device consent checks',
168
+ unit: '1'
169
+ });
170
+ const initCount = meter.createCounter('c15t.init.count', {
171
+ description: 'Number of init endpoint calls',
172
+ unit: '1'
173
+ });
174
+ const httpRequestDuration = meter.createHistogram('c15t.http.request.duration', {
175
+ description: 'HTTP request latency',
176
+ unit: 'ms'
177
+ });
178
+ const httpRequestCount = meter.createCounter('c15t.http.request.count', {
179
+ description: 'Number of HTTP requests',
180
+ unit: '1'
181
+ });
182
+ const httpErrorCount = meter.createCounter('c15t.http.error.count', {
183
+ description: 'Number of HTTP errors',
184
+ unit: '1'
185
+ });
186
+ const dbQueryDuration = meter.createHistogram('c15t.db.query.duration', {
187
+ description: 'Database query latency',
188
+ unit: 'ms'
189
+ });
190
+ const dbQueryCount = meter.createCounter('c15t.db.query.count', {
191
+ description: 'Number of database queries',
192
+ unit: '1'
193
+ });
194
+ const dbErrorCount = meter.createCounter('c15t.db.error.count', {
195
+ description: 'Number of database errors',
196
+ unit: '1'
197
+ });
198
+ const cacheHit = meter.createCounter('c15t.cache.hit', {
199
+ description: 'Number of cache hits',
200
+ unit: '1'
201
+ });
202
+ const cacheMiss = meter.createCounter('c15t.cache.miss', {
203
+ description: 'Number of cache misses',
204
+ unit: '1'
205
+ });
206
+ const cacheLatency = meter.createHistogram('c15t.cache.latency', {
207
+ description: 'Cache operation latency',
208
+ unit: 'ms'
209
+ });
210
+ const gvlFetchDuration = meter.createHistogram('c15t.gvl.fetch.duration', {
211
+ description: 'GVL fetch latency',
212
+ unit: 'ms'
213
+ });
214
+ const gvlFetchCount = meter.createCounter('c15t.gvl.fetch.count', {
215
+ description: 'Number of GVL fetches',
216
+ unit: '1'
217
+ });
218
+ const gvlFetchError = meter.createCounter('c15t.gvl.fetch.error', {
219
+ description: 'Number of GVL fetch errors',
220
+ unit: '1'
221
+ });
222
+ return {
223
+ consentCreated,
224
+ consentAccepted,
225
+ consentRejected,
226
+ subjectCreated,
227
+ subjectLinked,
228
+ consentCheckCount,
229
+ initCount,
230
+ httpRequestDuration,
231
+ httpRequestCount,
232
+ httpErrorCount,
233
+ dbQueryDuration,
234
+ dbQueryCount,
235
+ dbErrorCount,
236
+ cacheHit,
237
+ cacheMiss,
238
+ cacheLatency,
239
+ gvlFetchDuration,
240
+ gvlFetchCount,
241
+ gvlFetchError,
242
+ recordConsentCreated (attributes) {
243
+ consentCreated.add(1, sanitizeAttributes(attributes));
244
+ },
245
+ recordConsentAccepted (attributes) {
246
+ consentAccepted.add(1, sanitizeAttributes(attributes));
247
+ },
248
+ recordConsentRejected (attributes) {
249
+ consentRejected.add(1, sanitizeAttributes(attributes));
250
+ },
251
+ recordSubjectCreated (attributes) {
252
+ subjectCreated.add(1, sanitizeAttributes(attributes));
253
+ },
254
+ recordSubjectLinked (identityProvider) {
255
+ subjectLinked.add(1, {
256
+ identityProvider: identityProvider || 'unknown'
257
+ });
258
+ },
259
+ recordConsentCheck (type, found) {
260
+ consentCheckCount.add(1, {
261
+ type,
262
+ found: String(found)
263
+ });
264
+ },
265
+ recordInit (attributes) {
266
+ initCount.add(1, sanitizeAttributes(attributes));
267
+ },
268
+ recordHttpRequest (attributes, durationMs) {
269
+ const attrs = sanitizeAttributes(attributes);
270
+ httpRequestCount.add(1, attrs);
271
+ httpRequestDuration.record(durationMs, attrs);
272
+ if (attributes.status >= 400) httpErrorCount.add(1, attrs);
273
+ },
274
+ recordDbQuery (attributes, durationMs) {
275
+ const attrs = sanitizeAttributes(attributes);
276
+ dbQueryCount.add(1, attrs);
277
+ dbQueryDuration.record(durationMs, attrs);
278
+ },
279
+ recordDbError (attributes) {
280
+ dbErrorCount.add(1, sanitizeAttributes(attributes));
281
+ },
282
+ recordCacheHit (layer) {
283
+ cacheHit.add(1, {
284
+ layer
285
+ });
286
+ },
287
+ recordCacheMiss (layer) {
288
+ cacheMiss.add(1, {
289
+ layer
290
+ });
291
+ },
292
+ recordCacheLatency (attributes, durationMs) {
293
+ cacheLatency.record(durationMs, sanitizeAttributes(attributes));
294
+ },
295
+ recordGvlFetch (attributes, durationMs) {
296
+ const attrs = sanitizeAttributes(attributes);
297
+ gvlFetchCount.add(1, attrs);
298
+ gvlFetchDuration.record(durationMs, attrs);
299
+ },
300
+ recordGvlError (attributes) {
301
+ gvlFetchError.add(1, sanitizeAttributes(attributes));
302
+ }
303
+ };
304
+ }
305
+ let metricsInstance = null;
306
+ function getMetrics(options) {
307
+ if (metricsInstance) return metricsInstance;
308
+ if (!create_telemetry_options_isTelemetryEnabled(options)) return null;
309
+ metricsInstance = createMetrics(getMeter(options));
310
+ return metricsInstance;
311
+ }
312
+ const GVL_TTL_MS = 259200000;
313
+ const memory_memoryCache = new Map();
314
+ function createMemoryCacheAdapter() {
315
+ return {
316
+ async get (key) {
317
+ const entry = memory_memoryCache.get(key);
318
+ if (!entry) return null;
319
+ if (Date.now() > entry.expiresAt) {
320
+ memory_memoryCache.delete(key);
321
+ return null;
322
+ }
323
+ return entry.value;
324
+ },
325
+ async set (key, value, ttlMs = 300000) {
326
+ memory_memoryCache.set(key, {
327
+ value,
328
+ expiresAt: Date.now() + ttlMs
329
+ });
330
+ },
331
+ async delete (key) {
332
+ memory_memoryCache.delete(key);
333
+ },
334
+ async has (key) {
335
+ const entry = memory_memoryCache.get(key);
336
+ if (!entry) return false;
337
+ if (Date.now() > entry.expiresAt) {
338
+ memory_memoryCache.delete(key);
339
+ return false;
340
+ }
341
+ return true;
342
+ }
343
+ };
344
+ }
345
+ function createGVLCacheKey(appName, language, vendorIds) {
346
+ const sortedIds = vendorIds ? [
347
+ ...vendorIds
348
+ ].sort((a, b)=>a - b).join(',') : 'all';
349
+ return `${appName}:gvl:${language}:${sortedIds}`;
350
+ }
351
+ const GVL_ENDPOINT = 'https://gvl.consent.io';
352
+ const inflightRequests = new Map();
353
+ async function fetchGVLWithLanguage(language, vendorIds, endpoint = GVL_ENDPOINT) {
354
+ const sortedVendorIds = vendorIds ? [
355
+ ...vendorIds
356
+ ].sort((a, b)=>a - b) : [];
357
+ const dedupeKey = `${endpoint}|${language}|${sortedVendorIds.join(',')}`;
358
+ const existingRequest = inflightRequests.get(dedupeKey);
359
+ if (existingRequest) return existingRequest;
360
+ const url = new URL(endpoint);
361
+ if (sortedVendorIds.length > 0) url.searchParams.set('vendorIds', sortedVendorIds.join(','));
362
+ const promise = (async ()=>{
363
+ const fetchStart = Date.now();
364
+ try {
365
+ const gvl = await withExternalSpan({
366
+ url: url.toString(),
367
+ method: 'GET'
368
+ }, async ()=>{
369
+ const response = await fetch(url.toString(), {
370
+ headers: {
371
+ 'Accept-Language': language
372
+ }
373
+ });
374
+ if (204 === response.status) return null;
375
+ if (!response.ok) throw new Error(`Failed to fetch GVL: ${response.status} ${response.statusText}`);
376
+ const text = await response.text();
377
+ const trimmed = text.trim().replace(/^\uFEFF/, '');
378
+ let parsed;
379
+ try {
380
+ parsed = JSON.parse(trimmed);
381
+ } catch {
382
+ let depth = 0;
383
+ let end = -1;
384
+ const start = trimmed.indexOf('{');
385
+ if (start >= 0) for(let i = start; i < trimmed.length; i++){
386
+ const c = trimmed[i];
387
+ if ('{' === c) depth++;
388
+ else if ('}' === c) {
389
+ depth--;
390
+ if (0 === depth) {
391
+ end = i + 1;
392
+ break;
393
+ }
394
+ }
395
+ }
396
+ if (end > 0) parsed = JSON.parse(trimmed.slice(0, end));
397
+ else throw new SyntaxError('Invalid GVL response: not valid JSON');
398
+ }
399
+ if (!parsed.vendorListVersion || !parsed.purposes || !parsed.vendors) throw new Error('Invalid GVL response: missing required fields');
400
+ return parsed;
401
+ });
402
+ getMetrics()?.recordGvlFetch({
403
+ language,
404
+ source: 'fetch',
405
+ status: 200
406
+ }, Date.now() - fetchStart);
407
+ return gvl;
408
+ } catch (error) {
409
+ getMetrics()?.recordGvlError({
410
+ language,
411
+ errorType: error instanceof Error ? error.name : 'UnknownError'
412
+ });
413
+ throw error;
414
+ } finally{
415
+ inflightRequests.delete(dedupeKey);
416
+ }
417
+ })();
418
+ inflightRequests.set(dedupeKey, promise);
419
+ return promise;
420
+ }
421
+ function createGVLResolver(options) {
422
+ const { appName, bundled, cacheAdapter, vendorIds, endpoint } = options;
423
+ const memoryCache = createMemoryCacheAdapter();
424
+ return {
425
+ async get (language) {
426
+ const cacheKey = createGVLCacheKey(appName, language, vendorIds);
427
+ if (bundled?.[language]) return bundled[language];
428
+ const memoryHit = await withCacheSpan('get', 'memory', ()=>memoryCache.get(cacheKey));
429
+ if (memoryHit) {
430
+ getMetrics()?.recordCacheHit('memory');
431
+ return memoryHit;
432
+ }
433
+ getMetrics()?.recordCacheMiss('memory');
434
+ if (cacheAdapter) {
435
+ const externalHit = await withCacheSpan('get', 'external', ()=>cacheAdapter.get(cacheKey));
436
+ if (externalHit) {
437
+ getMetrics()?.recordCacheHit('external');
438
+ await withCacheSpan('set', 'memory', ()=>memoryCache.set(cacheKey, externalHit, 300000));
439
+ return externalHit;
440
+ }
441
+ getMetrics()?.recordCacheMiss('external');
442
+ }
443
+ const gvl = await fetchGVLWithLanguage(language, vendorIds, endpoint);
444
+ if (gvl) {
445
+ await withCacheSpan('set', 'memory', ()=>memoryCache.set(cacheKey, gvl, 300000));
446
+ if (cacheAdapter) await withCacheSpan('set', 'external', ()=>cacheAdapter.set(cacheKey, gvl, GVL_TTL_MS));
447
+ }
448
+ return gvl;
449
+ }
450
+ };
451
+ }
452
+ const external_jose_namespaceObject = require("jose");
453
+ const POLICY_SNAPSHOT_JWT_HEADER = {
454
+ alg: 'HS256',
455
+ typ: 'JWT'
456
+ };
457
+ const DEFAULT_POLICY_SNAPSHOT_ISSUER = 'c15t';
458
+ const DEFAULT_POLICY_SNAPSHOT_AUDIENCE = 'c15t-policy-snapshot';
459
+ function resolveSnapshotIssuer(options) {
460
+ return options?.issuer?.trim() || DEFAULT_POLICY_SNAPSHOT_ISSUER;
461
+ }
462
+ function resolveSnapshotAudience(params) {
463
+ const configuredAudience = params.options?.audience?.trim();
464
+ if (configuredAudience) return configuredAudience;
465
+ return params.tenantId ? `${DEFAULT_POLICY_SNAPSHOT_AUDIENCE}:${params.tenantId}` : DEFAULT_POLICY_SNAPSHOT_AUDIENCE;
466
+ }
467
+ function getSigningKey(secret) {
468
+ return new TextEncoder().encode(secret);
469
+ }
470
+ async function createPolicySnapshotToken(params) {
471
+ const { options } = params;
472
+ if (!options?.signingKey) return;
473
+ const iat = Math.floor(Date.now() / 1000);
474
+ const ttlSeconds = options.ttlSeconds ?? 1800;
475
+ const exp = iat + ttlSeconds;
476
+ const iss = resolveSnapshotIssuer(options);
477
+ const aud = resolveSnapshotAudience({
478
+ options,
479
+ tenantId: params.tenantId
480
+ });
481
+ const payload = {
482
+ iss,
483
+ aud,
484
+ sub: params.policyId,
485
+ tenantId: params.tenantId,
486
+ policyId: params.policyId,
487
+ fingerprint: params.fingerprint,
488
+ matchedBy: params.matchedBy,
489
+ country: params.country,
490
+ region: params.region,
491
+ jurisdiction: params.jurisdiction,
492
+ language: params.language,
493
+ model: params.model,
494
+ policyI18n: params.policyI18n,
495
+ expiryDays: params.expiryDays,
496
+ scopeMode: params.scopeMode,
497
+ uiMode: params.uiMode,
498
+ bannerUi: params.bannerUi,
499
+ dialogUi: params.dialogUi,
500
+ categories: params.categories,
501
+ preselectedCategories: params.preselectedCategories,
502
+ gpc: params.gpc,
503
+ proofConfig: params.proofConfig,
504
+ iat,
505
+ exp
506
+ };
507
+ const token = await new external_jose_namespaceObject.SignJWT(payload).setProtectedHeader(POLICY_SNAPSHOT_JWT_HEADER).setIssuedAt(iat).setExpirationTime(exp).sign(getSigningKey(options.signingKey));
508
+ return {
509
+ token,
510
+ payload
511
+ };
512
+ }
513
+ function normalizeHeader(value) {
514
+ if (!value) return null;
515
+ return Array.isArray(value) ? value[0] ?? null : value;
516
+ }
517
+ function getGeoHeaders(headers) {
518
+ const countryCode = normalizeHeader(headers.get('x-c15t-country')) ?? normalizeHeader(headers.get('cf-ipcountry')) ?? normalizeHeader(headers.get('x-vercel-ip-country')) ?? normalizeHeader(headers.get('x-amz-cf-ipcountry')) ?? normalizeHeader(headers.get('x-country-code'));
519
+ const regionCode = normalizeHeader(headers.get('x-c15t-region')) ?? normalizeHeader(headers.get('x-vercel-ip-country-region')) ?? normalizeHeader(headers.get('x-region-code'));
520
+ return {
521
+ countryCode,
522
+ regionCode
523
+ };
524
+ }
525
+ function checkJurisdiction(countryCode, regionCode) {
526
+ const jurisdictions = {
527
+ EU: new Set([
528
+ 'AT',
529
+ 'BE',
530
+ 'BG',
531
+ 'HR',
532
+ 'CY',
533
+ 'CZ',
534
+ 'DK',
535
+ 'EE',
536
+ 'FI',
537
+ 'FR',
538
+ 'DE',
539
+ 'GR',
540
+ 'HU',
541
+ 'IE',
542
+ 'IT',
543
+ 'LV',
544
+ 'LT',
545
+ 'LU',
546
+ 'MT',
547
+ 'NL',
548
+ 'PL',
549
+ 'PT',
550
+ 'RO',
551
+ 'SK',
552
+ 'SI',
553
+ 'ES',
554
+ 'SE'
555
+ ]),
556
+ EEA: new Set([
557
+ 'IS',
558
+ 'NO',
559
+ 'LI'
560
+ ]),
561
+ UK: new Set([
562
+ 'GB'
563
+ ]),
564
+ CH: new Set([
565
+ 'CH'
566
+ ]),
567
+ BR: new Set([
568
+ 'BR'
569
+ ]),
570
+ CA: new Set([
571
+ 'CA'
572
+ ]),
573
+ AU: new Set([
574
+ 'AU'
575
+ ]),
576
+ JP: new Set([
577
+ 'JP'
578
+ ]),
579
+ KR: new Set([
580
+ 'KR'
581
+ ]),
582
+ US_CCPA_REGIONS: new Set([
583
+ 'CA'
584
+ ]),
585
+ CA_QC_REGIONS: new Set([
586
+ 'QC'
587
+ ])
588
+ };
589
+ let jurisdiction = 'NONE';
590
+ if (countryCode) {
591
+ const normalizedCountryCode = countryCode.toUpperCase();
592
+ const normalizedRegionCode = regionCode && 'string' == typeof regionCode ? (regionCode.includes('-') ? regionCode.split('-').pop() : regionCode).toUpperCase() : null;
593
+ if ('US' === normalizedCountryCode && normalizedRegionCode && jurisdictions.US_CCPA_REGIONS.has(normalizedRegionCode)) return 'CCPA';
594
+ if ('CA' === normalizedCountryCode && normalizedRegionCode && jurisdictions.CA_QC_REGIONS.has(normalizedRegionCode)) return 'QC_LAW25';
595
+ const jurisdictionMap = [
596
+ {
597
+ sets: [
598
+ jurisdictions.UK
599
+ ],
600
+ code: 'UK_GDPR'
601
+ },
602
+ {
603
+ sets: [
604
+ jurisdictions.EU,
605
+ jurisdictions.EEA
606
+ ],
607
+ code: 'GDPR'
608
+ },
609
+ {
610
+ sets: [
611
+ jurisdictions.CH
612
+ ],
613
+ code: 'CH'
614
+ },
615
+ {
616
+ sets: [
617
+ jurisdictions.BR
618
+ ],
619
+ code: 'BR'
620
+ },
621
+ {
622
+ sets: [
623
+ jurisdictions.CA
624
+ ],
625
+ code: 'PIPEDA'
626
+ },
627
+ {
628
+ sets: [
629
+ jurisdictions.AU
630
+ ],
631
+ code: 'AU'
632
+ },
633
+ {
634
+ sets: [
635
+ jurisdictions.JP
636
+ ],
637
+ code: 'APPI'
638
+ },
639
+ {
640
+ sets: [
641
+ jurisdictions.KR
642
+ ],
643
+ code: 'PIPA'
644
+ }
645
+ ];
646
+ for (const { sets, code } of jurisdictionMap)if (sets.some((set)=>set.has(normalizedCountryCode))) {
647
+ jurisdiction = code;
648
+ break;
649
+ }
650
+ }
651
+ return jurisdiction;
652
+ }
653
+ async function getLocation(request, options) {
654
+ if (options.disableGeoLocation) return {
655
+ countryCode: null,
656
+ regionCode: null
657
+ };
658
+ const { countryCode, regionCode } = getGeoHeaders(request.headers);
659
+ return {
660
+ countryCode,
661
+ regionCode
662
+ };
663
+ }
664
+ function getJurisdiction(location, options) {
665
+ if (options.disableGeoLocation) return 'GDPR';
666
+ return checkJurisdiction(location.countryCode, location.regionCode);
667
+ }
668
+ const translations_namespaceObject = require("@c15t/translations");
669
+ const all_namespaceObject = require("@c15t/translations/all");
670
+ const DEFAULT_PROFILE = 'default';
671
+ const warnedKeys = new Set();
672
+ function isSupportedBaseLanguage(lang) {
673
+ return lang in all_namespaceObject.baseTranslations;
674
+ }
675
+ function warnOnce(logger, key, message, metadata) {
676
+ if (!logger || warnedKeys.has(key)) return;
677
+ warnedKeys.add(key);
678
+ logger.warn(message, metadata);
679
+ }
680
+ function normalizeLanguage(value) {
681
+ if (!value) return;
682
+ const normalized = value.split(',')[0]?.split(';')[0]?.trim().toLowerCase();
683
+ if (!normalized) return;
684
+ return normalized.split('-')[0] ?? void 0;
685
+ }
686
+ function normalizeProfiles(params) {
687
+ const profiles = params.i18n?.messages;
688
+ const legacy = params.customTranslations;
689
+ if (profiles && Object.keys(profiles).length > 0) {
690
+ if (legacy && Object.keys(legacy).length > 0) warnOnce(params.logger, 'i18n.customTranslations.ignored', '`customTranslations` is deprecated and ignored when `i18n.messages` is configured.');
691
+ return profiles;
692
+ }
693
+ if (legacy && Object.keys(legacy).length > 0) {
694
+ warnOnce(params.logger, 'i18n.customTranslations.deprecated', '`customTranslations` is deprecated. Use `i18n.messages` instead.');
695
+ return {
696
+ [DEFAULT_PROFILE]: {
697
+ translations: legacy
698
+ }
699
+ };
700
+ }
701
+ return {};
702
+ }
703
+ function buildCandidates(input) {
704
+ const raw = [
705
+ {
706
+ language: input.language,
707
+ reason: 'profile_language'
708
+ },
709
+ {
710
+ language: input.fallbackLanguage,
711
+ reason: 'profile_fallback'
712
+ }
713
+ ];
714
+ const dedupe = new Set();
715
+ return raw.filter((candidate)=>{
716
+ const key = candidate.language;
717
+ if (dedupe.has(key)) return false;
718
+ dedupe.add(key);
719
+ return true;
720
+ });
721
+ }
722
+ function getProfileLanguages(profiles, profile) {
723
+ return Object.keys(profiles[profile]?.translations ?? {}).sort();
724
+ }
725
+ function getSelectableLanguages(input) {
726
+ return getProfileLanguages(input.profiles, input.profile);
727
+ }
728
+ function resolveFallbackLanguage(input) {
729
+ const configuredFallbackLanguage = normalizeLanguage(input.profile?.fallbackLanguage) ?? 'en';
730
+ const profileLanguages = Object.keys(input.profile?.translations ?? {}).sort();
731
+ if (profileLanguages.includes(configuredFallbackLanguage)) return configuredFallbackLanguage;
732
+ if (profileLanguages.includes('en')) return 'en';
733
+ return profileLanguages[0] ?? configuredFallbackLanguage;
734
+ }
735
+ function resolveActiveProfile(input) {
736
+ const requestedProfile = input.policyProfile ?? input.defaultProfile;
737
+ if (input.profiles[requestedProfile]) return requestedProfile;
738
+ if (input.policyProfile) warnOnce(input.logger, `i18n.profile.missing:${requestedProfile}`, `Policy i18n profile '${requestedProfile}' does not exist. Falling back to default profile '${input.defaultProfile}'.`);
739
+ return input.defaultProfile;
740
+ }
741
+ function validateMessages(options) {
742
+ return (0, types_namespaceObject.validatePolicyI18nConfig)({
743
+ customTranslations: options.customTranslations,
744
+ i18n: options.i18n,
745
+ policies: options.policies
746
+ });
747
+ }
748
+ function getTranslationsData(acceptLanguage, customTranslations, options) {
749
+ const profiles = normalizeProfiles({
750
+ customTranslations,
751
+ i18n: options?.i18n,
752
+ logger: options?.logger
753
+ });
754
+ const defaultProfile = options?.i18n?.defaultProfile ?? DEFAULT_PROFILE;
755
+ const profile = resolveActiveProfile({
756
+ profiles,
757
+ defaultProfile,
758
+ policyProfile: options?.policyI18n?.messageProfile,
759
+ logger: options?.logger
760
+ });
761
+ const configuredLanguages = Object.keys(profiles).length > 0 ? getSelectableLanguages({
762
+ profiles,
763
+ profile
764
+ }) : Object.keys(all_namespaceObject.baseTranslations);
765
+ const fallbackLanguage = Object.keys(profiles).length > 0 ? resolveFallbackLanguage({
766
+ profile: profiles[profile]
767
+ }) : 'en';
768
+ const policyLanguage = normalizeLanguage(options?.policyI18n?.language);
769
+ const requestedLanguage = policyLanguage ?? (0, translations_namespaceObject.selectLanguage)(configuredLanguages, {
770
+ header: acceptLanguage,
771
+ fallback: fallbackLanguage
772
+ });
773
+ const candidates = buildCandidates({
774
+ language: requestedLanguage,
775
+ fallbackLanguage
776
+ });
777
+ const selectedCandidate = candidates.find((candidate)=>!!profiles[profile]?.translations[candidate.language]);
778
+ if (selectedCandidate && 'profile_language' !== selectedCandidate.reason) warnOnce(options?.logger, `i18n.fallback:${profile}:${requestedLanguage}:${selectedCandidate.language}`, `Policy translation fallback used (${selectedCandidate.reason}).`, {
779
+ requestedProfile: profile,
780
+ requestedLanguage,
781
+ resolvedProfile: profile,
782
+ resolvedLanguage: selectedCandidate.language
783
+ });
784
+ let language = selectedCandidate?.language ?? requestedLanguage;
785
+ if (!selectedCandidate && !isSupportedBaseLanguage(language)) {
786
+ warnOnce(options?.logger, `i18n.base-fallback:${language}`, `No translation found for '${language}'. Falling back to base English translations.`);
787
+ language = 'en';
788
+ }
789
+ const base = isSupportedBaseLanguage(language) ? all_namespaceObject.baseTranslations[language] : all_namespaceObject.baseTranslations.en;
790
+ const custom = selectedCandidate ? profiles[profile]?.translations[selectedCandidate.language] : void 0;
791
+ const translations = custom ? (0, translations_namespaceObject.deepMergeTranslations)(base, custom) : base;
792
+ return {
793
+ translations: translations,
794
+ language
795
+ };
796
+ }
797
+ function stripIabTranslations(translations) {
798
+ const { iab: _iab, ...rest } = translations;
799
+ return rest;
800
+ }
801
+ function resolveNoPolicyFallback() {
802
+ return {
803
+ id: 'no_banner',
804
+ model: 'none',
805
+ ui: {
806
+ mode: 'none'
807
+ }
808
+ };
809
+ }
810
+ async function resolveInitPayload(request, options, logger) {
811
+ const acceptLanguage = request.headers.get('accept-language') || 'en';
812
+ const location = await getLocation(request, options);
813
+ const jurisdiction = getJurisdiction(location, options);
814
+ const hasExplicitPolicyPack = void 0 !== options.policyPacks;
815
+ const isExplicitEmptyPolicyPack = hasExplicitPolicyPack && (options.policyPacks?.length ?? 0) === 0;
816
+ const policyDecision = isExplicitEmptyPolicyPack ? void 0 : await resolvePolicyDecision({
817
+ policies: options.policyPacks,
818
+ countryCode: location.countryCode,
819
+ regionCode: location.regionCode,
820
+ jurisdiction,
821
+ iabEnabled: options.iab?.enabled === true
822
+ });
823
+ if (hasExplicitPolicyPack && !isExplicitEmptyPolicyPack && !policyDecision) logger?.warn('Policy packs configured but no policy matched', {
824
+ country: location.countryCode,
825
+ region: location.regionCode
826
+ });
827
+ const resolvedPolicy = hasExplicitPolicyPack ? policyDecision?.policy ?? resolveNoPolicyFallback() : void 0;
828
+ const iabOptions = options.iab;
829
+ const shouldIncludeIabPayload = iabOptions?.enabled === true && (!hasExplicitPolicyPack || resolvedPolicy?.model === 'iab');
830
+ const translationsResult = getTranslationsData(acceptLanguage, options.customTranslations, {
831
+ i18n: options.i18n,
832
+ policyI18n: resolvedPolicy?.i18n,
833
+ logger
834
+ });
835
+ const responseTranslations = shouldIncludeIabPayload ? translationsResult : {
836
+ ...translationsResult,
837
+ translations: stripIabTranslations(translationsResult.translations)
838
+ };
839
+ let gvl = null;
840
+ if (shouldIncludeIabPayload && iabOptions) {
841
+ const language = translationsResult.language.split('-')[0] || 'en';
842
+ const gvlResolver = createGVLResolver({
843
+ appName: options.appName || 'c15t',
844
+ bundled: iabOptions.bundled,
845
+ cacheAdapter: options.cache?.adapter,
846
+ vendorIds: iabOptions.vendorIds,
847
+ endpoint: iabOptions.endpoint
848
+ });
849
+ gvl = await gvlResolver.get(language);
850
+ }
851
+ const customVendors = shouldIncludeIabPayload ? iabOptions?.customVendors : void 0;
852
+ const snapshot = policyDecision ? await createPolicySnapshotToken({
853
+ options: options.policySnapshot,
854
+ tenantId: options.tenantId,
855
+ policyId: policyDecision.policy.id,
856
+ fingerprint: policyDecision.fingerprint,
857
+ matchedBy: policyDecision.matchedBy,
858
+ country: location?.countryCode ?? null,
859
+ region: location?.regionCode ?? null,
860
+ jurisdiction,
861
+ language: translationsResult.language,
862
+ model: policyDecision.policy.model,
863
+ policyI18n: policyDecision.policy.i18n,
864
+ expiryDays: policyDecision.policy.consent?.expiryDays,
865
+ scopeMode: policyDecision.policy.consent?.scopeMode,
866
+ uiMode: policyDecision.policy.ui?.mode,
867
+ bannerUi: policyDecision.policy.ui?.banner,
868
+ dialogUi: policyDecision.policy.ui?.dialog,
869
+ categories: policyDecision.policy.consent?.categories,
870
+ preselectedCategories: policyDecision.policy.consent?.preselectedCategories,
871
+ gpc: policyDecision.policy.consent?.gpc,
872
+ proofConfig: policyDecision.policy.proof
873
+ }) : void 0;
874
+ const gpc = '1' === request.headers.get('sec-gpc');
875
+ getMetrics()?.recordInit({
876
+ jurisdiction,
877
+ country: location?.countryCode ?? void 0,
878
+ region: location?.regionCode ?? void 0,
879
+ gpc
880
+ });
881
+ return {
882
+ jurisdiction,
883
+ location,
884
+ translations: responseTranslations,
885
+ branding: options.branding || 'c15t',
886
+ ...shouldIncludeIabPayload && {
887
+ gvl,
888
+ customVendors
889
+ },
890
+ ...resolvedPolicy && {
891
+ policy: resolvedPolicy
892
+ },
893
+ ...policyDecision && {
894
+ policyDecision: {
895
+ policyId: policyDecision.policy.id,
896
+ fingerprint: policyDecision.fingerprint,
897
+ matchedBy: policyDecision.matchedBy,
898
+ country: location.countryCode,
899
+ region: location.regionCode,
900
+ jurisdiction
901
+ }
902
+ },
903
+ ...snapshot?.token && {
904
+ policySnapshotToken: snapshot.token
905
+ },
906
+ ...shouldIncludeIabPayload && iabOptions?.cmpId != null && {
907
+ cmpId: iabOptions.cmpId
908
+ }
909
+ };
910
+ }
911
+ const STRIP_REGEX = /^(?:https?:\/\/)|^(?:wss?:\/\/)|(?:\/+$)|(?::\d+$)/g;
912
+ function matchesWildcard(hostname, wildcardPattern, logger) {
913
+ const wildcardDomain = wildcardPattern.slice(2);
914
+ const isValid = hostname !== wildcardDomain && hostname.endsWith(`.${wildcardDomain}`);
915
+ logger?.debug(`Wildcard match result: ${isValid} ${hostname} ends with .${wildcardDomain}`);
916
+ return isValid;
917
+ }
918
+ function isOriginTrusted(origin, trustedDomains, logger) {
919
+ try {
920
+ if (0 === trustedDomains.length) throw new Error('No trusted domains');
921
+ logger?.debug(`Checking if origin ${origin} is trusted in ${trustedDomains}`);
922
+ if (trustedDomains.includes('*')) {
923
+ logger?.debug('Allowing all origins');
924
+ return true;
925
+ }
926
+ const url = new URL(origin);
927
+ const originHostname = url.hostname.toLowerCase();
928
+ logger?.debug(`Parsed origin hostname: ${originHostname}`);
929
+ return trustedDomains.some((domain)=>{
930
+ if (!domain || '' === domain.trim()) {
931
+ logger?.debug('Skipping empty domain');
932
+ return false;
933
+ }
934
+ const strippedDomain = domain.replace(STRIP_REGEX, '').toLowerCase();
935
+ logger?.debug(`Checking against stripped domain: ${strippedDomain}`);
936
+ if (strippedDomain.startsWith('*.')) return matchesWildcard(originHostname, strippedDomain, logger);
937
+ const isMatch = originHostname === strippedDomain;
938
+ logger?.debug(`Exact match result: ${isMatch} ${originHostname} === ${strippedDomain}`);
939
+ return isMatch;
940
+ });
941
+ } catch (error) {
942
+ logger?.error('Error validating origin:', error);
943
+ return false;
944
+ }
945
+ }
946
+ function c15tEdgeInit(options) {
947
+ const logger = (0, logger_namespaceObject.createLogger)(options.logger);
948
+ const validation = validateMessages({
949
+ customTranslations: options.customTranslations,
950
+ i18n: options.i18n,
951
+ policies: options.policyPacks
952
+ });
953
+ if (validation.errors.length > 0) throw new Error(`Edge init validation failed: ${validation.errors.join(', ')}`);
954
+ for (const warning of validation.warnings)logger.warn(warning);
955
+ if (options.policyPacks) inspectPolicies(options.policyPacks, {
956
+ iabEnabled: options.iab?.enabled === true
957
+ });
958
+ return async (request)=>{
959
+ if ('OPTIONS' === request.method) return new Response(null, {
960
+ status: 204,
961
+ headers: buildCorsHeaders(request, options.trustedOrigins, logger)
962
+ });
963
+ try {
964
+ const payload = await resolveInitPayload(request, options, logger);
965
+ const headers = new Headers({
966
+ 'content-type': 'application/json'
967
+ });
968
+ applyCorsHeaders(headers, request, options.trustedOrigins, logger);
969
+ return new Response(JSON.stringify(payload), {
970
+ status: 200,
971
+ headers
972
+ });
973
+ } catch (error) {
974
+ logger.error('Edge init handler error', error);
975
+ const errorHeaders = new Headers({
976
+ 'content-type': 'application/json'
977
+ });
978
+ applyCorsHeaders(errorHeaders, request, options.trustedOrigins, logger);
979
+ return new Response(JSON.stringify({
980
+ code: 'INTERNAL_SERVER_ERROR',
981
+ message: 'Internal server error',
982
+ status: 500
983
+ }), {
984
+ status: 500,
985
+ headers: errorHeaders
986
+ });
987
+ }
988
+ };
989
+ }
990
+ function buildCorsHeaders(request, trustedOrigins, logger) {
991
+ const origin = request.headers.get('origin');
992
+ const headers = {
993
+ 'access-control-allow-methods': 'GET, OPTIONS',
994
+ 'access-control-allow-headers': 'content-type, accept-language',
995
+ 'access-control-max-age': '86400'
996
+ };
997
+ if (origin && isTrusted(origin, trustedOrigins, logger)) {
998
+ headers['access-control-allow-origin'] = origin;
999
+ headers.vary = 'Origin';
1000
+ }
1001
+ return headers;
1002
+ }
1003
+ function applyCorsHeaders(headers, request, trustedOrigins, logger) {
1004
+ const origin = request.headers.get('origin');
1005
+ if (origin && isTrusted(origin, trustedOrigins, logger)) {
1006
+ headers.set('access-control-allow-origin', origin);
1007
+ headers.set('vary', 'Origin');
1008
+ }
1009
+ }
1010
+ function isTrusted(origin, trustedOrigins, logger) {
1011
+ if (0 === trustedOrigins.length) return false;
1012
+ return isOriginTrusted(origin, trustedOrigins, logger);
1013
+ }
1014
+ function getLocationFromHeaders(headers) {
1015
+ const countryCode = headers.get('x-c15t-country') ?? headers.get('cf-ipcountry') ?? headers.get('x-vercel-ip-country') ?? headers.get('x-amz-cf-ipcountry') ?? headers.get('x-country-code');
1016
+ const regionCode = headers.get('x-c15t-region') ?? headers.get('x-vercel-ip-country-region') ?? headers.get('x-region-code');
1017
+ return {
1018
+ countryCode,
1019
+ regionCode
1020
+ };
1021
+ }
1022
+ function resolve_consent_resolveNoPolicyFallback() {
1023
+ return {
1024
+ id: 'no_banner',
1025
+ model: 'none',
1026
+ ui: {
1027
+ mode: 'none'
1028
+ }
1029
+ };
1030
+ }
1031
+ function resolveDefaultConsent(policy, gpc) {
1032
+ const model = policy.model;
1033
+ const categories = policy.consent?.categories ?? [];
1034
+ const preselected = new Set(policy.consent?.preselectedCategories ?? []);
1035
+ const respectsGpc = policy.consent?.gpc === true && gpc;
1036
+ const defaults = {};
1037
+ defaults.necessary = {
1038
+ granted: true,
1039
+ required: true
1040
+ };
1041
+ if ('none' === model) {
1042
+ for (const category of categories)if ('*' !== category && 'necessary' !== category) defaults[category] = {
1043
+ granted: true,
1044
+ required: false
1045
+ };
1046
+ return defaults;
1047
+ }
1048
+ if ('opt-out' === model) {
1049
+ for (const category of categories){
1050
+ if ('*' === category || 'necessary' === category) continue;
1051
+ const gpcOverride = respectsGpc && ('marketing' === category || 'measurement' === category);
1052
+ defaults[category] = {
1053
+ granted: !gpcOverride,
1054
+ required: false
1055
+ };
1056
+ }
1057
+ return defaults;
1058
+ }
1059
+ for (const category of categories)if ('*' !== category && 'necessary' !== category) defaults[category] = {
1060
+ granted: preselected.has(category),
1061
+ required: false
1062
+ };
1063
+ return defaults;
1064
+ }
1065
+ function resolveConsent(request, options, logger) {
1066
+ const location = options.disableGeoLocation ? {
1067
+ countryCode: null,
1068
+ regionCode: null
1069
+ } : getLocationFromHeaders(request.headers);
1070
+ const jurisdiction = options.disableGeoLocation ? 'GDPR' : checkJurisdiction(location.countryCode, location.regionCode);
1071
+ const gpc = '1' === request.headers.get('sec-gpc');
1072
+ const hasExplicitPolicyPack = void 0 !== options.policyPacks;
1073
+ const isExplicitEmptyPolicyPack = hasExplicitPolicyPack && (options.policyPacks?.length ?? 0) === 0;
1074
+ const policyMatch = isExplicitEmptyPolicyPack ? void 0 : resolvePolicySync({
1075
+ policies: options.policyPacks,
1076
+ countryCode: location.countryCode,
1077
+ regionCode: location.regionCode,
1078
+ jurisdiction
1079
+ });
1080
+ if (hasExplicitPolicyPack && !isExplicitEmptyPolicyPack && !policyMatch) logger?.warn('Policy packs configured but no policy matched', {
1081
+ country: location.countryCode,
1082
+ region: location.regionCode
1083
+ });
1084
+ const resolvedPolicy = hasExplicitPolicyPack ? policyMatch?.policy ?? resolve_consent_resolveNoPolicyFallback() : resolve_consent_resolveNoPolicyFallback();
1085
+ const model = resolvedPolicy.model;
1086
+ const showBanner = 'none' !== model && resolvedPolicy.ui?.mode !== 'none';
1087
+ const defaults = resolveDefaultConsent(resolvedPolicy, gpc);
1088
+ return {
1089
+ jurisdiction,
1090
+ location,
1091
+ model,
1092
+ policyId: resolvedPolicy.id,
1093
+ defaults,
1094
+ showBanner,
1095
+ gpc
1096
+ };
1097
+ }
1098
+ exports.c15tEdgeInit = __webpack_exports__.c15tEdgeInit;
1099
+ exports.resolveConsent = __webpack_exports__.resolveConsent;
1100
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
1101
+ "c15tEdgeInit",
1102
+ "resolveConsent"
1103
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
1104
+ Object.defineProperty(exports, '__esModule', {
1105
+ value: true
1106
+ });