@kywi-software/core 0.14.0 → 0.15.0

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 (478) hide show
  1. package/AGENT-PATTERNS.md +153 -17
  2. package/README.md +38 -12
  3. package/dist/admin/chrome.d.ts.map +1 -1
  4. package/dist/admin/chrome.js +6 -7
  5. package/dist/admin/chrome.js.map +1 -1
  6. package/dist/admin/field-components.d.ts.map +1 -1
  7. package/dist/admin/field-components.js +27 -1
  8. package/dist/admin/field-components.js.map +1 -1
  9. package/dist/admin/form-helpers.d.ts.map +1 -1
  10. package/dist/admin/form-helpers.js +6 -1
  11. package/dist/admin/form-helpers.js.map +1 -1
  12. package/dist/admin/layout-editor/chrome-env.d.ts +35 -0
  13. package/dist/admin/layout-editor/chrome-env.d.ts.map +1 -0
  14. package/dist/admin/layout-editor/chrome-env.js +13 -0
  15. package/dist/admin/layout-editor/chrome-env.js.map +1 -0
  16. package/dist/admin/layout-editor/component-actions.d.ts +58 -7
  17. package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
  18. package/dist/admin/layout-editor/component-actions.js +131 -5
  19. package/dist/admin/layout-editor/component-actions.js.map +1 -1
  20. package/dist/admin/layout-editor/component-fork.d.ts +4 -4
  21. package/dist/admin/layout-editor/component-fork.d.ts.map +1 -1
  22. package/dist/admin/layout-editor/component-fork.js +76 -10
  23. package/dist/admin/layout-editor/component-fork.js.map +1 -1
  24. package/dist/admin/layout-editor/component-picker-field.d.ts +17 -3
  25. package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -1
  26. package/dist/admin/layout-editor/component-picker-field.js +5 -2
  27. package/dist/admin/layout-editor/component-picker-field.js.map +1 -1
  28. package/dist/admin/layout-editor/drag-feedback.d.ts +25 -1
  29. package/dist/admin/layout-editor/drag-feedback.d.ts.map +1 -1
  30. package/dist/admin/layout-editor/drag-feedback.js +9 -0
  31. package/dist/admin/layout-editor/drag-feedback.js.map +1 -1
  32. package/dist/admin/layout-editor/drag-utils.d.ts +103 -5
  33. package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
  34. package/dist/admin/layout-editor/drag-utils.js +131 -4
  35. package/dist/admin/layout-editor/drag-utils.js.map +1 -1
  36. package/dist/admin/layout-editor/editor-canvas.d.ts +11 -0
  37. package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
  38. package/dist/admin/layout-editor/editor-canvas.js +134 -20
  39. package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
  40. package/dist/admin/layout-editor/editor-dialog.d.ts +58 -3
  41. package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -1
  42. package/dist/admin/layout-editor/editor-dialog.js +71 -9
  43. package/dist/admin/layout-editor/editor-dialog.js.map +1 -1
  44. package/dist/admin/layout-editor/editor-state.d.ts +119 -0
  45. package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
  46. package/dist/admin/layout-editor/editor-state.js +188 -6
  47. package/dist/admin/layout-editor/editor-state.js.map +1 -1
  48. package/dist/admin/layout-editor/editor-toolbar.d.ts +10 -1
  49. package/dist/admin/layout-editor/editor-toolbar.d.ts.map +1 -1
  50. package/dist/admin/layout-editor/editor-toolbar.js +2 -2
  51. package/dist/admin/layout-editor/editor-toolbar.js.map +1 -1
  52. package/dist/admin/layout-editor/editor.css +216 -8
  53. package/dist/admin/layout-editor/inline-text.d.ts +15 -1
  54. package/dist/admin/layout-editor/inline-text.d.ts.map +1 -1
  55. package/dist/admin/layout-editor/inline-text.js +30 -2
  56. package/dist/admin/layout-editor/inline-text.js.map +1 -1
  57. package/dist/admin/layout-editor/layout-editor.d.ts +21 -16
  58. package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
  59. package/dist/admin/layout-editor/layout-editor.js +40 -17
  60. package/dist/admin/layout-editor/layout-editor.js.map +1 -1
  61. package/dist/admin/layout-editor/linked-component-notes.d.ts +88 -0
  62. package/dist/admin/layout-editor/linked-component-notes.d.ts.map +1 -0
  63. package/dist/admin/layout-editor/linked-component-notes.js +88 -0
  64. package/dist/admin/layout-editor/linked-component-notes.js.map +1 -0
  65. package/dist/admin/layout-editor/module-overlay.d.ts +23 -4
  66. package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
  67. package/dist/admin/layout-editor/module-overlay.js +56 -10
  68. package/dist/admin/layout-editor/module-overlay.js.map +1 -1
  69. package/dist/admin/layout-editor/module-variant-container-config.d.ts.map +1 -1
  70. package/dist/admin/layout-editor/module-variant-container-config.js +9 -2
  71. package/dist/admin/layout-editor/module-variant-container-config.js.map +1 -1
  72. package/dist/admin/layout-editor/module-variant-container-panel.d.ts +75 -0
  73. package/dist/admin/layout-editor/module-variant-container-panel.d.ts.map +1 -0
  74. package/dist/admin/layout-editor/module-variant-container-panel.js +29 -0
  75. package/dist/admin/layout-editor/module-variant-container-panel.js.map +1 -0
  76. package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
  77. package/dist/admin/layout-editor/node-lookup.js +33 -3
  78. package/dist/admin/layout-editor/node-lookup.js.map +1 -1
  79. package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
  80. package/dist/admin/layout-editor/overlay-shell.js +19 -4
  81. package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
  82. package/dist/admin/layout-editor/props-panel.d.ts +28 -11
  83. package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
  84. package/dist/admin/layout-editor/props-panel.js +75 -125
  85. package/dist/admin/layout-editor/props-panel.js.map +1 -1
  86. package/dist/admin/layout-editor/section-variant-container-config.d.ts.map +1 -1
  87. package/dist/admin/layout-editor/section-variant-container-config.js +11 -2
  88. package/dist/admin/layout-editor/section-variant-container-config.js.map +1 -1
  89. package/dist/admin/layout-editor/use-chrome-flip.d.ts +99 -11
  90. package/dist/admin/layout-editor/use-chrome-flip.d.ts.map +1 -1
  91. package/dist/admin/layout-editor/use-chrome-flip.js +268 -97
  92. package/dist/admin/layout-editor/use-chrome-flip.js.map +1 -1
  93. package/dist/admin/layout-editor/use-component-connect.d.ts +13 -0
  94. package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -1
  95. package/dist/admin/layout-editor/use-component-connect.js +116 -20
  96. package/dist/admin/layout-editor/use-component-connect.js.map +1 -1
  97. package/dist/admin/layout-editor/use-component-fork.d.ts +49 -19
  98. package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -1
  99. package/dist/admin/layout-editor/use-component-fork.js +28 -19
  100. package/dist/admin/layout-editor/use-component-fork.js.map +1 -1
  101. package/dist/admin/layout-editor/use-component-library.d.ts +4 -4
  102. package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -1
  103. package/dist/admin/layout-editor/use-component-library.js +1 -1
  104. package/dist/admin/layout-editor/use-component-library.js.map +1 -1
  105. package/dist/admin/layout-editor/use-editor-dnd.d.ts +10 -0
  106. package/dist/admin/layout-editor/use-editor-dnd.d.ts.map +1 -1
  107. package/dist/admin/layout-editor/use-editor-dnd.js +234 -14
  108. package/dist/admin/layout-editor/use-editor-dnd.js.map +1 -1
  109. package/dist/admin/layout-editor/variant-container-config.d.ts.map +1 -1
  110. package/dist/admin/layout-editor/variant-container-config.js +1 -1
  111. package/dist/admin/layout-editor/variant-container-config.js.map +1 -1
  112. package/dist/admin/layout-editor/variant-editor.d.ts +16 -15
  113. package/dist/admin/layout-editor/variant-editor.d.ts.map +1 -1
  114. package/dist/admin/layout-editor/variant-editor.js +16 -5
  115. package/dist/admin/layout-editor/variant-editor.js.map +1 -1
  116. package/dist/admin/primitives.d.ts.map +1 -1
  117. package/dist/admin/primitives.js +1 -1
  118. package/dist/admin/primitives.js.map +1 -1
  119. package/dist/admin/registry.d.ts +12 -0
  120. package/dist/admin/registry.d.ts.map +1 -1
  121. package/dist/admin/registry.js +12 -0
  122. package/dist/admin/registry.js.map +1 -1
  123. package/dist/admin/server.d.ts +10 -1
  124. package/dist/admin/server.d.ts.map +1 -1
  125. package/dist/admin/server.js +4 -1
  126. package/dist/admin/server.js.map +1 -1
  127. package/dist/admin/site-switcher.d.ts +16 -3
  128. package/dist/admin/site-switcher.d.ts.map +1 -1
  129. package/dist/admin/site-switcher.js +18 -3
  130. package/dist/admin/site-switcher.js.map +1 -1
  131. package/dist/admin/styles/admin.css +0 -3
  132. package/dist/admin/surface-matcher.d.ts +6 -2
  133. package/dist/admin/surface-matcher.d.ts.map +1 -1
  134. package/dist/admin/surface-matcher.js +42 -5
  135. package/dist/admin/surface-matcher.js.map +1 -1
  136. package/dist/admin/surfaces/components/components-data.d.ts +31 -11
  137. package/dist/admin/surfaces/components/components-data.d.ts.map +1 -1
  138. package/dist/admin/surfaces/components/components-data.js +17 -4
  139. package/dist/admin/surfaces/components/components-data.js.map +1 -1
  140. package/dist/admin/surfaces/components/components-list.d.ts.map +1 -1
  141. package/dist/admin/surfaces/components/components-list.js +20 -7
  142. package/dist/admin/surfaces/components/components-list.js.map +1 -1
  143. package/dist/admin/surfaces/components/definition-canvas.d.ts +11 -3
  144. package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -1
  145. package/dist/admin/surfaces/components/definition-canvas.js +138 -17
  146. package/dist/admin/surfaces/components/definition-canvas.js.map +1 -1
  147. package/dist/admin/surfaces/dashboard/dashboard-index.d.ts.map +1 -1
  148. package/dist/admin/surfaces/dashboard/dashboard-index.js +2 -2
  149. package/dist/admin/surfaces/dashboard/dashboard-index.js.map +1 -1
  150. package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
  151. package/dist/admin/surfaces/layouts/layout-editor-client.js +12 -11
  152. package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
  153. package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -1
  154. package/dist/admin/surfaces/menus/menu-editor.js +17 -4
  155. package/dist/admin/surfaces/menus/menu-editor.js.map +1 -1
  156. package/dist/admin/surfaces/menus/menu-tree.d.ts +18 -4
  157. package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -1
  158. package/dist/admin/surfaces/menus/menu-tree.js +18 -3
  159. package/dist/admin/surfaces/menus/menu-tree.js.map +1 -1
  160. package/dist/admin/surfaces/menus/menus-data.d.ts +18 -0
  161. package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -1
  162. package/dist/admin/surfaces/menus/menus-data.js +4 -0
  163. package/dist/admin/surfaces/menus/menus-data.js.map +1 -1
  164. package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -1
  165. package/dist/admin/surfaces/menus/menus-list.js +2 -12
  166. package/dist/admin/surfaces/menus/menus-list.js.map +1 -1
  167. package/dist/admin/surfaces/users/users-data.d.ts +14 -0
  168. package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
  169. package/dist/admin/surfaces/users/users-data.js +19 -0
  170. package/dist/admin/surfaces/users/users-data.js.map +1 -1
  171. package/dist/admin/surfaces/users/users-detail.d.ts.map +1 -1
  172. package/dist/admin/surfaces/users/users-detail.js +40 -4
  173. package/dist/admin/surfaces/users/users-detail.js.map +1 -1
  174. package/dist/admin/surfaces/users/users-new.d.ts.map +1 -1
  175. package/dist/admin/surfaces/users/users-new.js +8 -5
  176. package/dist/admin/surfaces/users/users-new.js.map +1 -1
  177. package/dist/admin/user-form.d.ts +10 -1
  178. package/dist/admin/user-form.d.ts.map +1 -1
  179. package/dist/admin/user-form.js +2 -2
  180. package/dist/admin/user-form.js.map +1 -1
  181. package/dist/api/admin-features-routes.js +2 -2
  182. package/dist/api/admin-features-routes.js.map +1 -1
  183. package/dist/api/audience-preview-routes.d.ts +7 -0
  184. package/dist/api/audience-preview-routes.d.ts.map +1 -1
  185. package/dist/api/audience-preview-routes.js +4 -4
  186. package/dist/api/audience-preview-routes.js.map +1 -1
  187. package/dist/api/audience-routes.d.ts +7 -0
  188. package/dist/api/audience-routes.d.ts.map +1 -1
  189. package/dist/api/audience-routes.js +21 -15
  190. package/dist/api/audience-routes.js.map +1 -1
  191. package/dist/api/audience-runtime-routes.d.ts +6 -0
  192. package/dist/api/audience-runtime-routes.d.ts.map +1 -1
  193. package/dist/api/audience-runtime-routes.js +38 -3
  194. package/dist/api/audience-runtime-routes.js.map +1 -1
  195. package/dist/api/auth-routes.d.ts.map +1 -1
  196. package/dist/api/auth-routes.js +10 -4
  197. package/dist/api/auth-routes.js.map +1 -1
  198. package/dist/api/auth.d.ts +1 -0
  199. package/dist/api/auth.d.ts.map +1 -1
  200. package/dist/api/auth.js +43 -3
  201. package/dist/api/auth.js.map +1 -1
  202. package/dist/api/bulk-routes.d.ts.map +1 -1
  203. package/dist/api/bulk-routes.js +7 -7
  204. package/dist/api/bulk-routes.js.map +1 -1
  205. package/dist/api/category-routes.js +3 -3
  206. package/dist/api/category-routes.js.map +1 -1
  207. package/dist/api/comment-routes.js +8 -8
  208. package/dist/api/comment-routes.js.map +1 -1
  209. package/dist/api/component-routes.d.ts +25 -0
  210. package/dist/api/component-routes.d.ts.map +1 -1
  211. package/dist/api/component-routes.js +41 -16
  212. package/dist/api/component-routes.js.map +1 -1
  213. package/dist/api/content-routes.js +13 -13
  214. package/dist/api/content-routes.js.map +1 -1
  215. package/dist/api/dashboard-routes.js +1 -1
  216. package/dist/api/dashboard-routes.js.map +1 -1
  217. package/dist/api/experiment-routes.d.ts +7 -0
  218. package/dist/api/experiment-routes.d.ts.map +1 -1
  219. package/dist/api/experiment-routes.js +8 -8
  220. package/dist/api/experiment-routes.js.map +1 -1
  221. package/dist/api/experiment-runtime-routes.d.ts +6 -0
  222. package/dist/api/experiment-runtime-routes.d.ts.map +1 -1
  223. package/dist/api/experiment-runtime-routes.js +47 -11
  224. package/dist/api/experiment-runtime-routes.js.map +1 -1
  225. package/dist/api/feed-routes.d.ts +2 -2
  226. package/dist/api/feed-routes.js +3 -3
  227. package/dist/api/feed-routes.js.map +1 -1
  228. package/dist/api/form-routes.js +4 -4
  229. package/dist/api/form-routes.js.map +1 -1
  230. package/dist/api/graphql/resolvers.d.ts +1 -1
  231. package/dist/api/graphql/resolvers.d.ts.map +1 -1
  232. package/dist/api/graphql/resolvers.js +68 -33
  233. package/dist/api/graphql/resolvers.js.map +1 -1
  234. package/dist/api/group-routes.js +6 -6
  235. package/dist/api/group-routes.js.map +1 -1
  236. package/dist/api/index.d.ts +1 -0
  237. package/dist/api/index.d.ts.map +1 -1
  238. package/dist/api/index.js +39 -6
  239. package/dist/api/index.js.map +1 -1
  240. package/dist/api/layout-routes.d.ts.map +1 -1
  241. package/dist/api/layout-routes.js +27 -3
  242. package/dist/api/layout-routes.js.map +1 -1
  243. package/dist/api/media-routes.d.ts.map +1 -1
  244. package/dist/api/media-routes.js +50 -26
  245. package/dist/api/media-routes.js.map +1 -1
  246. package/dist/api/menu-routes.d.ts +9 -1
  247. package/dist/api/menu-routes.d.ts.map +1 -1
  248. package/dist/api/menu-routes.js +44 -10
  249. package/dist/api/menu-routes.js.map +1 -1
  250. package/dist/api/nav-routes.d.ts +6 -0
  251. package/dist/api/nav-routes.d.ts.map +1 -1
  252. package/dist/api/nav-routes.js +24 -3
  253. package/dist/api/nav-routes.js.map +1 -1
  254. package/dist/api/openapi.d.ts.map +1 -1
  255. package/dist/api/openapi.js +68 -33
  256. package/dist/api/openapi.js.map +1 -1
  257. package/dist/api/search-routes.js +2 -2
  258. package/dist/api/search-routes.js.map +1 -1
  259. package/dist/api/section-template-routes.d.ts.map +1 -1
  260. package/dist/api/section-template-routes.js +35 -18
  261. package/dist/api/section-template-routes.js.map +1 -1
  262. package/dist/api/site-admin-routes.d.ts +10 -1
  263. package/dist/api/site-admin-routes.d.ts.map +1 -1
  264. package/dist/api/site-admin-routes.js +21 -1
  265. package/dist/api/site-admin-routes.js.map +1 -1
  266. package/dist/api/site-context.d.ts +35 -5
  267. package/dist/api/site-context.d.ts.map +1 -1
  268. package/dist/api/site-context.js +21 -6
  269. package/dist/api/site-context.js.map +1 -1
  270. package/dist/api/tag-routes.js +3 -3
  271. package/dist/api/tag-routes.js.map +1 -1
  272. package/dist/api/translation-routes.js +5 -5
  273. package/dist/api/translation-routes.js.map +1 -1
  274. package/dist/api/user-routes.d.ts.map +1 -1
  275. package/dist/api/user-routes.js +134 -19
  276. package/dist/api/user-routes.js.map +1 -1
  277. package/dist/api/webhook-routes.js +5 -5
  278. package/dist/api/webhook-routes.js.map +1 -1
  279. package/dist/api/workflow-routes.js +8 -8
  280. package/dist/api/workflow-routes.js.map +1 -1
  281. package/dist/audiences/collectors/identity.d.ts +14 -1
  282. package/dist/audiences/collectors/identity.d.ts.map +1 -1
  283. package/dist/audiences/collectors/identity.js +16 -3
  284. package/dist/audiences/collectors/identity.js.map +1 -1
  285. package/dist/audiences/collectors/index.d.ts +12 -2
  286. package/dist/audiences/collectors/index.d.ts.map +1 -1
  287. package/dist/audiences/collectors/index.js +16 -5
  288. package/dist/audiences/collectors/index.js.map +1 -1
  289. package/dist/audiences/collectors/pinned-audience.d.ts +28 -2
  290. package/dist/audiences/collectors/pinned-audience.d.ts.map +1 -1
  291. package/dist/audiences/collectors/pinned-audience.js +35 -5
  292. package/dist/audiences/collectors/pinned-audience.js.map +1 -1
  293. package/dist/audiences/collectors/utm.d.ts +15 -1
  294. package/dist/audiences/collectors/utm.d.ts.map +1 -1
  295. package/dist/audiences/collectors/utm.js +16 -2
  296. package/dist/audiences/collectors/utm.js.map +1 -1
  297. package/dist/audiences/consent-config.d.ts +21 -0
  298. package/dist/audiences/consent-config.d.ts.map +1 -0
  299. package/dist/audiences/consent-config.js +15 -0
  300. package/dist/audiences/consent-config.js.map +1 -0
  301. package/dist/audiences/consent-startup.d.ts +39 -0
  302. package/dist/audiences/consent-startup.d.ts.map +1 -0
  303. package/dist/audiences/consent-startup.js +105 -0
  304. package/dist/audiences/consent-startup.js.map +1 -0
  305. package/dist/audiences/consent.d.ts +192 -0
  306. package/dist/audiences/consent.d.ts.map +1 -0
  307. package/dist/audiences/consent.js +322 -0
  308. package/dist/audiences/consent.js.map +1 -0
  309. package/dist/audiences/engine.d.ts +7 -0
  310. package/dist/audiences/engine.d.ts.map +1 -1
  311. package/dist/audiences/engine.js +6 -2
  312. package/dist/audiences/engine.js.map +1 -1
  313. package/dist/audiences/index.d.ts +3 -0
  314. package/dist/audiences/index.d.ts.map +1 -1
  315. package/dist/audiences/index.js +6 -0
  316. package/dist/audiences/index.js.map +1 -1
  317. package/dist/audiences/server-eval.d.ts +13 -1
  318. package/dist/audiences/server-eval.d.ts.map +1 -1
  319. package/dist/audiences/server-eval.js +18 -2
  320. package/dist/audiences/server-eval.js.map +1 -1
  321. package/dist/audiences/ssr.d.ts +18 -1
  322. package/dist/audiences/ssr.d.ts.map +1 -1
  323. package/dist/audiences/ssr.js +18 -1
  324. package/dist/audiences/ssr.js.map +1 -1
  325. package/dist/audiences/utm-persistence.d.ts +20 -7
  326. package/dist/audiences/utm-persistence.d.ts.map +1 -1
  327. package/dist/audiences/utm-persistence.js +20 -7
  328. package/dist/audiences/utm-persistence.js.map +1 -1
  329. package/dist/auth/roles.d.ts +11 -0
  330. package/dist/auth/roles.d.ts.map +1 -1
  331. package/dist/auth/roles.js +13 -0
  332. package/dist/auth/roles.js.map +1 -1
  333. package/dist/auth/tokens.d.ts +7 -0
  334. package/dist/auth/tokens.d.ts.map +1 -1
  335. package/dist/auth/tokens.js +24 -2
  336. package/dist/auth/tokens.js.map +1 -1
  337. package/dist/config/types.d.ts +43 -0
  338. package/dist/config/types.d.ts.map +1 -1
  339. package/dist/config/types.js.map +1 -1
  340. package/dist/config/validate.d.ts.map +1 -1
  341. package/dist/config/validate.js +3 -0
  342. package/dist/config/validate.js.map +1 -1
  343. package/dist/db/apply-snapshot.d.ts +18 -0
  344. package/dist/db/apply-snapshot.d.ts.map +1 -1
  345. package/dist/db/apply-snapshot.js +41 -16
  346. package/dist/db/apply-snapshot.js.map +1 -1
  347. package/dist/db/component-instance-queries.d.ts +79 -19
  348. package/dist/db/component-instance-queries.d.ts.map +1 -1
  349. package/dist/db/component-instance-queries.js +266 -83
  350. package/dist/db/component-instance-queries.js.map +1 -1
  351. package/dist/db/component-queries.d.ts +1 -16
  352. package/dist/db/component-queries.d.ts.map +1 -1
  353. package/dist/db/component-queries.js +7 -56
  354. package/dist/db/component-queries.js.map +1 -1
  355. package/dist/db/content-queries.d.ts.map +1 -1
  356. package/dist/db/content-queries.js +1 -2
  357. package/dist/db/content-queries.js.map +1 -1
  358. package/dist/db/extension-queries.d.ts +2 -2
  359. package/dist/db/feed-queries.d.ts +3 -3
  360. package/dist/db/index.d.ts +1 -0
  361. package/dist/db/index.d.ts.map +1 -1
  362. package/dist/db/index.js +1 -0
  363. package/dist/db/index.js.map +1 -1
  364. package/dist/db/layout-queries.d.ts +2 -1
  365. package/dist/db/layout-queries.d.ts.map +1 -1
  366. package/dist/db/layout-queries.js +3 -3
  367. package/dist/db/layout-queries.js.map +1 -1
  368. package/dist/db/menu-queries.d.ts +69 -5
  369. package/dist/db/menu-queries.d.ts.map +1 -1
  370. package/dist/db/menu-queries.js +120 -13
  371. package/dist/db/menu-queries.js.map +1 -1
  372. package/dist/db/section-template-queries.d.ts +62 -0
  373. package/dist/db/section-template-queries.d.ts.map +1 -0
  374. package/dist/db/section-template-queries.js +178 -0
  375. package/dist/db/section-template-queries.js.map +1 -0
  376. package/dist/db/site-plugin-queries.d.ts +2 -2
  377. package/dist/db/tree-queries.d.ts.map +1 -1
  378. package/dist/db/tree-queries.js +5 -0
  379. package/dist/db/tree-queries.js.map +1 -1
  380. package/dist/db/webhook-queries.d.ts +3 -3
  381. package/dist/db/workflow-queries.d.ts.map +1 -1
  382. package/dist/db/workflow-queries.js +5 -20
  383. package/dist/db/workflow-queries.js.map +1 -1
  384. package/dist/experiments/runtime.d.ts +21 -3
  385. package/dist/experiments/runtime.d.ts.map +1 -1
  386. package/dist/experiments/runtime.js +21 -3
  387. package/dist/experiments/runtime.js.map +1 -1
  388. package/dist/layout/component-refs.d.ts +90 -2
  389. package/dist/layout/component-refs.d.ts.map +1 -1
  390. package/dist/layout/component-refs.js +293 -16
  391. package/dist/layout/component-refs.js.map +1 -1
  392. package/dist/layout/index.d.ts +4 -3
  393. package/dist/layout/index.d.ts.map +1 -1
  394. package/dist/layout/index.js +3 -2
  395. package/dist/layout/index.js.map +1 -1
  396. package/dist/layout/legacy-variant-container.d.ts +123 -0
  397. package/dist/layout/legacy-variant-container.d.ts.map +1 -0
  398. package/dist/layout/legacy-variant-container.js +397 -0
  399. package/dist/layout/legacy-variant-container.js.map +1 -0
  400. package/dist/layout/module-permissions.d.ts.map +1 -1
  401. package/dist/layout/module-permissions.js +25 -1
  402. package/dist/layout/module-permissions.js.map +1 -1
  403. package/dist/layout/modules-extended.d.ts +28 -1
  404. package/dist/layout/modules-extended.d.ts.map +1 -1
  405. package/dist/layout/modules-extended.js +73 -1
  406. package/dist/layout/modules-extended.js.map +1 -1
  407. package/dist/layout/modules.d.ts.map +1 -1
  408. package/dist/layout/modules.js +9 -1
  409. package/dist/layout/modules.js.map +1 -1
  410. package/dist/layout/personalization.d.ts +83 -0
  411. package/dist/layout/personalization.d.ts.map +1 -1
  412. package/dist/layout/personalization.js +250 -4
  413. package/dist/layout/personalization.js.map +1 -1
  414. package/dist/layout/registry.d.ts.map +1 -1
  415. package/dist/layout/registry.js +20 -0
  416. package/dist/layout/registry.js.map +1 -1
  417. package/dist/layout/renderer.d.ts +29 -2
  418. package/dist/layout/renderer.d.ts.map +1 -1
  419. package/dist/layout/renderer.js +23 -6
  420. package/dist/layout/renderer.js.map +1 -1
  421. package/dist/layout/types.d.ts +17 -0
  422. package/dist/layout/types.d.ts.map +1 -1
  423. package/dist/layout/types.js +7 -0
  424. package/dist/layout/types.js.map +1 -1
  425. package/dist/media/inline-risk.d.ts +26 -0
  426. package/dist/media/inline-risk.d.ts.map +1 -0
  427. package/dist/media/inline-risk.js +142 -0
  428. package/dist/media/inline-risk.js.map +1 -0
  429. package/dist/nav/builder.d.ts.map +1 -1
  430. package/dist/nav/builder.js +15 -3
  431. package/dist/nav/builder.js.map +1 -1
  432. package/dist/nav/index.d.ts +1 -1
  433. package/dist/nav/index.d.ts.map +1 -1
  434. package/dist/nav/index.js +1 -1
  435. package/dist/nav/index.js.map +1 -1
  436. package/dist/nav/menu-resolver.d.ts +11 -0
  437. package/dist/nav/menu-resolver.d.ts.map +1 -1
  438. package/dist/nav/menu-resolver.js +49 -9
  439. package/dist/nav/menu-resolver.js.map +1 -1
  440. package/dist/nav/paths.d.ts +37 -0
  441. package/dist/nav/paths.d.ts.map +1 -0
  442. package/dist/nav/paths.js +48 -0
  443. package/dist/nav/paths.js.map +1 -0
  444. package/dist/nav/types.d.ts +6 -0
  445. package/dist/nav/types.d.ts.map +1 -1
  446. package/dist/nav/url-resolver.d.ts +1 -5
  447. package/dist/nav/url-resolver.d.ts.map +1 -1
  448. package/dist/nav/url-resolver.js +6 -12
  449. package/dist/nav/url-resolver.js.map +1 -1
  450. package/dist/schema/base.d.ts +24 -4
  451. package/dist/schema/base.d.ts.map +1 -1
  452. package/dist/schema/base.js +17 -4
  453. package/dist/schema/base.js.map +1 -1
  454. package/dist/schema/components.d.ts +90 -9
  455. package/dist/schema/components.d.ts.map +1 -1
  456. package/dist/schema/components.js +113 -22
  457. package/dist/schema/components.js.map +1 -1
  458. package/dist/schema/mysql-tables.d.ts +5758 -48
  459. package/dist/schema/mysql-tables.d.ts.map +1 -1
  460. package/dist/schema/mysql-tables.js +620 -46
  461. package/dist/schema/mysql-tables.js.map +1 -1
  462. package/dist/scope/kywi-form.d.ts +11 -0
  463. package/dist/scope/kywi-form.d.ts.map +1 -1
  464. package/dist/scope/kywi-form.js +11 -1
  465. package/dist/scope/kywi-form.js.map +1 -1
  466. package/dist/scope/kywi-wizard-form.d.ts.map +1 -1
  467. package/dist/scope/kywi-wizard-form.js +76 -2
  468. package/dist/scope/kywi-wizard-form.js.map +1 -1
  469. package/dist/scope/sticky-offset.d.ts +34 -13
  470. package/dist/scope/sticky-offset.d.ts.map +1 -1
  471. package/dist/scope/sticky-offset.js +236 -43
  472. package/dist/scope/sticky-offset.js.map +1 -1
  473. package/dist/site/styles.css +61 -15
  474. package/dist/versioning/scheduler.d.ts +28 -0
  475. package/dist/versioning/scheduler.d.ts.map +1 -1
  476. package/dist/versioning/scheduler.js +50 -3
  477. package/dist/versioning/scheduler.js.map +1 -1
  478. package/package.json +7 -2
