@kywi-software/core 0.6.7 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/AGENT-PATTERNS.md +58 -2
  2. package/dist/admin/registry.d.ts +2 -2
  3. package/dist/admin/registry.d.ts.map +1 -1
  4. package/dist/admin/registry.js +41 -19
  5. package/dist/admin/registry.js.map +1 -1
  6. package/dist/admin/styles/admin.css +130 -0
  7. package/dist/admin/surfaces/menus/menu-editor.d.ts +3 -0
  8. package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -0
  9. package/dist/admin/surfaces/menus/menu-editor.js +260 -0
  10. package/dist/admin/surfaces/menus/menu-editor.js.map +1 -0
  11. package/dist/admin/surfaces/menus/menu-tree.d.ts +123 -0
  12. package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -0
  13. package/dist/admin/surfaces/menus/menu-tree.js +292 -0
  14. package/dist/admin/surfaces/menus/menu-tree.js.map +1 -0
  15. package/dist/admin/surfaces/menus/menus-data.d.ts +101 -0
  16. package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -0
  17. package/dist/admin/surfaces/menus/menus-data.js +98 -0
  18. package/dist/admin/surfaces/menus/menus-data.js.map +1 -0
  19. package/dist/admin/surfaces/menus/menus-list.d.ts +3 -0
  20. package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -0
  21. package/dist/admin/surfaces/menus/menus-list.js +105 -0
  22. package/dist/admin/surfaces/menus/menus-list.js.map +1 -0
  23. package/dist/admin/surfaces/menus/page-picker.d.ts +10 -0
  24. package/dist/admin/surfaces/menus/page-picker.d.ts.map +1 -0
  25. package/dist/admin/surfaces/menus/page-picker.js +38 -0
  26. package/dist/admin/surfaces/menus/page-picker.js.map +1 -0
  27. package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
  28. package/dist/admin/surfaces/settings/admin-features.js +1 -0
  29. package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
  30. package/dist/api/feed-routes.d.ts +2 -2
  31. package/dist/api/index.d.ts +1 -0
  32. package/dist/api/index.d.ts.map +1 -1
  33. package/dist/api/index.js +5 -0
  34. package/dist/api/index.js.map +1 -1
  35. package/dist/api/menu-routes.d.ts +46 -0
  36. package/dist/api/menu-routes.d.ts.map +1 -0
  37. package/dist/api/menu-routes.js +247 -0
  38. package/dist/api/menu-routes.js.map +1 -0
  39. package/dist/api/openapi.d.ts.map +1 -1
  40. package/dist/api/openapi.js +105 -0
  41. package/dist/api/openapi.js.map +1 -1
  42. package/dist/cache/cached-queries.d.ts +22 -0
  43. package/dist/cache/cached-queries.d.ts.map +1 -1
  44. package/dist/cache/cached-queries.js +31 -1
  45. package/dist/cache/cached-queries.js.map +1 -1
  46. package/dist/cache/keys.d.ts +2 -0
  47. package/dist/cache/keys.d.ts.map +1 -1
  48. package/dist/cache/keys.js +4 -0
  49. package/dist/cache/keys.js.map +1 -1
  50. package/dist/db/index.d.ts +1 -0
  51. package/dist/db/index.d.ts.map +1 -1
  52. package/dist/db/index.js +1 -0
  53. package/dist/db/index.js.map +1 -1
  54. package/dist/db/menu-queries.d.ts +182 -0
  55. package/dist/db/menu-queries.d.ts.map +1 -0
  56. package/dist/db/menu-queries.js +326 -0
  57. package/dist/db/menu-queries.js.map +1 -0
  58. package/dist/layout/index.d.ts +1 -0
  59. package/dist/layout/index.d.ts.map +1 -1
  60. package/dist/layout/index.js +1 -0
  61. package/dist/layout/index.js.map +1 -1
  62. package/dist/layout/modules-extended.d.ts +32 -2
  63. package/dist/layout/modules-extended.d.ts.map +1 -1
  64. package/dist/layout/modules-extended.js +159 -39
  65. package/dist/layout/modules-extended.js.map +1 -1
  66. package/dist/layout/nav-hydration.d.ts +62 -0
  67. package/dist/layout/nav-hydration.d.ts.map +1 -0
  68. package/dist/layout/nav-hydration.js +149 -0
  69. package/dist/layout/nav-hydration.js.map +1 -0
  70. package/dist/layout/registry.d.ts +0 -26
  71. package/dist/layout/registry.d.ts.map +1 -1
  72. package/dist/layout/registry.js +22 -8
  73. package/dist/layout/registry.js.map +1 -1
  74. package/dist/nav/builder.d.ts +16 -0
  75. package/dist/nav/builder.d.ts.map +1 -1
  76. package/dist/nav/builder.js +21 -2
  77. package/dist/nav/builder.js.map +1 -1
  78. package/dist/nav/index.d.ts +1 -0
  79. package/dist/nav/index.d.ts.map +1 -1
  80. package/dist/nav/index.js +1 -0
  81. package/dist/nav/index.js.map +1 -1
  82. package/dist/nav/menu-resolver.d.ts +52 -0
  83. package/dist/nav/menu-resolver.d.ts.map +1 -0
  84. package/dist/nav/menu-resolver.js +113 -0
  85. package/dist/nav/menu-resolver.js.map +1 -0
  86. package/dist/nav/types.d.ts +30 -0
  87. package/dist/nav/types.d.ts.map +1 -1
  88. package/dist/schema/base.d.ts +331 -0
  89. package/dist/schema/base.d.ts.map +1 -1
  90. package/dist/schema/base.js +45 -0
  91. package/dist/schema/base.js.map +1 -1
  92. package/dist/schema/mysql-tables.d.ts +303 -0
  93. package/dist/schema/mysql-tables.d.ts.map +1 -1
  94. package/dist/schema/mysql-tables.js +25 -0
  95. package/dist/schema/mysql-tables.js.map +1 -1
  96. package/dist/scope/create-scope.d.ts.map +1 -1
  97. package/dist/scope/create-scope.js +27 -1
  98. package/dist/scope/create-scope.js.map +1 -1
  99. package/dist/scope/types.d.ts +28 -1
  100. package/dist/scope/types.d.ts.map +1 -1
  101. package/dist/site/styles.css +380 -0
  102. 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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"}
@@ -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"}
@@ -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';
@@ -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): import("react/jsx-runtime").JSX.Element;
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): import("react/jsx-runtime").JSX.Element;
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":"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"}
1
+ {"version":3,"file":"modules-extended.d.ts","sourceRoot":"","sources":["../../src/layout/modules-extended.tsx"],"names":[],"mappings":"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"}