@murumets-ee/menus 0.107.0 → 0.108.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.
package/dist/admin.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { AdminRoute, ToolkitApp } from "@murumets-ee/core";
3
+ import { TranslatableSource, TranslatableSourceText } from "@murumets-ee/content/translation";
3
4
  import { ResolvedMenuNavItem } from "@murumets-ee/blocks";
4
5
 
5
6
  //#region src/menu-item-schema.d.ts
@@ -183,6 +184,60 @@ declare function measureMenuTree(tree: unknown): MenuTreeMeasurement;
183
184
  */
184
185
  declare function validateTreeDepth(tree: unknown, maxDepth: number): boolean;
185
186
  //#endregion
187
+ //#region src/translatable-source.d.ts
188
+ /** The largest page `list` returns, whatever the caller asks for. */
189
+ declare const MAX_MENU_SOURCE_PAGE = 200;
190
+ /**
191
+ * What identifies the tree a set of texts was read from: sha256 of its JSON.
192
+ *
193
+ * Any change to the tree — a label, an order, a new item — is a new revision,
194
+ * so `write` can refuse to lay translations over a tree that moved under them.
195
+ */
196
+ declare function menuTreeRevision(tree: unknown): string;
197
+ /**
198
+ * The labels of a stored tree that want a translation.
199
+ *
200
+ * An item contributes when its `label` is a MAP with a non-empty string for
201
+ * `sourceLocale` and — in `'missing'` mode — no non-empty string yet for
202
+ * `targetLocale`. `label: null` means "use the linked entity's live title",
203
+ * which is that entity's text, not the menu's, and is never offered.
204
+ */
205
+ declare function collectMenuLabelTexts(tree: unknown, input: {
206
+ sourceLocale: string;
207
+ targetLocale: string;
208
+ mode: 'missing' | 'all';
209
+ }): TranslatableSourceText[];
210
+ /**
211
+ * A copy of `tree` with `label[targetLocale]` set on each item named in
212
+ * `texts`. The input is not modified.
213
+ *
214
+ * Only an item whose label is already a map takes a translation: a `null`
215
+ * label stays `null` (it follows the linked entity's title in every locale),
216
+ * and an id in `texts` that matches no such item is ignored. A text is trimmed;
217
+ * an empty one is skipped; one longer than {@link MAX_LABEL_LENGTH} throws,
218
+ * naming the item.
219
+ */
220
+ declare function applyMenuLabelTranslations(tree: unknown, targetLocale: string, texts: Readonly<Record<string, string>>): {
221
+ tree: unknown[];
222
+ applied: number;
223
+ };
224
+ /**
225
+ * Menu labels, for a whole-site translation. Contributed on the menus plugin's
226
+ * `contributes['content.translatableSources']` via {@link menusContributions}.
227
+ */
228
+ declare const menuTranslatableSource: TranslatableSource;
229
+ /**
230
+ * Everything `@murumets-ee/menus` contributes to other plugins' slots, as the
231
+ * value of the menus plugin's `contributes` field.
232
+ *
233
+ * Declared HERE rather than inline in the factory because the factory lives in
234
+ * `@murumets-ee/menus-ui/plugin` (this package stays react-free) while what is
235
+ * contributed is server behaviour this package owns.
236
+ */
237
+ declare const menusContributions: {
238
+ 'content.translatableSources': TranslatableSource[];
239
+ };
240
+ //#endregion
186
241
  //#region src/admin/editor-state.d.ts
187
242
  /** The menu row projected to exactly what the embedded editor needs. */
