@kywi-software/core 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +8 -0
  14. package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
  15. package/dist/admin/layout-editor/editor-canvas.js +120 -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 +160 -190
  33. package/dist/admin/layout-editor/layout-editor.js.map +1 -1
  34. package/dist/admin/layout-editor/linked-component.d.ts +39 -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 +35 -0
  43. package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
  44. package/dist/admin/layout-editor/node-lookup.js +91 -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 +54 -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 +61 -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 +292 -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
@@ -1,5 +1,7 @@
1
1
  import { eq, sql, getTableColumns } from 'drizzle-orm';
2
2
  import { kywiContent } from '../schema/base.js';
3
+ import { validateLayoutDocument } from '../layout/types.js';
4
+ import { setContentLayout } from './layout-queries.js';
3
5
  /**
4
6
  * Shared "apply a stored snapshot back onto the live content row" logic.
5
7
  *
@@ -13,16 +15,29 @@ import { kywiContent } from '../schema/base.js';
13
15
  * timestamps as ISO strings that drizzle's `timestamp` columns cannot serialise
14
16
  * (they call `.toISOString()` on the value), and (b) identity/tree-placement
15
17
  * columns (id, siteId, path, slug, parentId, …) are the row's spine and must not
16
- * be rewritten from history. This module centralises that sanitisation so the
17
- * changeset-publish and revision-approve paths behave identically.
18
+ * be rewritten from history, and (c) `layout` is a document with rules, not a
19
+ * blob: it is validated and written through `setContentLayout` so the component
20
+ * instance index stays true (kywi-cms#147). This module centralises that
21
+ * sanitisation so the changeset-publish and revision-approve paths behave
22
+ * identically — and so does the version restore in db/workflow-queries.ts, which
23
+ * shares the layout half.
18
24
  */
19
25
  /**
20
- * Columns never applied from a stored snapshot. Three groups: row identity
21
- * (id/siteId), tree placement + addressing (path, depth, parentId, slug,
22
- * sortOrder — owned by the move/slug-cascade machinery, never restored from a
23
- * content snapshot), and write bookkeeping (created*, updated*, deletedAt).
24
- * `status` and `publishedAt` are skipped too: an apply is always a publish, so
25
- * the caller sets them explicitly.
26
+ * Columns never applied from a stored snapshot by the raw column write. Three
27
+ * groups: row identity (id/siteId), tree placement + addressing (path, depth,
28
+ * parentId, slug, sortOrder — owned by the move/slug-cascade machinery, never
29
+ * restored from a content snapshot), and write bookkeeping (created*, updated*,
30
+ * deletedAt). `status` and `publishedAt` are skipped too: an apply is always a
31
+ * publish, so the caller sets them explicitly.
32
+ *
33
+ * `layout` is skipped here for a different reason (kywi-cms#147): it IS applied,
34
+ * but never as a plain column. It goes through {@link takeSnapshotLayout} +
35
+ * `setContentLayout` so the document is validated and the
36
+ * `kywi_component_instances` index is reconciled in the same transaction. Before
37
+ * that, a snapshot's layout rode along in this raw `set(...)`, which is how a
38
+ * changeset publish or revision approve could store a layout no validator had
39
+ * ever seen and leave the component index describing a page that no longer
40
+ * exists.
26
41
  */
