@kywi-software/core 0.11.0 → 0.12.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 (216) hide show
  1. package/AGENT-PATTERNS.md +96 -10
  2. package/dist/admin/content-form.d.ts.map +1 -1
  3. package/dist/admin/content-form.js +97 -10
  4. package/dist/admin/content-form.js.map +1 -1
  5. package/dist/admin/layout-editor/component-actions.d.ts +219 -22
  6. package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
  7. package/dist/admin/layout-editor/component-actions.js +356 -36
  8. package/dist/admin/layout-editor/component-actions.js.map +1 -1
  9. package/dist/admin/layout-editor/component-fork.d.ts +224 -0
  10. package/dist/admin/layout-editor/component-fork.d.ts.map +1 -0
  11. package/dist/admin/layout-editor/component-fork.js +342 -0
  12. package/dist/admin/layout-editor/component-fork.js.map +1 -0
  13. package/dist/admin/layout-editor/editor-canvas.d.ts +12 -0
  14. package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
  15. package/dist/admin/layout-editor/editor-canvas.js +76 -12
  16. package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
  17. package/dist/admin/layout-editor/editor-dialog.d.ts +164 -0
  18. package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -0
  19. package/dist/admin/layout-editor/editor-dialog.js +195 -0
  20. package/dist/admin/layout-editor/editor-dialog.js.map +1 -0
  21. package/dist/admin/layout-editor/editor-state.d.ts +76 -0
  22. package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
  23. package/dist/admin/layout-editor/editor-state.js +47 -1
  24. package/dist/admin/layout-editor/editor-state.js.map +1 -1
  25. package/dist/admin/layout-editor/editor.css +279 -2
  26. package/dist/admin/layout-editor/index.d.ts +10 -1
  27. package/dist/admin/layout-editor/index.d.ts.map +1 -1
  28. package/dist/admin/layout-editor/index.js +11 -1
  29. package/dist/admin/layout-editor/index.js.map +1 -1
  30. package/dist/admin/layout-editor/layout-editor.d.ts +58 -1
  31. package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
  32. package/dist/admin/layout-editor/layout-editor.js +161 -190
  33. package/dist/admin/layout-editor/layout-editor.js.map +1 -1
  34. package/dist/admin/layout-editor/linked-component.d.ts +38 -0
  35. package/dist/admin/layout-editor/linked-component.d.ts.map +1 -0
  36. package/dist/admin/layout-editor/linked-component.js +42 -0
  37. package/dist/admin/layout-editor/linked-component.js.map +1 -0
  38. package/dist/admin/layout-editor/module-overlay.d.ts +10 -1
  39. package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
  40. package/dist/admin/layout-editor/module-overlay.js +33 -4
  41. package/dist/admin/layout-editor/module-overlay.js.map +1 -1
  42. package/dist/admin/layout-editor/node-lookup.d.ts +34 -0
  43. package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
  44. package/dist/admin/layout-editor/node-lookup.js +90 -0
  45. package/dist/admin/layout-editor/node-lookup.js.map +1 -1
  46. package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
  47. package/dist/admin/layout-editor/overlay-shell.js +114 -23
  48. package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
  49. package/dist/admin/layout-editor/props-panel.d.ts +55 -1
  50. package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
  51. package/dist/admin/layout-editor/props-panel.js +118 -9
  52. package/dist/admin/layout-editor/props-panel.js.map +1 -1
  53. package/dist/admin/layout-editor/section-overlay.d.ts +9 -1
  54. package/dist/admin/layout-editor/section-overlay.d.ts.map +1 -1
  55. package/dist/admin/layout-editor/section-overlay.js +14 -4
  56. package/dist/admin/layout-editor/section-overlay.js.map +1 -1
  57. package/dist/admin/layout-editor/section-template-picker.d.ts +27 -1
  58. package/dist/admin/layout-editor/section-template-picker.d.ts.map +1 -1
  59. package/dist/admin/layout-editor/section-template-picker.js +71 -17
  60. package/dist/admin/layout-editor/section-template-picker.js.map +1 -1
  61. package/dist/admin/layout-editor/use-component-connect.d.ts +65 -0
  62. package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -0
  63. package/dist/admin/layout-editor/use-component-connect.js +294 -0
  64. package/dist/admin/layout-editor/use-component-connect.js.map +1 -0
  65. package/dist/admin/layout-editor/use-component-fork.d.ts +123 -0
  66. package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -0
  67. package/dist/admin/layout-editor/use-component-fork.js +346 -0
  68. package/dist/admin/layout-editor/use-component-fork.js.map +1 -0
  69. package/dist/admin/layout-editor/use-component-library.d.ts +94 -0
  70. package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -0
  71. package/dist/admin/layout-editor/use-component-library.js +55 -0
  72. package/dist/admin/layout-editor/use-component-library.js.map +1 -0
  73. package/dist/admin/registry.d.ts +11 -2
  74. package/dist/admin/registry.d.ts.map +1 -1
  75. package/dist/admin/registry.js +40 -4
  76. package/dist/admin/registry.js.map +1 -1
  77. package/dist/admin/server.d.ts +1 -0
  78. package/dist/admin/server.d.ts.map +1 -1
  79. package/dist/admin/server.js +5 -0
  80. package/dist/admin/server.js.map +1 -1
  81. package/dist/admin/styles/admin.css +43 -0
  82. package/dist/admin/surfaces/components/component-edit.d.ts +3 -0
  83. package/dist/admin/surfaces/components/component-edit.d.ts.map +1 -0
  84. package/dist/admin/surfaces/components/component-edit.js +235 -0
  85. package/dist/admin/surfaces/components/component-edit.js.map +1 -0
  86. package/dist/admin/surfaces/components/components-data.d.ts +153 -0
  87. package/dist/admin/surfaces/components/components-data.d.ts.map +1 -0
  88. package/dist/admin/surfaces/components/components-data.js +154 -0
  89. package/dist/admin/surfaces/components/components-data.js.map +1 -0
  90. package/dist/admin/surfaces/components/components-list.d.ts +3 -0
  91. package/dist/admin/surfaces/components/components-list.d.ts.map +1 -0
  92. package/dist/admin/surfaces/components/components-list.js +196 -0
  93. package/dist/admin/surfaces/components/components-list.js.map +1 -0
  94. package/dist/admin/surfaces/components/definition-canvas.d.ts +73 -0
  95. package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -0
  96. package/dist/admin/surfaces/components/definition-canvas.js +207 -0
  97. package/dist/admin/surfaces/components/definition-canvas.js.map +1 -0
  98. package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
  99. package/dist/admin/surfaces/layouts/layout-editor-client.js +14 -2
  100. package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
  101. package/dist/admin/surfaces/layouts/layouts-data.d.ts +3 -14
  102. package/dist/admin/surfaces/layouts/layouts-data.d.ts.map +1 -1
  103. package/dist/admin/surfaces/layouts/layouts-data.js +4 -7
  104. package/dist/admin/surfaces/layouts/layouts-data.js.map +1 -1
  105. package/dist/admin/surfaces/layouts/layouts-list.d.ts.map +1 -1
  106. package/dist/admin/surfaces/layouts/layouts-list.js +16 -22
  107. package/dist/admin/surfaces/layouts/layouts-list.js.map +1 -1
  108. package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
  109. package/dist/admin/surfaces/settings/admin-features.js +1 -0
  110. package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
  111. package/dist/api/bulk-routes.d.ts.map +1 -1
  112. package/dist/api/bulk-routes.js +25 -0
  113. package/dist/api/bulk-routes.js.map +1 -1
  114. package/dist/api/changeset-routes.d.ts.map +1 -1
  115. package/dist/api/changeset-routes.js +17 -3
  116. package/dist/api/changeset-routes.js.map +1 -1
  117. package/dist/api/component-routes.d.ts.map +1 -1
  118. package/dist/api/component-routes.js +228 -8
  119. package/dist/api/component-routes.js.map +1 -1
  120. package/dist/api/content-routes.d.ts.map +1 -1
  121. package/dist/api/content-routes.js +64 -0
  122. package/dist/api/content-routes.js.map +1 -1
  123. package/dist/api/feed-routes.d.ts +6 -6
  124. package/dist/api/graphql/resolvers.d.ts +4 -4
  125. package/dist/api/layout-routes.d.ts.map +1 -1
  126. package/dist/api/layout-routes.js +4 -17
  127. package/dist/api/layout-routes.js.map +1 -1
  128. package/dist/api/layout-write-guard.d.ts +80 -0
  129. package/dist/api/layout-write-guard.d.ts.map +1 -0
  130. package/dist/api/layout-write-guard.js +88 -0
  131. package/dist/api/layout-write-guard.js.map +1 -0
  132. package/dist/api/section-template-routes.d.ts.map +1 -1
  133. package/dist/api/section-template-routes.js +11 -0
  134. package/dist/api/section-template-routes.js.map +1 -1
  135. package/dist/api/translation-routes.d.ts.map +1 -1
  136. package/dist/api/translation-routes.js +8 -0
  137. package/dist/api/translation-routes.js.map +1 -1
  138. package/dist/api/version-routes.d.ts.map +1 -1
  139. package/dist/api/version-routes.js +20 -8
  140. package/dist/api/version-routes.js.map +1 -1
  141. package/dist/api/workflow-routes.d.ts.map +1 -1
  142. package/dist/api/workflow-routes.js +53 -8
  143. package/dist/api/workflow-routes.js.map +1 -1
  144. package/dist/db/analytics-queries.d.ts +3 -3
  145. package/dist/db/apply-snapshot.d.ts +75 -8
  146. package/dist/db/apply-snapshot.d.ts.map +1 -1
  147. package/dist/db/apply-snapshot.js +104 -8
  148. package/dist/db/apply-snapshot.js.map +1 -1
  149. package/dist/db/audit-queries.d.ts +12 -12
  150. package/dist/db/category-queries.d.ts +3 -3
  151. package/dist/db/changeset-audit-queries.d.ts +4 -4
  152. package/dist/db/changeset-queries.d.ts +7 -7
  153. package/dist/db/comment-queries.d.ts +8 -8
  154. package/dist/db/comment-subscription-queries.d.ts +2 -2
  155. package/dist/db/component-instance-queries.d.ts +197 -0
  156. package/dist/db/component-instance-queries.d.ts.map +1 -0
  157. package/dist/db/component-instance-queries.js +405 -0
  158. package/dist/db/component-instance-queries.js.map +1 -0
  159. package/dist/db/content-queries.d.ts.map +1 -1
  160. package/dist/db/content-queries.js +39 -2
  161. package/dist/db/content-queries.js.map +1 -1
  162. package/dist/db/extension-queries.d.ts +7 -7
  163. package/dist/db/feed-queries.d.ts +3 -3
  164. package/dist/db/index.d.ts +1 -0
  165. package/dist/db/index.d.ts.map +1 -1
  166. package/dist/db/index.js +1 -0
  167. package/dist/db/index.js.map +1 -1
  168. package/dist/db/layout-queries.d.ts +13 -1
  169. package/dist/db/layout-queries.d.ts.map +1 -1
  170. package/dist/db/layout-queries.js +52 -7
  171. package/dist/db/layout-queries.js.map +1 -1
  172. package/dist/db/locale-queries.d.ts.map +1 -1
  173. package/dist/db/locale-queries.js +0 -0
  174. package/dist/db/locale-queries.js.map +1 -1
  175. package/dist/db/media-queries.d.ts +12 -12
  176. package/dist/db/revision-queries.d.ts +3 -3
  177. package/dist/db/site-admin-queries.d.ts +2 -2
  178. package/dist/db/site-membership-queries.d.ts +3 -3
  179. package/dist/db/site-plugin-queries.d.ts +2 -2
  180. package/dist/db/site-queries.d.ts +6 -6
  181. package/dist/db/version-queries.d.ts +12 -12
  182. package/dist/db/webhook-queries.d.ts +11 -11
  183. package/dist/db/workflow-queries.d.ts +6 -6
  184. package/dist/db/workflow-queries.d.ts.map +1 -1
  185. package/dist/db/workflow-queries.js +11 -2
  186. package/dist/db/workflow-queries.js.map +1 -1
  187. package/dist/layout/component-refs.d.ts +465 -0
  188. package/dist/layout/component-refs.d.ts.map +1 -0
  189. package/dist/layout/component-refs.js +848 -0
  190. package/dist/layout/component-refs.js.map +1 -0
  191. package/dist/layout/index.d.ts +2 -1
  192. package/dist/layout/index.d.ts.map +1 -1
  193. package/dist/layout/index.js +1 -0
  194. package/dist/layout/index.js.map +1 -1
  195. package/dist/layout/module-permissions.d.ts +49 -1
  196. package/dist/layout/module-permissions.d.ts.map +1 -1
  197. package/dist/layout/module-permissions.js +117 -6
  198. package/dist/layout/module-permissions.js.map +1 -1
  199. package/dist/layout/renderer.d.ts +51 -4
  200. package/dist/layout/renderer.d.ts.map +1 -1
  201. package/dist/layout/renderer.js +36 -38
  202. package/dist/layout/renderer.js.map +1 -1
  203. package/dist/layout/types.d.ts +42 -0
  204. package/dist/layout/types.d.ts.map +1 -1
  205. package/dist/layout/types.js +54 -11
  206. package/dist/layout/types.js.map +1 -1
  207. package/dist/schema/base.d.ts +1 -1
  208. package/dist/schema/components.d.ts +150 -0
  209. package/dist/schema/components.d.ts.map +1 -1
  210. package/dist/schema/components.js +50 -4
  211. package/dist/schema/components.js.map +1 -1
  212. package/dist/versioning/scheduler.d.ts +8 -0
  213. package/dist/versioning/scheduler.d.ts.map +1 -1
  214. package/dist/versioning/scheduler.js +21 -7
  215. package/dist/versioning/scheduler.js.map +1 -1
  216. package/package.json +1 -1
