@kywi-software/core 0.6.7 → 0.7.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 +58 -2
- package/dist/admin/registry.d.ts +2 -2
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +41 -19
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/styles/admin.css +130 -0
- package/dist/admin/surfaces/menus/menu-editor.d.ts +3 -0
- package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -0
- package/dist/admin/surfaces/menus/menu-editor.js +260 -0
- package/dist/admin/surfaces/menus/menu-editor.js.map +1 -0
- package/dist/admin/surfaces/menus/menu-tree.d.ts +123 -0
- package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -0
- package/dist/admin/surfaces/menus/menu-tree.js +292 -0
- package/dist/admin/surfaces/menus/menu-tree.js.map +1 -0
- package/dist/admin/surfaces/menus/menus-data.d.ts +101 -0
- package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -0
- package/dist/admin/surfaces/menus/menus-data.js +98 -0
- package/dist/admin/surfaces/menus/menus-data.js.map +1 -0
- package/dist/admin/surfaces/menus/menus-list.d.ts +3 -0
- package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -0
- package/dist/admin/surfaces/menus/menus-list.js +105 -0
- package/dist/admin/surfaces/menus/menus-list.js.map +1 -0
- package/dist/admin/surfaces/menus/page-picker.d.ts +10 -0
- package/dist/admin/surfaces/menus/page-picker.d.ts.map +1 -0
- package/dist/admin/surfaces/menus/page-picker.js +38 -0
- package/dist/admin/surfaces/menus/page-picker.js.map +1 -0
- 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/feed-routes.d.ts +2 -2
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +5 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/menu-routes.d.ts +46 -0
- package/dist/api/menu-routes.d.ts.map +1 -0
- package/dist/api/menu-routes.js +247 -0
- package/dist/api/menu-routes.js.map +1 -0
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +105 -0
- package/dist/api/openapi.js.map +1 -1
- package/dist/cache/cached-queries.d.ts +22 -0
- package/dist/cache/cached-queries.d.ts.map +1 -1
- package/dist/cache/cached-queries.js +31 -1
- package/dist/cache/cached-queries.js.map +1 -1
- package/dist/cache/keys.d.ts +2 -0
- package/dist/cache/keys.d.ts.map +1 -1
- package/dist/cache/keys.js +4 -0
- package/dist/cache/keys.js.map +1 -1
- 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/menu-queries.d.ts +182 -0
- package/dist/db/menu-queries.d.ts.map +1 -0
- package/dist/db/menu-queries.js +326 -0
- package/dist/db/menu-queries.js.map +1 -0
- package/dist/layout/index.d.ts +1 -0
- 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/modules-extended.d.ts +32 -2
- package/dist/layout/modules-extended.d.ts.map +1 -1
- package/dist/layout/modules-extended.js +159 -39
- package/dist/layout/modules-extended.js.map +1 -1
- package/dist/layout/nav-hydration.d.ts +62 -0
- package/dist/layout/nav-hydration.d.ts.map +1 -0
- package/dist/layout/nav-hydration.js +149 -0
- package/dist/layout/nav-hydration.js.map +1 -0
- package/dist/layout/registry.d.ts +0 -26
- package/dist/layout/registry.d.ts.map +1 -1
- package/dist/layout/registry.js +22 -8
- package/dist/layout/registry.js.map +1 -1
- package/dist/nav/builder.d.ts +16 -0
- package/dist/nav/builder.d.ts.map +1 -1
- package/dist/nav/builder.js +21 -2
- package/dist/nav/builder.js.map +1 -1
- package/dist/nav/index.d.ts +1 -0
- package/dist/nav/index.d.ts.map +1 -1
- package/dist/nav/index.js +1 -0
- package/dist/nav/index.js.map +1 -1
- package/dist/nav/menu-resolver.d.ts +52 -0
- package/dist/nav/menu-resolver.d.ts.map +1 -0
- package/dist/nav/menu-resolver.js +113 -0
- package/dist/nav/menu-resolver.js.map +1 -0
- package/dist/nav/types.d.ts +30 -0
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/schema/base.d.ts +331 -0
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +45 -0
- package/dist/schema/base.js.map +1 -1
- package/dist/schema/mysql-tables.d.ts +303 -0
- package/dist/schema/mysql-tables.d.ts.map +1 -1
- package/dist/schema/mysql-tables.js +25 -0
- package/dist/schema/mysql-tables.js.map +1 -1
- package/dist/scope/create-scope.d.ts.map +1 -1
- package/dist/scope/create-scope.js +27 -1
- package/dist/scope/create-scope.js.map +1 -1
- package/dist/scope/types.d.ts +28 -1
- package/dist/scope/types.d.ts.map +1 -1
- package/dist/site/styles.css +380 -0
- package/package.json +1 -1
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* menu-queries.ts
|
|
3
|
+
*
|
|
4
|
+
* Persistence for named navigation menus (#110): `kywi_menus` + `kywi_menu_items`.
|
|
5
|
+
*
|
|
6
|
+
* Two read shapes come out of here, and the difference matters:
|
|
7
|
+
*
|
|
8
|
+
* - the **admin** shape ({@link MenuItemAdminNode}) keeps every item, annotated
|
|
9
|
+
* with why it would or would not render — `contentMissing`, `contentStatus`,
|
|
10
|
+
* `resolvable`. That is what makes a broken nav link visible to the owner
|
|
11
|
+
* instead of shipping a silent 404 to visitors.
|
|
12
|
+
* - the **public** shape is built on top of this by `nav/menu-resolver.ts`,
|
|
13
|
+
* which drops everything `resolvable === false`.
|
|
14
|
+
*
|
|
15
|
+
* Content-linked items store no href: the link is joined live from the content
|
|
16
|
+
* row's `path`, so moving a page never leaves a stale menu entry behind.
|
|
17
|
+
*/
|
|
18
|
+
import { randomUUID } from 'node:crypto';
|
|
19
|
+
import { eq, and, asc, inArray, sql } from 'drizzle-orm';
|
|
20
|
+
import { kywiMenus, kywiMenuItems, kywiContent } from '../schema/base.js';
|
|
21
|
+
/**
|
|
22
|
+
* Raised when a menu-item payload breaks the contentId-XOR-externalUrl rule or
|
|
23
|
+
* names a content slug that does not exist in the site. Carries the offending
|
|
24
|
+
* item's label path (`Products > Pricing`) so the API can say *which* item is
|
|
25
|
+
* wrong rather than rejecting the whole tree anonymously.
|
|
26
|
+
*/
|
|
27
|
+
export class MenuItemValidationError extends Error {
|
|
28
|
+
itemPath;
|
|
29
|
+
constructor(itemPath, message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'MenuItemValidationError';
|
|
32
|
+
this.itemPath = itemPath;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ── Menu CRUD ─────────────────────────────────────────────────────────────────
|
|
36
|
+
export async function listMenus(db, siteId) {
|
|
37
|
+
const rows = await db
|
|
38
|
+
.select()
|
|
39
|
+
.from(kywiMenus)
|
|
40
|
+
.where(eq(kywiMenus.siteId, siteId))
|
|
41
|
+
.orderBy(asc(kywiMenus.slug));
|
|
42
|
+
return rows;
|
|
43
|
+
}
|
|
44
|
+
export async function getMenuById(db, id, siteId) {
|
|
45
|
+
const [menu] = await db
|
|
46
|
+
.select()
|
|
47
|
+
.from(kywiMenus)
|
|
48
|
+
.where(and(eq(kywiMenus.id, id), eq(kywiMenus.siteId, siteId)))
|
|
49
|
+
.limit(1);
|
|
50
|
+
return menu ?? null;
|
|
51
|
+
}
|
|
52
|
+
export async function getMenuBySlug(db, siteId, slug) {
|
|
53
|
+
const [menu] = await db
|
|
54
|
+
.select()
|
|
55
|
+
.from(kywiMenus)
|
|
56
|
+
.where(and(eq(kywiMenus.slug, slug), eq(kywiMenus.siteId, siteId)))
|
|
57
|
+
.limit(1);
|
|
58
|
+
return menu ?? null;
|
|
59
|
+
}
|
|
60
|
+
export async function createMenu(db, data) {
|
|
61
|
+
const [menu] = await db
|
|
62
|
+
.insert(kywiMenus)
|
|
63
|
+
.values({ siteId: data.siteId, slug: data.slug, name: data.name })
|
|
64
|
+
.returning();
|
|
65
|
+
return menu;
|
|
66
|
+
}
|
|
67
|
+
export async function updateMenu(db, id, siteId, data) {
|
|
68
|
+
const patch = { updatedAt: new Date() };
|
|
69
|
+
if (data.slug !== undefined)
|
|
70
|
+
patch.slug = data.slug;
|
|
71
|
+
if (data.name !== undefined)
|
|
72
|
+
patch.name = data.name;
|
|
73
|
+
const [menu] = await db
|
|
74
|
+
.update(kywiMenus)
|
|
75
|
+
.set(patch)
|
|
76
|
+
.where(and(eq(kywiMenus.id, id), eq(kywiMenus.siteId, siteId)))
|
|
77
|
+
.returning();
|
|
78
|
+
return menu ?? null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Delete a menu. Its items go with it via `ON DELETE CASCADE`, but they are
|
|
82
|
+
* deleted explicitly first so the behaviour is identical on a MySQL install
|
|
83
|
+
* whose FKs were created without the cascade (and so a mocked db in tests sees
|
|
84
|
+
* the same two statements).
|
|
85
|
+
*/
|
|
86
|
+
export async function deleteMenu(db, id, siteId) {
|
|
87
|
+
const menu = await getMenuById(db, id, siteId);
|
|
88
|
+
if (!menu)
|
|
89
|
+
return false;
|
|
90
|
+
await runInTransaction(db, async (tx) => {
|
|
91
|
+
await tx.delete(kywiMenuItems).where(eq(kywiMenuItems.menuId, id));
|
|
92
|
+
await tx.delete(kywiMenus).where(eq(kywiMenus.id, id));
|
|
93
|
+
});
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
// ── Item reads ────────────────────────────────────────────────────────────────
|
|
97
|
+
/**
|
|
98
|
+
* Fetch a menu's items joined to their linked content rows, ordered so that
|
|
99
|
+
* {@link assembleMenuItemTree} can rely on sibling order.
|
|
100
|
+
*/
|
|
101
|
+
export async function getMenuItemRows(db, menuId) {
|
|
102
|
+
const rows = await db
|
|
103
|
+
.select({
|
|
104
|
+
id: kywiMenuItems.id,
|
|
105
|
+
menuId: kywiMenuItems.menuId,
|
|
106
|
+
parentId: kywiMenuItems.parentId,
|
|
107
|
+
sortOrder: kywiMenuItems.sortOrder,
|
|
108
|
+
label: kywiMenuItems.label,
|
|
109
|
+
contentId: kywiMenuItems.contentId,
|
|
110
|
+
externalUrl: kywiMenuItems.externalUrl,
|
|
111
|
+
openInNewWindow: kywiMenuItems.openInNewWindow,
|
|
112
|
+
description: kywiMenuItems.description,
|
|
113
|
+
contentPath: kywiContent.path,
|
|
114
|
+
contentStatus: kywiContent.status,
|
|
115
|
+
contentDeletedAt: kywiContent.deletedAt,
|
|
116
|
+
})
|
|
117
|
+
.from(kywiMenuItems)
|
|
118
|
+
.leftJoin(kywiContent, eq(kywiMenuItems.contentId, kywiContent.id))
|
|
119
|
+
.where(eq(kywiMenuItems.menuId, menuId))
|
|
120
|
+
.orderBy(asc(kywiMenuItems.sortOrder));
|
|
121
|
+
return rows;
|
|
122
|
+
}
|
|
123
|
+
/** Statuses whose content is visible to anonymous visitors. */
|
|
124
|
+
const PUBLIC_STATUSES = new Set(['published']);
|
|
125
|
+
/**
|
|
126
|
+
* Assemble flat joined rows into the nested admin tree, computing the
|
|
127
|
+
* `href`/`contentMissing`/`resolvable` flags per item.
|
|
128
|
+
*
|
|
129
|
+
* Rows whose `parentId` points at an item outside this set are treated as
|
|
130
|
+
* roots, so a corrupt parent link degrades to a visible top-level entry rather
|
|
131
|
+
* than a silently vanished one.
|
|
132
|
+
*/
|
|
133
|
+
export function assembleMenuItemTree(rows) {
|
|
134
|
+
const childrenMap = new Map();
|
|
135
|
+
for (const row of rows) {
|
|
136
|
+
const key = row.parentId;
|
|
137
|
+
const list = childrenMap.get(key);
|
|
138
|
+
if (list)
|
|
139
|
+
list.push(row);
|
|
140
|
+
else
|
|
141
|
+
childrenMap.set(key, [row]);
|
|
142
|
+
}
|
|
143
|
+
for (const list of childrenMap.values()) {
|
|
144
|
+
list.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
145
|
+
}
|
|
146
|
+
const known = new Set(rows.map(r => r.id));
|
|
147
|
+
function build(row) {
|
|
148
|
+
const isExternal = row.externalUrl != null && row.externalUrl !== '';
|
|
149
|
+
const contentLive = row.contentPath != null && row.contentDeletedAt == null;
|
|
150
|
+
const href = isExternal ? row.externalUrl : contentLive ? row.contentPath : null;
|
|
151
|
+
const contentMissing = !isExternal && !contentLive;
|
|
152
|
+
const resolvable = isExternal
|
|
153
|
+
? true
|
|
154
|
+
: contentLive && row.contentStatus != null && PUBLIC_STATUSES.has(row.contentStatus);
|
|
155
|
+
return {
|
|
156
|
+
id: row.id,
|
|
157
|
+
menuId: row.menuId,
|
|
158
|
+
parentId: row.parentId,
|
|
159
|
+
sortOrder: row.sortOrder,
|
|
160
|
+
label: row.label,
|
|
161
|
+
contentId: row.contentId,
|
|
162
|
+
externalUrl: row.externalUrl,
|
|
163
|
+
openInNewWindow: row.openInNewWindow,
|
|
164
|
+
description: row.description,
|
|
165
|
+
href,
|
|
166
|
+
contentStatus: row.contentStatus,
|
|
167
|
+
contentMissing,
|
|
168
|
+
resolvable,
|
|
169
|
+
children: (childrenMap.get(row.id) ?? []).map(build),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const roots = rows.filter(r => r.parentId === null || !known.has(r.parentId));
|
|
173
|
+
return roots.sort((a, b) => a.sortOrder - b.sortOrder).map(build);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Read a menu by slug with its full nested item tree (admin shape — includes
|
|
177
|
+
* unresolvable items, flagged). Null when the site has no such menu.
|
|
178
|
+
*/
|
|
179
|
+
export async function getMenuWithItems(db, siteId, slug) {
|
|
180
|
+
const menu = await getMenuBySlug(db, siteId, slug);
|
|
181
|
+
if (!menu)
|
|
182
|
+
return null;
|
|
183
|
+
const rows = await getMenuItemRows(db, menu.id);
|
|
184
|
+
return { ...menu, items: assembleMenuItemTree(rows) };
|
|
185
|
+
}
|
|
186
|
+
// ── Item writes ───────────────────────────────────────────────────────────────
|
|
187
|
+
/**
|
|
188
|
+
* Run `fn` inside a DB transaction when the client supports one, otherwise run
|
|
189
|
+
* it inline against `db`. Mirrors the guard in content-queries.ts (#95): unit
|
|
190
|
+
* tests hand these queries a minimal chainable mock with no `.transaction`, and
|
|
191
|
+
* those callers exercise statement shape, not atomicity.
|
|
192
|
+
*/
|
|
193
|
+
async function runInTransaction(db, fn) {
|
|
194
|
+
if ('transaction' in db && typeof db.transaction === 'function') {
|
|
195
|
+
return db.transaction(fn);
|
|
196
|
+
}
|
|
197
|
+
return fn(db);
|
|
198
|
+
}
|
|
199
|
+
function labelPath(trail, label) {
|
|
200
|
+
return [...trail, label || '(untitled)'].join(' > ');
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Validate the contentId-XOR-externalUrl rule over a nested payload.
|
|
204
|
+
*
|
|
205
|
+
* This is the code-side stand-in for a CHECK constraint: expressed here it
|
|
206
|
+
* reads identically on Postgres and MySQL and surfaces as a 400 naming the bad
|
|
207
|
+
* item, rather than as a driver error naming a constraint.
|
|
208
|
+
*/
|
|
209
|
+
export function assertMenuItemsValid(items, trail = []) {
|
|
210
|
+
for (const item of items) {
|
|
211
|
+
const path = labelPath(trail, item.label);
|
|
212
|
+
if (typeof item.label !== 'string' || item.label.trim() === '') {
|
|
213
|
+
throw new MenuItemValidationError(path, 'Menu item label is required');
|
|
214
|
+
}
|
|
215
|
+
const targets = [item.contentId, item.contentSlug, item.externalUrl].filter(v => typeof v === 'string' && v.trim() !== '');
|
|
216
|
+
if (targets.length === 0) {
|
|
217
|
+
throw new MenuItemValidationError(path, `Menu item "${item.label}" needs a target: set contentSlug (or contentId) to link a page, or externalUrl to link off-site`);
|
|
218
|
+
}
|
|
219
|
+
if (targets.length > 1) {
|
|
220
|
+
throw new MenuItemValidationError(path, `Menu item "${item.label}" sets more than one target — use exactly one of contentSlug, contentId or externalUrl`);
|
|
221
|
+
}
|
|
222
|
+
if (item.children && item.children.length > 0) {
|
|
223
|
+
assertMenuItemsValid(item.children, [...trail, item.label]);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function collectSlugs(items, out) {
|
|
228
|
+
for (const item of items) {
|
|
229
|
+
if (typeof item.contentSlug === 'string' && item.contentSlug.trim() !== '') {
|
|
230
|
+
out.add(item.contentSlug);
|
|
231
|
+
}
|
|
232
|
+
if (item.children)
|
|
233
|
+
collectSlugs(item.children, out);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Rewrite `contentSlug` references to `contentId`, in one batched lookup for
|
|
238
|
+
* the whole tree. Agents and the admin UI address pages by slug; the stored
|
|
239
|
+
* link is always the id, so a later slug change cannot orphan the menu entry.
|
|
240
|
+
*
|
|
241
|
+
* Throws {@link MenuItemValidationError} naming the item whose slug is unknown.
|
|
242
|
+
*/
|
|
243
|
+
export async function resolveMenuItemContentSlugs(db, siteId, items) {
|
|
244
|
+
const slugs = new Set();
|
|
245
|
+
collectSlugs(items, slugs);
|
|
246
|
+
if (slugs.size === 0)
|
|
247
|
+
return items;
|
|
248
|
+
const rows = await db
|
|
249
|
+
.select({ id: kywiContent.id, slug: kywiContent.slug })
|
|
250
|
+
.from(kywiContent)
|
|
251
|
+
.where(and(eq(kywiContent.siteId, siteId), inArray(kywiContent.slug, [...slugs]), sql `${kywiContent.deletedAt} IS NULL`));
|
|
252
|
+
const bySlug = new Map();
|
|
253
|
+
for (const row of rows) {
|
|
254
|
+
if (!bySlug.has(row.slug))
|
|
255
|
+
bySlug.set(row.slug, row.id);
|
|
256
|
+
}
|
|
257
|
+
function rewrite(list, trail) {
|
|
258
|
+
return list.map(item => {
|
|
259
|
+
const next = { ...item };
|
|
260
|
+
if (typeof item.contentSlug === 'string' && item.contentSlug.trim() !== '') {
|
|
261
|
+
const id = bySlug.get(item.contentSlug);
|
|
262
|
+
if (!id) {
|
|
263
|
+
throw new MenuItemValidationError(labelPath(trail, item.label), `No content found with slug "${item.contentSlug}" in this site`);
|
|
264
|
+
}
|
|
265
|
+
next.contentId = id;
|
|
266
|
+
delete next.contentSlug;
|
|
267
|
+
}
|
|
268
|
+
if (item.children && item.children.length > 0) {
|
|
269
|
+
next.children = rewrite(item.children, [...trail, item.label]);
|
|
270
|
+
}
|
|
271
|
+
return next;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return rewrite(items, []);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Flatten a nested payload into insertable rows, minting ids up front so a
|
|
278
|
+
* child can reference its parent in the same batch. `sortOrder` is the item's
|
|
279
|
+
* index among its siblings — position is the payload's order, never a field the
|
|
280
|
+
* caller has to keep consistent.
|
|
281
|
+
*/
|
|
282
|
+
export function flattenMenuItems(menuId, items, newId = randomUUID) {
|
|
283
|
+
const out = [];
|
|
284
|
+
function walk(list, parentId) {
|
|
285
|
+
list.forEach((item, index) => {
|
|
286
|
+
const id = newId();
|
|
287
|
+
const external = typeof item.externalUrl === 'string' && item.externalUrl.trim() !== '';
|
|
288
|
+
out.push({
|
|
289
|
+
id,
|
|
290
|
+
menuId,
|
|
291
|
+
parentId,
|
|
292
|
+
sortOrder: index,
|
|
293
|
+
label: item.label,
|
|
294
|
+
contentId: external ? null : item.contentId ?? null,
|
|
295
|
+
externalUrl: external ? item.externalUrl : null,
|
|
296
|
+
openInNewWindow: item.openInNewWindow ?? false,
|
|
297
|
+
description: item.description ?? null,
|
|
298
|
+
});
|
|
299
|
+
if (item.children && item.children.length > 0)
|
|
300
|
+
walk(item.children, id);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
walk(items, null);
|
|
304
|
+
return out;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Replace a menu's entire item tree.
|
|
308
|
+
*
|
|
309
|
+
* Full-replace rather than diff-and-patch, so the write is idempotent: sending
|
|
310
|
+
* the same tree twice leaves the menu in the same state, which is what makes
|
|
311
|
+
* this safe for an agent to call repeatedly (the `upsert_menu` MCP tool).
|
|
312
|
+
*
|
|
313
|
+
* The delete + inserts run in one transaction — a failure part-way through must
|
|
314
|
+
* not leave the site with a half-empty navigation.
|
|
315
|
+
*/
|
|
316
|
+
export async function replaceMenuItems(db, menuId, items) {
|
|
317
|
+
assertMenuItemsValid(items);
|
|
318
|
+
const rows = flattenMenuItems(menuId, items);
|
|
319
|
+
await runInTransaction(db, async (tx) => {
|
|
320
|
+
await tx.delete(kywiMenuItems).where(eq(kywiMenuItems.menuId, menuId));
|
|
321
|
+
if (rows.length > 0) {
|
|
322
|
+
await tx.insert(kywiMenuItems).values(rows);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=menu-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-queries.js","sourceRoot":"","sources":["../../src/db/menu-queries.ts"],"names":[],"mappings":"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"}
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './types.js';
|
|
|
2
2
|
export { createModuleRegistry, BUILT_IN_MODULES, type ModuleRegistry, type ModuleRegistryEntry } from './registry.js';
|
|
3
3
|
export { mergeLayoutCascade, type CascadeRule } from './cascade.js';
|
|
4
4
|
export { KywiLayout, KywiRegion, AudienceMetaTags, type ComponentResolver, type SectionComponentResolver, type PersonalizationState, type ModuleComponentMap, } from './renderer.js';
|
|
5
|
+
export { hydrateLayoutNav, type NavHydrationResolver, } from './nav-hydration.js';
|
|
5
6
|
export { hydrateLayoutFeeds, contentRowsToFeedItems, type FeedDisplayItem, type FeedItemsResolver, } from './feed-hydration.js';
|
|
6
7
|
export { resolvePageVariantRegions, applyPageVariant } from './personalization.js';
|
|
7
8
|
export { BUILT_IN_MODULE_COMPONENTS } from './modules.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACrH,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACrH,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAA"}
|
package/dist/layout/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from './types.js';
|
|
|
2
2
|
export { createModuleRegistry, BUILT_IN_MODULES } from './registry.js';
|
|
3
3
|
export { mergeLayoutCascade } from './cascade.js';
|
|
4
4
|
export { KywiLayout, KywiRegion, AudienceMetaTags, } from './renderer.js';
|
|
5
|
+
export { hydrateLayoutNav, } from './nav-hydration.js';
|
|
5
6
|
export { hydrateLayoutFeeds, contentRowsToFeedItems, } from './feed-hydration.js';
|
|
6
7
|
export { resolvePageVariantRegions, applyPageVariant } from './personalization.js';
|
|
7
8
|
export { BUILT_IN_MODULE_COMPONENTS } from './modules.js';
|
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAiD,MAAM,eAAe,CAAA;AACrH,OAAO,EAAE,kBAAkB,EAAoB,MAAM,cAAc,CAAA;AACnE,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,GAKjB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,GAGvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAsB,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GAEnB,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAiD,MAAM,eAAe,CAAA;AACrH,OAAO,EAAE,kBAAkB,EAAoB,MAAM,cAAc,CAAA;AACnE,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,GAKjB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,gBAAgB,GAEjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,GAGvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAsB,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GAEnB,MAAM,gBAAgB,CAAA"}
|
|
@@ -17,8 +17,38 @@ export declare function PricingModule({ props }: ModuleProps): import("react/jsx
|
|
|
17
17
|
export declare function FaqModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
18
18
|
export declare function CountdownModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
19
19
|
export declare function AlertModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* One normalized navigation item.
|
|
22
|
+
*
|
|
23
|
+
* Two producers feed the nav modules and both land here:
|
|
24
|
+
* 1. the menu resolver (kywi-cms#110), which hydrates `props.items` with
|
|
25
|
+
* `{ id, label, href, target, description, isActive, isAncestor, children }`;
|
|
26
|
+
* 2. hand-authored JSON in the props panel, historically just
|
|
27
|
+
* `{ label, href, children? }` (+ an occasional `isActive`).
|
|
28
|
+
*
|
|
29
|
+
* `normalizeNavItems` accepts either and fills the gaps, so a renderer only
|
|
30
|
+
* ever deals with one shape. `path` is a positional key (`"1-0"`) used for
|
|
31
|
+
* React keys and for deriving stable, SSR-safe panel ids.
|
|
32
|
+
*/
|
|
33
|
+
export interface NavItemNode {
|
|
34
|
+
id: string;
|
|
35
|
+
path: string;
|
|
36
|
+
label: string;
|
|
37
|
+
href?: string | undefined;
|
|
38
|
+
target?: '_blank' | undefined;
|
|
39
|
+
description?: string | undefined;
|
|
40
|
+
isActive: boolean;
|
|
41
|
+
isAncestor: boolean;
|
|
42
|
+
children: NavItemNode[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Presentation variants shared by `navMenu` and `navigation`. The two legacy
|
|
46
|
+
* `navigation.variant` values map onto the closest new one so sites authored
|
|
47
|
+
* before this existed keep rendering (and keep their `kywi-navigation-*` class).
|
|
48
|
+
*/
|
|
49
|
+
export type NavVariant = 'horizontal' | 'mega' | 'vertical' | 'footer';
|
|
20
50
|
export declare function BreadcrumbsModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
-
export declare function NavMenuModule({ props }: ModuleProps):
|
|
51
|
+
export declare function NavMenuModule({ props }: ModuleProps): React.JSX.Element;
|
|
22
52
|
export declare function SearchBoxModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
23
53
|
export declare function FormEmbedModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
24
54
|
export declare function CategoryListModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -32,7 +62,7 @@ export declare function TagCloudModule({ props }: ModuleProps): import("react/js
|
|
|
32
62
|
export declare function RelatedContentModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
33
63
|
export declare function CategorySummaryModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
34
64
|
export declare function SiteMapModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
-
export declare function NavigationModule({ props }: ModuleProps):
|
|
65
|
+
export declare function NavigationModule({ props }: ModuleProps): React.JSX.Element;
|
|
36
66
|
export declare function SearchModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
37
67
|
export declare function ComponentModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
38
68
|
export declare function FormModule({ props }: ModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modules-extended.d.ts","sourceRoot":"","sources":["../../src/layout/modules-extended.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0C,MAAM,OAAO,CAAA;AAQ9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAcD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAqBjD;AAID,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAUjD;AAID,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAarD;AAID,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAwChD;AAID,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CA0BpD;AAID,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAyD/C;AAqBD,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAyBvD;AAID,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAgB/C;AAID,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAwBhD;AAID,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAoBvD;AAID,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAsCnD;AAID,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAa/C;AAID,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CA2BrD;AAID,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,2CAcjD;AAID,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"modules-extended.d.ts","sourceRoot":"","sources":["../../src/layout/modules-extended.tsx"],"names":[],"mappings":"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"}
|