@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.
- package/AGENT-PATTERNS.md +96 -10
- package/dist/admin/content-form.d.ts.map +1 -1
- package/dist/admin/content-form.js +97 -10
- package/dist/admin/content-form.js.map +1 -1
- package/dist/admin/layout-editor/component-actions.d.ts +219 -22
- package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-actions.js +356 -36
- package/dist/admin/layout-editor/component-actions.js.map +1 -1
- package/dist/admin/layout-editor/component-fork.d.ts +224 -0
- package/dist/admin/layout-editor/component-fork.d.ts.map +1 -0
- package/dist/admin/layout-editor/component-fork.js +342 -0
- package/dist/admin/layout-editor/component-fork.js.map +1 -0
- package/dist/admin/layout-editor/editor-canvas.d.ts +8 -0
- package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.js +120 -12
- package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
- package/dist/admin/layout-editor/editor-dialog.d.ts +164 -0
- package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -0
- package/dist/admin/layout-editor/editor-dialog.js +195 -0
- package/dist/admin/layout-editor/editor-dialog.js.map +1 -0
- package/dist/admin/layout-editor/editor-state.d.ts +76 -0
- package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-state.js +47 -1
- package/dist/admin/layout-editor/editor-state.js.map +1 -1
- package/dist/admin/layout-editor/editor.css +279 -2
- package/dist/admin/layout-editor/index.d.ts +10 -1
- package/dist/admin/layout-editor/index.d.ts.map +1 -1
- package/dist/admin/layout-editor/index.js +11 -1
- package/dist/admin/layout-editor/index.js.map +1 -1
- package/dist/admin/layout-editor/layout-editor.d.ts +58 -1
- package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/layout-editor.js +160 -190
- package/dist/admin/layout-editor/layout-editor.js.map +1 -1
- package/dist/admin/layout-editor/linked-component.d.ts +39 -0
- package/dist/admin/layout-editor/linked-component.d.ts.map +1 -0
- package/dist/admin/layout-editor/linked-component.js +42 -0
- package/dist/admin/layout-editor/linked-component.js.map +1 -0
- package/dist/admin/layout-editor/module-overlay.d.ts +10 -1
- package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-overlay.js +33 -4
- package/dist/admin/layout-editor/module-overlay.js.map +1 -1
- package/dist/admin/layout-editor/node-lookup.d.ts +35 -0
- package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
- package/dist/admin/layout-editor/node-lookup.js +91 -0
- package/dist/admin/layout-editor/node-lookup.js.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.js +114 -23
- package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
- package/dist/admin/layout-editor/props-panel.d.ts +54 -1
- package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
- package/dist/admin/layout-editor/props-panel.js +118 -9
- package/dist/admin/layout-editor/props-panel.js.map +1 -1
- package/dist/admin/layout-editor/section-overlay.d.ts +9 -1
- package/dist/admin/layout-editor/section-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-overlay.js +14 -4
- package/dist/admin/layout-editor/section-overlay.js.map +1 -1
- package/dist/admin/layout-editor/section-template-picker.d.ts +27 -1
- package/dist/admin/layout-editor/section-template-picker.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-template-picker.js +71 -17
- package/dist/admin/layout-editor/section-template-picker.js.map +1 -1
- package/dist/admin/layout-editor/use-component-connect.d.ts +61 -0
- package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -0
- package/dist/admin/layout-editor/use-component-connect.js +292 -0
- package/dist/admin/layout-editor/use-component-connect.js.map +1 -0
- package/dist/admin/layout-editor/use-component-fork.d.ts +123 -0
- package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -0
- package/dist/admin/layout-editor/use-component-fork.js +346 -0
- package/dist/admin/layout-editor/use-component-fork.js.map +1 -0
- package/dist/admin/layout-editor/use-component-library.d.ts +94 -0
- package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -0
- package/dist/admin/layout-editor/use-component-library.js +55 -0
- package/dist/admin/layout-editor/use-component-library.js.map +1 -0
- package/dist/admin/registry.d.ts +11 -2
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +40 -4
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/server.d.ts +1 -0
- package/dist/admin/server.d.ts.map +1 -1
- package/dist/admin/server.js +5 -0
- package/dist/admin/server.js.map +1 -1
- package/dist/admin/styles/admin.css +43 -0
- package/dist/admin/surfaces/components/component-edit.d.ts +3 -0
- package/dist/admin/surfaces/components/component-edit.d.ts.map +1 -0
- package/dist/admin/surfaces/components/component-edit.js +235 -0
- package/dist/admin/surfaces/components/component-edit.js.map +1 -0
- package/dist/admin/surfaces/components/components-data.d.ts +153 -0
- package/dist/admin/surfaces/components/components-data.d.ts.map +1 -0
- package/dist/admin/surfaces/components/components-data.js +154 -0
- package/dist/admin/surfaces/components/components-data.js.map +1 -0
- package/dist/admin/surfaces/components/components-list.d.ts +3 -0
- package/dist/admin/surfaces/components/components-list.d.ts.map +1 -0
- package/dist/admin/surfaces/components/components-list.js +196 -0
- package/dist/admin/surfaces/components/components-list.js.map +1 -0
- package/dist/admin/surfaces/components/definition-canvas.d.ts +73 -0
- package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -0
- package/dist/admin/surfaces/components/definition-canvas.js +207 -0
- package/dist/admin/surfaces/components/definition-canvas.js.map +1 -0
- package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
- package/dist/admin/surfaces/layouts/layout-editor-client.js +14 -2
- package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
- package/dist/admin/surfaces/layouts/layouts-data.d.ts +3 -14
- package/dist/admin/surfaces/layouts/layouts-data.d.ts.map +1 -1
- package/dist/admin/surfaces/layouts/layouts-data.js +4 -7
- package/dist/admin/surfaces/layouts/layouts-data.js.map +1 -1
- package/dist/admin/surfaces/layouts/layouts-list.d.ts.map +1 -1
- package/dist/admin/surfaces/layouts/layouts-list.js +16 -22
- package/dist/admin/surfaces/layouts/layouts-list.js.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.js +1 -0
- package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
- package/dist/api/bulk-routes.d.ts.map +1 -1
- package/dist/api/bulk-routes.js +25 -0
- package/dist/api/bulk-routes.js.map +1 -1
- package/dist/api/changeset-routes.d.ts.map +1 -1
- package/dist/api/changeset-routes.js +17 -3
- package/dist/api/changeset-routes.js.map +1 -1
- package/dist/api/component-routes.d.ts.map +1 -1
- package/dist/api/component-routes.js +228 -8
- package/dist/api/component-routes.js.map +1 -1
- package/dist/api/content-routes.d.ts.map +1 -1
- package/dist/api/content-routes.js +64 -0
- package/dist/api/content-routes.js.map +1 -1
- package/dist/api/feed-routes.d.ts +6 -6
- package/dist/api/graphql/resolvers.d.ts +4 -4
- package/dist/api/layout-routes.d.ts.map +1 -1
- package/dist/api/layout-routes.js +4 -17
- package/dist/api/layout-routes.js.map +1 -1
- package/dist/api/layout-write-guard.d.ts +80 -0
- package/dist/api/layout-write-guard.d.ts.map +1 -0
- package/dist/api/layout-write-guard.js +88 -0
- package/dist/api/layout-write-guard.js.map +1 -0
- package/dist/api/section-template-routes.d.ts.map +1 -1
- package/dist/api/section-template-routes.js +11 -0
- package/dist/api/section-template-routes.js.map +1 -1
- package/dist/api/translation-routes.d.ts.map +1 -1
- package/dist/api/translation-routes.js +8 -0
- package/dist/api/translation-routes.js.map +1 -1
- package/dist/api/version-routes.d.ts.map +1 -1
- package/dist/api/version-routes.js +20 -8
- package/dist/api/version-routes.js.map +1 -1
- package/dist/api/workflow-routes.d.ts.map +1 -1
- package/dist/api/workflow-routes.js +53 -8
- package/dist/api/workflow-routes.js.map +1 -1
- package/dist/db/analytics-queries.d.ts +3 -3
- package/dist/db/apply-snapshot.d.ts +75 -8
- package/dist/db/apply-snapshot.d.ts.map +1 -1
- package/dist/db/apply-snapshot.js +104 -8
- package/dist/db/apply-snapshot.js.map +1 -1
- package/dist/db/audit-queries.d.ts +12 -12
- package/dist/db/category-queries.d.ts +3 -3
- package/dist/db/changeset-audit-queries.d.ts +4 -4
- package/dist/db/changeset-queries.d.ts +7 -7
- package/dist/db/comment-queries.d.ts +8 -8
- package/dist/db/comment-subscription-queries.d.ts +2 -2
- package/dist/db/component-instance-queries.d.ts +197 -0
- package/dist/db/component-instance-queries.d.ts.map +1 -0
- package/dist/db/component-instance-queries.js +405 -0
- package/dist/db/component-instance-queries.js.map +1 -0
- package/dist/db/content-queries.d.ts.map +1 -1
- package/dist/db/content-queries.js +39 -2
- package/dist/db/content-queries.js.map +1 -1
- package/dist/db/extension-queries.d.ts +7 -7
- package/dist/db/feed-queries.d.ts +3 -3
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/layout-queries.d.ts +13 -1
- package/dist/db/layout-queries.d.ts.map +1 -1
- package/dist/db/layout-queries.js +52 -7
- package/dist/db/layout-queries.js.map +1 -1
- package/dist/db/locale-queries.d.ts.map +1 -1
- package/dist/db/locale-queries.js +0 -0
- package/dist/db/locale-queries.js.map +1 -1
- package/dist/db/media-queries.d.ts +12 -12
- package/dist/db/revision-queries.d.ts +3 -3
- package/dist/db/site-admin-queries.d.ts +2 -2
- package/dist/db/site-membership-queries.d.ts +3 -3
- package/dist/db/site-plugin-queries.d.ts +2 -2
- package/dist/db/site-queries.d.ts +6 -6
- package/dist/db/version-queries.d.ts +12 -12
- package/dist/db/webhook-queries.d.ts +11 -11
- package/dist/db/workflow-queries.d.ts +6 -6
- package/dist/db/workflow-queries.d.ts.map +1 -1
- package/dist/db/workflow-queries.js +11 -2
- package/dist/db/workflow-queries.js.map +1 -1
- package/dist/layout/component-refs.d.ts +465 -0
- package/dist/layout/component-refs.d.ts.map +1 -0
- package/dist/layout/component-refs.js +848 -0
- package/dist/layout/component-refs.js.map +1 -0
- package/dist/layout/index.d.ts +2 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +1 -0
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/module-permissions.d.ts +49 -1
- package/dist/layout/module-permissions.d.ts.map +1 -1
- package/dist/layout/module-permissions.js +117 -6
- package/dist/layout/module-permissions.js.map +1 -1
- package/dist/layout/renderer.d.ts +51 -4
- package/dist/layout/renderer.d.ts.map +1 -1
- package/dist/layout/renderer.js +36 -38
- package/dist/layout/renderer.js.map +1 -1
- package/dist/layout/types.d.ts +42 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/types.js +54 -11
- package/dist/layout/types.js.map +1 -1
- package/dist/schema/base.d.ts +1 -1
- package/dist/schema/components.d.ts +150 -0
- package/dist/schema/components.d.ts.map +1 -1
- package/dist/schema/components.js +50 -4
- package/dist/schema/components.js.map +1 -1
- package/dist/versioning/scheduler.d.ts +8 -0
- package/dist/versioning/scheduler.d.ts.map +1 -1
- package/dist/versioning/scheduler.js +21 -7
- package/dist/versioning/scheduler.js.map +1 -1
- 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
|
|
17
|
-
*
|
|
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
|
|
21
|
-
* (id/siteId), tree placement + addressing (path, depth,
|
|
22
|
-
* sortOrder — owned by the move/slug-cascade machinery, never
|
|
23
|
-
* content snapshot), and write bookkeeping (created*, updated*,
|
|
24
|
-
* `status` and `publishedAt` are skipped too: an apply is always a
|
|
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":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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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"}
|