@@ -8,6 +8,7 @@
8
8
  * - Clone / Duplicate
9
9
  * - Copy / Paste (clipboard serialization)
10
10
  */
11
+ import { collectComponentRefs, componentDetachSource, detachComponentFromLayout, detachModuleNode, detachSectionNode, detachVariantContainerNode, materializeModuleNode, } from '../../layout/component-refs.js';
11
12
  import { generateId } from './generate-id.js';
12
13
  // ── Connected Placement ──────────────────────────────────────────
13
14
  /**
@@ -63,6 +64,27 @@ export function resolveSectionComponentDefinition(component) {
63
64
  return null;
64
65
  return def;
65
66
  }
67
+ /**
68
+ * Project a saved variant-container component to its stored
69
+ * {@link VariantContainer} definition — the shape the renderer's
70
+ * `VariantContainerComponentResolver` expects (kywi-cms#147). Returns null for a
71
+ * non-container component or a malformed definition, so an unresolvable
72
+ * reference falls through to the container's own inline copy.
73
+ *
74
+ * The public site's `variantContainerComponentResolver` is just
75
+ * `id => resolveVariantContainerComponentDefinition(await getComponentById(db, id, siteId))`
76
+ * — the third member of the family, wired exactly like the other two.
77
+ */
78
+ export function resolveVariantContainerComponentDefinition(component) {
79
+ if (!component || component.type !== 'variantContainer')
80
+ return null;
81
+ const def = component.definition;
82
+ if (!def || typeof def !== 'object')
83
+ return null;
84
+ if (def.type !== 'variantContainer')
85
+ return null;
86
+ return def;
87
+ }
66
88
  /**
67
89
  * Build a `LayoutSection` that references a saved section component by id
68
90
  * (kywi-cms#69). The resolved definition's columns/style are carried as the
@@ -77,68 +99,331 @@ export function buildConnectedSectionNode(component) {
77
99
  return null;
78
100
  return { ...def, componentId: component.id };
79
101
  }
102
+ /**
103
+ * Build a `VariantContainer` that references a saved variant-container component
104
+ * by id (kywi-cms#147) — the third member of the `buildConnected*` family.
105
+ *
106
+ * As with a connected section, the resolved definition rides along as the inline
107
+ * fallback copy and `componentId` is stamped so the renderer resolves it live;
108
+ * returns null when the component isn't a resolvable container.
109
+ *
110
+ * The one thing NOT copied is the definition's experiment binding.
111
+ * `applyVariantContainerPlacement` gives the PLACEMENT's `experimentId` /
112
+ * `winnerId` priority precisely because they identify *this page's* experiment
113
+ * run — which arms report where, and which arm has been locked in. Carrying the
114
+ * saved component's binding into a new placement would silently enrol a second
115
+ * page's container in the first page's experiment (`cloneVariantContainer`'s own
116
+ * docstring flags the same hazard for duplication and tells callers to re-bind).
117
+ * So an `ab_test` placement is born with a FRESH `experimentId` and no winner,
118
+ * which is exactly what `WRAP_SECTION_IN_VARIANT_CONTAINER` mints for a
119
+ * hand-built container. A `personalization` container has no binding to mint.
120
+ */
121
+ export function buildConnectedVariantContainerNode(component) {
122
+ const def = resolveVariantContainerComponentDefinition(component ?? null);
123
+ if (!def || !component)
124
+ return null;
125
+ const { experimentId: _boundElsewhere, winnerId: _decidedElsewhere, ...rest } = def;
126
+ return {
127
+ ...rest,
128
+ ...(def.mode === 'ab_test' ? { experimentId: generateId() } : {}),
129
+ componentId: component.id,
130
+ };
131
+ }
132
+ // ── Flattening nested links (kywi-cms#147) ───────────────────────
133
+ /**
134
+ * How many materialisation passes {@link flattenComponentLinks} will make.
135
+ *
136
+ * WHY IT IS UNREACHABLE, and why it is here anyway (kywi-cms#147 T3 review, M3).
137
+ * Two independent bounds already guarantee convergence:
138
+ *
139
+ * - materialising a RESOLVABLE link strips every link inside what it bakes in
140
+ * (`stripLinksInSection`, called from the placement helpers — deliberately, so
141
+ * neither detach nor pre-resolution can promote a dormant nested link), so a
142
+ * resolvable link can never produce another one. Not even a cyclic definition
143
+ * — `A`'s definition naming `A` — survives one pass;
144
+ * - materialising an UNRESOLVABLE link only reveals what the document already
145
+ * held one level down, and that nesting is bounded by the node kinds
146
+ * themselves: container → arm section → module, with module definitions being
147
+ * leaves. Three passes, worst case, for a linked container.
148
+ *
149
+ * So this is a guard against a future change to those walkers, not an expected
150
+ * limit — and it fails SAFE rather than silently: flattening stops with links
151
+ * still inside, the API refuses the definition, and the owner sees the validator's
152
+ * own words in the dialog. Exported so a test can pin that reasoning instead of
153
+ * trusting it.
154
+ */
155
+ export const MAX_FLATTEN_PASSES = 8;
156
+ /**
157
+ * Is this a SECTION or a VARIANT CONTAINER (rather than a module node)?
158
+ *
159
+ * `node.type` alone is not enough. A region node's `type` is a fixed literal, but
160
+ * a MODULE's `type` is a registry name — an arbitrary string a host module pack
161
+ * chooses — so a custom module registered as `section` or `variantContainer`
162
+ * would be misread as a region node by a bare `type ===` check and saved as the
163
+ * wrong kind of component (its definition stored as a layout section that the
164
+ * validator then rejects). Checking the structure the kind is defined BY closes
165
+ * that: a section has `columns`, a container has `defaultSections`, and no module
166
+ * node has either.
167
+ */
168
+ function isRegionNodeShape(node) {
169
+ if (typeof node !== 'object' || node === null)
170
+ return false;
171
+ const candidate = node;
172
+ if (candidate.type === 'section')
173
+ return Array.isArray(candidate.columns);
174
+ if (candidate.type === 'variantContainer')
175
+ return Array.isArray(candidate.defaultSections);
176
+ return false;
177
+ }
178
+ /**
179
+ * Materialise every component link INSIDE a selection, so what is left is a
180
+ * self-contained tree — the shape "save as component" is allowed to store.
181
+ *
182
+ * WHY THIS IS MANDATORY. `validateComponentDefinition` REFUSES a definition that
183
+ * links to another component (kywi-cms#147, T2 round 1), so saving a section that
184
+ * happens to contain a connected module would just 400. That refusal is not a
185
+ * technicality: a nested link is invisible to `collectComponentRefs` (which stops
186
+ * at a connected node), so the instance index, the usage counts and the delete
187
+ * gate would never see it, and the component could be deleted while a page still
188
+ * rendered it one level down. The flows that want nesting therefore MATERIALISE
189
+ * rather than link — which is this function.
190
+ *
191
+ * HOW. Each pass asks the canonical walker where the links are
192
+ * ({@link collectComponentRefs}) and rewrites each one with the canonical
193
+ * whole-document detach ({@link detachComponentFromLayout}) — the same code the
194
+ * server's detach-all runs — so a materialised link bakes in exactly what the
195
+ * page was rendering through it. A link the caller cannot resolve is materialised
196
+ * from the `unresolvable` source, which drops the link and keeps the node's own
197
+ * inline content: again exactly what the visitor sees today, since an
198
+ * unresolvable link renders its fallback copy.
199
+ *
200
+ * It LOOPS because `collectComponentRefs` deliberately does not descend into a
201
+ * connected section/container: an unresolvable connected section keeps its inline
202
+ * fallback copy, and that copy may itself hold a link which only becomes visible
203
+ * once the outer link is gone. Each pass removes at least one link, so the loop
204
+ * converges; the cap is a belt-and-braces bound, not an expected limit.
205
+ *
206
+ * The result is JSON-round-tripped: `detachComponentFromLayout` is a projection
207
+ * whose nested `props`/`style` still point into the component definitions it read
208
+ * (cached API rows in the editor), and a definition about to be POSTed must not
209
+ * alias them — see `detachedCopy`.
210
+ */
211
+ export function flattenComponentLinks(source, resolveLink) {
212
+ return flattenWithCount(source, resolveLink).node;
213
+ }
214
+ /**
215
+ * How many component links {@link flattenComponentLinks} would materialise in
216
+ * this selection — the number the save dialog discloses.
217
+ *
218
+ * NOT `collectComponentRefs(...).length` (kywi-cms#147 T3 review, M2): that
219
+ * walker stops at a connected node, so a link hidden in a connected node's
220
+ * inline fallback copy is invisible to it while the flattening finds it on the
221
+ * next pass and rewrites it anyway. Counting one and doing the other means the
222
+ * dialog understates its own blast radius — "1 instance will stop following its
223
+ * source" for a save that actually unhooks two. So the count comes from running
224
+ * the real fixpoint and tallying what it rewrote.
225
+ *
226
+ * The root's OWN link is included when it carries one, so a caller talking about
227
+ * links *inside* the selection subtracts it (the flows that offer this never
228
+ * pass a linked root — saving an instance as a new component is not offered).
229
+ */
230
+ export function countComponentLinksToFlatten(source, resolveLink) {
231
+ return flattenWithCount(source, resolveLink).materialised;
232
+ }
233
+ /** {@link flattenComponentLinks}, reporting how many links it rewrote. */
234
+ function flattenWithCount(source, resolveLink) {
235
+ const sourceFor = (componentId) => resolveLink?.(componentId) ?? { kind: 'unresolvable' };
236
+ // A module node is a leaf: the only link it can carry is its own, and there is
237
+ // no document shape to walk. (Saving an already-linked node as a NEW component
238
+ // is not offered in the UI, but materialising it here is the same
239
+ // render-faithful answer, so the function is total.)
240
+ if (!isRegionNodeShape(source)) {
241
+ const node = source;
242
+ if (!node.componentId)
243
+ return { node: detachedCopy(source), materialised: 0 };
244
+ return {
245
+ node: detachedCopy(materializeModuleNode(node, sourceFor(node.componentId), 'drop')),
246
+ materialised: 1,
247
+ };
248
+ }
249
+ let node = source;
250
+ let materialised = 0;
251
+ for (let pass = 0; pass < MAX_FLATTEN_PASSES; pass++) {
252
+ const refs = collectComponentRefs({ regions: { selection: [node] } });
253
+ if (refs.length === 0)
254
+ break;
255
+ let layout = { regions: { selection: [node] } };
256
+ for (const componentId of new Set(refs.map(ref => ref.componentId))) {
257
+ layout = detachComponentFromLayout(layout, componentId, sourceFor(componentId)).layout;
258
+ }
259
+ const rewritten = layout.regions['selection']?.[0];
260
+ if (rewritten === undefined)
261
+ break;
262
+ // Counted per PLACEMENT, not per component: two instances of one component
263
+ // are two links that stop following it.
264
+ materialised += refs.length;
265
+ node = rewritten;
266
+ }
267
+ return { node: detachedCopy(node), materialised };
268
+ }
80
269
  // ── Detach from Source ───────────────────────────────────────────