27
42
  export const SNAPSHOT_SKIP_FIELDS = new Set([
28
43
  'id',
@@ -41,6 +56,7 @@ export const SNAPSHOT_SKIP_FIELDS = new Set([
41
56
  'baseType',
42
57
  'status',
43
58
  'publishedAt',
59
+ 'layout',
44
60
  ]);
45
61
  const BASE_COLUMNS = getTableColumns(kywiContent);
46
62
  const DATE_COLUMN_NAMES = new Set(Object.entries(BASE_COLUMNS)
@@ -94,6 +110,76 @@ export function extractCustomFieldsFromSnapshot(snapshot, customFieldNames, cust
94
110
  }
95
111
  return out;
96
112
  }
113
+ /**
114
+ * Thrown when a snapshot carries a `layout` that is not a valid layout document.
115
+ *
116
+ * An apply (changeset publish, revision approve, version restore) refuses rather
117
+ * than writing it: a malformed document in the column is what makes a page
118
+ * permanently un-editable — every later layout save rejects it — so propagating
119
+ * one from history would turn a bad snapshot into a bad live page. Refusing
120
+ * leaves the currently stored layout untouched and, because every apply runs in
121
+ * a transaction, rolls the whole operation back. Routes surface it as a 409 so
122
+ * the operator sees WHY the publish/approve/restore did not happen instead of
123
+ * discovering later that the page cannot be edited.
124
+ *
125
+ * Reachable only for content authored before the layout write guards existed (or
126
+ * edited directly in the database): every door that writes a layout now
127
+ * validates it first, so no new snapshot can carry an invalid one.
128
+ */
129
+ export class SnapshotLayoutInvalidError extends Error {
130
+ contentId;
131
+ reason;
132
+ constructor(contentId, reason) {
133
+ super(`The stored snapshot for content ${contentId} carries an invalid layout ` +
134
+ `document, so it cannot be applied: ${reason}. The live content was left ` +
135
+ `unchanged. Re-save the page's layout through the editor to repair it.`);
136
+ this.name = 'SnapshotLayoutInvalidError';
137
+ this.contentId = contentId;
138
+ this.reason = reason;
139
+ }
140
+ }
141
+ /**
142
+ * Pure: the layout a snapshot wants applied, validated.
143
+ *
144
+ * `present: false` means the snapshot captured no layout at all — leave the
145
+ * stored one alone (a base-only snapshot must never blank a page). `layout: null`
146
+ * is an explicit clear, which still has to go through `setContentLayout` so the
147
+ * page's index rows go with it. Anything present but malformed throws
148
+ * {@link SnapshotLayoutInvalidError}.
149
+ *
150
+ * Validation also NORMALISES (the zod schemas strip unknown keys), so callers
151
+ * must store the returned document rather than the raw snapshot value.
152
+ *
153
+ * Deliberately does NOT run the admin-only-module gate. That gate is
154
+ * differential and role-based, and an apply is not an authoring act: the modules
155
+ * were introduced (and gated) when the revision/changeset/version was created,
156
+ * whereas the actor here is an approver, a publisher, or — for a scheduled
157
+ * changeset publish — no user at all. Gating at apply time would both break
158
+ * scheduled publishes and refuse an editor's approval of a layout a siteAdmin
159
+ * legitimately authored. See the comment on the submit route (api/workflow-routes)
160
+ * for the author-side half of this split.
161
+ */
162
+ export function takeSnapshotLayout(snapshot, contentId) {
163
+ if (!('layout' in snapshot))
164
+ return { present: false };
165
+ const raw = snapshot['layout'];
166
+ if (raw === null || raw === undefined)
167
+ return { present: true, layout: null };
168
+ const result = validateLayoutDocument(raw);
169
+ if (!result.success)
170
+ throw new SnapshotLayoutInvalidError(contentId, result.error);
171
+ return { present: true, layout: result.data };
172
+ }
173
+ /**
174
+ * Apply a snapshot's layout (if it captured one) through the indexing write path.
175
+ * The shared tail of every snapshot apply — see {@link takeSnapshotLayout}.
176
+ */
177
+ export async function applySnapshotLayout(db, contentId, snapshot) {
178
+ const layout = takeSnapshotLayout(snapshot, contentId);
179
+ if (!layout.present)
180
+ return;
181
+ await setContentLayout(db, contentId, layout.layout);
182
+ }
97
183
  /**
98
184
  * Apply a stored snapshot onto the live content row using an existing
99
185
  * transaction/handle. Writes the sanitised base columns and (when a customTable
@@ -107,6 +193,11 @@ export function extractCustomFieldsFromSnapshot(snapshot, customFieldNames, cust
107
193
  export async function applyContentSnapshot(db, contentId, snapshot, opts = {}) {
108
194
  const forceStatus = opts.forceStatus ?? 'published';
109
195
  const base = sanitizeSnapshotForContentUpdate(snapshot);
196
+ // Validate the layout BEFORE the first write, so an unusable snapshot is
197
+ // refused without having touched a single column (the callers' transactions
198
+ // would roll it back either way, but the ordering keeps that independent of
199
+ // whether the handle we were given is transactional at all).
200
+ const layout = takeSnapshotLayout(snapshot, contentId);
110
201
  const setValues = {
111
202
  ...base,
112
203
  status: forceStatus,
@@ -121,6 +212,11 @@ export async function applyContentSnapshot(db, contentId, snapshot, opts = {}) {
121
212
  .update(kywiContent)
122
213
  .set(setValues)
123
214
  .where(eq(kywiContent.id, contentId));
215
+ // The layout is a second, indexed statement rather than a column in the update
216
+ // above (kywi-cms#147). Both callers run us inside their transaction, so the
217
+ // layout, the columns and the component index still commit together.
218
+ if (layout.present)
219
+ await setContentLayout(db, contentId, layout.layout);
124
220
  const customFields = extractCustomFieldsFromSnapshot(snapshot, opts.customFieldNames ?? [], opts.customTable ?? null);
125
221
  if (opts.customTable && Object.keys(customFields).length > 0) {
126
222
  const result = await db
@@ -1 +1 @@
1
- {"version":3,"file":"apply-snapshot.js","sourceRoot":"","sources":["../../src/db/apply-snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply-snapshot.js","sourceRoot":"","sources":["../../src/db/apply-snapshot.ts"],"names":[],"mappings":"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"}
@@ -12,37 +12,37 @@ export declare function createAuditEntry(db: KywiDb, data: {
12
12
  }): Promise<{
13
13
  id: string;
14
14
  siteId: string;
15
- createdAt: Date;
16
15
  contentId: string;
17
- userId: string;
18
16
  action: string;
17
+ createdAt: Date;
18
+ userEmail: string;
19
+ userId: string;
20
+ changedFields: unknown;
19
21
  fromStatus: string | null;
20
22
  toStatus: string | null;
21
- changedFields: unknown;
22
- userEmail: string;
23
23
  }>;
24
24
  export declare function listAuditEntries(db: KywiDb, contentId: string, limit?: number): Promise<{
25
25
  id: string;
26
26
  siteId: string;
27
- createdAt: Date;
28
27
  contentId: string;
29
- userId: string;
30
28
  action: string;
29
+ createdAt: Date;
30
+ userEmail: string;
31
+ userId: string;
32
+ changedFields: unknown;
31
33
  fromStatus: string | null;
32
34
  toStatus: string | null;
33
- changedFields: unknown;
34
- userEmail: string;
35
35
  }[]>;
36
36
  export declare function listSiteAuditEntries(db: KywiDb, siteId: string, limit?: number): Promise<{
37
37
  id: string;
38
38
  siteId: string;
39
- createdAt: Date;
40
39
  contentId: string;
41
- userId: string;
42
40
  action: string;
41
+ createdAt: Date;
42
+ userEmail: string;
43
+ userId: string;
44
+ changedFields: unknown;
43
45
  fromStatus: string | null;
44
46
  toStatus: string | null;
45
- changedFields: unknown;
46
- userEmail: string;
47
47
  }[]>;
48
48
  //# sourceMappingURL=audit-queries.d.ts.map
@@ -24,9 +24,9 @@ export declare function listCategories(db: KywiDb, siteId: string, parentId?: st
24
24
  sortOrder: number;
25
25
  updatedAt: Date;
26
26
  name: string;
27
+ description: string | null;
27
28
  createdAt: Date;
28
29
  isActive: boolean;
29
- description: string | null;
30
30
  isInterestGroup: boolean;
31
31
  notes: string | null;
32
32
  }[]>;
@@ -38,9 +38,9 @@ export declare function getCategoryById(db: KywiDb, id: string, siteId?: string)
38
38
  sortOrder: number;
39
39
  updatedAt: Date;
40
40
  name: string;
41
+ description: string | null;
41
42
  createdAt: Date;
42
43
  isActive: boolean;
43
- description: string | null;
44
44
  isInterestGroup: boolean;
45
45
  notes: string | null;
46
46
  } | null>;
@@ -62,9 +62,9 @@ export declare function createCategory(db: KywiDb, data: {
62
62
  sortOrder: number;
63
63
  updatedAt: Date;
64
64
  name: string;
65
+ description: string | null;
65
66
  createdAt: Date;
66
67
  isActive: boolean;
67
- description: string | null;
68
68
  isInterestGroup: boolean;
69
69
  notes: string | null;
70
70
  }>;
@@ -13,20 +13,20 @@ export declare function createChangesetAuditEntry(db: KywiDb, data: {
13
13
  }): Promise<{
14
14
  id: string;
15
15
  siteId: string;
16
+ action: string;
16
17
  createdAt: Date;
17
18
  userId: string;
18
- action: string;
19
- changesetId: string;
20
19
  detail: unknown;
20
+ changesetId: string;
21
21
  }>;
22
22
  /** List a changeset's audit trail, newest first. */
23
23
  export declare function listChangesetAudit(db: KywiDb, changesetId: string, limit?: number): Promise<{
24
24
  id: string;
25
25
  siteId: string;
26
+ action: string;
26
27
  createdAt: Date;
27
28
  userId: string;
28
- action: string;
29
- changesetId: string;
30
29
  detail: unknown;
30
+ changesetId: string;
31
31
  }[]>;
32
32
  //# sourceMappingURL=changeset-audit-queries.d.ts.map
@@ -37,9 +37,9 @@ export declare function createChangeset(db: KywiDb, data: {
37
37
  publishedAt: Date | null;
38
38
  updatedAt: Date;
39
39
  name: string;
40
+ description: string | null;
40
41
  createdAt: Date;
41
42
  createdBy: string;
42
- description: string | null;
43
43
  scheduledPublishAt: Date | null;
44
44
  publishedBy: string | null;
45
45
  }>;
@@ -50,9 +50,9 @@ export declare function getChangeset(db: KywiDb, id: string, siteId?: string): P
50
50
  publishedAt: Date | null;
51
51
  updatedAt: Date;
52
52
  name: string;
53
+ description: string | null;
53
54
  createdAt: Date;
54
55
  createdBy: string;
55
- description: string | null;
56
56
  scheduledPublishAt: Date | null;
57
57
  publishedBy: string | null;
58
58
  } | null>;
@@ -63,9 +63,9 @@ export declare function listChangesets(db: KywiDb, siteId: string, status?: stri
63
63
  publishedAt: Date | null;
64
64
  updatedAt: Date;
65
65
  name: string;
66
+ description: string | null;
66
67
  createdAt: Date;
67
68
  createdBy: string;
68
- description: string | null;
69
69
  scheduledPublishAt: Date | null;
70
70
  publishedBy: string | null;
71
71
  }[]>;
@@ -93,20 +93,20 @@ export declare function addChangesetItem(db: KywiDb, data: {
93
93
  action: string;
94
94
  }): Promise<{
95
95
  id: string;
96
- createdAt: Date;
97
96
  contentId: string;
98
97
  action: string;
99
- changesetId: string;
98
+ createdAt: Date;
100
99
  versionId: string | null;
100
+ changesetId: string;
101
101
  }>;
102
102
  export declare function removeChangesetItem(db: KywiDb, itemId: string): Promise<void>;
103
103
  export declare function listChangesetItems(db: KywiDb, changesetId: string): Promise<{
104
104
  id: string;
105
- createdAt: Date;
106
105
  contentId: string;
107
106
  action: string;
108
- changesetId: string;
107
+ createdAt: Date;
109
108
  versionId: string | null;
109
+ changesetId: string;
110
110
  }[]>;
111
111
  export declare function publishChangeset(db: KywiDb, changesetId: string, publishedBy: string, opts?: PublishChangesetOptions): Promise<any>;
112
112
  export declare function rollbackChangeset(db: KywiDb, changesetId: string): Promise<any>;
@@ -6,11 +6,11 @@ export declare function listComments(db: KywiDb, contentId: string, status?: str
6
6
  status: string;
7
7
  body: string;
8
8
  updatedAt: Date;
9
- createdAt: Date;
10
9
  contentId: string;
11
- authorId: string | null;
10
+ createdAt: Date;
12
11
  authorName: string | null;
13
12
  authorEmail: string | null;
13
+ authorId: string | null;
14
14
  }[]>;
15
15
  export declare function listSiteComments(db: KywiDb, siteId: string, status?: string, limit?: number): Promise<{
16
16
  id: string;
@@ -19,11 +19,11 @@ export declare function listSiteComments(db: KywiDb, siteId: string, status?: st
19
19
  status: string;
20
20
  body: string;
21
21
  updatedAt: Date;
22
- createdAt: Date;
23
22
  contentId: string;
24
- authorId: string | null;
23
+ createdAt: Date;
25
24
  authorName: string | null;
26
25
  authorEmail: string | null;
26
+ authorId: string | null;
27
27
  }[]>;
28
28
  export declare function getCommentById(db: KywiDb, id: string, siteId?: string): Promise<{
29
29
  id: string;
@@ -32,11 +32,11 @@ export declare function getCommentById(db: KywiDb, id: string, siteId?: string):
32
32
  status: string;
33
33
  body: string;
34
34
  updatedAt: Date;
35
- createdAt: Date;
36
35
  contentId: string;
37
- authorId: string | null;
36
+ createdAt: Date;
38
37
  authorName: string | null;
39
38
  authorEmail: string | null;
39
+ authorId: string | null;
40
40
  } | null>;
41
41
  export declare function createComment(db: KywiDb, data: {
42
42
  siteId: string;
@@ -54,11 +54,11 @@ export declare function createComment(db: KywiDb, data: {
54
54
  status: string;
55
55
  body: string;
56
56
  updatedAt: Date;
57
- createdAt: Date;
58
57
  contentId: string;
59
- authorId: string | null;
58
+ createdAt: Date;
60
59
  authorName: string | null;
61
60
  authorEmail: string | null;
61
+ authorId: string | null;
62
62
  }>;
63
63
  export declare function updateComment(db: KywiDb, id: string, data: {
64
64
  body?: string;
@@ -2,8 +2,8 @@ import type { KywiDb } from './client.js';
2
2
  export declare function subscribe(db: KywiDb, contentId: string, email: string, userId?: string): Promise<{
3
3
  id: string;
4
4
  email: string;
5
- createdAt: Date;
6
5
  contentId: string;
6
+ createdAt: Date;
7
7
  isActive: boolean;
8
8
  userId: string | null;
9
9
  }>;
@@ -11,8 +11,8 @@ export declare function unsubscribe(db: KywiDb, contentId: string, email: string
11
11
  export declare function listSubscribers(db: KywiDb, contentId: string): Promise<{
12
12
  id: string;
13
13
  email: string;
14
- createdAt: Date;
15
14
  contentId: string;
15
+ createdAt: Date;
16
16
  isActive: boolean;
17
17
  userId: string | null;
18
18
  }[]>;
@@ -0,0 +1,197 @@
1
+ import type { KywiComponentRow } from '../schema/components.js';
2
+ import type { KywiDb } from './client.js';
3
+ import type { LayoutDocument } from '../layout/types.js';
4
+ import type { ComponentDefinitionLookup } from '../layout/module-permissions.js';
5
+ /**
6
+ * Component ids reach us from layout JSONB, which is user data — a hand-edited
7
+ * or imported layout can carry a `componentId` that is not a UUID at all.
8
+ * Passing one to a `uuid` column comparison is a driver error ("invalid input
9
+ * syntax for type uuid") that would fail the whole layout save, so non-UUID
10
+ * links are simply not indexable (the renderer already treats them as
11
+ * unresolvable).
12
+ *
13
+ * Canonical (lower-case) form is required, deliberately. Postgres renders a
14
+ * `uuid` column lower-case and the renderer matches links against those strings
15
+ * byte-for-byte, so an upper-case link resolves to nothing on the page. Postgres
16
+ * would happily match it in a `uuid` comparison, though — indexing it would
17
+ * count an instance that no visitor can see and that the layout scan (a text
18
+ * `LIKE` on the canonical id) could never find again. What is indexed is exactly
19
+ * what the renderer can resolve.
20
+ */
21
+ export declare function isIndexableComponentId(componentId: string): boolean;
22
+ /**
23
+ * The definitions behind the `componentId` links a write ADDS, in the shape the
24
+ * admin-only-module gate reads. Returns undefined when the write adds no link —
25
+ * the common case, which then costs no query at all.
26
+ *
27
+ * ONE loader for every door that writes a layout: `PUT .../layout`, the content
28
+ * `PUT`/`PATCH` that carries a `layout` field, and `detachComponentEverywhere`.
29
+ * Linking a component introduces whatever modules its definition contains, so a
30
+ * door that gates modules but not links is not a gate; having each door build its
31
+ * own lookup is how one of them ends up not building it.
32
+ *
33
+ * Links whose id is not a canonical UUID are skipped: the renderer cannot resolve
34
+ * them either (and a `uuid` comparison against such a string is a driver error,
35
+ * not a miss), so they contribute nothing but a failed request.
36
+ */
37
+ export declare function buildAddedComponentLookup(db: KywiDb, incoming: LayoutDocument, stored: LayoutDocument | null | undefined, siteId: string | undefined): Promise<ComponentDefinitionLookup | undefined>;
38
+ export interface SyncComponentInstancesParams {
39
+ siteId: string;
40
+ contentId: string;
41
+ /** `kywi_content.content_type_name`, denormalised onto each row. */
42
+ contentType: string;
43
+ before: LayoutDocument | null | undefined;
44
+ after: LayoutDocument | null | undefined;
45
+ }
46
+ export interface SyncComponentInstancesResult {
47
+ added: number;
48
+ removed: number;
49
+ }
50
+ /**
51
+ * Bring the index rows for one content document in line with its new layout.
52
+ *
53
+ * Only the difference is written: moving a linked node around a page is not a
54
+ * change of placement, so a save that reshuffles a layout writes nothing here.
55
+ * Added links are filtered to components that actually exist in the SAME site —
56
+ * a link to a deleted or foreign component is left unindexed rather than
57
+ * blowing up the save on a foreign-key violation (the renderer degrades to the
58
+ * node's own inline copy for exactly those links).
59
+ */
60
+ export declare function syncComponentInstances(db: KywiDb, params: SyncComponentInstancesParams): Promise<SyncComponentInstancesResult>;
61
+ export interface ComponentUsageItem {
62
+ contentId: string;
63
+ contentType: string;
64
+ title: string | null;
65
+ nodeIds: string[];
66
+ }
67
+ export interface ComponentUsage {
68
+ /** Total placements on LIVE (not soft-deleted) documents. */
69
+ instances: number;
70
+ /** Distinct live documents holding at least one placement. */
71
+ pages: number;
72
+ /** Live documents only — what a "N instances across M pages" dialog names. */
73
+ items: ComponentUsageItem[];
74
+ /**
75
+ * Placements held by soft-deleted (trashed) documents, counted separately.
76
+ *
77
+ * A trashed page still holds the link, and restoring it brings the link back,
78
+ * so these are NOT zero-cost: the delete gate has to add them in (otherwise
79
+ * deleting the component leaves a restored page pointing at nothing), and
80
+ * detach-all rewrites trashed documents along with live ones. They are kept
81
+ * out of `instances`/`pages`/`items` because a user reading "this appears on
82
+ * 4 pages" means four pages they can navigate to.
83
+ */
84
+ trashedInstances: number;
85
+ trashedPages: number;
86
+ }
87
+ /**
88
+ * Where a component is placed, with the page titles the confirm dialogs name.
89
+ * One indexed read plus a join — the shape both the admin library and the save
90
+ * fork consume.
91
+ *
92
+ * Trashed documents are partitioned out of the headline numbers rather than
93
+ * dropped: see {@link ComponentUsage.trashedInstances}.
94
+ */
95
+ export declare function getComponentUsage(db: KywiDb, componentId: string, siteId: string): Promise<ComponentUsage>;
96
+ export interface ComponentUsageCount {
97
+ componentId: string;
98
+ instances: number;
99
+ pages: number;
100
+ trashedInstances: number;
101
+ }
102
+ /**
103
+ * Per-component placement counts for a whole site — one grouped read, so the
104
+ * library list doesn't fan out into a usage query per row.
105
+ *
106
+ * The live/trashed split matches {@link getComponentUsage} exactly, so the
107
+ * number in the library list is the same number the component's own usage
108
+ * dialog shows.
109
+ */
110
+ export declare function listComponentUsageCounts(db: KywiDb, siteId: string): Promise<ComponentUsageCount[]>;
111
+ /** Why one document was left alone by {@link detachComponentEverywhere}. */
112
+ export type DetachSkipReason = 'invalidLayout' | 'adminOnlyModule';
113
+ export interface DetachSkippedPage {
114
+ contentId: string;
115
+ contentType: string;
116
+ reason: DetachSkipReason;
117
+ detail: string;
118
+ }
119
+ export interface DetachEverywhereResult {
120
+ /** Documents rewritten. */
121
+ pages: number;
122
+ /** Placements materialised into independent copies. */
123
+ instances: number;
124
+ /**
125
+ * Documents deliberately left untouched, each with the reason. Empty on the
126
+ * happy path; when it is not empty the component still has instances and
127
+ * must not be deleted.
128
+ */
129
+ skipped: DetachSkippedPage[];
130
+ }
131
+ export interface DetachEverywhereOptions {
132
+ /**
133
+ * The role of the caller on whose behalf this rewrite happens. Materialising
134
+ * a component definition writes real module nodes into pages, so the same
135
+ * admin-only-module gate the layout PUT applies has to apply here — otherwise
136
+ * detach-all is a way to place an `html` module on every page in the site
137
+ * without ever passing that gate.
138
+ */
139
+ actorRole: string;
140
+ }
141
+ /**
142
+ * Materialise every placement of a component into an independent copy, so the
143
+ * component can be deleted without any page changing what it renders.
144
+ *
145
+ * Candidate documents come from a scan of the site's layouts (a `::text LIKE`
146
+ * on the component's own UUID), NOT from the instance index. The index is a
147
+ * derived cache; if it ever drifted, trusting it here would leave a page
148
+ * pointing at a component that is about to disappear. The scan is bounded by
149
+ * the site and only materialises rows that actually contain the id. Trashed
150
+ * (soft-deleted) documents are included deliberately: they still hold the link
151
+ * and restoring one must not resurrect a dangling reference.
152
+ *
153
+ * Two guards run per document, and BOTH are per-document skips rather than a
154
+ * failure of the whole operation:
155
+ *
156
+ * - the rewritten document must pass `validateLayoutDocument`. A malformed
157
+ * component definition would otherwise be copied into every referencing page
158
+ * and make each of them permanently un-editable (every later layout PUT
159
+ * would 400 on a document the user cannot repair through the UI). A page
160
+ * whose layout was ALREADY invalid before the rewrite is skipped by the same
161
+ * rule — it needs fixing regardless, and knowingly writing an invalid
162
+ * document is never the better option;
163
+ * - the rewritten document must not introduce an admin-only module the caller
164
+ * could not have added by hand — the same differential check
165
+ * `PUT .../layout` applies, with the same role.
166
+ *
167
+ * Skipping is the honest choice over failing everything: one bad page must not
168
+ * make the component undetachable — and so undeletable — everywhere else. The
169
+ * caller is told exactly which documents were left and why, the skipped pages
170
+ * keep their (still working) links, and the delete gate still sees those
171
+ * instances, so a component can never be deleted out from under a page.
172
+ *
173
+ * Everything — the layout rewrites, the index updates, and the sweep of any
174
+ * leftover index rows — happens in one transaction, and each layout is re-read
175
+ * `FOR UPDATE` inside it so a concurrent editor save can't be silently
176
+ * overwritten (it waits, then the detach sees its result).
177
+ */
178
+ export declare function detachComponentEverywhere(db: KywiDb, component: Pick<KywiComponentRow, 'id' | 'siteId' | 'type' | 'moduleType' | 'definition'>, options: DetachEverywhereOptions): Promise<DetachEverywhereResult>;
179
+ export interface ReindexResult {
180
+ documentsScanned: number;
181
+ instances: number;
182
+ }
183
+ /**
184
+ * Rebuild the instance index from the layouts themselves.
185
+ *
186
+ * This is what makes the index safe on an upgrade: the table ships empty while
187
+ * existing installs already have layouts full of `componentId` links, and
188
+ * `kywi migrate` runs this as a post-step so no operator has to know it exists.
189
+ * It is idempotent (it clears the scope it is about to rebuild) and doubles as
190
+ * the repair path if the index is ever suspected of drift.
191
+ *
192
+ * Only documents whose layout mentions a known component id are parsed, so the
193
+ * cost is one indexed-free scan plus a parse of the pages that actually use
194
+ * components — not a parse of every layout in the database.
195
+ */
196
+ export declare function reindexComponentInstances(db: KywiDb, siteId?: string): Promise<ReindexResult>;
197
+ //# sourceMappingURL=component-instance-queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-instance-queries.d.ts","sourceRoot":"","sources":["../../src/db/component-instance-queries.ts"],"names":[],"mappings":"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"}