@@ -1,7 +1,20 @@
1
1
  import { COOKIE_NAMES } from '../cookies.js';
2
- export function collectIdentity(cookies) {
3
- const visitorId = cookies.get(COOKIE_NAMES.VISITOR) ?? '';
4
- const knownRaw = cookies.get(COOKIE_NAMES.KNOWN);
2
+ import { cookieAllowed, readConsentFromCookieHeader } from '../consent.js';
3
+ /**
4
+ * Read the visitor's stored identity — the `kywi_visitor` id and the
5
+ * adapter-pushed `kywi_known` flag.
6
+ *
7
+ * Both are `personalization` cookies, so both are treated as ABSENT unless the
8
+ * visitor consents (kywi-cms#91): a visitor who rejects must stop being
9
+ * recognised, not merely stop accumulating new cookies. An empty `visitorId` is
10
+ * already the "no identity yet" value every caller handles — the request still
11
+ * resolves and renders, anonymously.
12
+ */
13
+ export function collectIdentity(cookies, gate = {}) {
14
+ const consent = readConsentFromCookieHeader(gate.cookieHeader);
15
+ const mayRead = (name) => cookieAllowed(name, consent, gate);
16
+ const visitorId = (mayRead(COOKIE_NAMES.VISITOR) ? cookies.get(COOKIE_NAMES.VISITOR) : undefined) ?? '';
17
+ const knownRaw = mayRead(COOKIE_NAMES.KNOWN) ? cookies.get(COOKIE_NAMES.KNOWN) : undefined;
5
18
  let isKnown = false;
6
19
  let maLeadId = null;
7
20
  if (knownRaw) {
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/audiences/collectors/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAQ5C,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAChD,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,QAAQ,GAAkB,IAAI,CAAA;IAClC,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAA0B,CAAA;YAC1D,OAAO,GAAG,IAAI,CAAA;YACd,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;AACzC,CAAC"}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/audiences/collectors/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAA2B,MAAM,eAAe,CAAA;AAQnG;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA4B,EAC5B,OAA8D,EAAE;IAEhE,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC9D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACvG,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC1F,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,QAAQ,GAAkB,IAAI,CAAA;IAClC,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAA0B,CAAA;YAC1D,OAAO,GAAG,IAAI,CAAA;YACd,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;AACzC,CAAC"}
@@ -2,7 +2,17 @@ export { collectUtm, type UtmSignals } from './utm.js';
2
2
  export { collectReferrer, classifyReferrer, type ReferrerSignals, type ReferrerSourceType } from './referrer.js';
3
3
  export { collectIdentity, type IdentitySignals } from './identity.js';
4
4
  export { collectOptOut } from './opt-out.js';
5
- export { collectPinnedAudience } from './pinned-audience.js';
5
+ export { collectPinnedAudience, parseAudiencePin, buildAudiencePinValue, type AudiencePin, } from './pinned-audience.js';
6
6
  import type { VisitorSignals } from '../types.js';
7
- export declare function runServerCollectors(req: Request): Partial<VisitorSignals>;
7
+ import type { ConsentGateOptions } from '../consent.js';
8
+ /**
9
+ * Collect every server-resolvable signal off the request.
10
+ *
11
+ * The personalization-category cookies (`kywi_utm`, `kywi_visitor`,
12
+ * `kywi_known`) are read only for a consenting visitor — pass `requireConsent:
13
+ * false` to turn that off for a site whose consent lives in external tooling
14
+ * (kywi-cms#91). Un-stored signals (this URL's `utm_*` params, the referrer) are
15
+ * always collected: they are the request itself, not tracking carried into it.
16
+ */
17
+ export declare function runServerCollectors(req: Request, gate?: ConsentGateOptions): Partial<VisitorSignals>;
8
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAChH,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAOjD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAYzE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAChH,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAMjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAczB"}
@@ -2,17 +2,28 @@ export { collectUtm } from './utm.js';
2
2
  export { collectReferrer, classifyReferrer } from './referrer.js';
3
3
  export { collectIdentity } from './identity.js';
4
4
  export { collectOptOut } from './opt-out.js';
5
- export { collectPinnedAudience } from './pinned-audience.js';
5
+ export { collectPinnedAudience, parseAudiencePin, buildAudiencePinValue, } from './pinned-audience.js';
6
6
  import { parseCookies } from '../cookies.js';
7
7
  import { collectUtm } from './utm.js';
8
8
  import { collectReferrer } from './referrer.js';
9
9
  import { collectIdentity } from './identity.js';
10
10
  import { collectOptOut } from './opt-out.js';
11
- export function runServerCollectors(req) {
12
- const cookies = parseCookies(req.headers.get('cookie') ?? '');
13
- const utm = collectUtm(req, cookies);
11
+ /**
12
+ * Collect every server-resolvable signal off the request.
13
+ *
14
+ * The personalization-category cookies (`kywi_utm`, `kywi_visitor`,
15
+ * `kywi_known`) are read only for a consenting visitor — pass `requireConsent:
16
+ * false` to turn that off for a site whose consent lives in external tooling
17
+ * (kywi-cms#91). Un-stored signals (this URL's `utm_*` params, the referrer) are
18
+ * always collected: they are the request itself, not tracking carried into it.
19
+ */
20
+ export function runServerCollectors(req, gate = {}) {
21
+ const cookieHeader = req.headers.get('cookie');
22
+ const cookies = parseCookies(cookieHeader ?? '');
23
+ const readGate = { ...gate, cookieHeader };
24
+ const utm = collectUtm(req, cookies, readGate);
14
25
  const referrer = collectReferrer(req, utm.medium);
15
- const identity = collectIdentity(cookies);
26
+ const identity = collectIdentity(cookies, readGate);
16
27
  const isOptedOut = collectOptOut(cookies);
17
28
  return {
18
29
  utm,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/audiences/collectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAiD,MAAM,eAAe,CAAA;AAChH,OAAO,EAAE,eAAe,EAAwB,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAG5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAC7D,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IACzC,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACzC,OAAO;QACL,GAAG;QACH,QAAQ;QACR,QAAQ;QACR,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE;KACtF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/audiences/collectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAiD,MAAM,eAAe,CAAA;AAChH,OAAO,EAAE,eAAe,EAAwB,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GAEtB,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAG5C;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAY,EACZ,OAA2B,EAAE;IAE7B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;IAChD,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,CAAA;IAC1C,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACnD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACzC,OAAO;QACL,GAAG;QACH,QAAQ;QACR,QAAQ;QACR,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE;KACtF,CAAA;AACH,CAAC"}
@@ -1,4 +1,27 @@
1
+ import { type ConsentGateOptions } from '../consent.js';
1
2
  import type { Audience } from '../types.js';
3
+ /**
4
+ * The `kywi_audience` cookie's value, which records HOW the pin was made.
5
+ *
6
+ * Two writes share this cookie and they carry different consent weight
7
+ * (kywi-cms#91): the runtime automatically remembering what it resolved is
8
+ * `personalization` tracking, while an audience the visitor picked by hand in
9
+ * the transparency panel is an `essential` preference. The cookie has to say
10
+ * which, or the read side cannot apply the right rule and a hand-picked audience
11
+ * would be stored and then silently ignored.
12
+ */
13
+ export interface AudiencePin {
14
+ id: string;
15
+ /** The visitor chose this deliberately, so it is an `essential` preference. */
16
+ viaSwitcher: boolean;
17
+ }
18
+ /** Encode a pin for the `kywi_audience` cookie. */
19
+ export declare function buildAudiencePinValue(id: string, viaSwitcher: boolean): string;
20
+ /**
21
+ * Decode a `kywi_audience` cookie value. A bare id — every cookie written before
22
+ * kywi-cms#91, and every boot pin since — reads as a non-switcher pin.
23
+ */
24
+ export declare function parseAudiencePin(raw: string | undefined | null): AudiencePin | null;
2
25
  /**
3
26
  * Read the client-pinned audience (`kywi_audience` cookie).
4
27
  *
@@ -11,7 +34,10 @@ import type { Audience } from '../types.js';
11
34
  * and deletes it), so the id is untrusted input: it is only honoured when it
12
35
  * names a *currently-active* audience for this render. A stale, forged, or
13
36
  * archived id is treated as absent — the caller falls through to signal-derived
14
- * resolution and the render never errors.
37
+ * resolution and the render never errors. So is a pin the visitor has not
38
+ * consented to being remembered by.
15
39
  */
16
- export declare function collectPinnedAudience(cookies: Map<string, string>, activeAudiences: Audience[]): string | null;
40
+ export declare function collectPinnedAudience(cookies: Map<string, string>, activeAudiences: Audience[], gate?: ConsentGateOptions & {
41
+ cookieHeader?: string | null;
42
+ }): string | null;
17
43
  //# sourceMappingURL=pinned-audience.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-audience.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/pinned-audience.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,eAAe,EAAE,QAAQ,EAAE,GAC1B,MAAM,GAAG,IAAI,CAIf"}
1
+ {"version":3,"file":"pinned-audience.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/pinned-audience.ts"],"names":[],"mappings":"AACA,OAAO,EAA8C,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACnG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,+EAA+E;IAC/E,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAK9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAOnF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,eAAe,EAAE,QAAQ,EAAE,EAC3B,IAAI,GAAE,kBAAkB,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC/D,MAAM,GAAG,IAAI,CAYf"}
@@ -1,4 +1,25 @@
1
1
  import { COOKIE_NAMES } from '../cookies.js';
2
+ import { cookieAllowedByHeader, SWITCHER_PIN_PREFIX } from '../consent.js';
3
+ /** Encode a pin for the `kywi_audience` cookie. */
4
+ export function buildAudiencePinValue(id, viaSwitcher) {
5
+ // A plain id stays a plain id: the un-prefixed form is what every version
6
+ // before kywi-cms#91 wrote, and keeping it means an existing cookie survives
7
+ // the upgrade reading exactly as it always did (as a boot pin).
8
+ return viaSwitcher ? `${SWITCHER_PIN_PREFIX}${id}` : id;
9
+ }
10
+ /**
11
+ * Decode a `kywi_audience` cookie value. A bare id — every cookie written before
12
+ * kywi-cms#91, and every boot pin since — reads as a non-switcher pin.
13
+ */
14
+ export function parseAudiencePin(raw) {
15
+ if (!raw)
16
+ return null;
17
+ if (raw.startsWith(SWITCHER_PIN_PREFIX)) {
18
+ const id = raw.slice(SWITCHER_PIN_PREFIX.length);
19
+ return id ? { id, viaSwitcher: true } : null;
20
+ }
21
+ return { id: raw, viaSwitcher: false };
22
+ }
2
23
  /**
3
24
  * Read the client-pinned audience (`kywi_audience` cookie).
4
25
  *
@@ -11,12 +32,21 @@ import { COOKIE_NAMES } from '../cookies.js';
11
32
  * and deletes it), so the id is untrusted input: it is only honoured when it
12
33
  * names a *currently-active* audience for this render. A stale, forged, or
13
34
  * archived id is treated as absent — the caller falls through to signal-derived
14
- * resolution and the render never errors.
35
+ * resolution and the render never errors. So is a pin the visitor has not
36
+ * consented to being remembered by.
15
37
  */
16
- export function collectPinnedAudience(cookies, activeAudiences) {
17
- const pinned = cookies.get(COOKIE_NAMES.AUDIENCE);
18
- if (!pinned)
38
+ export function collectPinnedAudience(cookies, activeAudiences, gate = {}) {
39
+ const pin = parseAudiencePin(cookies.get(COOKIE_NAMES.AUDIENCE));
40
+ if (!pin)
41
+ return null;
42
+ // An automatic pin is `personalization`: a visitor who rejects stops being
43
+ // resolved from tracking they no longer consent to. A pin they set by hand is
44
+ // `essential` and is honoured either way — refusing to act on the switcher
45
+ // they just used would make the panel lie about what its buttons do
46
+ // (kywi-cms#91).
47
+ if (!pin.viaSwitcher && !cookieAllowedByHeader(COOKIE_NAMES.AUDIENCE, gate.cookieHeader, gate)) {
19
48
  return null;
20
- return activeAudiences.some((a) => a.id === pinned) ? pinned : null;
49
+ }
50
+ return activeAudiences.some((a) => a.id === pin.id) ? pin.id : null;
21
51
  }
22
52
  //# sourceMappingURL=pinned-audience.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-audience.js","sourceRoot":"","sources":["../../../src/audiences/collectors/pinned-audience.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA4B,EAC5B,eAA2B;IAE3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;IACjD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AACrE,CAAC"}
1
+ {"version":3,"file":"pinned-audience.js","sourceRoot":"","sources":["../../../src/audiences/collectors/pinned-audience.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAA2B,MAAM,eAAe,CAAA;AAmBnG,mDAAmD;AACnD,MAAM,UAAU,qBAAqB,CAAC,EAAU,EAAE,WAAoB;IACpE,0EAA0E;IAC1E,6EAA6E;IAC7E,gEAAgE;IAChE,OAAO,WAAW,CAAC,CAAC,CAAC,GAAG,mBAAmB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAA8B;IAC7D,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,IAAI,GAAG,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAA;QAChD,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9C,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;AACxC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA4B,EAC5B,eAA2B,EAC3B,OAA8D,EAAE;IAEhE,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChE,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,2EAA2E;IAC3E,8EAA8E;IAC9E,2EAA2E;IAC3E,oEAAoE;IACpE,iBAAiB;IACjB,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/F,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACrE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { type ConsentGateOptions } from '../consent.js';
1
2
  export interface UtmSignals {
2
3
  source: string | null;
3
4
  medium: string | null;
@@ -5,5 +6,18 @@ export interface UtmSignals {
5
6
  term: string | null;
6
7
  content: string | null;
7
8
  }
8
- export declare function collectUtm(req: Request, cookies: Map<string, string>): UtmSignals;
9
+ /**
10
+ * Resolve the visitor's UTM attribution: this request's `utm_*` query params,
11
+ * falling back to the persisted `kywi_utm` cookie.
12
+ *
13
+ * The cookie fallback is IGNORED unless the visitor consents to personalization
14
+ * (kywi-cms#91). Blocking the write alone would not be enough — a visitor who
15
+ * accepted last month and rejects today still carries the cookie, and reading it
16
+ * would keep them in a campaign audience they just opted out of. The URL's own
17
+ * `utm_*` params are always honoured: they are this request's content, not
18
+ * stored tracking.
19
+ */
20
+ export declare function collectUtm(req: Request, cookies: Map<string, string>, gate?: ConsentGateOptions & {
21
+ cookieHeader?: string | null;
22
+ }): UtmSignals;
9
23
  //# sourceMappingURL=utm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utm.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/utm.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAcjF"}
1
+ {"version":3,"file":"utm.d.ts","sourceRoot":"","sources":["../../../src/audiences/collectors/utm.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAE9E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,IAAI,GAAE,kBAAkB,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC/D,UAAU,CAgBZ"}
@@ -1,8 +1,22 @@
1
1
  import { COOKIE_NAMES } from '../cookies.js';
2
- export function collectUtm(req, cookies) {
2
+ import { cookieAllowedByHeader } from '../consent.js';
3
+ /**
4
+ * Resolve the visitor's UTM attribution: this request's `utm_*` query params,
5
+ * falling back to the persisted `kywi_utm` cookie.
6
+ *
7
+ * The cookie fallback is IGNORED unless the visitor consents to personalization
8
+ * (kywi-cms#91). Blocking the write alone would not be enough — a visitor who
9
+ * accepted last month and rejects today still carries the cookie, and reading it
10
+ * would keep them in a campaign audience they just opted out of. The URL's own
11
+ * `utm_*` params are always honoured: they are this request's content, not
12
+ * stored tracking.
13
+ */
14
+ export function collectUtm(req, cookies, gate = {}) {
3
15
  const url = new URL(req.url);
4
16
  let cookieUtm = {};
5
- const raw = cookies.get(COOKIE_NAMES.UTM);
17
+ const raw = cookieAllowedByHeader(COOKIE_NAMES.UTM, gate.cookieHeader ?? req.headers.get('cookie'), gate)
18
+ ? cookies.get(COOKIE_NAMES.UTM)
19
+ : undefined;
6
20
  if (raw) {
7
21
  try {
8
22
  cookieUtm = JSON.parse(raw);
@@ -1 +1 @@
1
- {"version":3,"file":"utm.js","sourceRoot":"","sources":["../../../src/audiences/collectors/utm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAU5C,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,OAA4B;IACnE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,SAAS,GAAwB,EAAE,CAAA;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;IACzC,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC;IACD,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI;QACtE,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI;QACtE,QAAQ,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,QAAQ,IAAI,IAAI;QAC5E,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,IAAI,IAAI,IAAI;QAChE,OAAO,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,OAAO,IAAI,IAAI;KAC1E,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"utm.js","sourceRoot":"","sources":["../../../src/audiences/collectors/utm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAA2B,MAAM,eAAe,CAAA;AAU9E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CACxB,GAAY,EACZ,OAA4B,EAC5B,OAA8D,EAAE;IAEhE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,SAAS,GAAwB,EAAE,CAAA;IACvC,MAAM,GAAG,GAAG,qBAAqB,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;QACvG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC;QAC/B,CAAC,CAAC,SAAS,CAAA;IACb,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC;IACD,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI;QACtE,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,IAAI;QACtE,QAAQ,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,QAAQ,IAAI,IAAI;QAC5E,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,IAAI,IAAI,IAAI;QAChE,OAAO,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,OAAO,IAAI,IAAI;KAC1E,CAAA;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Resolve `theme.personalization.requireConsent` from a `KywiConfig`
3
+ * (kywi-cms#91).
4
+ *
5
+ * Kept out of `./consent.ts` because that module must import nothing at all —
6
+ * it is pulled into Next.js edge middleware. This file's only import is a TYPE,
7
+ * which erases at compile time, but it lives next door rather than inside the
8
+ * gate so the edge entry stays obviously dependency-free.
9
+ */
10
+ import type { KywiConfig } from '../config/types.js';
11
+ /**
12
+ * Does this site require consent before personalization cookies are written?
13
+ *
14
+ * **True unless a theme explicitly opts out.** The flag lives on the theme, so
15
+ * it resolves the same way `clientRuntimeEnabled` / `transparencyNoticeEnabled`
16
+ * do in the reference app: the named site's theme, falling back to the first
17
+ * site's theme and then the first theme declared. A site with no theme at all
18
+ * requires consent — the safe answer is the default answer.
19
+ */
20
+ export declare function personalizationRequiresConsent(config: KywiConfig, siteId?: string): boolean;
21
+ //# sourceMappingURL=consent-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-config.d.ts","sourceRoot":"","sources":["../../src/audiences/consent-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3F"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Does this site require consent before personalization cookies are written?
3
+ *
4
+ * **True unless a theme explicitly opts out.** The flag lives on the theme, so
5
+ * it resolves the same way `clientRuntimeEnabled` / `transparencyNoticeEnabled`
6
+ * do in the reference app: the named site's theme, falling back to the first
7
+ * site's theme and then the first theme declared. A site with no theme at all
8
+ * requires consent — the safe answer is the default answer.
9
+ */
10
+ export function personalizationRequiresConsent(config, siteId) {
11
+ const site = (siteId ? config.sites.find((s) => s.id === siteId) : undefined) ?? config.sites[0];
12
+ const theme = config.themes.find((t) => t.name === site?.theme) ?? config.themes[0];
13
+ return theme?.personalization?.requireConsent !== false;
14
+ }
15
+ //# sourceMappingURL=consent-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-config.js","sourceRoot":"","sources":["../../src/audiences/consent-config.ts"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAAkB,EAAE,MAAe;IAChF,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChG,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACnF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,KAAK,KAAK,CAAA;AACzD,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { KywiDb } from '../db/client.js';
2
+ /** The env var mirroring `theme.personalization.requireConsent` for edge middleware. */
3
+ export declare const REQUIRE_CONSENT_ENV = "KYWI_REQUIRE_CONSENT";
4
+ /** How `middleware.ts` reads the mirror: anything but the literal "false" is true. */
5
+ export declare function requireConsentFromEnv(env?: Record<string, string | undefined>): boolean;
6
+ /**
7
+ * Fail startup when the config flag and its edge mirror disagree.
8
+ *
9
+ * Deliberately a throw and not a warning: the two halves of one setting pointing
10
+ * opposite ways is never intentional, and the resulting behaviour (cookies
11
+ * written by the edge that the API then declines to read, or vice versa) is
12
+ * exactly the kind of bug that survives to production because nothing is
13
+ * visibly broken.
14
+ */
15
+ export declare function assertConsentEnvAgreement(requireConsentFromConfig: boolean, env?: Record<string, string | undefined>): void;
16
+ /**
17
+ * Build the once-only "consent required, but nothing asks for it" check.
18
+ *
19
+ * Returns a function safe to call on every request: it runs at most once, never
20
+ * awaits (the first request does not pay for it), and swallows every error. A
21
+ * warning that could break a page, or add latency to the hot path, would not be
22
+ * worth having.
23
+ *
24
+ * The check is a `::text LIKE` prefilter — the same shape
25
+ * `checkAudienceDeletionSafety` uses — looking for anything that mentions the
26
+ * module type at all. Over-matching is fine here: a false negative (staying
27
+ * quiet) is the safe direction for an advisory warning.
28
+ *
29
+ * It reads BOTH places a module can be placed: `kywi_content.layout` and
30
+ * `kywi_section_templates.definition`. A banner composed from a blueprint is a
31
+ * banner, and scanning pages alone told a site that builds every page that way
32
+ * that consent could never be granted — while the banner was on screen.
33
+ */
34
+ export declare function createConsentBannerCheck(deps: {
35
+ db: KywiDb;
36
+ requireConsent: boolean;
37
+ warn?: (message: string) => void;
38
+ }): () => void;
39
+ //# sourceMappingURL=consent-startup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-startup.d.ts","sourceRoot":"","sources":["../../src/audiences/consent-startup.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,yBAAyB,CAAA;AAEzD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,OAAO,CAEpG;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,wBAAwB,EAAE,OAAO,EACjC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,IAAI,CAcN;AASD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,cAAc,EAAE,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,MAAM,IAAI,CA8Bb"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Startup checks for the cookie-consent gate (kywi-cms#91).
3
+ *
4
+ * Two failure modes are invisible at runtime and expensive to discover later:
5
+ *
6
+ * 1. The config flag and its edge mirror disagree. `middleware.ts` runs on the
7
+ * edge and cannot read `kywi.config.ts`, so `requireConsent` is mirrored as
8
+ * `KYWI_REQUIRE_CONSENT`. If the two drift, the middleware and the API
9
+ * disagree about whether a visitor may be tracked — one writes
10
+ * `kywi_visitor`, the other refuses to read it — and nothing anywhere says
11
+ * so. That is a misconfiguration, and it fails the deploy.
12
+ *
13
+ * 2. Consent is required and no page offers a way to give it. Every
14
+ * personalization cookie is then permanently suppressed: audiences,
15
+ * experiments and UTM attribution quietly do nothing, and the site looks
16
+ * broken rather than gated. That is a WARNING, not an error — a site may
17
+ * legitimately have no personalization at all — but it must be said out
18
+ * loud, once, rather than left for someone to debug.
19
+ */
20
+ import { sql } from 'drizzle-orm';
21
+ /** The env var mirroring `theme.personalization.requireConsent` for edge middleware. */
22
+ export const REQUIRE_CONSENT_ENV = 'KYWI_REQUIRE_CONSENT';
23
+ /** How `middleware.ts` reads the mirror: anything but the literal "false" is true. */
24
+ export function requireConsentFromEnv(env = process.env) {
25
+ return env[REQUIRE_CONSENT_ENV] !== 'false';
26
+ }
27
+ /**
28
+ * Fail startup when the config flag and its edge mirror disagree.
29
+ *
30
+ * Deliberately a throw and not a warning: the two halves of one setting pointing
31
+ * opposite ways is never intentional, and the resulting behaviour (cookies
32
+ * written by the edge that the API then declines to read, or vice versa) is
33
+ * exactly the kind of bug that survives to production because nothing is
34
+ * visibly broken.
35
+ */
36
+ export function assertConsentEnvAgreement(requireConsentFromConfig, env = process.env) {
37
+ const fromEnv = requireConsentFromEnv(env);
38
+ if (fromEnv === requireConsentFromConfig)
39
+ return;
40
+ const raw = env[REQUIRE_CONSENT_ENV];
41
+ throw new Error(`Cookie-consent misconfiguration: theme.personalization.requireConsent is ` +
42
+ `${requireConsentFromConfig} but ${REQUIRE_CONSENT_ENV} is ` +
43
+ `${raw === undefined ? 'unset (which means true)' : JSON.stringify(raw)}.\n` +
44
+ ` Next.js edge middleware cannot read kywi.config.ts, so it mirrors that flag ` +
45
+ `through ${REQUIRE_CONSENT_ENV}. While they disagree, the middleware and the API ` +
46
+ `disagree about whether a visitor may be tracked.\n` +
47
+ ` Set both, or neither: ${REQUIRE_CONSENT_ENV}=false alongside ` +
48
+ `personalization: { requireConsent: false }, or remove both.`);
49
+ }
50
+ const NO_BANNER_WARNING = '[kywi] Cookie consent is required (theme.personalization.requireConsent) but no ' +
51
+ 'page or layout places the `cookieConsent` module, so no visitor can ever grant it. ' +
52
+ 'Every personalization cookie stays suppressed: audiences, A/B bucketing and UTM ' +
53
+ 'attribution will resolve to default content for everyone. Place the module, or set ' +
54
+ 'personalization: { requireConsent: false } if consent is collected by external tooling.';
55
+ /**
56
+ * Build the once-only "consent required, but nothing asks for it" check.
57
+ *
58
+ * Returns a function safe to call on every request: it runs at most once, never
59
+ * awaits (the first request does not pay for it), and swallows every error. A
60
+ * warning that could break a page, or add latency to the hot path, would not be
61
+ * worth having.
62
+ *
63
+ * The check is a `::text LIKE` prefilter — the same shape
64
+ * `checkAudienceDeletionSafety` uses — looking for anything that mentions the
65
+ * module type at all. Over-matching is fine here: a false negative (staying
66
+ * quiet) is the safe direction for an advisory warning.
67
+ *
68
+ * It reads BOTH places a module can be placed: `kywi_content.layout` and
69
+ * `kywi_section_templates.definition`. A banner composed from a blueprint is a
70
+ * banner, and scanning pages alone told a site that builds every page that way
71
+ * that consent could never be granted — while the banner was on screen.
72
+ */
73
+ export function createConsentBannerCheck(deps) {
74
+ const warn = deps.warn ?? ((m) => console.warn(m));
75
+ let started = false;
76
+ return () => {
77
+ if (started || !deps.requireConsent)
78
+ return;
79
+ started = true;
80
+ void (async () => {
81
+ try {
82
+ const rows = await deps.db.execute(sql `
83
+ SELECT 1 AS found
84
+ FROM kywi_content
85
+ WHERE layout IS NOT NULL
86
+ AND layout::text LIKE ${'%"cookieConsent"%'}
87
+ UNION ALL
88
+ SELECT 1 AS found
89
+ FROM kywi_section_templates
90
+ WHERE definition IS NOT NULL
91
+ AND definition::text LIKE ${'%"cookieConsent"%'}
92
+ LIMIT 1
93
+ `);
94
+ if (rows.length === 0)
95
+ warn(NO_BANNER_WARNING);
96
+ }
97
+ catch {
98
+ // No content table yet (a fresh install mid-migration), a dialect that
99
+ // cannot cast, a transient connection failure — none of that is worth
100
+ // failing or logging a request over. Silence is the safe direction.
101
+ }
102
+ })();
103
+ };
104
+ }
105
+ //# sourceMappingURL=consent-startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-startup.js","sourceRoot":"","sources":["../../src/audiences/consent-startup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjC,wFAAwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,CAAA;AAEzD,sFAAsF;AACtF,MAAM,UAAU,qBAAqB,CAAC,MAA0C,OAAO,CAAC,GAAG;IACzF,OAAO,GAAG,CAAC,mBAAmB,CAAC,KAAK,OAAO,CAAA;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACvC,wBAAiC,EACjC,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,OAAO,KAAK,wBAAwB;QAAE,OAAM;IAChD,MAAM,GAAG,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAA;IACpC,MAAM,IAAI,KAAK,CACb,2EAA2E;QACzE,GAAG,wBAAwB,QAAQ,mBAAmB,MAAM;QAC5D,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK;QAC5E,gFAAgF;QAChF,WAAW,mBAAmB,oDAAoD;QAClF,oDAAoD;QACpD,2BAA2B,mBAAmB,mBAAmB;QACjE,6DAA6D,CAChE,CAAA;AACH,CAAC;AAED,MAAM,iBAAiB,GACrB,kFAAkF;IAClF,qFAAqF;IACrF,kFAAkF;IAClF,qFAAqF;IACrF,yFAAyF,CAAA;AAE3F;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAIxC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,OAAO,GAAG,EAAE;QACV,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAM;QAC3C,OAAO,GAAG,IAAI,CAAA;QACd,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAChC,GAAG,CAAA;;;;sCAIyB,mBAAmB;;;;;0CAKf,mBAAmB;;WAElD,CACF,CAAA;gBACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,uEAAuE;gBACvE,sEAAsE;gBACtE,oEAAoE;YACtE,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;IACN,CAAC,CAAA;AACH,CAAC"}