270
+ //
271
+ // THERE ARE TWO DETACHES, AND THEY ARE NOT INTERCHANGEABLE (final review, M6).
272
+ //
273
+ // The three `detach*FromComponent` helpers below are the props rail's "Detach
274
+ // from component": they materialise the component's CURRENT definition into the
275
+ // node and drop the link, so the page keeps rendering exactly what it rendered a
276
+ // moment ago. That is right for a node that is showing the definition.
277
+ //
278
+ // The save fork's "Save to this page only" is a different function —
279
+ // `detachInstanceKeepingEdits` in `./component-fork.ts` — because there the node
280
+ // is NOT showing the definition: the author has edited it, and materialising the
281
+ // stored definition would throw that edit away, which is the one thing that
282
+ // button must not do. Its docstring carries the full contrast (section/container
283
+ // keep their edited subtree; a module's overrides merge on top of the
284
+ // definition). Reach for it whenever the node is dirty; reach for these when it
285
+ // is not. Calling the wrong one silently reverts or silently keeps an edit.
286
+ //
287
+ // Both delegate to the same canonical machinery in `layout/component-refs.ts`, so
288
+ // neither invents a third answer to "what does a detached node contain".
289
+ /**
290
+ * Deep-copy a materialised node before it enters editor state.
291
+ *
292
+ * The canonical detach in `layout/component-refs.ts` is a projection: it builds
293
+ * new nodes but nested `props`/`style` values still point at the component
294
+ * definition it read. That is harmless server-side, where the result is
295
+ * serialised into jsonb on the next line — but in the editor the definition is a
296
+ * cached `GET /components` row that would then be mutated by editing the very
297
+ * section the user just detached. Layout data is jsonb by definition, so a JSON
298
+ * round-trip is a total deep copy — and it is exactly the round-trip the server
299
+ * result goes through, which is why the two stay byte-identical.
300
+ */
301
+ function detachedCopy(node) {
302
+ return JSON.parse(JSON.stringify(node));
303
+ }
81
304
  /**
82
305
  * Convert a connected module node (with componentId) into a disconnected
83
- * inline node. Snapshots the component's current definition into the node.
306
+ * inline node, materialising the component's CURRENT definition.
307
+ *
308
+ * Thin wrapper over the canonical `layout/component-refs.ts` implementation —
309
+ * the same function the server-side detach-all runs — so detaching one instance
310
+ * in the editor and detaching every instance from the API produce byte-identical
311
+ * nodes for the same placement. Two implementations of "what does detaching
312
+ * produce" is how a page silently changes content depending on which button was
313
+ * pressed.
84
314
  *
85
- * If the node has no componentId or component is null, returns the node as-is.
315
+ * A node with no componentId is returned as-is (there is nothing to detach). A
316
+ * missing or unresolvable component drops the link and keeps the node exactly as
317
+ * it renders today, rather than inventing content the page never showed.
86
318
  */