188
243
  interface MenuEditorStateMenu {
@@ -304,5 +359,5 @@ declare function resolveMenuItemSummaries(app: ToolkitApp, refs: ReadonlyArray<{
304
359
  id: string;
305
360
  }>): Promise<Map<string, MenuItemSummary>>;
306
361
  //#endregion
307
- export { ANCHOR_PATTERN, type BlockAnchor, MAX_ANCHOR_LENGTH, MAX_MENU_DEPTH, MAX_MENU_TREE_NODES, MAX_RESOLVED_HANDLES, type MenuEditorStateEntityType, type MenuEditorStateMenu, type MenuEditorStateResponse, type MenuItem, type MenuItemSummary, type MenuSchemaOptions, type ResolvedMenusResponse, buildMenuItemSchema, buildMenuTreeSchema, measureMenuTree, menusRoutes, resolveMenuItemSummaries, validateTreeDepth };
362
+ export { ANCHOR_PATTERN, type BlockAnchor, MAX_ANCHOR_LENGTH, MAX_MENU_DEPTH, MAX_MENU_SOURCE_PAGE, MAX_MENU_TREE_NODES, MAX_RESOLVED_HANDLES, type MenuEditorStateEntityType, type MenuEditorStateMenu, type MenuEditorStateResponse, type MenuItem, type MenuItemSummary, type MenuSchemaOptions, type ResolvedMenusResponse, applyMenuLabelTranslations, buildMenuItemSchema, buildMenuTreeSchema, collectMenuLabelTexts, measureMenuTree, menuTranslatableSource, menuTreeRevision, menusContributions, menusRoutes, resolveMenuItemSummaries, validateTreeDepth };
308
363
  //# sourceMappingURL=admin.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.mts","names":[],"sources":["../src/menu-item-schema.ts","../src/admin/editor-state.ts","../src/admin/routes.ts","../src/admin/summaries.ts"],"mappings":";;;;;;;;;;cAkCa,cAAA;;;;;AA4Fa;AAgB1B;;cAhGa,mBAAA;;;;;;;;;AAmHO;AAcpB;;cAlGa,iBAAA;;AAyHN;AAIP;;;;AAMgB;cAhHH,cAAA,EAAc,MAAqB;;;;;;;;;;;;;;;;;AAqOb;AAkDnC;;;;;;;;KA5PY,aAAA;EACN,IAAA;EAAgB,MAAA;EAAgB,EAAA;EAAY,MAAA;AAAA;EAC5C,IAAA;EAAa,GAAA;AAAA;EACb,IAAA;EAAe,KAAA;AAAA;;;AAoQV;AAYX;;;;AAAmE;AA0CnE;;;;AAAiE;;KA1SrD,QAAA;2DAEV,EAAA,UCvHkC;EDyHlC,IAAA;ECnHc;;;;;;;;ED4Hd,IAAA,GAAO,aAAA,cCtHI;EDwHX,KAAA,EAAO,MAAA,yBCpHQ;EDsHf,OAAA,GAAU,MAAA;EACV,MAAA;EACA,QAAA,EAAU,QAAA;AAAA;AClHZ;;;;;;;;;;;AAAA,UDgIiB,eAAA;EC/Hf;;;;;;EDsIA,KAAA;ECnIS;EDqIT,MAAA;ECrIuC;EDuIvC,SAAA;AAAA;;;;;;UAQe,WAAA;EChHb;EDkHF,MAAA;EChHE;EDkHF,KAAK;AAAA;;UAIU,iBAAA;;AEqRjB;;;;EF/QE,cAAc;AAAA;;;;;;;iBAmHA,mBAAA,CACd,OAAA,EAAS,iBAAA,GACR,CAAA,CAAE,OAAA,CAAQ,QAAA,EAAU,CAAA,CAAE,UAAA;;iBAkDT,mBAAA,CACd,OAAA,EAAS,iBAAA,GACR,CAAA,CAAE,OAAA,CAAQ,QAAA,IAAY,CAAA,CAAE,UAAA;;UAKV,mBAAA;;EAEf,KAAA;;EAEA,SAAS;AAAA;;;;;;;;;;iBAYK,eAAA,CAAgB,IAAA,YAAgB,mBAAmB;;;;;;;iBA0CnD,iBAAA,CAAkB,IAAA,WAAe,QAAgB;;;;UC/ZhD,mBAAA;EACf,EAAA;EACA,MAAA;EACA,KAAA;EACA,QAAA;EACA,MAAA;EACA,IAAA,EAAM,QAAQ;ED6FM;;;;;ECvFpB,WAAA;AAAA;;UAIe,yBAAA;EACf,IAAA;EACA,KAAK;AAAA;;UAIU,uBAAA;EACf,IAAA,EAAM,mBAAA;EDiHI;EC/GV,SAAA,EAAW,QAAA,CAAS,MAAA,SAAe,eAAA;EACnC,OAAA,EAAS,aAAA;IAAgB,IAAA;IAAc,KAAA;EAAA;EACvC,aAAA;EDyGA;;;;;;;;AAIkB;ECnGlB,gBAAA;EACA,WAAA,WAAsB,yBAAA;EACtB,UAAA;ED+G8B;;;;;AAWrB;AAQX;;;;AAIO;AAIP;;;;EC1HE,KAAA;IACE,IAAA,EAAM,MAAA;IACN,SAAA;IACA,aAAA;IACA,SAAA;EAAA;AAAA;;;;ADsGO;AAQX;;;;AAIO;AAIP;;cEqRa,oBAAA;;UAYI,qBAAA;EAKf,KAAA,EAAO,MAAM,SAAS,mBAAA;AAAA;;;;;;;;;;;;;;;iBAmHR,WAAA,CAAA,GAAe,UAAU;;;;;;;;;;;;;;;;;;;;;iBCzfnB,wBAAA,CACpB,GAAA,EAAK,UAAA,EACL,IAAA,EAAM,aAAA;EAAgB,MAAA;EAAgB,EAAA;AAAA,KACrC,OAAA,CAAQ,GAAA,SAAY,eAAA"}
1
+ {"version":3,"file":"admin.d.mts","names":[],"sources":["../src/menu-item-schema.ts","../src/translatable-source.ts","../src/admin/editor-state.ts","../src/admin/routes.ts","../src/admin/summaries.ts"],"mappings":"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"}
package/dist/admin.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./columns-D9y6Mvcp.mjs";import{resolveLinkHref as f}from"@murumets-ee/blocks/links";import{z as p}from"zod";import{combineAdminRoutes as m,defineAdminRoute as h,getContext as g,getCurrentApp as _,getCurrentScope as v,siteSecurityFields as y}from"@murumets-ee/core";import{VIEW_UNPUBLISHED_ACTION as b,getBlockTreeFieldName as x,getEntityTitleField as S,getSearchableConfig as C}from"@murumets-ee/entity";import{QueryClient as w}from"@murumets-ee/entity/query";import{eq as ee,inArray as T}from"drizzle-orm";function E(e,t,n){if(typeof e!=`object`||!e||Array.isArray(e))return;let r=e;for(let e of t===n?[t]:[t,n]){if(!Object.hasOwn(r,e))continue;let t=r[e];if(typeof t==`string`&&t.length>0)return t}}function D(e,t){if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e;if(!Object.hasOwn(n,t))return;let r=n[t];return typeof r==`boolean`?r:void 0}function O(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function k(t,n,r,i){let a=new Map,o=new Map,s=500,c=0;function l(e,t,n){let r=e.get(t);r?r.add(n):e.set(t,new Set([n]))}function u(t,d){if(d>i||!Array.isArray(t))return[];let f=t,p=[];for(let t of f){if(s<=0){c++;continue}if(!O(t))continue;let i=t.id,f=t.kind;if(typeof i!=`string`||i.length===0||f!==`link`&&f!==`header`||D(t.enabled,n)===!1)continue;s--;let m;if(f===`link`){let n=e.safeParse(t.link);if(!n.success)continue;m=n.data}else if(t.link!==void 0)continue;let h=u(t.children,d+1);m?.kind===`entity`&&(l(a,m.entity,m.id),E(t.label,n,r)===void 0&&l(o,m.entity,m.id)),p.push({id:i,kind:f,link:m,label:t.label,newTab:t.newTab===!0,children:h})}return p}return{nodes:u(t,1),idsByType:a,titleIdsByType:o,droppedForBudget:c}}async function A(e,t,n,r){let i=new Map,a=new Map,o=new Map,s=[...e.idsByType.entries()];return s.length>16&&n.logger?.warn({handle:r,locale:t,entityTypes:s.length,cap:16},`menu resolution dropped entity-type groups over the fan-out cap`),await Promise.all(s.slice(0,16).map(async([r,s])=>{let c=[...s],l=await n.resolveCanonicalPaths(r,c,t);if(i.set(r,l),l.size===0)return;let u=[...l.keys()],d=await n.filterPublished(r,u,t);a.set(r,d);let f=e.titleIdsByType.get(r);if(f===void 0)return;let p=u.filter(e=>f.has(e)&&d.has(e));p.length!==0&&o.set(r,await n.resolveTitles(r,p,t))})),{paths:i,published:a,titles:o}}function j(e,t,n,r){let i=[];for(let a of e){let e=j(a.children,t,n,r),o=E(a.label,t,r.defaultLocale);if(a.kind===`header`){if(e.length===0||o===void 0)continue;i.push({id:a.id,kind:`header`,label:o,href:null,newTab:!1,isActive:!1,inActiveTrail:!1,children:e});continue}let s=a.link;if(s===void 0)continue;let c,l=o;if(s.kind===`entity`){let e=n.paths.get(s.entity)?.get(s.id);if(e===void 0||n.published.get(s.entity)?.has(s.id)!==!0)continue;c=s.anchor===void 0?e:`${e}#${s.anchor}`,l??=n.titles.get(s.entity)?.get(s.id)}else c=f(s);c===null||c.length===0||l===void 0||l.length===0||i.push({id:a.id,kind:`link`,label:l,href:c,newTab:a.newTab,isActive:!1,inActiveTrail:!1,children:e})}return i}function M(e){let t=e.indexOf(`#`),n=t===-1?e:e.slice(0,t);return n.length>1&&n.endsWith(`/`)?n.slice(0,-1):n}function N(e,t){let n=!1;return{items:e.map(e=>{let r=N(e.children,t),i=e.href!==null&&M(e.href)===t,a=r.containsActive;return(i||a)&&(n=!0),{...e,isActive:i,inActiveTrail:a,children:r.items}}),containsActive:n}}function P(e,t){return{...e,items:N(e.items,M(t)).items}}async function F(e,t,n){if(e.length===0||e.length>128)return null;let r=await n.getMenuRow(e);if(r===null)return null;let i=r.maxDepth,a=typeof i==`number`&&Number.isInteger(i)&&i>=1?Math.min(i,6):3,o=k(r.tree,t.locale,n.defaultLocale,a);o.droppedForBudget>0&&n.logger?.warn({handle:e,locale:t.locale,dropped:o.droppedForBudget,cap:500},`menu resolution dropped items over the node budget`);let s=await A(o,t.locale,n,e),c={handle:e,items:j(o.nodes,t.locale,s,n)};return t.currentPath===void 0?c:P(c,t.currentPath)}function I(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function L(e,t){if(!I(e))return;let n={};for(let[r,i]of Object.entries(e))t(i)&&(n[r]=i);return n}const te=e=>typeof e==`string`,ne=e=>typeof e==`boolean`;function R(t){let n=500,r=0;function i(t,a){if(!Array.isArray(t))return[];let o=t;if(a>6)return r+=o.length,[];let s=[];for(let t of o){if(!I(t)){r++;continue}let o=t.id,c=t.kind;if(typeof o!=`string`||o.length===0){r++;continue}if(c!==`link`&&c!==`header`){r++;continue}let l;if(c===`link`){let n=e.safeParse(t.link);if(!n.success){r++;continue}l=n.data}else if(t.link!==void 0){r++;continue}if(n<=0){r++;continue}n--;let u=L(t.label,te),d=u!==void 0&&Object.keys(u).length>0?u:void 0,f=L(t.enabled,ne),p=f!==void 0&&Object.keys(f).length>0?f:void 0;s.push({id:o,kind:c,link:l,label:d??null,enabled:p,newTab:typeof t.newTab==`boolean`?t.newTab:void 0,children:i(t.children,a+1)})}return s}return{items:i(t,1),dropped:r}}function z(e){let t=new Set,n=[];function r(e){for(let i of e){let e=i.link;if(e?.kind===`entity`){let r=`${e.entity}:${e.id}`;t.has(r)||(t.add(r),n.push({entity:e.entity,id:e.id}))}r(i.children)}}return r(e),n}const B=1e3;function V(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function H(e){let t=e.props;if(!V(t))return;let n=t.anchor;if(typeof n!=`string`||n.length===0||n.length>128||!i.test(n))return;let r=t.anchorLabel;return{anchor:n,label:typeof r==`string`&&r.length>0&&r.length<=200?r:n}}function U(e,t){let n=[];if(!Array.isArray(e))return{anchors:n,truncated:!1,visited:0};let r=e,i=0,a=!1;r.length>1e3&&(a=!0);let o=[];for(let e=Math.min(r.length,B)-1;e>=0;e--)o.push(r[e]);for(;o.length>0;){if(i>=1e3||n.length>=200){a=!0;break}let e=o.pop();if(i++,!V(e))continue;let t=H(e);t!==void 0&&n.push(t);let r=e.children;if(Array.isArray(r)){let e=r,t=Math.max(B-i,0);e.length>t&&(a=!0);for(let n=Math.min(e.length,t)-1;n>=0;n--)o.push(e[n])}}return a&&t?.warn({visited:i,collected:n.length,nodeBudget:B,resultCap:200},`anchor collection stopped at a hard bound — the returned list is incomplete`),{anchors:n,truncated:a,visited:i}}function W(e,t){return`${e}:${t}`}const G={title:null,exists:!1,published:null};function K(e){let t=new Map,n=0,r=0;for(let i of e){if(typeof i.entity!=`string`||typeof i.id!=`string`||i.entity.length===0||i.id.length===0)continue;let e=t.get(i.entity);if(!e?.has(i.id)){if(n>=500){r++;continue}n++,e?e.add(i.id):t.set(i.entity,new Set([i.id]))}}let i=Math.max(0,t.size-16);return{groups:t,droppedRefs:r,droppedGroups:i}}async function q(e,t){let n=new Map;if(t.length===0)return n;let r=e.logger.child({resolve:`menu-item-summaries`}),{groups:i,droppedRefs:a,droppedGroups:o}=K(t);return a>0&&r.warn({dropped:a,cap:500},`menu item summaries dropped targets over the ref budget — some rows will show no status`),o>0&&r.warn({dropped:o,cap:16},`menu item summaries dropped entity-type groups over the fan-out cap`),await Promise.all([...i.entries()].slice(0,16).map(([t,i])=>J(e,r,t,i,n))),n}async function J(e,t,n,r,i){let a=e.entities.get(n);if(a===void 0)return;let o=S(a),s=o!==`id`,c=a.behaviors?.some(e=>e.name===`publishable`)??!1,l=[...r];try{let t=e.getClient(a),r=await t.findMany({where:T(u(t.getTable(),`id`),l),limit:l.length}),d=new Set;for(let e of r){let t=e,r=t.id;if(typeof r!=`string`)continue;let a=s?t[o]:void 0;d.add(r),i.set(W(n,r),{title:typeof a==`string`&&a.length>0?a:null,exists:!0,published:c?t.status===`published`:null})}if((a.scope??`global`)===`global`)for(let e of l)d.has(e)||i.set(W(n,e),G)}catch(e){t.warn({entity:n,count:l.length,error:String(e)},`menu item summaries could not be resolved for this entity type`)}}const Y=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function X(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`}})}function Z(e,t){return X({error:e},t)}function Q(){return X([])}function re(e){return x(e)??null}const ie=h({prefix:`menus`,path:`anchors`,method:`GET`,permission:`menu:view`,defaultRoles:[`admin`],description:`List a published document's addressable block anchors for the menu editor's anchor picker.`,tokens:`accept`,handler:async(e,t)=>{let n=new URL(e.url).searchParams,r=n.get(`entity`),i=n.get(`id`);if(r===null||r.length===0)return Z(`query param 'entity' is required`,400);if(r.length>64)return Z(`query param 'entity' is too long`,400);if(i===null||!Y.test(i))return Z(`query param 'id' must be a uuid`,400);let a=_();if(a===void 0)return Z(`Internal error`,500);let o=a.logger.child({route:`menus/anchors`,entity:r});if(!t.checkPermission(r,`view`))return o.debug({userId:t.user.id,role:t.user.role},`anchors lookup returned empty — caller holds no view grant on the target entity`),Q();let s=a.entities.get(r);if(s===void 0)return Q();let c=re(s);if(c===null)return Q();let l=v(),u=await new w({entity:s,db:a.db.readOnly,logger:o,contextResolver:()=>({user:{id:t.user.id,groups:[t.user.role??`viewer`]},checker:(e,n,r)=>r!==b&&t.checkPermission(n,r),...l!==void 0&&{scope:l},...y(void 0,a)})}).findById(i,{...t.locale!==void 0&&{locale:t.locale},...t.defaultLocale!==void 0&&{defaultLocale:t.defaultLocale}});if(u===null)return Q();let{anchors:d}=U(u[c],o);return X(d)}}),ae=async(e,t)=>{let n=new URL(e.url).searchParams.get(`handle`);if(n===null||n.length===0)return Z(`query param 'handle' is required`,400);if(n.length>128)return Z(`query param 'handle' is too long`,400);let r=_();if(r===void 0)return Z(`Internal error`,500);let i=r.logger.child({route:`menus/editor-state`}),a=r.getClient(o),s=(await a.findMany({where:ee(u(a.getTable(),`handle`),n),limit:1}))[0];if(s===void 0)return Z(`Menu not found`,404);let l=s.id,d=typeof s.title==`string`?s.title:``,f=s.maxDepth,p=typeof f==`number`&&Number.isInteger(f)&&f>=1?Math.min(f,6):3,m=s.status===`published`?`published`:`draft`,h=g()?.availableLocales,v=t.defaultLocale??h?.[0]??`en`,y=h&&h.length>0?[...h]:[],b=(y.includes(v)?y:[v,...y]).map(e=>({code:e,label:e})),x=await oe(r,l,i),S=x?.data,{items:w,dropped:T}=R(S!==void 0&&`tree`in S?S.tree:s.tree);T>0&&i.warn({menuId:l,handle:n,dropped:T},`menu editor-state: stored tree contained items that could not be read — the embedded editor shows the rest`);let E=await q(r,z(w)),D=Object.fromEntries(E),O=[...r.entities.values()].filter(e=>C(e)!==void 0&&t.checkPermission(e.name,`view`)).map(e=>({name:e.name,label:e.admin?.labelSingular??e.admin?.label??e.name})),k=t.checkPermission(`menu`,`publish`);return X({menu:{id:l,handle:n,title:d,maxDepth:p,status:m,tree:w,entityTypes:c(S!==void 0&&`entityTypes`in S?S.entityTypes:s.entityTypes)},summaries:D,locales:b,defaultLocale:v,droppedItemCount:T,entityTypes:O,canPublish:k,...x!==void 0&&{draft:x}})};async function oe(e,t,n){try{let{ContentClient:n}=await import(`@murumets-ee/content/client`),r=await new n({admin:e.getClient(o),entity:o}).getDraft(t,`_`);return r?{data:r.data,createdBy:r.createdBy,createdByName:r.createdByName,updatedAt:r.updatedAt instanceof Date?r.updatedAt.toISOString():String(r.updatedAt)}:void 0}catch(e){n.warn({err:e,menuId:t},`menu editor-state: draft state unavailable — continuing without`);return}}const $=h({prefix:`menus`,path:`editor-state`,method:`GET`,permission:`menu:view`,defaultRoles:[`admin`],description:`Read a menu's full tree + editor metadata by handle, for the blocks editor's in-place Tier 3 menu surface.`,tokens:`accept`,handler:ae}),se=8,ce=p.object({handles:p.array(p.string().min(1).max(128)).min(1).max(8)}),le=h({prefix:`menus`,path:`resolved`,method:`GET`,permission:`blocks:read-editor-state`,defaultRoles:[`admin`,`editor`],description:`Read the published, resolved items of the menus an editing canvas names, by handle.`,tokens:`accept`,handler:async(e,t)=>{let n=ce.safeParse({handles:[...new Set(new URL(e.url).searchParams.getAll(`handle`))]});if(!n.success)return Z(`query param 'handle' must be given 1 to 8 times, each 1 to 128 characters`,400);let{handles:r}=n.data,i=_();if(i===void 0)return Z(`Internal error`,500);let a=i.logger.child({route:`menus/resolved`}),{buildMenuResolveDeps:o}=await import(`./menu-resolve-context-2s6VJs_m.mjs`),s=o(i),c=t.locale??t.defaultLocale??s.defaultLocale,l=await Promise.all(r.map(async e=>{try{let t=await F(e,{locale:c},s);return[e,t===null?null:t.items]}catch(t){a.warn({err:t,handle:e,locale:c},`menu failed to resolve for the canvas; it is left out of the answer`);return}}));return X({menus:Object.fromEntries(l.filter(e=>e!==void 0))})}});function ue(){return m([ie,$,le])}export{i as ANCHOR_PATTERN,s as MAX_ANCHOR_LENGTH,l as MAX_MENU_DEPTH,t as MAX_MENU_TREE_NODES,se as MAX_RESOLVED_HANDLES,a as buildMenuItemSchema,d as buildMenuTreeSchema,n as measureMenuTree,ue as menusRoutes,q as resolveMenuItemSummaries,r as validateTreeDepth};
1
+ import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./columns-DwDukx_r.mjs";import{resolveLinkHref as f}from"@murumets-ee/blocks/links";import{z as p}from"zod";import{createHash as m}from"node:crypto";import{getContentConfig as h}from"@murumets-ee/content/plugin";import{combineAdminRoutes as g,defineAdminRoute as _,getContext as v,getCurrentApp as y,getCurrentScope as b,siteSecurityFields as x}from"@murumets-ee/core";import{asc as S,eq as ee,gt as C,inArray as w}from"drizzle-orm";import{VIEW_UNPUBLISHED_ACTION as T,getBlockTreeFieldName as E,getEntityTitleField as D,getSearchableConfig as te}from"@murumets-ee/entity";import{QueryClient as O}from"@murumets-ee/entity/query";const ne=200,k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function A(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function j(e){return typeof e==`string`&&e.trim()!==``}function M(e){let t=[],n=Array.isArray(e)?[...e].reverse():[];for(;n.length>0;){let e=n.pop();if(A(e)){if(t.push(e),t.length>500)throw Error(`menu tree has more than 500 items`);if(Array.isArray(e.children))for(let t=e.children.length-1;t>=0;t--)n.push(e.children[t])}}return t}function N(e){return m(`sha256`).update(JSON.stringify(Array.isArray(e)?e:[])).digest(`hex`)}function P(e,t){let{sourceLocale:n,targetLocale:r,mode:i}=t;if(n===r)return[];let a=[],o=new Set;for(let t of M(e)){let{id:e,label:s}=t;if(!j(e)||o.has(e)||!A(s))continue;let c=Object.hasOwn(s,n)?s[n]:void 0;if(!j(c))continue;let l=Object.hasOwn(s,r)?s[r]:void 0;i===`missing`&&j(l)||(o.add(e),a.push({key:e,text:c,maxLength:200}))}return a}function F(e,t,n){let r=Array.isArray(e)?structuredClone(e):[],i=0;for(let e of M(r)){let{id:r,label:a}=e;if(typeof r!=`string`||!Object.hasOwn(n,r)||!A(a))continue;let o=n[r];if(typeof o!=`string`)continue;let s=o.trim();if(s!==``){if(s.length>200)throw Error(`menu item ${r}: the translated label is longer than 200 characters`);e.label={...a,[t]:s},i++}}return{tree:r,applied:i}}function I(e){if(e===null||typeof e==`string`||typeof e==`boolean`)return e;if(typeof e==`number`)return Number.isFinite(e)?e:null;if(Array.isArray(e))return e.map(I);if(A(e)){let t={};for(let[n,r]of Object.entries(e))r!==void 0&&(t[n]=I(r));return t}return null}async function re(e){let{ContentClient:t}=await import(`@murumets-ee/content/client`);return new t({admin:e.getClient(o),entity:o})}async function L(e,t){if(!k.test(t))return null;let n=await e.getClient(o).findById(t);if(!n)return null;let r=await re(e),i=await r.getDraft(t,`_`),a=A(i?.data)?i.data:void 0;return{tree:a!==void 0&&`tree`in a?a.tree:n.tree,draftData:a,content:r}}async function ie(e,t){if(t.after!==void 0&&!k.test(t.after))throw Error("menu translatable source: `after` is not a menu id");let n=Number.isFinite(t.limit)?Math.min(Math.max(Math.trunc(t.limit),1),200):200,r=e.getClient(o),i=u(r.getTable(),`id`);return(await r.findMany({...t.after!==void 0&&{where:C(i,t.after)},orderBy:S(i),limit:n})).map(e=>{let t=e;return{id:t.id,label:typeof t.title==`string`?t.title:``}})}async function ae(e,t){let n=await L(e,t.id);return n===null?null:{revision:N(n.tree),texts:P(n.tree,t)}}function oe(){let e=v(),t=e?.user?.groups[0];if(t===void 0||e?.checker?.(t,o.name,`update`)!==!0)throw Error(`menu translatable source: the caller may not update menus`)}async function se(e,t,n){oe();let r=await L(e,t.id);if(r===null)return`not_found`;if(N(r.tree)!==t.revision)return`changed`;if(!n.includes(t.targetLocale))throw Error(`menu ${t.id}: the target locale is not one of the site's content languages (${n.join(`, `)})`);let{tree:i,applied:a}=F(r.tree,t.targetLocale,t.texts);if(a===0)return`written`;let s=d({allowedLocales:n}).safeParse(i);if(!s.success){let e=s.error.issues.slice(0,5).map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);throw Error(`menu ${t.id}: the translated tree is not valid — ${e}`)}let{LockService:c}=await import(`@murumets-ee/content/lock`),l=await new c({app:e}).getLock(o.name,t.id,`_`);if(l&&l.lockedBy!==t.user.id)throw Error(`menu ${t.id}: is being edited by ${l.lockedByName??l.lockedBy} — try again when they have finished`);return await r.content.saveDraft(t.id,{...r.draftData,tree:I(s.data)},`_`,t.user),`written`}function R(){let e=y();if(e===void 0)throw Error(`menu translatable source: called outside a request context`);return e}function ce(){let e=v()?.availableLocales;return e!==void 0&&e.length>0?e:h().locales.map(e=>e.code)}const z={kind:`menu`,label:`Menus`,labelKey:`Menus.translatableSource.menu`,permission:{resource:`menu`,action:`update`},draft:!0,list:e=>ie(R(),e),read:e=>ae(R(),e),write:e=>se(R(),e,ce())},le={"content.translatableSources":[z]};function B(e,t,n){if(typeof e!=`object`||!e||Array.isArray(e))return;let r=e;for(let e of t===n?[t]:[t,n]){if(!Object.hasOwn(r,e))continue;let t=r[e];if(typeof t==`string`&&t.length>0)return t}}function ue(e,t){if(typeof e!=`object`||!e||Array.isArray(e))return;let n=e;if(!Object.hasOwn(n,t))return;let r=n[t];return typeof r==`boolean`?r:void 0}function de(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function fe(t,n,r,i){let a=new Map,o=new Map,s=500,c=0;function l(e,t,n){let r=e.get(t);r?r.add(n):e.set(t,new Set([n]))}function u(t,d){if(d>i||!Array.isArray(t))return[];let f=t,p=[];for(let t of f){if(s<=0){c++;continue}if(!de(t))continue;let i=t.id,f=t.kind;if(typeof i!=`string`||i.length===0||f!==`link`&&f!==`header`||ue(t.enabled,n)===!1)continue;s--;let m;if(f===`link`){let n=e.safeParse(t.link);if(!n.success)continue;m=n.data}else if(t.link!==void 0)continue;let h=u(t.children,d+1);m?.kind===`entity`&&(l(a,m.entity,m.id),B(t.label,n,r)===void 0&&l(o,m.entity,m.id)),p.push({id:i,kind:f,link:m,label:t.label,newTab:t.newTab===!0,children:h})}return p}return{nodes:u(t,1),idsByType:a,titleIdsByType:o,droppedForBudget:c}}async function pe(e,t,n,r){let i=new Map,a=new Map,o=new Map,s=[...e.idsByType.entries()];return s.length>16&&n.logger?.warn({handle:r,locale:t,entityTypes:s.length,cap:16},`menu resolution dropped entity-type groups over the fan-out cap`),await Promise.all(s.slice(0,16).map(async([r,s])=>{let c=[...s],l=await n.resolveCanonicalPaths(r,c,t);if(i.set(r,l),l.size===0)return;let u=[...l.keys()],d=await n.filterPublished(r,u,t);a.set(r,d);let f=e.titleIdsByType.get(r);if(f===void 0)return;let p=u.filter(e=>f.has(e)&&d.has(e));p.length!==0&&o.set(r,await n.resolveTitles(r,p,t))})),{paths:i,published:a,titles:o}}function V(e,t,n,r){let i=[];for(let a of e){let e=V(a.children,t,n,r),o=B(a.label,t,r.defaultLocale);if(a.kind===`header`){if(e.length===0||o===void 0)continue;i.push({id:a.id,kind:`header`,label:o,href:null,newTab:!1,isActive:!1,inActiveTrail:!1,children:e});continue}let s=a.link;if(s===void 0)continue;let c,l=o;if(s.kind===`entity`){let e=n.paths.get(s.entity)?.get(s.id);if(e===void 0||n.published.get(s.entity)?.has(s.id)!==!0)continue;c=s.anchor===void 0?e:`${e}#${s.anchor}`,l??=n.titles.get(s.entity)?.get(s.id)}else c=f(s);c===null||c.length===0||l===void 0||l.length===0||i.push({id:a.id,kind:`link`,label:l,href:c,newTab:a.newTab,isActive:!1,inActiveTrail:!1,children:e})}return i}function H(e){let t=e.indexOf(`#`),n=t===-1?e:e.slice(0,t);return n.length>1&&n.endsWith(`/`)?n.slice(0,-1):n}function U(e,t){let n=!1;return{items:e.map(e=>{let r=U(e.children,t),i=e.href!==null&&H(e.href)===t,a=r.containsActive;return(i||a)&&(n=!0),{...e,isActive:i,inActiveTrail:a,children:r.items}}),containsActive:n}}function me(e,t){return{...e,items:U(e.items,H(t)).items}}async function he(e,t,n){if(e.length===0||e.length>128)return null;let r=await n.getMenuRow(e);if(r===null)return null;let i=r.maxDepth,a=typeof i==`number`&&Number.isInteger(i)&&i>=1?Math.min(i,6):3,o=fe(r.tree,t.locale,n.defaultLocale,a);o.droppedForBudget>0&&n.logger?.warn({handle:e,locale:t.locale,dropped:o.droppedForBudget,cap:500},`menu resolution dropped items over the node budget`);let s=await pe(o,t.locale,n,e),c={handle:e,items:V(o.nodes,t.locale,s,n)};return t.currentPath===void 0?c:me(c,t.currentPath)}function W(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function G(e,t){if(!W(e))return;let n={};for(let[r,i]of Object.entries(e))t(i)&&(n[r]=i);return n}const ge=e=>typeof e==`string`,_e=e=>typeof e==`boolean`;function ve(t){let n=500,r=0;function i(t,a){if(!Array.isArray(t))return[];let o=t;if(a>6)return r+=o.length,[];let s=[];for(let t of o){if(!W(t)){r++;continue}let o=t.id,c=t.kind;if(typeof o!=`string`||o.length===0){r++;continue}if(c!==`link`&&c!==`header`){r++;continue}let l;if(c===`link`){let n=e.safeParse(t.link);if(!n.success){r++;continue}l=n.data}else if(t.link!==void 0){r++;continue}if(n<=0){r++;continue}n--;let u=G(t.label,ge),d=u!==void 0&&Object.keys(u).length>0?u:void 0,f=G(t.enabled,_e),p=f!==void 0&&Object.keys(f).length>0?f:void 0;s.push({id:o,kind:c,link:l,label:d??null,enabled:p,newTab:typeof t.newTab==`boolean`?t.newTab:void 0,children:i(t.children,a+1)})}return s}return{items:i(t,1),dropped:r}}function ye(e){let t=new Set,n=[];function r(e){for(let i of e){let e=i.link;if(e?.kind===`entity`){let r=`${e.entity}:${e.id}`;t.has(r)||(t.add(r),n.push({entity:e.entity,id:e.id}))}r(i.children)}}return r(e),n}const K=1e3;function q(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function be(e){let t=e.props;if(!q(t))return;let n=t.anchor;if(typeof n!=`string`||n.length===0||n.length>128||!i.test(n))return;let r=t.anchorLabel;return{anchor:n,label:typeof r==`string`&&r.length>0&&r.length<=200?r:n}}function xe(e,t){let n=[];if(!Array.isArray(e))return{anchors:n,truncated:!1,visited:0};let r=e,i=0,a=!1;r.length>1e3&&(a=!0);let o=[];for(let e=Math.min(r.length,K)-1;e>=0;e--)o.push(r[e]);for(;o.length>0;){if(i>=1e3||n.length>=200){a=!0;break}let e=o.pop();if(i++,!q(e))continue;let t=be(e);t!==void 0&&n.push(t);let r=e.children;if(Array.isArray(r)){let e=r,t=Math.max(K-i,0);e.length>t&&(a=!0);for(let n=Math.min(e.length,t)-1;n>=0;n--)o.push(e[n])}}return a&&t?.warn({visited:i,collected:n.length,nodeBudget:K,resultCap:200},`anchor collection stopped at a hard bound — the returned list is incomplete`),{anchors:n,truncated:a,visited:i}}function J(e,t){return`${e}:${t}`}const Se={title:null,exists:!1,published:null};function Ce(e){let t=new Map,n=0,r=0;for(let i of e){if(typeof i.entity!=`string`||typeof i.id!=`string`||i.entity.length===0||i.id.length===0)continue;let e=t.get(i.entity);if(!e?.has(i.id)){if(n>=500){r++;continue}n++,e?e.add(i.id):t.set(i.entity,new Set([i.id]))}}let i=Math.max(0,t.size-16);return{groups:t,droppedRefs:r,droppedGroups:i}}async function Y(e,t){let n=new Map;if(t.length===0)return n;let r=e.logger.child({resolve:`menu-item-summaries`}),{groups:i,droppedRefs:a,droppedGroups:o}=Ce(t);return a>0&&r.warn({dropped:a,cap:500},`menu item summaries dropped targets over the ref budget — some rows will show no status`),o>0&&r.warn({dropped:o,cap:16},`menu item summaries dropped entity-type groups over the fan-out cap`),await Promise.all([...i.entries()].slice(0,16).map(([t,i])=>we(e,r,t,i,n))),n}async function we(e,t,n,r,i){let a=e.entities.get(n);if(a===void 0)return;let o=D(a),s=o!==`id`,c=a.behaviors?.some(e=>e.name===`publishable`)??!1,l=[...r];try{let t=e.getClient(a),r=await t.findMany({where:w(u(t.getTable(),`id`),l),limit:l.length}),d=new Set;for(let e of r){let t=e,r=t.id;if(typeof r!=`string`)continue;let a=s?t[o]:void 0;d.add(r),i.set(J(n,r),{title:typeof a==`string`&&a.length>0?a:null,exists:!0,published:c?t.status===`published`:null})}if((a.scope??`global`)===`global`)for(let e of l)d.has(e)||i.set(J(n,e),Se)}catch(e){t.warn({entity:n,count:l.length,error:String(e)},`menu item summaries could not be resolved for this entity type`)}}const Te=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function X(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":`application/json`}})}function Z(e,t){return X({error:e},t)}function Q(){return X([])}function Ee(e){return E(e)??null}const De=_({prefix:`menus`,path:`anchors`,method:`GET`,permission:`menu:view`,defaultRoles:[`admin`],description:`List a published document's addressable block anchors for the menu editor's anchor picker.`,tokens:`accept`,handler:async(e,t)=>{let n=new URL(e.url).searchParams,r=n.get(`entity`),i=n.get(`id`);if(r===null||r.length===0)return Z(`query param 'entity' is required`,400);if(r.length>64)return Z(`query param 'entity' is too long`,400);if(i===null||!Te.test(i))return Z(`query param 'id' must be a uuid`,400);let a=y();if(a===void 0)return Z(`Internal error`,500);let o=a.logger.child({route:`menus/anchors`,entity:r});if(!t.checkPermission(r,`view`))return o.debug({userId:t.user.id,role:t.user.role},`anchors lookup returned empty — caller holds no view grant on the target entity`),Q();let s=a.entities.get(r);if(s===void 0)return Q();let c=Ee(s);if(c===null)return Q();let l=b(),u=await new O({entity:s,db:a.db.readOnly,logger:o,contextResolver:()=>({user:{id:t.user.id,groups:[t.user.role??`viewer`]},checker:(e,n,r)=>r!==T&&t.checkPermission(n,r),...l!==void 0&&{scope:l},...x(void 0,a)})}).findById(i,{...t.locale!==void 0&&{locale:t.locale},...t.defaultLocale!==void 0&&{defaultLocale:t.defaultLocale}});if(u===null)return Q();let{anchors:d}=xe(u[c],o);return X(d)}}),Oe=async(e,t)=>{let n=new URL(e.url).searchParams.get(`handle`);if(n===null||n.length===0)return Z(`query param 'handle' is required`,400);if(n.length>128)return Z(`query param 'handle' is too long`,400);let r=y();if(r===void 0)return Z(`Internal error`,500);let i=r.logger.child({route:`menus/editor-state`}),a=r.getClient(o),s=(await a.findMany({where:ee(u(a.getTable(),`handle`),n),limit:1}))[0];if(s===void 0)return Z(`Menu not found`,404);let l=s.id,d=typeof s.title==`string`?s.title:``,f=s.maxDepth,p=typeof f==`number`&&Number.isInteger(f)&&f>=1?Math.min(f,6):3,m=s.status===`published`?`published`:`draft`,h=v()?.availableLocales,g=t.defaultLocale??h?.[0]??`en`,_=h&&h.length>0?[...h]:[],b=(_.includes(g)?_:[g,..._]).map(e=>({code:e,label:e})),x=await ke(r,l,i),S=x?.data,{items:C,dropped:w}=ve(S!==void 0&&`tree`in S?S.tree:s.tree);w>0&&i.warn({menuId:l,handle:n,dropped:w},`menu editor-state: stored tree contained items that could not be read — the embedded editor shows the rest`);let T=await Y(r,ye(C)),E=Object.fromEntries(T),D=[...r.entities.values()].filter(e=>te(e)!==void 0&&t.checkPermission(e.name,`view`)).map(e=>({name:e.name,label:e.admin?.labelSingular??e.admin?.label??e.name})),O=t.checkPermission(`menu`,`publish`);return X({menu:{id:l,handle:n,title:d,maxDepth:p,status:m,tree:C,entityTypes:c(S!==void 0&&`entityTypes`in S?S.entityTypes:s.entityTypes)},summaries:E,locales:b,defaultLocale:g,droppedItemCount:w,entityTypes:D,canPublish:O,...x!==void 0&&{draft:x}})};async function ke(e,t,n){try{let{ContentClient:n}=await import(`@murumets-ee/content/client`),r=await new n({admin:e.getClient(o),entity:o}).getDraft(t,`_`);return r?{data:r.data,createdBy:r.createdBy,createdByName:r.createdByName,updatedAt:r.updatedAt instanceof Date?r.updatedAt.toISOString():String(r.updatedAt)}:void 0}catch(e){n.warn({err:e,menuId:t},`menu editor-state: draft state unavailable — continuing without`);return}}const Ae=_({prefix:`menus`,path:`editor-state`,method:`GET`,permission:`menu:view`,defaultRoles:[`admin`],description:`Read a menu's full tree + editor metadata by handle, for the blocks editor's in-place Tier 3 menu surface.`,tokens:`accept`,handler:Oe}),$=8,je=p.object({handles:p.array(p.string().min(1).max(128)).min(1).max(8)}),Me=_({prefix:`menus`,path:`resolved`,method:`GET`,permission:`blocks:read-editor-state`,defaultRoles:[`admin`,`editor`],description:`Read the published, resolved items of the menus an editing canvas names, by handle.`,tokens:`accept`,handler:async(e,t)=>{let n=je.safeParse({handles:[...new Set(new URL(e.url).searchParams.getAll(`handle`))]});if(!n.success)return Z(`query param 'handle' must be given 1 to 8 times, each 1 to 128 characters`,400);let{handles:r}=n.data,i=y();if(i===void 0)return Z(`Internal error`,500);let a=i.logger.child({route:`menus/resolved`}),{buildMenuResolveDeps:o}=await import(`./menu-resolve-context-DLIUP8RY.mjs`),s=o(i),c=t.locale??t.defaultLocale??s.defaultLocale,l=await Promise.all(r.map(async e=>{try{let t=await he(e,{locale:c},s);return[e,t===null?null:t.items]}catch(t){a.warn({err:t,handle:e,locale:c},`menu failed to resolve for the canvas; it is left out of the answer`);return}}));return X({menus:Object.fromEntries(l.filter(e=>e!==void 0))})}});function Ne(){return g([De,Ae,Me])}export{i as ANCHOR_PATTERN,s as MAX_ANCHOR_LENGTH,l as MAX_MENU_DEPTH,ne as MAX_MENU_SOURCE_PAGE,t as MAX_MENU_TREE_NODES,$ as MAX_RESOLVED_HANDLES,F as applyMenuLabelTranslations,a as buildMenuItemSchema,d as buildMenuTreeSchema,P as collectMenuLabelTexts,n as measureMenuTree,z as menuTranslatableSource,N as menuTreeRevision,le as menusContributions,Ne as menusRoutes,Y as resolveMenuItemSummaries,r as validateTreeDepth};
2
2
  //# sourceMappingURL=admin.mjs.map