@kywi-software/core 0.14.0 → 0.15.1

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 (633) hide show
  1. package/AGENT-PATTERNS.md +200 -17
  2. package/README.md +38 -12
  3. package/dist/admin/audience-editor.d.ts +2 -0
  4. package/dist/admin/audience-editor.d.ts.map +1 -1
  5. package/dist/admin/audience-editor.js +4 -2
  6. package/dist/admin/audience-editor.js.map +1 -1
  7. package/dist/admin/chrome.d.ts.map +1 -1
  8. package/dist/admin/chrome.js +6 -7
  9. package/dist/admin/chrome.js.map +1 -1
  10. package/dist/admin/condition-builder.d.ts.map +1 -1
  11. package/dist/admin/condition-builder.js +16 -3
  12. package/dist/admin/condition-builder.js.map +1 -1
  13. package/dist/admin/field-components.d.ts.map +1 -1
  14. package/dist/admin/field-components.js +27 -1
  15. package/dist/admin/field-components.js.map +1 -1
  16. package/dist/admin/form-helpers.d.ts.map +1 -1
  17. package/dist/admin/form-helpers.js +6 -1
  18. package/dist/admin/form-helpers.js.map +1 -1
  19. package/dist/admin/layout-editor/chrome-env.d.ts +35 -0
  20. package/dist/admin/layout-editor/chrome-env.d.ts.map +1 -0
  21. package/dist/admin/layout-editor/chrome-env.js +13 -0
  22. package/dist/admin/layout-editor/chrome-env.js.map +1 -0
  23. package/dist/admin/layout-editor/component-actions.d.ts +58 -7
  24. package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
  25. package/dist/admin/layout-editor/component-actions.js +131 -5
  26. package/dist/admin/layout-editor/component-actions.js.map +1 -1
  27. package/dist/admin/layout-editor/component-fork.d.ts +4 -4
  28. package/dist/admin/layout-editor/component-fork.d.ts.map +1 -1
  29. package/dist/admin/layout-editor/component-fork.js +76 -10
  30. package/dist/admin/layout-editor/component-fork.js.map +1 -1
  31. package/dist/admin/layout-editor/component-picker-field.d.ts +17 -3
  32. package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -1
  33. package/dist/admin/layout-editor/component-picker-field.js +5 -2
  34. package/dist/admin/layout-editor/component-picker-field.js.map +1 -1
  35. package/dist/admin/layout-editor/drag-feedback.d.ts +25 -1
  36. package/dist/admin/layout-editor/drag-feedback.d.ts.map +1 -1
  37. package/dist/admin/layout-editor/drag-feedback.js +9 -0
  38. package/dist/admin/layout-editor/drag-feedback.js.map +1 -1
  39. package/dist/admin/layout-editor/drag-utils.d.ts +103 -5
  40. package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
  41. package/dist/admin/layout-editor/drag-utils.js +131 -4
  42. package/dist/admin/layout-editor/drag-utils.js.map +1 -1
  43. package/dist/admin/layout-editor/editor-canvas.d.ts +11 -0
  44. package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
  45. package/dist/admin/layout-editor/editor-canvas.js +134 -20
  46. package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
  47. package/dist/admin/layout-editor/editor-dialog.d.ts +58 -3
  48. package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -1
  49. package/dist/admin/layout-editor/editor-dialog.js +71 -9
  50. package/dist/admin/layout-editor/editor-dialog.js.map +1 -1
  51. package/dist/admin/layout-editor/editor-state.d.ts +119 -0
  52. package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
  53. package/dist/admin/layout-editor/editor-state.js +188 -6
  54. package/dist/admin/layout-editor/editor-state.js.map +1 -1
  55. package/dist/admin/layout-editor/editor-toolbar.d.ts +10 -1
  56. package/dist/admin/layout-editor/editor-toolbar.d.ts.map +1 -1
  57. package/dist/admin/layout-editor/editor-toolbar.js +2 -2
  58. package/dist/admin/layout-editor/editor-toolbar.js.map +1 -1
  59. package/dist/admin/layout-editor/editor.css +216 -8
  60. package/dist/admin/layout-editor/inline-text.d.ts +15 -1
  61. package/dist/admin/layout-editor/inline-text.d.ts.map +1 -1
  62. package/dist/admin/layout-editor/inline-text.js +30 -2
  63. package/dist/admin/layout-editor/inline-text.js.map +1 -1
  64. package/dist/admin/layout-editor/layout-editor.d.ts +21 -16
  65. package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
  66. package/dist/admin/layout-editor/layout-editor.js +40 -17
  67. package/dist/admin/layout-editor/layout-editor.js.map +1 -1
  68. package/dist/admin/layout-editor/linked-component-notes.d.ts +88 -0
  69. package/dist/admin/layout-editor/linked-component-notes.d.ts.map +1 -0
  70. package/dist/admin/layout-editor/linked-component-notes.js +88 -0
  71. package/dist/admin/layout-editor/linked-component-notes.js.map +1 -0
  72. package/dist/admin/layout-editor/module-overlay.d.ts +23 -4
  73. package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
  74. package/dist/admin/layout-editor/module-overlay.js +56 -10
  75. package/dist/admin/layout-editor/module-overlay.js.map +1 -1
  76. package/dist/admin/layout-editor/module-variant-container-config.d.ts.map +1 -1
  77. package/dist/admin/layout-editor/module-variant-container-config.js +9 -2
  78. package/dist/admin/layout-editor/module-variant-container-config.js.map +1 -1
  79. package/dist/admin/layout-editor/module-variant-container-panel.d.ts +75 -0
  80. package/dist/admin/layout-editor/module-variant-container-panel.d.ts.map +1 -0
  81. package/dist/admin/layout-editor/module-variant-container-panel.js +29 -0
  82. package/dist/admin/layout-editor/module-variant-container-panel.js.map +1 -0
  83. package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
  84. package/dist/admin/layout-editor/node-lookup.js +33 -3
  85. package/dist/admin/layout-editor/node-lookup.js.map +1 -1
  86. package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
  87. package/dist/admin/layout-editor/overlay-shell.js +19 -4
  88. package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
  89. package/dist/admin/layout-editor/props-panel.d.ts +28 -11
  90. package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
  91. package/dist/admin/layout-editor/props-panel.js +75 -125
  92. package/dist/admin/layout-editor/props-panel.js.map +1 -1
  93. package/dist/admin/layout-editor/section-variant-container-config.d.ts.map +1 -1
  94. package/dist/admin/layout-editor/section-variant-container-config.js +11 -2
  95. package/dist/admin/layout-editor/section-variant-container-config.js.map +1 -1
  96. package/dist/admin/layout-editor/use-chrome-flip.d.ts +99 -11
  97. package/dist/admin/layout-editor/use-chrome-flip.d.ts.map +1 -1
  98. package/dist/admin/layout-editor/use-chrome-flip.js +268 -97
  99. package/dist/admin/layout-editor/use-chrome-flip.js.map +1 -1
  100. package/dist/admin/layout-editor/use-component-connect.d.ts +13 -0
  101. package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -1
  102. package/dist/admin/layout-editor/use-component-connect.js +116 -20
  103. package/dist/admin/layout-editor/use-component-connect.js.map +1 -1
  104. package/dist/admin/layout-editor/use-component-fork.d.ts +49 -19
  105. package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -1
  106. package/dist/admin/layout-editor/use-component-fork.js +28 -19
  107. package/dist/admin/layout-editor/use-component-fork.js.map +1 -1
  108. package/dist/admin/layout-editor/use-component-library.d.ts +4 -4
  109. package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -1
  110. package/dist/admin/layout-editor/use-component-library.js +1 -1
  111. package/dist/admin/layout-editor/use-component-library.js.map +1 -1
  112. package/dist/admin/layout-editor/use-editor-dnd.d.ts +10 -0
  113. package/dist/admin/layout-editor/use-editor-dnd.d.ts.map +1 -1
  114. package/dist/admin/layout-editor/use-editor-dnd.js +234 -14
  115. package/dist/admin/layout-editor/use-editor-dnd.js.map +1 -1
  116. package/dist/admin/layout-editor/variant-container-config.d.ts.map +1 -1
  117. package/dist/admin/layout-editor/variant-container-config.js +1 -1
  118. package/dist/admin/layout-editor/variant-container-config.js.map +1 -1
  119. package/dist/admin/layout-editor/variant-editor.d.ts +16 -15
  120. package/dist/admin/layout-editor/variant-editor.d.ts.map +1 -1
  121. package/dist/admin/layout-editor/variant-editor.js +16 -5
  122. package/dist/admin/layout-editor/variant-editor.js.map +1 -1
  123. package/dist/admin/primitives.d.ts.map +1 -1
  124. package/dist/admin/primitives.js +1 -1
  125. package/dist/admin/primitives.js.map +1 -1
  126. package/dist/admin/registry.d.ts +12 -0
  127. package/dist/admin/registry.d.ts.map +1 -1
  128. package/dist/admin/registry.js +12 -0
  129. package/dist/admin/registry.js.map +1 -1
  130. package/dist/admin/rule-tester.d.ts +1 -0
  131. package/dist/admin/rule-tester.d.ts.map +1 -1
  132. package/dist/admin/rule-tester.js +7 -4
  133. package/dist/admin/rule-tester.js.map +1 -1
  134. package/dist/admin/server.d.ts +10 -1
  135. package/dist/admin/server.d.ts.map +1 -1
  136. package/dist/admin/server.js +4 -1
  137. package/dist/admin/server.js.map +1 -1
  138. package/dist/admin/signal-options.d.ts +17 -0
  139. package/dist/admin/signal-options.d.ts.map +1 -1
  140. package/dist/admin/signal-options.js +28 -0
  141. package/dist/admin/signal-options.js.map +1 -1
  142. package/dist/admin/site-switcher.d.ts +16 -3
  143. package/dist/admin/site-switcher.d.ts.map +1 -1
  144. package/dist/admin/site-switcher.js +18 -3
  145. package/dist/admin/site-switcher.js.map +1 -1
  146. package/dist/admin/styles/admin.css +0 -3
  147. package/dist/admin/surface-matcher.d.ts +6 -2
  148. package/dist/admin/surface-matcher.d.ts.map +1 -1
  149. package/dist/admin/surface-matcher.js +42 -5
  150. package/dist/admin/surface-matcher.js.map +1 -1
  151. package/dist/admin/surfaces/audiences/audiences-data.d.ts +5 -0
  152. package/dist/admin/surfaces/audiences/audiences-data.d.ts.map +1 -1
  153. package/dist/admin/surfaces/audiences/audiences-data.js +3 -0
  154. package/dist/admin/surfaces/audiences/audiences-data.js.map +1 -1
  155. package/dist/admin/surfaces/components/components-data.d.ts +31 -11
  156. package/dist/admin/surfaces/components/components-data.d.ts.map +1 -1
  157. package/dist/admin/surfaces/components/components-data.js +17 -4
  158. package/dist/admin/surfaces/components/components-data.js.map +1 -1
  159. package/dist/admin/surfaces/components/components-list.d.ts.map +1 -1
  160. package/dist/admin/surfaces/components/components-list.js +20 -7
  161. package/dist/admin/surfaces/components/components-list.js.map +1 -1
  162. package/dist/admin/surfaces/components/definition-canvas.d.ts +11 -3
  163. package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -1
  164. package/dist/admin/surfaces/components/definition-canvas.js +138 -17
  165. package/dist/admin/surfaces/components/definition-canvas.js.map +1 -1
  166. package/dist/admin/surfaces/dashboard/dashboard-index.d.ts.map +1 -1
  167. package/dist/admin/surfaces/dashboard/dashboard-index.js +2 -2
  168. package/dist/admin/surfaces/dashboard/dashboard-index.js.map +1 -1
  169. package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
  170. package/dist/admin/surfaces/layouts/layout-editor-client.js +12 -11
  171. package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
  172. package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -1
  173. package/dist/admin/surfaces/menus/menu-editor.js +17 -4
  174. package/dist/admin/surfaces/menus/menu-editor.js.map +1 -1
  175. package/dist/admin/surfaces/menus/menu-tree.d.ts +18 -4
  176. package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -1
  177. package/dist/admin/surfaces/menus/menu-tree.js +18 -3
  178. package/dist/admin/surfaces/menus/menu-tree.js.map +1 -1
  179. package/dist/admin/surfaces/menus/menus-data.d.ts +18 -0
  180. package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -1
  181. package/dist/admin/surfaces/menus/menus-data.js +4 -0
  182. package/dist/admin/surfaces/menus/menus-data.js.map +1 -1
  183. package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -1
  184. package/dist/admin/surfaces/menus/menus-list.js +2 -12
  185. package/dist/admin/surfaces/menus/menus-list.js.map +1 -1
  186. package/dist/admin/surfaces/users/users-data.d.ts +14 -0
  187. package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
  188. package/dist/admin/surfaces/users/users-data.js +19 -0
  189. package/dist/admin/surfaces/users/users-data.js.map +1 -1
  190. package/dist/admin/surfaces/users/users-detail.d.ts.map +1 -1
  191. package/dist/admin/surfaces/users/users-detail.js +40 -4
  192. package/dist/admin/surfaces/users/users-detail.js.map +1 -1
  193. package/dist/admin/surfaces/users/users-new.d.ts.map +1 -1
  194. package/dist/admin/surfaces/users/users-new.js +8 -5
  195. package/dist/admin/surfaces/users/users-new.js.map +1 -1
  196. package/dist/admin/user-form.d.ts +10 -1
  197. package/dist/admin/user-form.d.ts.map +1 -1
  198. package/dist/admin/user-form.js +2 -2
  199. package/dist/admin/user-form.js.map +1 -1
  200. package/dist/api/admin-features-routes.js +2 -2
  201. package/dist/api/admin-features-routes.js.map +1 -1
  202. package/dist/api/api-key-routes.js +2 -2
  203. package/dist/api/api-key-routes.js.map +1 -1
  204. package/dist/api/audience-preview-routes.d.ts +7 -0
  205. package/dist/api/audience-preview-routes.d.ts.map +1 -1
  206. package/dist/api/audience-preview-routes.js +4 -4
  207. package/dist/api/audience-preview-routes.js.map +1 -1
  208. package/dist/api/audience-routes.d.ts +7 -0
  209. package/dist/api/audience-routes.d.ts.map +1 -1
  210. package/dist/api/audience-routes.js +31 -19
  211. package/dist/api/audience-routes.js.map +1 -1
  212. package/dist/api/audience-runtime-routes.d.ts +23 -0
  213. package/dist/api/audience-runtime-routes.d.ts.map +1 -1
  214. package/dist/api/audience-runtime-routes.js +511 -25
  215. package/dist/api/audience-runtime-routes.js.map +1 -1
  216. package/dist/api/auth-routes.d.ts.map +1 -1
  217. package/dist/api/auth-routes.js +10 -4
  218. package/dist/api/auth-routes.js.map +1 -1
  219. package/dist/api/auth.d.ts +1 -0
  220. package/dist/api/auth.d.ts.map +1 -1
  221. package/dist/api/auth.js +43 -3
  222. package/dist/api/auth.js.map +1 -1
  223. package/dist/api/ax-routes.d.ts.map +1 -1
  224. package/dist/api/ax-routes.js +7 -3
  225. package/dist/api/ax-routes.js.map +1 -1
  226. package/dist/api/bulk-routes.d.ts.map +1 -1
  227. package/dist/api/bulk-routes.js +7 -7
  228. package/dist/api/bulk-routes.js.map +1 -1
  229. package/dist/api/category-routes.js +6 -6
  230. package/dist/api/category-routes.js.map +1 -1
  231. package/dist/api/changeset-routes.js +2 -2
  232. package/dist/api/changeset-routes.js.map +1 -1
  233. package/dist/api/comment-routes.js +12 -12
  234. package/dist/api/comment-routes.js.map +1 -1
  235. package/dist/api/component-routes.d.ts +25 -0
  236. package/dist/api/component-routes.d.ts.map +1 -1
  237. package/dist/api/component-routes.js +44 -19
  238. package/dist/api/component-routes.js.map +1 -1
  239. package/dist/api/config-routes.js +4 -4
  240. package/dist/api/config-routes.js.map +1 -1
  241. package/dist/api/content-permission-routes.js +2 -2
  242. package/dist/api/content-permission-routes.js.map +1 -1
  243. package/dist/api/content-routes.d.ts.map +1 -1
  244. package/dist/api/content-routes.js +21 -16
  245. package/dist/api/content-routes.js.map +1 -1
  246. package/dist/api/content-type-routes.js +3 -3
  247. package/dist/api/content-type-routes.js.map +1 -1
  248. package/dist/api/dashboard-routes.js +1 -1
  249. package/dist/api/dashboard-routes.js.map +1 -1
  250. package/dist/api/experiment-routes.d.ts +7 -0
  251. package/dist/api/experiment-routes.d.ts.map +1 -1
  252. package/dist/api/experiment-routes.js +10 -10
  253. package/dist/api/experiment-routes.js.map +1 -1
  254. package/dist/api/experiment-runtime-routes.d.ts +6 -0
  255. package/dist/api/experiment-runtime-routes.d.ts.map +1 -1
  256. package/dist/api/experiment-runtime-routes.js +47 -11
  257. package/dist/api/experiment-runtime-routes.js.map +1 -1
  258. package/dist/api/extension-routes.js +4 -4
  259. package/dist/api/extension-routes.js.map +1 -1
  260. package/dist/api/feed-routes.d.ts +2 -2
  261. package/dist/api/feed-routes.js +5 -5
  262. package/dist/api/feed-routes.js.map +1 -1
  263. package/dist/api/form-routes.js +6 -6
  264. package/dist/api/form-routes.js.map +1 -1
  265. package/dist/api/graphql/resolvers.d.ts +1 -1
  266. package/dist/api/graphql/resolvers.d.ts.map +1 -1
  267. package/dist/api/graphql/resolvers.js +68 -33
  268. package/dist/api/graphql/resolvers.js.map +1 -1
  269. package/dist/api/group-routes.js +9 -9
  270. package/dist/api/group-routes.js.map +1 -1
  271. package/dist/api/index.d.ts +1 -0
  272. package/dist/api/index.d.ts.map +1 -1
  273. package/dist/api/index.js +43 -7
  274. package/dist/api/index.js.map +1 -1
  275. package/dist/api/layout-routes.d.ts +19 -1
  276. package/dist/api/layout-routes.d.ts.map +1 -1
  277. package/dist/api/layout-routes.js +92 -8
  278. package/dist/api/layout-routes.js.map +1 -1
  279. package/dist/api/layout-write-guard.d.ts +3 -2
  280. package/dist/api/layout-write-guard.d.ts.map +1 -1
  281. package/dist/api/layout-write-guard.js +12 -4
  282. package/dist/api/layout-write-guard.js.map +1 -1
  283. package/dist/api/media-routes.d.ts.map +1 -1
  284. package/dist/api/media-routes.js +100 -35
  285. package/dist/api/media-routes.js.map +1 -1
  286. package/dist/api/menu-routes.d.ts +9 -1
  287. package/dist/api/menu-routes.d.ts.map +1 -1
  288. package/dist/api/menu-routes.js +46 -12
  289. package/dist/api/menu-routes.js.map +1 -1
  290. package/dist/api/nav-routes.d.ts +6 -0
  291. package/dist/api/nav-routes.d.ts.map +1 -1
  292. package/dist/api/nav-routes.js +25 -4
  293. package/dist/api/nav-routes.js.map +1 -1
  294. package/dist/api/oauth-routes.js +2 -2
  295. package/dist/api/oauth-routes.js.map +1 -1
  296. package/dist/api/openapi.d.ts.map +1 -1
  297. package/dist/api/openapi.js +82 -34
  298. package/dist/api/openapi.js.map +1 -1
  299. package/dist/api/pagination.d.ts +10 -0
  300. package/dist/api/pagination.d.ts.map +1 -1
  301. package/dist/api/pagination.js +7 -1
  302. package/dist/api/pagination.js.map +1 -1
  303. package/dist/api/response.d.ts +29 -0
  304. package/dist/api/response.d.ts.map +1 -1
  305. package/dist/api/response.js +23 -3
  306. package/dist/api/response.js.map +1 -1
  307. package/dist/api/search-routes.d.ts.map +1 -1
  308. package/dist/api/search-routes.js +19 -5
  309. package/dist/api/search-routes.js.map +1 -1
  310. package/dist/api/section-template-routes.d.ts.map +1 -1
  311. package/dist/api/section-template-routes.js +37 -20
  312. package/dist/api/section-template-routes.js.map +1 -1
  313. package/dist/api/site-admin-routes.d.ts +10 -1
  314. package/dist/api/site-admin-routes.d.ts.map +1 -1
  315. package/dist/api/site-admin-routes.js +21 -1
  316. package/dist/api/site-admin-routes.js.map +1 -1
  317. package/dist/api/site-context.d.ts +35 -5
  318. package/dist/api/site-context.d.ts.map +1 -1
  319. package/dist/api/site-context.js +21 -6
  320. package/dist/api/site-context.js.map +1 -1
  321. package/dist/api/site-routes.js +2 -2
  322. package/dist/api/site-routes.js.map +1 -1
  323. package/dist/api/tag-routes.d.ts.map +1 -1
  324. package/dist/api/tag-routes.js +5 -5
  325. package/dist/api/tag-routes.js.map +1 -1
  326. package/dist/api/translation-routes.js +5 -5
  327. package/dist/api/translation-routes.js.map +1 -1
  328. package/dist/api/user-routes.d.ts.map +1 -1
  329. package/dist/api/user-routes.js +136 -21
  330. package/dist/api/user-routes.js.map +1 -1
  331. package/dist/api/version-routes.js +2 -2
  332. package/dist/api/version-routes.js.map +1 -1
  333. package/dist/api/webhook-routes.js +8 -8
  334. package/dist/api/webhook-routes.js.map +1 -1
  335. package/dist/api/workflow-routes.d.ts.map +1 -1
  336. package/dist/api/workflow-routes.js +23 -14
  337. package/dist/api/workflow-routes.js.map +1 -1
  338. package/dist/audiences/collectors/identity.d.ts +14 -1
  339. package/dist/audiences/collectors/identity.d.ts.map +1 -1
  340. package/dist/audiences/collectors/identity.js +16 -3
  341. package/dist/audiences/collectors/identity.js.map +1 -1
  342. package/dist/audiences/collectors/index.d.ts +16 -2
  343. package/dist/audiences/collectors/index.d.ts.map +1 -1
  344. package/dist/audiences/collectors/index.js +29 -5
  345. package/dist/audiences/collectors/index.js.map +1 -1
  346. package/dist/audiences/collectors/pinned-audience.d.ts +28 -2
  347. package/dist/audiences/collectors/pinned-audience.d.ts.map +1 -1
  348. package/dist/audiences/collectors/pinned-audience.js +35 -5
  349. package/dist/audiences/collectors/pinned-audience.js.map +1 -1
  350. package/dist/audiences/collectors/selfid.d.ts +25 -0
  351. package/dist/audiences/collectors/selfid.d.ts.map +1 -0
  352. package/dist/audiences/collectors/selfid.js +46 -0
  353. package/dist/audiences/collectors/selfid.js.map +1 -0
  354. package/dist/audiences/collectors/session.d.ts +41 -0
  355. package/dist/audiences/collectors/session.d.ts.map +1 -0
  356. package/dist/audiences/collectors/session.js +50 -0
  357. package/dist/audiences/collectors/session.js.map +1 -0
  358. package/dist/audiences/collectors/utm.d.ts +15 -1
  359. package/dist/audiences/collectors/utm.d.ts.map +1 -1
  360. package/dist/audiences/collectors/utm.js +16 -2
  361. package/dist/audiences/collectors/utm.js.map +1 -1
  362. package/dist/audiences/consent-config.d.ts +21 -0
  363. package/dist/audiences/consent-config.d.ts.map +1 -0
  364. package/dist/audiences/consent-config.js +15 -0
  365. package/dist/audiences/consent-config.js.map +1 -0
  366. package/dist/audiences/consent-startup.d.ts +39 -0
  367. package/dist/audiences/consent-startup.d.ts.map +1 -0
  368. package/dist/audiences/consent-startup.js +105 -0
  369. package/dist/audiences/consent-startup.js.map +1 -0
  370. package/dist/audiences/consent.d.ts +205 -0
  371. package/dist/audiences/consent.d.ts.map +1 -0
  372. package/dist/audiences/consent.js +335 -0
  373. package/dist/audiences/consent.js.map +1 -0
  374. package/dist/audiences/cookies.d.ts +21 -0
  375. package/dist/audiences/cookies.d.ts.map +1 -1
  376. package/dist/audiences/cookies.js +26 -0
  377. package/dist/audiences/cookies.js.map +1 -1
  378. package/dist/audiences/engine.d.ts +7 -0
  379. package/dist/audiences/engine.d.ts.map +1 -1
  380. package/dist/audiences/engine.js +7 -2
  381. package/dist/audiences/engine.js.map +1 -1
  382. package/dist/audiences/entry-page.d.ts +89 -0
  383. package/dist/audiences/entry-page.d.ts.map +1 -0
  384. package/dist/audiences/entry-page.js +116 -0
  385. package/dist/audiences/entry-page.js.map +1 -0
  386. package/dist/audiences/evaluator/instant-match.d.ts.map +1 -1
  387. package/dist/audiences/evaluator/instant-match.js +7 -0
  388. package/dist/audiences/evaluator/instant-match.js.map +1 -1
  389. package/dist/audiences/index.d.ts +6 -2
  390. package/dist/audiences/index.d.ts.map +1 -1
  391. package/dist/audiences/index.js +12 -2
  392. package/dist/audiences/index.js.map +1 -1
  393. package/dist/audiences/queries.d.ts +16 -0
  394. package/dist/audiences/queries.d.ts.map +1 -1
  395. package/dist/audiences/queries.js +28 -1
  396. package/dist/audiences/queries.js.map +1 -1
  397. package/dist/audiences/schema.d.ts +17 -0
  398. package/dist/audiences/schema.d.ts.map +1 -1
  399. package/dist/audiences/schema.js +7 -0
  400. package/dist/audiences/schema.js.map +1 -1
  401. package/dist/audiences/server-eval.d.ts +32 -1
  402. package/dist/audiences/server-eval.d.ts.map +1 -1
  403. package/dist/audiences/server-eval.js +35 -3
  404. package/dist/audiences/server-eval.js.map +1 -1
  405. package/dist/audiences/ssr.d.ts +18 -1
  406. package/dist/audiences/ssr.d.ts.map +1 -1
  407. package/dist/audiences/ssr.js +18 -1
  408. package/dist/audiences/ssr.js.map +1 -1
  409. package/dist/audiences/types.d.ts +22 -1
  410. package/dist/audiences/types.d.ts.map +1 -1
  411. package/dist/audiences/types.js +1 -0
  412. package/dist/audiences/types.js.map +1 -1
  413. package/dist/audiences/utm-persistence.d.ts +20 -7
  414. package/dist/audiences/utm-persistence.d.ts.map +1 -1
  415. package/dist/audiences/utm-persistence.js +20 -7
  416. package/dist/audiences/utm-persistence.js.map +1 -1
  417. package/dist/auth/roles.d.ts +11 -0
  418. package/dist/auth/roles.d.ts.map +1 -1
  419. package/dist/auth/roles.js +13 -0
  420. package/dist/auth/roles.js.map +1 -1
  421. package/dist/auth/tokens.d.ts +7 -0
  422. package/dist/auth/tokens.d.ts.map +1 -1
  423. package/dist/auth/tokens.js +24 -2
  424. package/dist/auth/tokens.js.map +1 -1
  425. package/dist/ax/content-source.d.ts +10 -2
  426. package/dist/ax/content-source.d.ts.map +1 -1
  427. package/dist/ax/content-source.js +81 -5
  428. package/dist/ax/content-source.js.map +1 -1
  429. package/dist/ax/effective-body.d.ts +28 -0
  430. package/dist/ax/effective-body.d.ts.map +1 -0
  431. package/dist/ax/effective-body.js +47 -0
  432. package/dist/ax/effective-body.js.map +1 -0
  433. package/dist/ax/index.d.ts +3 -1
  434. package/dist/ax/index.d.ts.map +1 -1
  435. package/dist/ax/index.js +2 -0
  436. package/dist/ax/index.js.map +1 -1
  437. package/dist/ax/jsonld.d.ts +31 -1
  438. package/dist/ax/jsonld.d.ts.map +1 -1
  439. package/dist/ax/jsonld.js +35 -22
  440. package/dist/ax/jsonld.js.map +1 -1
  441. package/dist/ax/layout-to-html.d.ts +127 -0
  442. package/dist/ax/layout-to-html.d.ts.map +1 -0
  443. package/dist/ax/layout-to-html.js +545 -0
  444. package/dist/ax/layout-to-html.js.map +1 -0
  445. package/dist/ax/llms-full-txt.d.ts +3 -1
  446. package/dist/ax/llms-full-txt.d.ts.map +1 -1
  447. package/dist/ax/llms-full-txt.js +5 -2
  448. package/dist/ax/llms-full-txt.js.map +1 -1
  449. package/dist/ax/page-markdown.d.ts +10 -2
  450. package/dist/ax/page-markdown.d.ts.map +1 -1
  451. package/dist/ax/page-markdown.js +16 -3
  452. package/dist/ax/page-markdown.js.map +1 -1
  453. package/dist/ax/summary.d.ts +4 -0
  454. package/dist/ax/summary.d.ts.map +1 -1
  455. package/dist/ax/summary.js +6 -1
  456. package/dist/ax/summary.js.map +1 -1
  457. package/dist/ax/types.d.ts +24 -0
  458. package/dist/ax/types.d.ts.map +1 -1
  459. package/dist/cache/content-invalidation.d.ts.map +1 -1
  460. package/dist/cache/content-invalidation.js +11 -0
  461. package/dist/cache/content-invalidation.js.map +1 -1
  462. package/dist/config/types.d.ts +43 -0
  463. package/dist/config/types.d.ts.map +1 -1
  464. package/dist/config/types.js.map +1 -1
  465. package/dist/config/validate.d.ts.map +1 -1
  466. package/dist/config/validate.js +3 -0
  467. package/dist/config/validate.js.map +1 -1
  468. package/dist/db/apply-snapshot.d.ts +25 -0
  469. package/dist/db/apply-snapshot.d.ts.map +1 -1
  470. package/dist/db/apply-snapshot.js +48 -16
  471. package/dist/db/apply-snapshot.js.map +1 -1
  472. package/dist/db/ax-queries.d.ts +6 -0
  473. package/dist/db/ax-queries.d.ts.map +1 -1
  474. package/dist/db/ax-queries.js +6 -0
  475. package/dist/db/ax-queries.js.map +1 -1
  476. package/dist/db/component-instance-queries.d.ts +79 -19
  477. package/dist/db/component-instance-queries.d.ts.map +1 -1
  478. package/dist/db/component-instance-queries.js +266 -83
  479. package/dist/db/component-instance-queries.js.map +1 -1
  480. package/dist/db/component-queries.d.ts +1 -16
  481. package/dist/db/component-queries.d.ts.map +1 -1
  482. package/dist/db/component-queries.js +7 -56
  483. package/dist/db/component-queries.js.map +1 -1
  484. package/dist/db/content-queries.d.ts.map +1 -1
  485. package/dist/db/content-queries.js +9 -2
  486. package/dist/db/content-queries.js.map +1 -1
  487. package/dist/db/extension-queries.d.ts +2 -2
  488. package/dist/db/feed-queries.d.ts +3 -3
  489. package/dist/db/index.d.ts +1 -0
  490. package/dist/db/index.d.ts.map +1 -1
  491. package/dist/db/index.js +1 -0
  492. package/dist/db/index.js.map +1 -1
  493. package/dist/db/layout-queries.d.ts +21 -3
  494. package/dist/db/layout-queries.d.ts.map +1 -1
  495. package/dist/db/layout-queries.js +14 -6
  496. package/dist/db/layout-queries.js.map +1 -1
  497. package/dist/db/menu-queries.d.ts +69 -5
  498. package/dist/db/menu-queries.d.ts.map +1 -1
  499. package/dist/db/menu-queries.js +120 -13
  500. package/dist/db/menu-queries.js.map +1 -1
  501. package/dist/db/search-queries.d.ts.map +1 -1
  502. package/dist/db/search-queries.js +24 -1
  503. package/dist/db/search-queries.js.map +1 -1
  504. package/dist/db/section-template-queries.d.ts +62 -0
  505. package/dist/db/section-template-queries.d.ts.map +1 -0
  506. package/dist/db/section-template-queries.js +178 -0
  507. package/dist/db/section-template-queries.js.map +1 -0
  508. package/dist/db/site-plugin-queries.d.ts +2 -2
  509. package/dist/db/tree-queries.d.ts.map +1 -1
  510. package/dist/db/tree-queries.js +5 -0
  511. package/dist/db/tree-queries.js.map +1 -1
  512. package/dist/db/webhook-queries.d.ts +3 -3
  513. package/dist/db/workflow-queries.d.ts.map +1 -1
  514. package/dist/db/workflow-queries.js +5 -20
  515. package/dist/db/workflow-queries.js.map +1 -1
  516. package/dist/experiments/runtime.d.ts +21 -3
  517. package/dist/experiments/runtime.d.ts.map +1 -1
  518. package/dist/experiments/runtime.js +21 -3
  519. package/dist/experiments/runtime.js.map +1 -1
  520. package/dist/hooks/ax-invalidation.d.ts.map +1 -1
  521. package/dist/hooks/ax-invalidation.js +4 -0
  522. package/dist/hooks/ax-invalidation.js.map +1 -1
  523. package/dist/layout/component-refs.d.ts +90 -2
  524. package/dist/layout/component-refs.d.ts.map +1 -1
  525. package/dist/layout/component-refs.js +293 -16
  526. package/dist/layout/component-refs.js.map +1 -1
  527. package/dist/layout/index.d.ts +7 -4
  528. package/dist/layout/index.d.ts.map +1 -1
  529. package/dist/layout/index.js +6 -3
  530. package/dist/layout/index.js.map +1 -1
  531. package/dist/layout/legacy-variant-container.d.ts +123 -0
  532. package/dist/layout/legacy-variant-container.d.ts.map +1 -0
  533. package/dist/layout/legacy-variant-container.js +397 -0
  534. package/dist/layout/legacy-variant-container.js.map +1 -0
  535. package/dist/layout/module-permissions.d.ts.map +1 -1
  536. package/dist/layout/module-permissions.js +26 -38
  537. package/dist/layout/module-permissions.js.map +1 -1
  538. package/dist/layout/modules-extended.d.ts +28 -1
  539. package/dist/layout/modules-extended.d.ts.map +1 -1
  540. package/dist/layout/modules-extended.js +73 -1
  541. package/dist/layout/modules-extended.js.map +1 -1
  542. package/dist/layout/modules.d.ts.map +1 -1
  543. package/dist/layout/modules.js +9 -1
  544. package/dist/layout/modules.js.map +1 -1
  545. package/dist/layout/personalization.d.ts +83 -0
  546. package/dist/layout/personalization.d.ts.map +1 -1
  547. package/dist/layout/personalization.js +250 -4
  548. package/dist/layout/personalization.js.map +1 -1
  549. package/dist/layout/registry.d.ts.map +1 -1
  550. package/dist/layout/registry.js +20 -0
  551. package/dist/layout/registry.js.map +1 -1
  552. package/dist/layout/renderer.d.ts +29 -2
  553. package/dist/layout/renderer.d.ts.map +1 -1
  554. package/dist/layout/renderer.js +23 -6
  555. package/dist/layout/renderer.js.map +1 -1
  556. package/dist/layout/seed-defaults.d.ts +45 -0
  557. package/dist/layout/seed-defaults.d.ts.map +1 -0
  558. package/dist/layout/seed-defaults.js +75 -0
  559. package/dist/layout/seed-defaults.js.map +1 -0
  560. package/dist/layout/types.d.ts +17 -0
  561. package/dist/layout/types.d.ts.map +1 -1
  562. package/dist/layout/types.js +7 -0
  563. package/dist/layout/types.js.map +1 -1
  564. package/dist/layout/walk.d.ts +14 -0
  565. package/dist/layout/walk.d.ts.map +1 -0
  566. package/dist/layout/walk.js +49 -0
  567. package/dist/layout/walk.js.map +1 -0
  568. package/dist/media/index.d.ts +1 -1
  569. package/dist/media/index.d.ts.map +1 -1
  570. package/dist/media/index.js +1 -1
  571. package/dist/media/index.js.map +1 -1
  572. package/dist/media/inline-risk.d.ts +26 -0
  573. package/dist/media/inline-risk.d.ts.map +1 -0
  574. package/dist/media/inline-risk.js +142 -0
  575. package/dist/media/inline-risk.js.map +1 -0
  576. package/dist/media/upload-allowlist.d.ts +23 -0
  577. package/dist/media/upload-allowlist.d.ts.map +1 -1
  578. package/dist/media/upload-allowlist.js +29 -0
  579. package/dist/media/upload-allowlist.js.map +1 -1
  580. package/dist/nav/builder.d.ts.map +1 -1
  581. package/dist/nav/builder.js +15 -3
  582. package/dist/nav/builder.js.map +1 -1
  583. package/dist/nav/index.d.ts +1 -1
  584. package/dist/nav/index.d.ts.map +1 -1
  585. package/dist/nav/index.js +1 -1
  586. package/dist/nav/index.js.map +1 -1
  587. package/dist/nav/menu-resolver.d.ts +11 -0
  588. package/dist/nav/menu-resolver.d.ts.map +1 -1
  589. package/dist/nav/menu-resolver.js +49 -9
  590. package/dist/nav/menu-resolver.js.map +1 -1
  591. package/dist/nav/paths.d.ts +37 -0
  592. package/dist/nav/paths.d.ts.map +1 -0
  593. package/dist/nav/paths.js +48 -0
  594. package/dist/nav/paths.js.map +1 -0
  595. package/dist/nav/types.d.ts +6 -0
  596. package/dist/nav/types.d.ts.map +1 -1
  597. package/dist/nav/url-resolver.d.ts +1 -5
  598. package/dist/nav/url-resolver.d.ts.map +1 -1
  599. package/dist/nav/url-resolver.js +6 -12
  600. package/dist/nav/url-resolver.js.map +1 -1
  601. package/dist/schema/base.d.ts +24 -4
  602. package/dist/schema/base.d.ts.map +1 -1
  603. package/dist/schema/base.js +17 -4
  604. package/dist/schema/base.js.map +1 -1
  605. package/dist/schema/components.d.ts +90 -9
  606. package/dist/schema/components.d.ts.map +1 -1
  607. package/dist/schema/components.js +113 -22
  608. package/dist/schema/components.js.map +1 -1
  609. package/dist/schema/mysql-tables.d.ts +5775 -48
  610. package/dist/schema/mysql-tables.d.ts.map +1 -1
  611. package/dist/schema/mysql-tables.js +622 -46
  612. package/dist/schema/mysql-tables.js.map +1 -1
  613. package/dist/scope/jsonld.d.ts +18 -3
  614. package/dist/scope/jsonld.d.ts.map +1 -1
  615. package/dist/scope/jsonld.js +6 -4
  616. package/dist/scope/jsonld.js.map +1 -1
  617. package/dist/scope/kywi-form.d.ts +11 -0
  618. package/dist/scope/kywi-form.d.ts.map +1 -1
  619. package/dist/scope/kywi-form.js +11 -1
  620. package/dist/scope/kywi-form.js.map +1 -1
  621. package/dist/scope/kywi-wizard-form.d.ts.map +1 -1
  622. package/dist/scope/kywi-wizard-form.js +76 -2
  623. package/dist/scope/kywi-wizard-form.js.map +1 -1
  624. package/dist/scope/sticky-offset.d.ts +34 -13
  625. package/dist/scope/sticky-offset.d.ts.map +1 -1
  626. package/dist/scope/sticky-offset.js +236 -43
  627. package/dist/scope/sticky-offset.js.map +1 -1
  628. package/dist/site/styles.css +61 -15
  629. package/dist/versioning/scheduler.d.ts +28 -0
  630. package/dist/versioning/scheduler.d.ts.map +1 -1
  631. package/dist/versioning/scheduler.js +50 -3
  632. package/dist/versioning/scheduler.js.map +1 -1
  633. package/package.json +12 -2
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Cookie consent — the category map, and the gate every optional cookie write
3
+ * passes through (kywi-cms#91).
4
+ *
5
+ * Before this module the `cookieConsent` layout module and the `kywi_consent`
6
+ * cookie were two halves of a feature that never met: the banner's buttons had
7
+ * no handlers, and no cookie-writing code path ever asked whether the visitor
8
+ * had consented. This file is the join. It owns three things:
9
+ *
10
+ * 1. `COOKIE_CONSENT_CATEGORY` — the SINGLE SOURCE OF TRUTH mapping every
11
+ * cookie the engine writes to the consent category it needs. Nothing else
12
+ * in the codebase may decide a cookie's category.
13
+ * 2. `cookieAllowed()` / `consentAllows()` — the gate. Every optional cookie
14
+ * write calls one of these first.
15
+ * 3. The browser-side read/write of the `kywi_consent` cookie itself, used by
16
+ * the `cookieConsent` layout module's buttons.
17
+ *
18
+ * ── Category decisions (owner-set) ──────────────────────────────────────────
19
+ *
20
+ * necessary / `essential` — always allowed, never gated:
21
+ * `kywi_consent` the consent record itself
22
+ * `kywi_optout` the personalization opt-out flag: a *suppression*
23
+ * preference. Blocking a visitor from recording "stop
24
+ * personalizing me" until they consent to cookies would
25
+ * be perverse, so this is necessary by construction.
26
+ * `kywi_preview_init` admin preview hand-off, not visitor tracking.
27
+ *
28
+ * `personalization` — gated:
29
+ * `kywi_visitor` visitor id, incl. experiment bucketing / exposure
30
+ * `kywi_signals` the signed server-resolved audience signals
31
+ * `kywi_utm` campaign attribution carried across navigation
32
+ * `kywi_audience` the audience the RUNTIME resolved and remembered. A pin
33
+ * the visitor chose by hand in the transparency panel is
34
+ * `essential` instead — see the `source` discussion in
35
+ * `api/audience-runtime-routes.ts`
36
+ * `kywi_known` adapter-pushed known-identity flag
37
+ * `kywi_entry` the first page of the session (kywi-cms#196). Carried
38
+ * across navigation, so it is exactly the kind of stored
39
+ * signal the gate governs — the landing request's own path
40
+ * is read straight off the URL either way, so a campaign
41
+ * link still personalizes the page it points at.
42
+ * `kywi_selfid` the visitor's self-ID answers, kept server-readable so a
43
+ * server-pruned variant arm can be chosen from them
44
+ * (kywi-cms#200). The audience PIN that a self-ID submit
45
+ * produces is `essential` under the `switcher:` rule
46
+ * below — a control the visitor operated by hand — but the
47
+ * stored attribute bag itself is tracking and is gated.
48
+ *
49
+ * Auth/session cookies (the admin's access + refresh cookies, CSRF) are
50
+ * `essential` by definition and deliberately never routed through this gate —
51
+ * they carry no tracking and the admin cannot function without them.
52
+ *
53
+ * ── Undecided means not consented ───────────────────────────────────────────
54
+ *
55
+ * A visitor who has not answered the banner has a null `ConsentState`, and
56
+ * `consentAllows(null, 'personalization')` is FALSE. This matches `hasConsent()`
57
+ * in `@kywi-software/js` and is the compliance-correct default. The consequence
58
+ * is deliberate: until a visitor accepts, personalization cookies are not
59
+ * written and pages degrade to their default (unpersonalized) content. Nothing
60
+ * fails — the request still resolves, the visitor id is still minted for the
61
+ * duration of that request, it just is not persisted.
62
+ *
63
+ * An unmapped cookie name is denied rather than allowed, so adding a new cookie
64
+ * without classifying it here fails closed. A core test asserts every name in
65
+ * `COOKIE_NAMES` appears in the map, so that failure surfaces at test time.
66
+ *
67
+ * ── The escape hatch: personalization.requireConsent ────────────────────────
68
+ *
69
+ * `theme.personalization.requireConsent` (kywi.config.ts) DEFAULTS TO TRUE — the
70
+ * compliant behaviour above. Setting it to `false` turns this gate off entirely:
71
+ * every category reads as allowed, decided or not, and the cookie writes behave
72
+ * as they did before kywi-cms#91. That is for a site whose consent is collected
73
+ * by external tooling (a third-party CMP) which suppresses cookies its own way;
74
+ * the site takes responsibility for compliance, and Kywi stops second-guessing
75
+ * it. It is NOT a way to opt out of consent — turning it off on a site with no
76
+ * other consent mechanism is the non-compliant configuration this issue existed
77
+ * to fix.
78
+ *
79
+ * Every gate function takes the flag through a `ConsentGateOptions` bag rather
80
+ * than reading config itself, because this module must stay dependency-free
81
+ * (see below). `personalizationRequiresConsent()` in `./consent-config.ts`
82
+ * resolves it from a `KywiConfig`; the edge middleware, which cannot import an
83
+ * app's config at all, mirrors it with `KYWI_REQUIRE_CONSENT=false`.
84
+ *
85
+ * EDGE-SAFE LEAF MODULE: this file imports nothing, so it can be pulled into
86
+ * Next.js edge middleware (where core's DB-backed code cannot run) and into
87
+ * `audiences/utm-persistence.ts`, which has the same constraint. It is
88
+ * published as its own export entry (`@kywi-software/core/audiences/consent`).
89
+ * Keep it dependency-free. The browser-only helpers guard on `document`, so
90
+ * importing this on the server or the edge is safe.
91
+ */
92
+ /** The cookie the visitor's consent decision is stored in. */
93
+ export const CONSENT_COOKIE = 'kywi_consent';
94
+ /** 1 year, in seconds — how long a consent decision is remembered. */
95
+ export const CONSENT_MAX_AGE = 365 * 24 * 3600;
96
+ /** The cookie an audience pin lives in. */
97
+ export const AUDIENCE_PIN_COOKIE = 'kywi_audience';
98
+ /**
99
+ * The `kywi_audience` value prefix marking a pin the visitor chose BY HAND in
100
+ * the transparency panel, as opposed to one the runtime remembered on its own.
101
+ *
102
+ * Owned here, in the zero-import leaf, because both halves of the feature need
103
+ * it and neither can import the other: `collectors/pinned-audience.ts` encodes
104
+ * and decodes with it, and `clearDeniedCookies` below must recognise it to avoid
105
+ * sweeping away a preference it is supposed to honour.
106
+ */
107
+ export const SWITCHER_PIN_PREFIX = 'switcher:';
108
+ /**
109
+ * Every cookie the engine writes → the consent category it requires.
110
+ * The single source of truth; see the file header for the reasoning behind
111
+ * each classification.
112
+ */
113
+ export const COOKIE_CONSENT_CATEGORY = {
114
+ kywi_consent: 'essential',
115
+ kywi_optout: 'essential',
116
+ kywi_preview_init: 'essential',
117
+ kywi_signals: 'personalization',
118
+ kywi_visitor: 'personalization',
119
+ kywi_utm: 'personalization',
120
+ kywi_audience: 'personalization',
121
+ kywi_known: 'personalization',
122
+ kywi_entry: 'personalization',
123
+ kywi_selfid: 'personalization',
124
+ };
125
+ /**
126
+ * The consent category `cookieName` requires, or `null` when the name is not
127
+ * classified. An unclassified cookie is denied by `cookieAllowed`.
128
+ */
129
+ export function consentCategoryFor(cookieName) {
130
+ return COOKIE_CONSENT_CATEGORY[cookieName] ?? null;
131
+ }
132
+ /** Parse a raw `kywi_consent` cookie value. Returns null when absent/malformed. */
133
+ export function parseConsentValue(raw) {
134
+ if (!raw)
135
+ return null;
136
+ let text = raw;
137
+ try {
138
+ text = decodeURIComponent(raw);
139
+ }
140
+ catch {
141
+ /* malformed escape — fall through with the raw value */
142
+ }
143
+ let parsed;
144
+ try {
145
+ parsed = JSON.parse(text);
146
+ }
147
+ catch {
148
+ return null;
149
+ }
150
+ if (typeof parsed !== 'object' || parsed === null)
151
+ return null;
152
+ const obj = parsed;
153
+ return {
154
+ essential: true,
155
+ analytics: obj.analytics === true,
156
+ marketing: obj.marketing === true,
157
+ personalization: obj.personalization === true,
158
+ };
159
+ }
160
+ /**
161
+ * Read the consent decision out of a request's `Cookie` header.
162
+ * Returns null when the header is absent or carries no usable decision.
163
+ *
164
+ * A header can legitimately carry the same cookie name twice — most often a
165
+ * `Path=/` cookie shadowed by a narrower one from an earlier deploy. Taking the
166
+ * first match and giving up if it will not parse would throw away a perfectly
167
+ * good decision sitting right behind a corrupt one, so keep looking.
168
+ */
169
+ export function readConsentFromCookieHeader(header) {
170
+ if (!header)
171
+ return null;
172
+ for (const pair of header.split(';')) {
173
+ const trimmed = pair.trim();
174
+ const eqIdx = trimmed.indexOf('=');
175
+ if (eqIdx < 0)
176
+ continue;
177
+ if (trimmed.slice(0, eqIdx) !== CONSENT_COOKIE)
178
+ continue;
179
+ const state = parseConsentValue(trimmed.slice(eqIdx + 1));
180
+ if (state)
181
+ return state;
182
+ }
183
+ return null;
184
+ }
185
+ /**
186
+ * Is `category` granted by `state`? `essential` is always granted — necessary
187
+ * cookies need no consent. Every other category requires an explicit `true`,
188
+ * so an undecided visitor (null state) grants nothing.
189
+ */
190
+ export function consentAllows(state, category, options = {}) {
191
+ if (options.requireConsent === false)
192
+ return true;
193
+ if (category === 'essential')
194
+ return true;
195
+ if (!state)
196
+ return false;
197
+ return state[category] === true;
198
+ }
199
+ /**
200
+ * The gate: may `cookieName` be written given `state`? Unclassified cookie
201
+ * names fail closed — unless the gate itself is off.
202
+ */
203
+ export function cookieAllowed(cookieName, state, options = {}) {
204
+ // With the gate off there is nothing to classify against — the site's own
205
+ // tooling decides, including for a cookie this map has never heard of.
206
+ if (options.requireConsent === false)
207
+ return true;
208
+ const category = consentCategoryFor(cookieName);
209
+ if (category === null)
210
+ return false;
211
+ return consentAllows(state, category);
212
+ }
213
+ /** Convenience for request handlers: gate `cookieName` against a `Cookie` header. */
214
+ export function cookieAllowedByHeader(cookieName, header, options = {}) {
215
+ return cookieAllowed(cookieName, readConsentFromCookieHeader(header), options);
216
+ }
217
+ /** Every cookie name classified into `category`. */
218
+ export function cookiesInCategory(category) {
219
+ return Object.entries(COOKIE_CONSENT_CATEGORY)
220
+ .filter(([, c]) => c === category)
221
+ .map(([name]) => name);
222
+ }
223
+ /* ── browser side: the cookieConsent module's read/write ─────────────────── */
224
+ /**
225
+ * Delete every cookie whose category `state` does not grant, and return the
226
+ * names deleted.
227
+ *
228
+ * Refusing to WRITE new cookies is only half of "Reject All" — a visitor who
229
+ * accepted last month and rejects today is still carrying a `kywi_visitor` id,
230
+ * and a gate that only blocks writes would keep reading it forever. So a
231
+ * decision revokes as well as denies (kywi-cms#91).
232
+ *
233
+ * `kywi_signals` is HttpOnly and cannot be removed from script; the attempt is
234
+ * harmless and the server stops writing it, after which it expires on its own
235
+ * 60-second horizon. The server-side read paths ALSO ignore personalization
236
+ * cookies whenever the gate denies, so a cookie script cannot clear is inert
237
+ * either way.
238
+ *
239
+ * No-op off the browser.
240
+ */
241
+ export function clearDeniedCookies(state) {
242
+ if (typeof document === 'undefined')
243
+ return [];
244
+ const deleted = [];
245
+ for (const [name, category] of Object.entries(COOKIE_CONSENT_CATEGORY)) {
246
+ if (consentAllows(state, category))
247
+ continue;
248
+ if (isDeliberatePreference(name, rawCookie(name)))
249
+ continue;
250
+ document.cookie = `${name}=; Path=/; Max-Age=0`;
251
+ deleted.push(name);
252
+ }
253
+ return deleted;
254
+ }
255
+ /** The raw (decoded) value of one cookie, or undefined. Browser-only. */
256
+ function rawCookie(name) {
257
+ if (typeof document === 'undefined')
258
+ return undefined;
259
+ for (const pair of document.cookie.split(';')) {
260
+ const trimmed = pair.trim();
261
+ const eqIdx = trimmed.indexOf('=');
262
+ if (eqIdx < 0 || trimmed.slice(0, eqIdx) !== name)
263
+ continue;
264
+ const raw = trimmed.slice(eqIdx + 1);
265
+ if (raw === '')
266
+ return undefined;
267
+ try {
268
+ return decodeURIComponent(raw);
269
+ }
270
+ catch {
271
+ return raw;
272
+ }
273
+ }
274
+ return undefined;
275
+ }
276
+ /**
277
+ * Does this cookie's CURRENT VALUE mark it as an explicit visitor preference
278
+ * that outranks its category?
279
+ *
280
+ * `kywi_audience` is the one cookie whose category depends on how it was
281
+ * written: automatic ("remember what I resolved") is `personalization`, but an
282
+ * audience the visitor picked by hand in the transparency panel is `essential`,
283
+ * on the same argument as `kywi_optout`. The category map is static and cannot
284
+ * express that, so the sweep asks the value.
285
+ *
286
+ * Without this, rejecting personalization would delete a choice the visitor made
287
+ * deliberately and which the server is under orders to keep honouring — the
288
+ * revocation would quietly undo the exemption.
289
+ */
290
+ function isDeliberatePreference(name, value) {
291
+ if (name !== AUDIENCE_PIN_COOKIE || value === undefined)
292
+ return false;
293
+ // The prefix alone is not a pin — `switcher:` with no id decodes to nothing
294
+ // (parseAudiencePin rejects it), so exempting it would strand a cookie nobody
295
+ // will ever honour.
296
+ return value.startsWith(SWITCHER_PIN_PREFIX) && value.length > SWITCHER_PIN_PREFIX.length;
297
+ }
298
+ /** Read the visitor's consent decision from `document.cookie`, or null. */
299
+ export function getConsentState() {
300
+ if (typeof document === 'undefined')
301
+ return null;
302
+ return readConsentFromCookieHeader(document.cookie);
303
+ }
304
+ /**
305
+ * Record a consent decision. `essential` is always forced true — the visitor
306
+ * cannot decline necessary cookies, and the banner renders that checkbox
307
+ * checked and disabled to say so. Returns the state written.
308
+ *
309
+ * Any category the decision denies is REVOKED at the same time: see
310
+ * `clearDeniedCookies`. Rejecting is not just "stop writing", it is "and delete
311
+ * what you already wrote".
312
+ */
313
+ export function setConsent(prefs) {
314
+ const state = {
315
+ essential: true,
316
+ analytics: prefs.analytics === true,
317
+ marketing: prefs.marketing === true,
318
+ personalization: prefs.personalization === true,
319
+ };
320
+ if (typeof document !== 'undefined') {
321
+ document.cookie =
322
+ `${CONSENT_COOKIE}=${encodeURIComponent(JSON.stringify(state))}` +
323
+ `; Path=/; Max-Age=${CONSENT_MAX_AGE}; SameSite=Lax`;
324
+ // A decision REVOKES as well as denies: cookies from an earlier, more
325
+ // permissive answer are removed here rather than lingering until they
326
+ // expire. Written first so the consent record survives its own sweep.
327
+ clearDeniedCookies(state);
328
+ }
329
+ return state;
330
+ }
331
+ /** Has the visitor granted `category`? See `consentAllows` for the semantics. */
332
+ export function hasConsent(category, options = {}) {
333
+ return consentAllows(getConsentState(), category, options);
334
+ }
335
+ //# sourceMappingURL=consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../src/audiences/consent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AAEH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAA;AAE5C,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,CAAA;AAE9C,2CAA2C;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAqB9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,YAAY,EAAE,WAAW;IACzB,WAAW,EAAE,WAAW;IACxB,iBAAiB,EAAE,WAAW;IAC9B,YAAY,EAAE,iBAAiB;IAC/B,YAAY,EAAE,iBAAiB;IAC/B,QAAQ,EAAE,iBAAiB;IAC3B,aAAa,EAAE,iBAAiB;IAChC,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,iBAAiB;IAC7B,WAAW,EAAE,iBAAiB;CACoB,CAAA;AAEpD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACnD,OAAQ,uBAA2D,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;AACzF,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,GAA8B;IAC9D,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,IAAI,IAAI,GAAG,GAAG,CAAA;IACd,IAAI,CAAC;QACH,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IACD,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC9D,MAAM,GAAG,GAAG,MAAiC,CAAA;IAC7C,OAAO;QACL,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,GAAG,CAAC,SAAS,KAAK,IAAI;QACjC,SAAS,EAAE,GAAG,CAAC,SAAS,KAAK,IAAI;QACjC,eAAe,EAAE,GAAG,CAAC,eAAe,KAAK,IAAI;KAC9C,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAiC;IAC3E,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,GAAG,CAAC;YAAE,SAAQ;QACvB,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,cAAc;YAAE,SAAQ;QACxD,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;QACzD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAA;IACzB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA0B,EAC1B,QAAyB,EACzB,UAA8B,EAAE;IAEhC,IAAI,OAAO,CAAC,cAAc,KAAK,KAAK;QAAE,OAAO,IAAI,CAAA;IACjD,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAA;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,UAAkB,EAClB,KAA0B,EAC1B,UAA8B,EAAE;IAEhC,0EAA0E;IAC1E,uEAAuE;IACvE,IAAI,OAAO,CAAC,cAAc,KAAK,KAAK;QAAE,OAAO,IAAI,CAAA;IACjD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAA;IAC/C,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IACnC,OAAO,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,MAAiC,EACjC,UAA8B,EAAE;IAEhC,OAAO,aAAa,CAAC,UAAU,EAAE,2BAA2B,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;AAChF,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,iBAAiB,CAAC,QAAyB;IACzD,OAAO,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAA;AAC1B,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,EAAE,CAAA;IAC9C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACvE,IAAI,aAAa,CAAC,KAAK,EAAE,QAA2B,CAAC;YAAE,SAAQ;QAC/D,IAAI,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAAE,SAAQ;QAC3D,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,sBAAsB,CAAA;QAC/C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IACrD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,IAAI;YAAE,SAAQ;QAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QACpC,IAAI,GAAG,KAAK,EAAE;YAAE,OAAO,SAAS,CAAA;QAChC,IAAI,CAAC;YAAC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,GAAG,CAAA;QAAC,CAAC;IAC7D,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,sBAAsB,CAAC,IAAY,EAAE,KAAyB;IACrE,IAAI,IAAI,KAAK,mBAAmB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACrE,4EAA4E;IAC5E,8EAA8E;IAC9E,oBAAoB;IACpB,OAAO,KAAK,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAA;AAC3F,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,eAAe;IAC7B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IAChD,OAAO,2BAA2B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AACrD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,KAA+C;IACxE,MAAM,KAAK,GAAiB;QAC1B,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI;QACnC,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI;QACnC,eAAe,EAAE,KAAK,CAAC,eAAe,KAAK,IAAI;KAChD,CAAA;IACD,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,QAAQ,CAAC,MAAM;YACb,GAAG,cAAc,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;gBAChE,qBAAqB,eAAe,gBAAgB,CAAA;QACtD,sEAAsE;QACtE,sEAAsE;QACtE,sEAAsE;QACtE,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,QAAyB,EAAE,UAA8B,EAAE;IACpF,OAAO,aAAa,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AAC5D,CAAC"}
@@ -6,6 +6,10 @@ export declare const COOKIE_NAMES: {
6
6
  readonly OPTOUT: "kywi_optout";
7
7
  readonly KNOWN: "kywi_known";
8
8
  readonly PREVIEW_INIT: "kywi_preview_init";
9
+ /** First page (path + query) of the visitor's session — kywi-cms#196. */
10
+ readonly ENTRY: "kywi_entry";
11
+ /** Server-readable copy of the visitor's self-ID answers — kywi-cms#200. */
12
+ readonly SELFID: "kywi_selfid";
9
13
  };
10
14
  export declare const COOKIE_MAX_AGE: {
11
15
  readonly SIGNALS: 60;
@@ -15,12 +19,29 @@ export declare const COOKIE_MAX_AGE: {
15
19
  readonly OPTOUT: number;
16
20
  readonly KNOWN: number;
17
21
  readonly PREVIEW_INIT: 30;
22
+ readonly ENTRY: -1;
23
+ /**
24
+ * Not a cookie of its own: the "until the browser closes" lifetime, for a
25
+ * write whose durability depends on consent. A self-ID pin from a visitor who
26
+ * has not consented is honoured for the session and then forgotten, rather
27
+ * than filed for 30 days (kywi-cms#200).
28
+ */
29
+ readonly SESSION: -1;
30
+ readonly SELFID: number;
18
31
  };
19
32
  export declare function signSignals(payload: unknown, secret: string): Promise<string>;
20
33
  export declare function verifySignals(token: string, secret: string): Promise<unknown | null>;
21
34
  export declare function parseCookies(cookieHeader: string): Map<string, string>;
35
+ /**
36
+ * `options.secure` adds the `Secure` attribute, which callers pass when the
37
+ * request being answered is https. It is opt-in rather than always-on because
38
+ * a browser silently DISCARDS a `Secure` cookie over plain http, which would
39
+ * break local development and any http-only deployment — so the caller, which
40
+ * is the only thing that knows the scheme, decides. Omitted, nothing changes.
41
+ */
22
42
  export declare function buildSetCookieHeader(name: string, value: string, maxAge: number, options?: {
23
43
  httpOnly?: boolean;
24
44
  sameSite?: 'Strict' | 'Lax' | 'None';
45
+ secure?: boolean;
25
46
  }): string;
26
47
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/audiences/cookies.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;CAQf,CAAA;AAEV,eAAO,MAAM,cAAc;;;;;;;;CAWjB,CAAA;AAEV,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMnF;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAQ1F;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBtE;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAA;CAAE,GACrE,MAAM,CAQR"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/audiences/cookies.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;IAQvB,yEAAyE;;IAEzE,4EAA4E;;CAEpE,CAAA;AAEV,eAAO,MAAM,cAAc;;;;;;;;;IAczB;;;;;OAKG;;;CAKK,CAAA;AAEV,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMnF;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAQ1F;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBtE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACvF,MAAM,CASR"}
@@ -7,6 +7,10 @@ export const COOKIE_NAMES = {
7
7
  OPTOUT: 'kywi_optout',
8
8
  KNOWN: 'kywi_known',
9
9
  PREVIEW_INIT: 'kywi_preview_init',
10
+ /** First page (path + query) of the visitor's session — kywi-cms#196. */
11
+ ENTRY: 'kywi_entry',
12
+ /** Server-readable copy of the visitor's self-ID answers — kywi-cms#200. */
13
+ SELFID: 'kywi_selfid',
10
14
  };
11
15
  export const COOKIE_MAX_AGE = {
12
16
  SIGNALS: 60,
@@ -19,6 +23,19 @@ export const COOKIE_MAX_AGE = {
19
23
  OPTOUT: 365 * 24 * 3600,
20
24
  KNOWN: 24 * 3600,
21
25
  PREVIEW_INIT: 30,
26
+ // A session cookie (negative = no Max-Age directive): a new visit is a new
27
+ // entry page, so this must not outlive the browser session.
28
+ ENTRY: -1,
29
+ /**
30
+ * Not a cookie of its own: the "until the browser closes" lifetime, for a
31
+ * write whose durability depends on consent. A self-ID pin from a visitor who
32
+ * has not consented is honoured for the session and then forgotten, rather
33
+ * than filed for 30 days (kywi-cms#200).
34
+ */
35
+ SESSION: -1,
36
+ // Self-ID answers persist on the same horizon as the audience they resolve to
37
+ // — long enough to be worth asking for, short enough to age out.
38
+ SELFID: 30 * 24 * 3600,
22
39
  };
23
40
  export async function signSignals(payload, secret) {
24
41
  const key = new TextEncoder().encode(secret);
@@ -65,6 +82,13 @@ export function parseCookies(cookieHeader) {
65
82
  }
66
83
  return map;
67
84
  }
85
+ /**
86
+ * `options.secure` adds the `Secure` attribute, which callers pass when the
87
+ * request being answered is https. It is opt-in rather than always-on because
88
+ * a browser silently DISCARDS a `Secure` cookie over plain http, which would
89
+ * break local development and any http-only deployment — so the caller, which
90
+ * is the only thing that knows the scheme, decides. Omitted, nothing changes.
91
+ */
68
92
  export function buildSetCookieHeader(name, value, maxAge, options) {
69
93
  const parts = [`${name}=${encodeURIComponent(value)}`];
70
94
  if (maxAge >= 0)
@@ -74,6 +98,8 @@ export function buildSetCookieHeader(name, value, maxAge, options) {
74
98
  if (options?.httpOnly !== false)
75
99
  parts.push('HttpOnly');
76
100
  parts.push(`SameSite=${options?.sameSite ?? 'Lax'}`);
101
+ if (options?.secure)
102
+ parts.push('Secure');
77
103
  return parts.join('; ');
78
104
  }
79
105
  //# sourceMappingURL=cookies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/audiences/cookies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/audiences/cookies.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,13 @@
1
1
  import type { VisitorContext, AudienceResult, Audience } from './types.js';
2
2
  export interface AudienceEngineConfig {
3
3
  audiences: Audience[];
4
+ /**
5
+ * `theme.personalization.requireConsent` (kywi-cms#91). Defaults to true —
6
+ * personalization cookies are neither written nor READ for a visitor who has
7
+ * not consented, so a stale id from an earlier "accept" cannot keep resolving
8
+ * them after they reject.
9
+ */
10
+ requireConsent?: boolean;
4
11
  }
5
12
  export interface AudienceEngine {
6
13
  evaluate(context: VisitorContext): Promise<AudienceResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/audiences/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM1F,MAAM,WAAW,oBAAoB;IAAG,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE;AAC/D,MAAM,WAAW,cAAc;IAAG,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;CAAE;AAe9F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CA4BjF"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/audiences/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM1F,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,QAAQ,EAAE,CAAA;IACrB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AACD,MAAM,WAAW,cAAc;IAAG,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;CAAE;AAgB9F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAiCjF"}
@@ -8,6 +8,7 @@ function mergeSignals(base, partial) {
8
8
  referrer: partial.referrer ?? base.referrer,
9
9
  session: partial.session ?? base.session,
10
10
  behavioral: partial.behavioral ?? base.behavioral,
11
+ query: { ...base.query, ...partial.query },
11
12
  selfId: { ...base.selfId, ...partial.selfId },
12
13
  identity: partial.identity ?? base.identity,
13
14
  adapters: { ...base.adapters, ...partial.adapters },
@@ -17,7 +18,10 @@ function mergeSignals(base, partial) {
17
18
  export function createAudienceEngine(config) {
18
19
  return {
19
20
  async evaluate(context) {
20
- const serverSignals = runServerCollectors(context.request);
21
+ // Built conditionally: under `exactOptionalPropertyTypes` an explicit
22
+ // `undefined` is not the same as an absent key.
23
+ const gate = config.requireConsent === undefined ? {} : { requireConsent: config.requireConsent };
24
+ const serverSignals = runServerCollectors(context.request, gate);
21
25
  let signals = mergeSignals(createEmptySignals(), serverSignals);
22
26
  if (context.partialSignals) {
23
27
  signals = mergeSignals(signals, context.partialSignals);
@@ -29,7 +33,8 @@ export function createAudienceEngine(config) {
29
33
  // (behavioral / self-ID) into the server render. Opt-out still wins below,
30
34
  // and `allMatchedIds` stays signal-derived (the pin overrides the winner,
31
35
  // not the set of audiences the current signals matched).
32
- const pinnedAudienceId = collectPinnedAudience(parseCookies(context.request.headers.get('cookie') ?? ''), config.audiences);
36
+ const cookieHeader = context.request.headers.get('cookie');
37
+ const pinnedAudienceId = collectPinnedAudience(parseCookies(cookieHeader ?? ''), config.audiences, { ...gate, cookieHeader });
33
38
  const resolvedWinner = pinnedAudienceId ?? winningAudienceId;
34
39
  return {
35
40
  winningAudienceId: isOptedOut ? null : resolvedWinner,
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/audiences/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAK3C,SAAS,YAAY,CAAC,IAAoB,EAAE,OAAgC;IAC1E,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;QAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU;QACjD,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;QAC3C,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;QACnD,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE;KACxC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAC/D,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAuB;YACpC,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;YAC1D,IAAI,OAAO,GAAG,YAAY,CAAC,kBAAkB,EAAE,EAAE,aAAa,CAAC,CAAA;YAC/D,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;YACzD,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAA;YAC1C,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YACxF,yEAAyE;YACzE,oEAAoE;YACpE,2EAA2E;YAC3E,0EAA0E;YAC1E,yDAAyD;YACzD,MAAM,gBAAgB,GAAG,qBAAqB,CAC5C,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EACzD,MAAM,CAAC,SAAS,CACjB,CAAA;YACD,MAAM,cAAc,GAAG,gBAAgB,IAAI,iBAAiB,CAAA;YAC5D,OAAO;gBACL,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;gBACrD,aAAa;gBACb,OAAO;gBACP,UAAU;aACX,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/audiences/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAc3C,SAAS,YAAY,CAAC,IAAoB,EAAE,OAAgC;IAC1E,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;QAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU;QACjD,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE;QAC1C,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;QAC3C,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;QACnD,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE;KACxC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA4B;IAC/D,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAuB;YACpC,sEAAsE;YACtE,gDAAgD;YAChD,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAA;YACjG,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAChE,IAAI,OAAO,GAAG,YAAY,CAAC,kBAAkB,EAAE,EAAE,aAAa,CAAC,CAAA;YAC/D,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;YACzD,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAA;YAC1C,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YACxF,yEAAyE;YACzE,oEAAoE;YACpE,2EAA2E;YAC3E,0EAA0E;YAC1E,yDAAyD;YACzD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC1D,MAAM,gBAAgB,GAAG,qBAAqB,CAC5C,YAAY,CAAC,YAAY,IAAI,EAAE,CAAC,EAChC,MAAM,CAAC,SAAS,EAChB,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,CAC1B,CAAA;YACD,MAAM,cAAc,GAAG,gBAAgB,IAAI,iBAAiB,CAAA;YAC5D,OAAO;gBACL,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;gBACrD,aAAa;gBACb,OAAO;gBACP,UAAU;aACX,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Entry page — the *write* side of the `kywi_entry` cookie contract
3
+ * (kywi-cms#196).
4
+ *
5
+ * `session.entryPage` has been in the signal catalogue and in the admin rule
6
+ * tester since the audience engine shipped, but nothing in core ever wrote it:
7
+ * `runServerCollectors` fed UTM params, the referrer and the visitor cookies
8
+ * into signal collection and left `session` at its schema defaults, so
9
+ * `entryPage` stayed `'/'` forever. A rule like
10
+ * `session.entryPage contains 'from=marketer'` could not fire on a real request
11
+ * no matter what the visitor did.
12
+ *
13
+ * This module is the missing writer, living next to its reader
14
+ * (`collectors/session.ts`) so a scaffolded app, the reference app and the
15
+ * runtime routes all share one implementation. The contract:
16
+ *
17
+ * • The value is `pathname + search` of the FIRST request of a session —
18
+ * `/developers?from=marketer`, not the whole URL. Query is included on
19
+ * purpose: a campaign link's own params are the interesting part.
20
+ * • It is written ONCE. A request that already carries the cookie returns
21
+ * `null` here, so "entry page" keeps meaning the page the visitor arrived
22
+ * on rather than quietly becoming "current page".
23
+ * • It is written only for a DOCUMENT request. If a subresource could record
24
+ * it, the first request of a session that happens to be `/kywi.js`, a font
25
+ * or an API call would name the entry page, and every rule downstream would
26
+ * be matching against an asset URL. Callers pass `Sec-Fetch-Dest` (and
27
+ * `Accept` for browsers that omit it); saying neither fails closed.
28
+ * • It is a SESSION cookie (no Max-Age): a new visit is a new entry page.
29
+ * • It is a `personalization` cookie in the category map, gated exactly like
30
+ * `kywi_visitor` and `kywi_utm` (kywi-cms#91). Without consent nothing is
31
+ * persisted — and the read side falls back to the CURRENT request's path,
32
+ * so a rule on the entry page still fires on the landing request itself.
33
+ * That fallback is also what makes `/developers?from=marketer` switch on
34
+ * the very request that carries it, with no reload, for everyone: a
35
+ * Set-Cookie only takes effect on the NEXT request.
36
+ *
37
+ * EDGE-SAFE LEAF MODULE: its only import is `./consent.js`, itself a zero-import
38
+ * leaf, because this is imported from Next.js edge middleware where core's
39
+ * DB-backed code cannot run. Keep it dependency-free beyond that. It is
40
+ * published as its own export entry (`@kywi-software/core/audiences/entry-page`)
41
+ * so importing it never drags in the DB-backed `audiences` barrel — the same
42
+ * arrangement as `utm-persistence.ts`.
43
+ */
44
+ import { type ConsentGateOptions } from './consent.js';
45
+ /**
46
+ * Cookie name the entry-page collector reads (mirrors `COOKIE_NAMES.ENTRY` in
47
+ * `audiences/cookies.ts`). Kept as a literal so this leaf imports nothing — the
48
+ * `cookies` module pulls in `jose`, which an edge writer does not need. A core
49
+ * test asserts this stays equal to `COOKIE_NAMES.ENTRY`, so the two cannot drift.
50
+ */
51
+ export declare const ENTRY_COOKIE = "kywi_entry";
52
+ /**
53
+ * The entry-page value for a URL: `pathname + search`, or `null` when the URL
54
+ * cannot be parsed. Exported because the READ side needs exactly the same
55
+ * derivation for its current-request fallback.
56
+ */
57
+ export declare function entryPagePath(url: string): string | null;
58
+ /**
59
+ * The value to write to `kywi_entry` for this request, or `null` to leave things
60
+ * alone. `null` when: the visitor has not consented to personalization, the
61
+ * cookie is already set (the session's entry page is already recorded), or the
62
+ * URL is unparseable.
63
+ *
64
+ * Callers write it as a SESSION cookie — `buildSetCookieHeader(ENTRY_COOKIE,
65
+ * value, -1, { httpOnly: false })`, or the framework equivalent with no
66
+ * `maxAge`.
67
+ */
68
+ export declare function entryPageCookieValue(url: string, options?: {
69
+ cookieHeader?: string | null;
70
+ /** The request's `Sec-Fetch-Dest` header. */
71
+ secFetchDest?: string | null;
72
+ /** The request's `Accept` header — the fallback when `Sec-Fetch-Dest` is absent. */
73
+ accept?: string | null;
74
+ } & ConsentGateOptions): string | null;
75
+ /**
76
+ * Is this request the visitor navigating to a PAGE, rather than the page
77
+ * fetching something?
78
+ *
79
+ * `Sec-Fetch-Dest` is authoritative where it exists (every current browser
80
+ * sends it, and it is one of the headers a page cannot forge). Without it, an
81
+ * `Accept` naming `text/html` is the long-standing signal. Neither is a no:
82
+ * a caller that cannot say what kind of request this is does not get to name
83
+ * the visitor's entry page.
84
+ */
85
+ export declare function isDocumentRequest(headers: {
86
+ secFetchDest?: string | null;
87
+ accept?: string | null;
88
+ }): boolean;
89
+ //# sourceMappingURL=entry-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-page.d.ts","sourceRoot":"","sources":["../../src/audiences/entry-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAE7E;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAe,CAAA;AAExC;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,kBAAuB,GAC1B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,OAAO,CAGV"}