87
319
  export function detachModuleFromComponent(node, component) {
88
- if (!node.componentId || !component)
320
+ if (!node.componentId)
89
321
  return node;
90
- const def = component.definition;
91
- const componentProps = (def.props ?? {});
92
- const componentStyle = (def.style ?? {});
93
- const resolvedProps = { ...componentProps, ...node.props };
94
- return {
95
- id: generateId(),
96
- type: component.moduleType ?? node.type,
97
- instanceId: generateId(),
98
- props: resolvedProps,
99
- style: { ...componentStyle, ...node.style },
100
- };
322
+ return detachedCopy(detachModuleNode(node, componentDetachSource(component)));
101
323
  }
102
324
  /**
103
325
  * Convert a connected section (with componentId) into a disconnected inline
104
- * section (kywi-cms#69). Drops the link and keeps a deep local copy with fresh
105
- * ids (reuse `cloneSection`) so the detached section is fully editable. v1
106
- * sections are all-or-nothing references the section already carries the
107
- * resolved definition as its inline copy so detach simply strips the link;
108
- * no per-instance prop merge (unlike `detachModuleFromComponent`).
326
+ * section (kywi-cms#69), materialising the component's CURRENT definition.
327
+ *
328
+ * The section's inline `columns` are only the stale fallback copy the renderer
329
+ * shows when the link cannot be resolved; strict-link semantics say the live
330
+ * definition is what the page is actually rendering, so that is what detaching
331
+ * has to bake in — re-keyed off this section's own id exactly as the renderer
332
+ * re-keys it. Hence the `component` argument, and hence the delegation to the
333
+ * canonical `layout/component-refs.ts` implementation shared with the server.
109
334
  *
110
- * If the section has no componentId, returns it as-is.
335
+ * A section with no componentId is returned as-is; an unresolvable component
336
+ * degrades to dropping the link and keeping the inline copy, which is once again
337
+ * exactly what the page was rendering.
111
338
  */
112
- export function detachSectionFromComponent(section) {
339
+ export function detachSectionFromComponent(section, component) {
113
340
  if (!section.componentId)
114
341
  return section;
115
- // Omit componentId rather than set it undefined so the source satisfies
116
- // LayoutSection under exactOptionalPropertyTypes; cloneSection then deep-copies
117
- // with fresh ids and (correctly) carries no link forward.
118
- const { componentId: _componentId, ...bare } = section;
119
- return cloneSection(bare);
342
+ return detachedCopy(detachSectionNode(section, componentDetachSource(component)));
120
343
  }
121
- // ── Save as Component ────────────────────────────────────────────
122
344
  /**
123
- * Build a component definition input from a module node or section.
124
- * This can then be passed to `createComponent()` from the DB layer.
345
+ * Convert a connected variant container into a disconnected inline one
346
+ * (kywi-cms#147), materialising the component's CURRENT definition the
347
+ * container counterpart of {@link detachSectionFromComponent}, delegating to the
348
+ * same canonical implementation the server-side detach-all runs.
349
+ *
350
+ * The placement's own `experimentId`/`winnerId` survive the materialisation:
351
+ * they bind this page's container to this page's experiment run, which detaching
352
+ * must not silently re-point at whatever the component was saved with.
353
+ */
354
+ export function detachVariantContainerFromComponent(container, component) {
355
+ if (!container.componentId)
356
+ return container;
357
+ return detachedCopy(detachVariantContainerNode(container, componentDetachSource(component)));
358
+ }
359
+ /**
360
+ * Build a component definition input from a module node, a section, or a
361
+ * section-level variant container (kywi-cms#147 adds the third).
362
+ * This can then be POSTed to `/components` (or passed to `createComponent()`).
363
+ *
364
+ * Any component link inside the selection is materialised first
365
+ * ({@link flattenComponentLinks}) — the API refuses a definition that links to
366
+ * another component, so this is not an optimisation but the difference between a
367
+ * save that works and a 400.
125
368
  */
126
- export function saveAsComponent(source, name, description) {
127
- if ('type' in source && source.type === 'section') {
369
+ export function saveAsComponent(source, name, options = {}) {
370
+ const { description, resolveLink } = options;
371
+ const flattened = flattenComponentLinks(source, resolveLink);
372
+ const described = description ? { description } : {};
373
+ // Structural checks, not `type ===` alone: a module's `type` is a registry name
374
+ // and a host pack may legitimately register one called `section` (see
375
+ // {@link isRegionNodeShape}).
376
+ if (isRegionNodeShape(flattened) && flattened.type === 'section') {
128
377
  // Section-level component
129
378
  return {
130
379
  name,
131
- description: description ?? null,
380
+ ...described,
132
381
  type: 'section',
133
- moduleType: null,
134
- definition: source,
382
+ definition: flattened,
383
+ };
384
+ }
385
+ if (isRegionNodeShape(flattened) && flattened.type === 'variantContainer') {
386
+ // Container-level component: a personalized / A-B'd band saved whole. Its
387
+ // arms travel with it; audience and experiment resolution still happen at
388
+ // render time, per placement.
389
+ //
390
+ // WHY `winnerId` IS DROPPED HERE AND `experimentId` IS NOT (final review, I2).
391
+ //
392
+ // `applyVariantContainerPlacement` gives the DEFINITION's experiment binding
393
+ // to any placement that names none of its own — which is every placement
394
+ // written straight over the API (the editors mint a fresh id per placement,
395
+ // `buildConnectedVariantContainerNode`). So whatever binding a definition
396
+ // carries is a binding future placements can inherit.
397
+ //
398
+ // A `winnerId` inheritable that way is the worst version of it: the run it
399
+ // names is DECIDED, so every inheriting placement serves one arm forever, on
400
+ // pages nobody tested. A definition must never lock a future placement to a
401
+ // finished run, and unlike the experiment id there is nothing to weigh
402
+ // against dropping it — a band with no declared winner simply resolves by
403
+ // audience/assignment, which is what a freshly placed band should do.
404
+ //
405
+ // `experimentId` cannot go the same way: `validateVariantContainer` REQUIRES
406
+ // one when `mode` is `ab_test`, so a bindingless definition is one no door
407
+ // would accept — the component would be born un-saveable and un-editable
408
+ // (`pinDefinitionBinding` in surfaces/components/definition-canvas.ts reaches
409
+ // the same conclusion from the definition-canvas side, for the same reason).
410
+ // It is still a shared-run hazard for an API-written placement, which is why
411
+ // AGENT-PATTERNS §4 step 2 tells an agent to mint a fresh one. Dropping the
412
+ // winner also matches `buildUpdateAll`, so the two ways a definition can be
413
+ // written from an edited band agree on what belongs to the page.
414
+ const { winnerId: _decidedOnTheSourcePage, ...definition } = flattened;
415
+ return {
416
+ name,
417
+ ...described,
418
+ type: 'variantContainer',
419
+ definition: definition,
135
420
  };
136
421
  }
137
422
  // Module-level component
138
- const moduleNode = source;
423
+ const moduleNode = flattened;
139
424
  return {
140
425
  name,
141
- description: description ?? null,
426
+ ...described,
142
427
  type: 'module',
143
428
  moduleType: moduleNode.type,
144
429
  definition: {
@@ -185,6 +470,38 @@ export function cloneSection(section) {
185
470
  ...(section.componentId !== undefined ? { componentId: section.componentId } : {}),
186
471
  };
187
472
  }
473
+ /**
474
+ * Deep-clone a variant container with fresh ids for the container, its variant
475
+ * arms and every section beneath them.
476
+ *
477
+ * A connected container's `componentId` is preserved, mirroring `cloneSection` /
478
+ * `cloneModule`: duplicating or pasting a linked container gives a second
479
+ * PLACEMENT of the same component, not a copy that has quietly stopped
480
+ * following it. The inline arms come along as the fallback copy, which is what
481
+ * keeps the duplicate rendering when the link can't be resolved.
482
+ *
483
+ * `mode` and the experiment binding are copied verbatim, so a duplicated
484
+ * `ab_test` container reports to the SAME experiment as its original. That is
485
+ * the honest copy semantic — two containers genuinely feeding one experiment —
486
+ * but it is rarely what a user wants, so callers offering a duplicate action on
487
+ * an A/B container should re-bind `experimentId` afterwards.
488
+ */
489
+ export function cloneVariantContainer(container) {
490
+ return {
491
+ id: generateId(),
492
+ type: 'variantContainer',
493
+ mode: container.mode,
494
+ ...(container.experimentId !== undefined ? { experimentId: container.experimentId } : {}),
495
+ ...(container.winnerId !== undefined ? { winnerId: container.winnerId } : {}),
496
+ defaultSections: container.defaultSections.map(cloneSection),
497
+ variants: container.variants.map((variant) => ({
498
+ ...variant,
499
+ id: generateId(),
500
+ sections: variant.sections.map(cloneSection),
501
+ })),
502
+ ...(container.componentId !== undefined ? { componentId: container.componentId } : {}),
503
+ };
504
+ }
188
505
  /** Deep-clone a column with fresh IDs. */
189
506
  function cloneColumn(column) {
190
507
  return {
@@ -216,6 +533,9 @@ export function pasteFromClipboard(payload) {
216
533
  if (payload.kind === 'section') {
217
534
  return cloneSection(parsed);
218
535
  }
536
+ if (payload.kind === 'variantContainer') {
537
+ return cloneVariantContainer(parsed);
538
+ }
219
539
  return null;
220
540
  }
221
541
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"component-actions.js","sourceRoot":"","sources":["../../../src/admin/layout-editor/component-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AA0B7C,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,UAAU,EAAE;QACxB,KAAK,EAAE,EAAE,WAAW,EAAE;QACtB,KAAK,EAAE,EAAE;QACT,WAAW;KACZ,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CACxC,SAA8F;IAE9F,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,IAAI,CAAA;IACnF,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAA;IACnE,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B;QACnD,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA2B;QAClD,UAAU,EAAE,SAAS,CAAC,UAAU;KACjC,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iCAAiC,CAC/C,SAAoE;IAEpE,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC3D,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,CAAA;IAChC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAChD,IAAK,GAA0B,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC/D,OAAO,GAAoB,CAAA;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAAgF;IAEhF,MAAM,GAAG,GAAG,iCAAiC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAA;IAChE,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IACnC,OAAO,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,CAAA;AAC9C,CAAC;AAED,oEAAoE;AAEpE;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAgB,EAChB,SAAkC;IAElC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAEhD,MAAM,GAAG,GAAG,SAAS,CAAC,UAAqC,CAAA;IAC3D,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAA;IACnE,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA2B,CAAA;IAClE,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;IAE1D,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI;QACvC,UAAU,EAAE,UAAU,EAAE;QACxB,KAAK,EAAE,aAAa;QACpB,KAAK,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;KAC5C,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAsB;IAC/D,IAAI,CAAC,OAAO,CAAC,WAAW;QAAE,OAAO,OAAO,CAAA;IACxC,wEAAwE;IACxE,gFAAgF;IAChF,0DAA0D;IAC1D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IACtD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC;AAED,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAkC,EAClC,IAAY,EACZ,WAAoB;IAEpB,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClD,0BAA0B;QAC1B,OAAO;YACL,IAAI;YACJ,WAAW,EAAE,WAAW,IAAI,IAAI;YAChC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,MAA4C;SACzD,CAAA;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,UAAU,GAAG,MAAoB,CAAA;IACvC,OAAO;QACL,IAAI;QACJ,WAAW,EAAE,WAAW,IAAI,IAAI;QAChC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,UAAU,CAAC,IAAI;QAC3B,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;YAC9B,KAAK,EAAE,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;SAC/B;KACF,CAAA;AACH,CAAC;AAED,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsB,EACtB,IAAY,EACZ,QAAiB;IAEjB,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,QAAQ,IAAI,SAAS;QAC/B,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC;KACrC,CAAA;AACH,CAAC;AAED,oEAAoE;AAEpE,+CAA+C;AAC/C,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,UAAU,EAAE;QACxB,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC;QACrC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACrD,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnF,CAAA;AACH,CAAC;AAED,0CAA0C;AAC1C,SAAS,WAAW,CAAC,MAAoB;IACvC,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;KACnD,CAAA;AACH,CAAC;AAED,oEAAoE;AAEpE;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAA0B,EAC1B,MAAkC;IAElC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;KAC7B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAA4B,CAAA;QAElE,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,WAAW,CAAC,MAA+B,CAAC,CAAA;QACrD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,YAAY,CAAC,MAAkC,CAAC,CAAA;QACzD,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"component-actions.js","sourceRoot":"","sources":["../../../src/admin/layout-editor/component-actions.ts"],"names":[],"mappings":"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"}