@lpdjs/firestore-repo-service 2.1.2 → 2.1.3

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.
@@ -552,7 +552,7 @@ function initColumnReorder(table) {
552
552
  });
553
553
  });
554
554
  }
555
- `;function ie(){return jsx("script",{dangerouslySetInnerHTML:{__html:Me}})}function J(e){return "<!DOCTYPE html>"+renderToString(e)}var W=({opts:e,children:t})=>{let{title:n,breadcrumb:s,flash:r,basePath:o="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsx("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:jsx("div",{class:"flex-1",children:jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})})}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[s&&s.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:s.map((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),r&&jsx("div",{role:"alert",class:`alert ${r.type==="success"?"alert-success":"alert-error"} mb-6`,children:jsx("span",{children:r.message})}),t]}),jsx(ie,{})]})]})};function ge(e,t){return J(jsx(W,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function he(e,t){return J(jsx(W,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:e.map(n=>jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxs("div",{class:"card-body p-5",children:[jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var Ue=[{value:"==",label:"="},{value:"!=",label:"\u2260"}],gt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"<",label:"<"},{value:"<=",label:"\u2264"},{value:">",label:">"},{value:">=",label:"\u2265"}],ht=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function bt(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return gt;case "ZodBoolean":return Ue;case "ZodArray":return ht;default:return Ue}}function vt({col:e,active:t}){let n=t?.value??"";if(e.zodType==="ZodBoolean")return jsxs("select",{name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",children:[jsx("option",{value:"",selected:n==="",children:"\u2014"}),jsx("option",{value:"true",selected:n==="true",children:"true"}),jsx("option",{value:"false",selected:n==="false",children:"false"})]});if(e.zodType==="ZodArray"){let s=t?.op==="array-contains-any";return jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:s?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsx("input",{type:"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"}):e.zodType==="ZodDate"?jsx("input",{type:"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full"}):jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"})}function be({action:e,columnMeta:t,activeFilters:n}){let s=Object.fromEntries(n.map(a=>[a.field,a])),r=n.length>0,o=t.filter(a=>a.zodType!=="ZodObject"&&a.zodType!=="ZodRecord");return jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:r?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",r&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:o.map(a=>{let f=bt(a.zodType),g=s[a.name],d=g?.op??f[0].value;return jsxs("div",{class:"flex flex-col gap-1.5",children:[jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:a.name}),jsxs("div",{class:"flex gap-1.5",children:[f.length>1?jsx("select",{name:`fo_${a.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:f.map(l=>jsx("option",{value:l.value,selected:l.value===d,children:l.label},l.value))}):jsx("input",{type:"hidden",name:`fo_${a.name}`,value:f[0].value}),jsx(vt,{col:a,active:g})]})]},a.name)})}),jsxs("div",{class:"flex gap-2 mt-4 pt-3 border-t border-base-200",children:[jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),r&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"})]})]})})]})}function ve(e,t,n,s,r,o){let a=n==="create"?`Create ${e}`:`Edit ${e} / ${s??""}`,f=n==="create"?[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:"New document"}]:[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:`Edit ${s??""}`}];return J(jsx(W,{opts:{title:a,breadcrumb:f,basePath:r,flash:o},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}function xe(e,t,n){let s=new URLSearchParams;for(let r of e)s.set(`fv_${r.field}`,r.value),s.set(`fo_${r.field}`,r.op);return t&&(s.set("ob",t.field),s.set("od",t.dir)),n&&s.set("ps",String(n)),s}function He(e,t,n,s,r){let o=xe(e,s,r);return o.set("cursor",t),o.set("dir",n),`?${o.toString()}`}function xt(e,t,n,s){let r=xe(n,void 0,s);return t?.field===e?t.dir==="asc"&&(r.set("ob",e),r.set("od","desc")):(r.set("ob",e),r.set("od","asc")),`?${r.toString()}`}function Rt(e,t,n){return `?${xe(t,n,e).toString()}`}function Re(e,t,n,s,r,o,a=[],f=[],g=false,d=[],l,R){let u=`${s}/${e}`,c=`${u}/create`;return J(jsxs(W,{opts:{title:e,breadcrumb:[{label:"Repositories",href:s},{label:e}],basePath:s,flash:o},children:[a.length>0&&jsx(be,{action:u,columnMeta:a,activeFilters:f}),jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3",children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length," document",t.length!==1&&"s"]}),jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsx("span",{children:"Rows"}),jsx("div",{class:"join",children:[10,25,50,100].map(p=>jsx("a",{href:Rt(p,f,l),class:`join-item btn btn-xs ${R===p?"btn-active btn-primary":"btn-outline"}`,children:p},p))})]})]}),jsx("a",{href:c,class:"btn btn-primary btn-sm",children:"+ New"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[[...n].map((p,b)=>{let m=l?.field===p,i=m?l.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:xt(p,l,f,R),class:`hover:text-base-content inline-flex items-center gap-0.5${m?" text-primary font-bold":""}`,children:[p,i]})},b)}),d.map((p,b)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:p.column},`rel-${b}`)),jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsx("tbody",{children:t.length===0?jsx("tr",{children:jsx("td",{colspan:n.length+d.length+1,class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((p,b)=>{let m=String(p.docId??p.id??""),i=`${s}/${e}/${encodeURIComponent(m)}/edit`,y=`${s}/${e}/${encodeURIComponent(m)}/delete`;return jsxs("tr",{class:"hover",children:[n.map((v,h)=>jsx("td",{class:"align-top py-2",children:jsx(ye,{val:p[v]})},h)),d.map((v,h)=>{let x=p[v.key];if(x==null||x==="")return jsx("td",{class:"py-2"},`rel-${h}`);let w=`${s}/${v.targetRepo}?fv_${v.targetKey}=${encodeURIComponent(String(x))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:w,class:"btn btn-xs btn-ghost btn-outline",children:v.column})},`rel-${h}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:i,class:"btn btn-xs btn-outline",children:"Edit"}),g&&jsx("form",{method:"post",action:y,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},b)})})]})}),(r.hasPrev||r.hasNext)&&jsxs("div",{class:"flex justify-center items-center mt-6 gap-2",children:[r.hasPrev?jsx("a",{href:He(f,r.prevCursor,"prev",l,R),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),r.hasNext?jsx("a",{href:He(f,r.nextCursor,"next",l,R),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]})]}))}var wt="";function St(e,t){return ge(e,t)}function we(e,t){return he(e,t)}function Se(e,t,n,s,r,o,a,f,g,d,l,R){return Re(e,t,n,s,r,o,a,f,g,d,l,R)}function X(e,t,n,s,r,o){return ve(e,t,n,s,r,o)}var Le="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Ct(){let e="";for(let t=0;t<20;t++)e+=Le.charAt(Math.floor(Math.random()*Le.length));return e}function Ve(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let s=n.split("/").filter(Boolean),r=[];for(let o=1;o<s.length;o+=2)r.push(s[o]);return r.length>0?r:void 0}async function $e(e,t){let n=e.documentKey??"docId",s=`by${n.charAt(0).toUpperCase()}${n.slice(1)}`;if(typeof e.repo.get[s]=="function")try{let o=await e.repo.get[s](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function A(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Ce(e,t){e.status(302).set("Location",t).send("");}function Oe(e,t){let n=t.shape,s={};for(let[r,o]of Object.entries(n)){let a=Ae(o);if(a==="ZodObject"){if(e[r+"__isnull"]==="1"){s[r]=null;continue}let d={},l=false;for(let[c,p]of Object.entries(e))c.startsWith(`${r}.`)&&(d[c.slice(r.length+1)]=p,l=true);if(l){let c=o;for(;;){let p=j(c);if(p==="ZodOptional"||p==="ZodNullable"||p==="ZodDefault")c=q(c);else break}s[r]=Oe(d,c);continue}let R=e[r],u=Array.isArray(R)?R[R.length-1]:R;if(u)try{s[r]=JSON.parse(u);}catch{s[r]=u;}continue}let f=e[r],g=Array.isArray(f)?f[f.length-1]:f;if(e[r+"__isnull"]==="1"){s[r]=null;continue}if(g===void 0||g===""){a==="ZodBoolean"&&(s[r]=false);continue}switch(a){case "ZodBoolean":g==="__null__"?s[r]=null:s[r]=g==="true"||g==="on"||g==="1";break;case "ZodNumber":case "ZodBigInt":s[r]=Number(g);break;case "ZodDate":s[r]=new Date(g);break;case "ZodArray":try{s[r]=JSON.parse(g);}catch{s[r]=g;}break;default:if(g.startsWith("{")||g.startsWith("["))try{s[r]=JSON.parse(g);break}catch{}s[r]=g;}}return s}function Je(e){let t=null;if(e instanceof Date)t=e;else if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")t=e.toDate();else if(typeof e=="object"&&e!==null&&"_seconds"in e&&"_nanoseconds"in e)t=new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));else if(typeof e=="string"||typeof e=="number"){let s=new Date(e);isNaN(s.getTime())||(t=s);}if(!t||isNaN(t.getTime()))return null;let n=s=>String(s).padStart(2,"0");return `${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}function Ae(e){let t=e;for(;;){let n=j(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=q(t);else return n}}function We(e,t,n=""){let s={};for(let r of Object.keys(t.shape)){let o=n?`${n}.${r}`:r,a=e[r];if(a===null){s[o]="__null__";continue}if(a===void 0)continue;let f=t.shape[r];for(;;){let d=j(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=q(f);else break}let g=j(f);if(g==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let d=We(a,f,o);Object.assign(s,d);}else if(g==="ZodDate"){let d=Je(a);d!==null&&(s[o]=d);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let d=Je(a);s[o]=d??JSON.stringify(a,null,2);}else typeof a=="object"?s[o]=JSON.stringify(a,null,2):s[o]=String(a);}return s}function ke(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?ke(n.nested,t):void 0}))}function Ot(e,t){let n=new Set(["==","!=","<","<=",">",">=","array-contains","array-contains-any"]),s=[];for(let[r,o]of Object.entries(e)){if(!r.startsWith("fv_"))continue;let a=r.slice(3);if(!t.has(a))continue;let f=(o??"").trim();if(!f)continue;let g=e[`fo_${a}`]??"==",d=n.has(g)?g:"==";s.push({field:a,op:d,value:f});}return s}function kt(e){let t=n=>n==="true"?true:n==="false"?false:n!==""&&!isNaN(Number(n))?Number(n):n;return e.map(n=>{if(n.op==="array-contains-any"){let s=n.value.split(",").map(r=>t(r.trim())).filter(r=>r!=="");return [n.field,n.op,s]}return [n.field,n.op,t(n.value)]})}function Ge(e,t,n=""){let s=[];for(let r of e){let o=n?`${n}.${r}`:r,a=t.shape[r];if(!a){s.push({name:o,zodType:"ZodString"});continue}let f=Ae(a);if(f==="ZodObject"){let g=a;for(;;){let l=j(g);if(l==="ZodOptional"||l==="ZodNullable"||l==="ZodDefault")g=q(g);else break}let d=ae(g);s.push(...Ge(Object.keys(d),g,o));}else s.push({name:o,zodType:f});}return s}function At(e,t){let n=t.split("."),s=e;for(let r of n){for(;;){let a=j(s);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")s=q(s);else break}let o=ae(s);if(!(r in o))return null;s=o[r];}return s}function ne(e,t){if(!t||t.length===0)return e;let n=[],s=new Map;for(let o of t){let a=o.indexOf(".");if(a===-1)n.push(o);else {let f=o.slice(0,a),g=o.slice(a+1);s.has(f)||s.set(f,[]),s.get(f).push(g);}}let r={};for(let o of n)o in e.shape&&(r[o]=e.shape[o]);for(let[o,a]of s){if(!(o in e.shape))continue;let f=e.shape[o];for(;;){let g=j(f);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")f=q(f);else break}if(j(f)!=="ZodObject"){r[o]=e.shape[o];continue}r[o]=ne(f,a);}return z.object(r)}function te(e,t){let n=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let o=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${a}/${f}${n}`}let s=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return s&&r.includes("cloudfunctions.net")?`/${s}${n}`:n}function Xe(e,t){return {handleDashboard:(d,l)=>{let R=te(d,t),u=Object.values(e).map(c=>({name:c.name,path:c.path}));A(l,we(u,R));},handleList:async(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=u.pageSize??25,p=d.query??{},b=p.cursor,m=p.dir==="prev"?"prev":"next",i=p.ob??"",y=p.od==="desc"?"desc":"asc",v=i?{field:i,dir:y}:void 0,h=parseInt(p.ps??""),x=Number.isFinite(h)&&h>0?Math.min(h,200):c,w=u.listColumns??Object.keys(u.schema.shape),S=u.documentKey??"docId",C=[S,...w.filter(I=>I!==S)],O=u.filterableFields?(()=>{let I=[];for(let L of u.filterableFields)(L.includes(".")||w.includes(L))&&I.push(L);return I})():w,T=(()=>{let I=[];for(let L of O)if(L.includes(".")){let Ee=At(u.schema,L);I.push({name:L,zodType:Ee?Ae(Ee):"ZodString"});}else I.push(...Ge([L],u.schema));return I})(),z=new Set(T.map(I=>I.name)),Z=Ot(p,z),re=kt(Z),E;if(b)try{let I=u.repo.ref;typeof I.doc=="function"&&(E=await I.doc(b).get());}catch{}let K=await u.repo.query.paginate({pageSize:x,cursor:E,direction:m,...re.length>0?{where:re}:{},...v?{orderBy:[{field:v.field,direction:v.dir}]}:{}}),ot=K.nextCursor?.id??"",it=K.prevCursor?.id??"",lt=te(d,t);A(l,Se(u.name,K.data,C,lt,{hasPrev:K.hasPrevPage,hasNext:K.hasNextPage,prevCursor:it,nextCursor:ot},void 0,T,Z,u.allowDelete??false,u.relationalMeta,v,x));},handleCreateForm:(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=te(d,t),p=ne(u.schema,u.createFields),b=U(p),m=`${c}/${u.name}/create`,i=V(b,m,"POST","Create document");A(l,X(u.name,i,"create",null,c));},handleCreateSubmit:async(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=te(d,t),p=d.body??{},b=Oe(p,u.schema),m=ne(u.schema,u.createFields),i=m.safeParse(b);if(!i.success){let y=U(m),v=`${c}/${u.name}/create`,h=V(y,v,"POST","Create document"),x=i.error.issues.map(w=>`${w.path.join(".")}: ${w.message}`).join(", ");A(l,X(u.name,h,"create",null,c,{type:"error",message:`Validation error: ${x}`}),422);return}try{if(u.isGroup&&u.parentKeys&&u.parentKeys.length>0){let y={...i.data};u.createdKey&&(y[u.createdKey]=new Date);let v=u.parentKeys.filter(S=>!y[S]);if(v.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${v.join(", ")}`);let h=u.parentKeys.map(S=>y[S]),x=u.documentKey??"docId",w=y[x]||Ct();await u.repo.set(...h,w,y);}else await u.repo.create(i.data);Ce(l,`${c}/${u.name}?flash=created`);}catch(y){let v=ne(u.schema,u.createFields),h=U(v),x=`${c}/${u.name}/create`,w=V(h,x,"POST","Create document");A(l,X(u.name,w,"create",null,c,{type:"error",message:`Save error: ${y.message}`}),500);}},handleEditForm:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}let p=null;try{p=await $e(c,u);}catch(x){A(l,`Error fetching document: ${x.message}`,500);return}if(!p){A(l,"Document not found",404);return}let b=We(p,c.schema),m=ne(c.schema,c.mutableFields),i=ke(U(m),b),y=te(d,t),v=`${y}/${c.name}/${encodeURIComponent(u)}/edit`,h=V(i,v,"POST","Save changes");A(l,X(c.name,h,"edit",u,y));},handleEditSubmit:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}let p=te(d,t),b=d.body??{},m=Oe(b,c.schema),i=ne(c.schema,c.mutableFields),v=i.partial().safeParse(m);if(!v.success){let h=Object.fromEntries(Object.entries(b).map(([O,T])=>[O,Array.isArray(T)?T.join(","):T??""])),x=ke(U(i),h),w=`${p}/${c.name}/${encodeURIComponent(u)}/edit`,S=V(x,w,"POST","Save changes"),C=v.error.issues.map(O=>`${O.path.join(".")}: ${O.message}`).join(", ");A(l,X(c.name,S,"edit",u,p,{type:"error",message:`Validation error: ${C}`}),422);return}try{let h=await $e(c,u),x=(h&&Ve(h,c.pathKey))??[u];await c.repo.update(...x,v.data),Ce(l,`${p}/${c.name}?flash=updated`);}catch(h){let x=ne(c.schema,c.mutableFields),w=U(x),S=`${p}/${c.name}/${encodeURIComponent(u)}/edit`,C=V(w,S,"POST","Save changes");A(l,X(c.name,C,"edit",u,p,{type:"error",message:`Save error: ${h.message}`}),500);}},handleDelete:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}if(!c.allowDelete){A(l,"Delete is not allowed for this repository",403);return}let p=te(d,t);try{let b=await $e(c,u),m=(b&&Ve(b,c.pathKey))??[u];await c.repo.delete(...m),Ce(l,`${p}/${c.name}?flash=deleted`);}catch(b){A(l,`Delete error: ${b.message}`,500);}}}}function Tt(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,s=>s===":"?s:`\\${s}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(s,r)=>(t.push(r),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function Pt(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var Q=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,n)=>{n.status(404).send("Not Found");};this.errorHandler=(t,n,s)=>{console.error("[MiniRouter]",t),s.status(500).send("Internal Server Error");};}use(t){return this.middlewares.push(t),this}get(t,n){return this.addRoute("GET",t,n)}post(t,n){return this.addRoute("POST",t,n)}put(t,n){return this.addRoute("PUT",t,n)}patch(t,n){return this.addRoute("PATCH",t,n)}delete(t,n){return this.addRoute("DELETE",t,n)}onNotFound(t){return this.notFoundHandler=t,this}onError(t){return this.errorHandler=t,this}addRoute(t,n,s){let{pattern:r,paramNames:o}=Tt(n);return this.routes.push({method:t.toUpperCase(),pattern:r,paramNames:o,handler:s}),this}async handle(t,n){let s=(t.method??"GET").toUpperCase(),r=Pt(t),o=null,a={};for(let d of this.routes){if(d.method!==s)continue;let l=r.match(d.pattern);if(l){o=d,a={},d.paramNames.forEach((R,u)=>{a[R]=decodeURIComponent(l[u+1]??"");});break}}let f=Object.assign(t,{params:a}),g=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,n,g);}catch(d){this.errorHandler(d,t,n);}}async runMiddlewareChain(t,n,s){let r=0,o=async()=>{if(r<this.middlewares.length){let a=this.middlewares[r++];await a(t,n,o);}else await s(t,n);};await o();}};async function _t(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Et(e){let t={};if(!e)return t;for(let n of e.split("&")){let s=n.indexOf("=");if(s===-1)continue;let r=decodeURIComponent(n.slice(0,s).replace(/\+/g," ")),o=decodeURIComponent(n.slice(s+1).replace(/\+/g," ")),a=t[r];a===void 0?t[r]=o:Array.isArray(a)?a.push(o):t[r]=[a,o];}return t}function Zt(e){let{basePath:t="/",repos:n,parseBody:s=true,auth:r,middleware:o=[],httpsOptions:a}=e,f=t==="/"?"":t.replace(/\/$/,""),g={};for(let[u,c]of Object.entries(n)){let p=c.schema??c.repo.schema??null;if(!p)throw new Error(`[createAdminServer] Repository "${u}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let b,m,i;if(c.fieldsConfig){let h=c.fieldsConfig;b=[],m=[],i=[];for(let[x,w]of Object.entries(h))for(let S of w)S==="filterable"?b.push(x):S==="mutable"?m.push(x):S==="create"&&i.push(x);b.length===0&&(b=void 0),m.length===0&&(m=void 0),i.length===0&&(i=void 0);}let y=(()=>{let h=c.repo._parentKeys;return h&&h.length>0?h:void 0})();if(y&&i)for(let h of y)i.includes(h)||i.push(h);let v={name:u,path:c.path,repo:c.repo,schema:p,documentKey:c.documentKey??"docId",pathKey:c.repo._pathKey??void 0,isGroup:!!c.repo._isGroup,parentKeys:y,createdKey:c.repo._createdKey??void 0,listColumns:c.listColumns,pageSize:c.pageSize,filterableFields:b,mutableFields:m,createFields:i,allowDelete:c.allowDelete??false,relationalMeta:(()=>{if(!c.relationalFields||c.relationalFields.length===0)return;let h=c.repo.relationalKeys??{},x=[];for(let w of c.relationalFields){let S=h[w.key];S&&x.push({key:w.key,column:w.column,targetRepo:String(S.repo),targetKey:String(S.key),type:S.type});}return x.length>0?x:void 0})()};g[u]=v;}let d=Xe(g,f),l=new Q;if(s&&l.use(async(u,c,p)=>{let b=u,m=String(b.headers?.["content-type"]??"");if(m.includes("application/x-www-form-urlencoded")){let i=await _t(b);u.body=Et(i);}else if(m.includes("application/json")&&typeof b.body=="string")try{u.body=JSON.parse(b.body);}catch{}await p();}),r)if(typeof r=="function")l.use(r);else {let u=r.realm??"Admin",c="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");l.use((p,b,m)=>{if((p.headers?.authorization??"")!==c){b.status(401).set("WWW-Authenticate",`Basic realm="${u}"`).set("Content-Type","text/plain").send("Unauthorized");return}m();});}for(let u of o)l.use(u);l.get(`${f}/`,d.handleDashboard),l.get(`${f}`,d.handleDashboard),l.get(`${f}/:repoName`,d.handleList),l.get(`${f}/:repoName/create`,d.handleCreateForm),l.post(`${f}/:repoName/create`,d.handleCreateSubmit),l.get(`${f}/:repoName/:id/edit`,d.handleEditForm),l.post(`${f}/:repoName/:id/edit`,d.handleEditSubmit),l.post(`${f}/:repoName/:id/delete`,d.handleDelete);let R=async(u,c)=>{await l.handle(u,c);};return a&&(R.httpsOptions=a),R}function rt(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function se(e,t,n,s=200){rt(e,{success:true,data:t,meta:n},s);}function P(e,t,n=400){rt(e,{success:false,error:t},n);}var Qe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Dt(){let e="";for(let t=0;t<20;t++)e+=Qe.charAt(Math.floor(Math.random()*Qe.length));return e}function Ft(e,t,n=[]){let s=e.shape,r={},o=t&&t.length>0?t:Object.keys(s);for(let a of o){if(n.includes(a))continue;let f=a.split(".")[0];f&&s[f]&&(r[f]=s[f]);}return z.object(r)}function Ye(e,t,n,s=false,r=[]){try{let o=Ft(e,n,r);return {success:!0,data:(s?o.partial():o).parse(t)}}catch(o){return o instanceof z.ZodError?{success:false,error:`Validation failed: ${o.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function It(e,t){let n=[],s=t?new Set(t):null,r={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[o,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(o))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let g=o.match(/^(\w+)__(\w+)$/),d,l="==";if(g&&g[1]&&g[2]){d=g[1];let u=g[2];if(r[u])l=r[u];else continue}else if(!g)d=o;else continue;if(s&&!s.has(d))continue;let R=f;l==="in"||l==="not-in"||l==="array-contains-any"?R=f.split(",").map(u=>et(u.trim())):R=et(f),n.push({field:d,op:l,value:R});}return n}function et(e){if(e==="true")return true;if(e==="false")return false;if(e==="null")return null;let t=Number(e);return !isNaN(t)&&e!==""?t:e}function ue(e){return e?{docId:e.id}:null}async function tt(e,t){if(!t||typeof t!="object")return;let n=t.docId;if(typeof n=="string")try{let s=e.repo.ref;if(typeof s.doc!="function")return;let r=await s.doc(n).get();return r.exists?r:void 0}catch{return}}function st(e,t,n){function s(c,p){return !c||!e[c]?(P(p,`Repository "${c}" not found`,404),null):e[c]}function r(c,p){if(!p)return;let b=c[p];if(typeof b!="string"||!b)return;let m=b.split("/").filter(Boolean),i=[];for(let y=1;y<m.length;y+=2)i.push(m[y]);return i.length>0?i:void 0}async function o(c,p){let b=`by${c.documentKey.charAt(0).toUpperCase()}${c.documentKey.slice(1)}`,m=c.repo.get[b];if(typeof m=="function")try{let y=await m(p);if(y)return y}catch{}return (await c.repo.query.by({where:[[c.documentKey,"==",p]],limit:1}))[0]??null}async function a(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.query??{},y=Math.min(Number(i.pageSize)||m.pageSize,100),v=i.cursor,h=i.direction?.toLowerCase()==="prev"?"prev":"next",x=i.orderBy,w=i.orderDir?.toLowerCase()==="desc"?"desc":"asc",S=i.select,C=S?S.split(",").map(E=>E.trim()):void 0,O;m.allowedIncludes&&i.includes&&(O=(typeof i.includes=="string"?i.includes.split(",").map(K=>K.trim()):Array.isArray(i.includes)?i.includes:[]).filter(K=>typeof K=="string"&&m.allowedIncludes.includes(K)),O?.length===0&&(O=void 0));let T=It(i,m.filterableFields),z={pageSize:y,direction:h};if(v)try{let E=typeof v=="string"?JSON.parse(v):v;z.cursor=await tt(m,E);}catch{}x&&(z.orderBy=[{field:x,direction:w}]),T.length>0&&(z.where=T.map(E=>[E.field,E.op,E.value])),C&&(z.select=C),O&&(z.include=O);let Z=await m.repo.query.paginate(z),re={items:Z.data,hasNextPage:Z.hasNextPage,hasPrevPage:Z.hasPrevPage,nextCursor:ue(Z.nextCursor),prevCursor:ue(Z.prevCursor)};se(p,re,{pageSize:y,hasMore:Z.hasNextPage});}catch(i){let y=n&&i instanceof Error?i.message:"Failed to fetch documents";P(p,y,500);}}async function f(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.body??{},y=Math.min(i.pageSize||m.pageSize,100),v=i.direction==="prev"?"prev":"next",h={pageSize:y,direction:v};if(i.cursor)try{let S=typeof i.cursor=="string"?JSON.parse(i.cursor):i.cursor;h.cursor=await tt(m,S);}catch{}if(m.allowedIncludes&&i.includes&&i.includes.length>0){let S=i.includes.filter(C=>typeof C=="string"?m.allowedIncludes.includes(C):typeof C=="object"&&C!==null&&"relation"in C&&typeof C.relation=="string"?m.allowedIncludes.includes(C.relation):!1);S.length>0&&(h.include=S);}if(i.where&&i.where.length>0){if(m.filterableFields){let S=new Set(m.filterableFields),C=i.where.filter(O=>!S.has(O[0]));if(C.length>0){P(p,`Fields not filterable: ${C.map(O=>O[0]).join(", ")}`,400);return}}h.where=i.where;}if(i.orWhere&&i.orWhere.length>0){if(m.filterableFields){let S=new Set(m.filterableFields),C=i.orWhere.filter(O=>!S.has(O[0]));if(C.length>0){P(p,`Fields not filterable: ${C.map(O=>O[0]).join(", ")}`,400);return}}h.orWhere=i.orWhere;}if(i.orWhereGroups&&i.orWhereGroups.length>0){if(m.filterableFields){let S=new Set(m.filterableFields);for(let C of i.orWhereGroups){let O=C.filter(T=>!S.has(T[0]));if(O.length>0){P(p,`Fields not filterable: ${O.map(T=>T[0]).join(", ")}`,400);return}}}h.orWhereGroups=i.orWhereGroups;}i.orderBy&&i.orderBy.length>0&&(h.orderBy=i.orderBy),i.select&&i.select.length>0&&(h.select=i.select);let x=await m.repo.query.paginate(h),w={items:x.data,hasNextPage:x.hasNextPage,hasPrevPage:x.hasPrevPage,nextCursor:ue(x.nextCursor),prevCursor:ue(x.prevCursor)};se(p,w,{pageSize:y,hasMore:x.hasNextPage});}catch(i){let y=n&&i instanceof Error?i.message:"Failed to query documents";P(p,y,500);}}async function g(c,p){let b=c.params||{},m=s(b.repoName,p);if(!m)return;let i=b.id;if(!i){P(p,"Document ID required",400);return}try{let y=await o(m,i);if(!y){P(p,"Document not found",404);return}se(p,y);}catch(y){let v=n&&y instanceof Error?y.message:"Failed to fetch document";P(p,v,500);}}async function d(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.body??{},y=Ye(m.schema,i,m.createFields,!1,m.systemKeys);if(!y.success){P(p,y.error,400);return}if(m.validate){let h=await m.validate(y.data,"create");if(h){P(p,h,400);return}}let v;if(m.isGroup&&m.parentKeys&&m.parentKeys.length>0){let h={...y.data};m.createdKey&&(h[m.createdKey]=new Date);let x=m.parentKeys.filter(C=>!h[C]);if(x.length>0){P(p,`Missing parent key(s) for subcollection create: ${x.join(", ")}`,400);return}let w=m.parentKeys.map(C=>h[C]),S=h[m.documentKey]||Dt();v=await m.repo.set(...w,S,h);}else v=await m.repo.create(y.data);se(p,v,void 0,201);}catch(i){let y=n&&i instanceof Error?i.message:"Failed to create document";P(p,y,500);}}async function l(c,p,b){let m=c.params||{},i=s(m.repoName,p);if(!i)return;let y=m.id;if(!y){P(p,"Document ID required",400);return}try{let v=c.body??{},h=Ye(i.schema,v,i.mutableFields,b,i.systemKeys);if(!h.success){P(p,h.error,400);return}if(i.validate){let C=await i.validate(h.data,"update");if(C){P(p,C,400);return}}let x=await o(i,y),w=(x&&r(x,i.pathKey))??[y],S=await i.repo.update(...w,h.data);se(p,S);}catch(v){let h=n&&v instanceof Error?v.message:"Failed to update document";P(p,h,500);}}async function R(c,p){let b=c.params||{},m=s(b.repoName,p);if(!m)return;if(!m.allowDelete){P(p,"Delete not allowed for this repository",403);return}let i=b.id;if(!i){P(p,"Document ID required",400);return}try{let y=await o(m,i),v=(y&&r(y,m.pathKey))??[i];await m.repo.delete(...v),se(p,{deleted:!0});}catch(y){let v=n&&y instanceof Error?y.message:"Failed to delete document";P(p,v,500);}}function u(c,p){p.status(204).set("Access-Control-Allow-Methods","GET, POST, PUT, PATCH, DELETE, OPTIONS").set("Access-Control-Allow-Headers","Content-Type, Authorization").set("Access-Control-Max-Age","86400").send("");}return {handleList:a,handleQuery:f,handleGet:g,handleCreate:d,handleUpdate:l,handleDelete:R,handleOptions:u}}function Te(e){try{return z.toJSONSchema(e,{target:"openapi-3.1"})}catch{return {type:"object"}}}function M(e){return {$ref:`#/components/schemas/${e}`}}function F(e){return {description:e,content:{"application/json":{schema:M("ErrorResponse")}}}}function ce(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function at(e){return {description:"Paginated list of documents",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:{type:"object",properties:{items:{type:"array",items:e},nextCursor:{oneOf:[{type:"object"},{type:"null"}]},prevCursor:{oneOf:[{type:"object"},{type:"null"}]},hasNextPage:{type:"boolean"},hasPrevPage:{type:"boolean"}},required:["items","hasNextPage","hasPrevPage"]},meta:{type:"object",properties:{pageSize:{type:"integer"},hasMore:{type:"boolean"},cursor:{oneOf:[{type:"string"},{type:"null"}]}}}},required:["success","data"]}}}}}function jt(e){return [{name:"pageSize",in:"query",schema:{type:"integer",default:e.pageSize,maximum:100},description:"Number of items per page"},{name:"cursor",in:"query",schema:{type:"string"},description:"Base64 pagination cursor"},{name:"orderBy",in:"query",schema:{type:"string"},description:"Field name to order by"},{name:"orderDir",in:"query",schema:{type:"string",enum:["asc","desc"]},description:"Order direction"},{name:"select",in:"query",schema:{type:"string"},description:"Comma-separated list of fields to return"}]}function Nt(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],s=[];for(let r of t){s.push({name:r,in:"query",schema:{type:"string"},description:`Filter by ${r} (equality)`});for(let o of n)s.push({name:`${r}__${o}`,in:"query",schema:{type:"string"},description:`Filter ${r} with operator ${o}`});}return s}function zt(){return {type:"object",properties:{where:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"AND conditions: [field, operator, value][]"},orWhere:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"Simple OR conditions (each independently OR'd)"},orWhereGroups:{type:"array",items:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3}},description:"Advanced OR groups (AND within, OR across groups)"},orderBy:{type:"array",items:{type:"object",properties:{field:{type:"string"},direction:{type:"string",enum:["asc","desc"]}},required:["field"]}},select:{type:"array",items:{type:"string"},description:"Fields to select (projection)"},pageSize:{type:"integer",maximum:100,description:"Number of items per page"},cursor:{oneOf:[{type:"string"},{type:"object"}],description:"Pagination cursor"},direction:{type:"string",enum:["next","prev"],description:"Pagination direction"},includes:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{relation:{type:"string"},select:{type:"array",items:{type:"string"}}},required:["relation"]}]},description:"Relations to include (populate)"}}}}function qt(e,t,n,s,r){let o={},a=e.name,f=`${t}/${e.name}`,g=`${f}/{${e.documentKey}}`,d={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};o[f]={get:{operationId:`list${Y(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...jt(e),...Nt(e)],responses:{200:at(M(n)),500:F("Internal server error")}},post:{operationId:`create${Y(e.name)}`,summary:`Create a ${H(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:M(s??n)}}},responses:{201:ce("Document created",M(n)),400:F("Validation error"),500:F("Internal server error")}}},o[`${f}/query`]={post:{operationId:`query${Y(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:M("QueryRequestBody")}}},responses:{200:at(M(n)),400:F("Invalid query"),500:F("Internal server error")}}};let l={};return l.get={operationId:`get${Y(H(e.name))}`,summary:`Get a single ${H(e.name)}`,tags:[a],parameters:[d],responses:{200:ce("Document found",M(n)),404:F("Document not found"),500:F("Internal server error")}},l.put={operationId:`update${Y(H(e.name))}`,summary:`Update a ${H(e.name)} (full replace)`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:M(r??n)}}},responses:{200:ce("Document updated",M(n)),400:F("Validation error"),404:F("Document not found"),500:F("Internal server error")}},l.patch={operationId:`patch${Y(H(e.name))}`,summary:`Partially update a ${H(e.name)}`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:{allOf:[M(r??n)],description:"All fields are optional for partial updates"}}}},responses:{200:ce("Document patched",M(n)),400:F("Validation error"),404:F("Document not found"),500:F("Internal server error")}},e.allowDelete&&(l.delete={operationId:`delete${Y(H(e.name))}`,summary:`Delete a ${H(e.name)}`,tags:[a],parameters:[d],responses:{200:ce("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:F("Document not found"),500:F("Internal server error")}}),o[g]=l,o}function _e(e,t,n={}){let{title:s="CRUD API",version:r="1.0.0",description:o,servers:a,auth:f=false}=n,g=t==="/"?"":t.replace(/\/$/,""),d={},l={},R=[];d.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},d.QueryRequestBody=zt();for(let[b,m]of Object.entries(e)){let i=Y(H(b)),y=`${i}Create`,v=`${i}Update`;d[i]=Te(m.schema);let h=T=>{let z=T&&T.length>0?T:Object.keys(m.schema.shape),Z={};for(let re of z){let E=re.split(".")[0];E&&m.schema.shape[E]&&!m.systemKeys.includes(E)&&(Z[E]=m.schema.shape[E]);}return Z},x=null,w=h(m.createFields);Object.keys(w).length>0&&(d[y]=Te(z.object(w)),x=y);let S=null,C=h(m.mutableFields);Object.keys(C).length>0&&(d[v]=Te(z.object(C)),S=v);let O=qt(m,g,i,x,S);Object.assign(l,O),R.push({name:b,description:`Operations on ${b} (collection: ${m.path})`});}let u={},c;return f==="basic"?(u.basicAuth={type:"http",scheme:"basic"},c=[{basicAuth:[]}]):f==="bearer"&&(u.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},c=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:s,version:r,...o?{description:o}:{}},...a&&a.length>0?{servers:a}:{},paths:l,components:{schemas:d,...Object.keys(u).length>0?{securitySchemes:u}:{}},...c?{security:c}:{},tags:R}}function Y(e){return e.charAt(0).toUpperCase()+e.slice(1)}function H(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}function Bt(e,t){return `<!DOCTYPE html>
555
+ `;function ie(){return jsx("script",{dangerouslySetInnerHTML:{__html:Me}})}function J(e){return "<!DOCTYPE html>"+renderToString(e)}var W=({opts:e,children:t})=>{let{title:n,breadcrumb:s,flash:r,basePath:o="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsx("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:jsx("div",{class:"flex-1",children:jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})})}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[s&&s.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:s.map((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),r&&jsx("div",{role:"alert",class:`alert ${r.type==="success"?"alert-success":"alert-error"} mb-6`,children:jsx("span",{children:r.message})}),t]}),jsx(ie,{})]})]})};function ge(e,t){return J(jsx(W,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function he(e,t){return J(jsx(W,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:e.map(n=>jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxs("div",{class:"card-body p-5",children:[jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var Ue=[{value:"==",label:"="},{value:"!=",label:"\u2260"}],gt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"<",label:"<"},{value:"<=",label:"\u2264"},{value:">",label:">"},{value:">=",label:"\u2265"}],ht=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function bt(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return gt;case "ZodBoolean":return Ue;case "ZodArray":return ht;default:return Ue}}function vt({col:e,active:t}){let n=t?.value??"";if(e.zodType==="ZodBoolean")return jsxs("select",{name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",children:[jsx("option",{value:"",selected:n==="",children:"\u2014"}),jsx("option",{value:"true",selected:n==="true",children:"true"}),jsx("option",{value:"false",selected:n==="false",children:"false"})]});if(e.zodType==="ZodArray"){let s=t?.op==="array-contains-any";return jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:s?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsx("input",{type:"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"}):e.zodType==="ZodDate"?jsx("input",{type:"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full"}):jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"})}function be({action:e,columnMeta:t,activeFilters:n}){let s=Object.fromEntries(n.map(a=>[a.field,a])),r=n.length>0,o=t.filter(a=>a.zodType!=="ZodObject"&&a.zodType!=="ZodRecord");return jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:r?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",r&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:o.map(a=>{let f=bt(a.zodType),g=s[a.name],d=g?.op??f[0].value;return jsxs("div",{class:"flex flex-col gap-1.5",children:[jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:a.name}),jsxs("div",{class:"flex gap-1.5",children:[f.length>1?jsx("select",{name:`fo_${a.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:f.map(l=>jsx("option",{value:l.value,selected:l.value===d,children:l.label},l.value))}):jsx("input",{type:"hidden",name:`fo_${a.name}`,value:f[0].value}),jsx(vt,{col:a,active:g})]})]},a.name)})}),jsxs("div",{class:"flex gap-2 mt-4 pt-3 border-t border-base-200",children:[jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),r&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"})]})]})})]})}function ve(e,t,n,s,r,o){let a=n==="create"?`Create ${e}`:`Edit ${e} / ${s??""}`,f=n==="create"?[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:"New document"}]:[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:`Edit ${s??""}`}];return J(jsx(W,{opts:{title:a,breadcrumb:f,basePath:r,flash:o},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}function xe(e,t,n){let s=new URLSearchParams;for(let r of e)s.set(`fv_${r.field}`,r.value),s.set(`fo_${r.field}`,r.op);return t&&(s.set("ob",t.field),s.set("od",t.dir)),n&&s.set("ps",String(n)),s}function Le(e,t,n,s,r){let o=xe(e,s,r);return o.set("cursor",t),o.set("dir",n),`?${o.toString()}`}function xt(e,t,n,s){let r=xe(n,void 0,s);return t?.field===e?t.dir==="asc"&&(r.set("ob",e),r.set("od","desc")):(r.set("ob",e),r.set("od","asc")),`?${r.toString()}`}function Rt(e,t,n){return `?${xe(t,n,e).toString()}`}function Re(e,t,n,s,r,o,a=[],f=[],g=false,d=[],l,R){let u=`${s}/${e}`,c=`${u}/create`;return J(jsxs(W,{opts:{title:e,breadcrumb:[{label:"Repositories",href:s},{label:e}],basePath:s,flash:o},children:[a.length>0&&jsx(be,{action:u,columnMeta:a,activeFilters:f}),jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3",children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length," document",t.length!==1&&"s"]}),jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsx("span",{children:"Rows"}),jsx("div",{class:"join",children:[10,25,50,100].map(p=>jsx("a",{href:Rt(p,f,l),class:`join-item btn btn-xs ${R===p?"btn-active btn-primary":"btn-outline"}`,children:p},p))})]})]}),jsx("a",{href:c,class:"btn btn-primary btn-sm",children:"+ New"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[[...n].map((p,b)=>{let m=l?.field===p,i=m?l.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:xt(p,l,f,R),class:`hover:text-base-content inline-flex items-center gap-0.5${m?" text-primary font-bold":""}`,children:[p,i]})},b)}),d.map((p,b)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:p.column},`rel-${b}`)),jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsx("tbody",{children:t.length===0?jsx("tr",{children:jsx("td",{colspan:n.length+d.length+1,class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((p,b)=>{let m=String(p.docId??p.id??""),i=`${s}/${e}/${encodeURIComponent(m)}/edit`,y=`${s}/${e}/${encodeURIComponent(m)}/delete`;return jsxs("tr",{class:"hover",children:[n.map((v,h)=>jsx("td",{class:"align-top py-2",children:jsx(ye,{val:p[v]})},h)),d.map((v,h)=>{let x=p[v.key];if(x==null||x==="")return jsx("td",{class:"py-2"},`rel-${h}`);let w=`${s}/${v.targetRepo}?fv_${v.targetKey}=${encodeURIComponent(String(x))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:w,class:"btn btn-xs btn-ghost btn-outline",children:v.column})},`rel-${h}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:i,class:"btn btn-xs btn-outline",children:"Edit"}),g&&jsx("form",{method:"post",action:y,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},b)})})]})}),(r.hasPrev||r.hasNext)&&jsxs("div",{class:"flex justify-center items-center mt-6 gap-2",children:[r.hasPrev?jsx("a",{href:Le(f,r.prevCursor,"prev",l,R),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),r.hasNext?jsx("a",{href:Le(f,r.nextCursor,"next",l,R),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]})]}))}var wt="";function St(e,t){return ge(e,t)}function we(e,t){return he(e,t)}function Se(e,t,n,s,r,o,a,f,g,d,l,R){return Re(e,t,n,s,r,o,a,f,g,d,l,R)}function X(e,t,n,s,r,o){return ve(e,t,n,s,r,o)}var He="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Ct(){let e="";for(let t=0;t<20;t++)e+=He.charAt(Math.floor(Math.random()*He.length));return e}function Ve(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let s=n.split("/").filter(Boolean),r=[];for(let o=1;o<s.length;o+=2)r.push(s[o]);return r.length>0?r:void 0}async function $e(e,t){let n=e.documentKey??"docId",s=`by${n.charAt(0).toUpperCase()}${n.slice(1)}`;if(typeof e.repo.get[s]=="function")try{let o=await e.repo.get[s](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function A(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Ce(e,t){e.status(302).set("Location",t).send("");}function Oe(e,t){let n=t.shape,s={};for(let[r,o]of Object.entries(n)){let a=Ae(o);if(a==="ZodObject"){if(e[r+"__isnull"]==="1"){s[r]=null;continue}let d={},l=false;for(let[c,p]of Object.entries(e))c.startsWith(`${r}.`)&&(d[c.slice(r.length+1)]=p,l=true);if(l){let c=o;for(;;){let p=j(c);if(p==="ZodOptional"||p==="ZodNullable"||p==="ZodDefault")c=q(c);else break}s[r]=Oe(d,c);continue}let R=e[r],u=Array.isArray(R)?R[R.length-1]:R;if(u)try{s[r]=JSON.parse(u);}catch{s[r]=u;}continue}let f=e[r],g=Array.isArray(f)?f[f.length-1]:f;if(e[r+"__isnull"]==="1"){s[r]=null;continue}if(g===void 0||g===""){a==="ZodBoolean"&&(s[r]=false);continue}switch(a){case "ZodBoolean":g==="__null__"?s[r]=null:s[r]=g==="true"||g==="on"||g==="1";break;case "ZodNumber":case "ZodBigInt":s[r]=Number(g);break;case "ZodDate":s[r]=new Date(g);break;case "ZodArray":try{s[r]=JSON.parse(g);}catch{s[r]=g;}break;default:if(g.startsWith("{")||g.startsWith("["))try{s[r]=JSON.parse(g);break}catch{}s[r]=g;}}return s}function Je(e){let t=null;if(e instanceof Date)t=e;else if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")t=e.toDate();else if(typeof e=="object"&&e!==null&&"_seconds"in e&&"_nanoseconds"in e)t=new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));else if(typeof e=="string"||typeof e=="number"){let s=new Date(e);isNaN(s.getTime())||(t=s);}if(!t||isNaN(t.getTime()))return null;let n=s=>String(s).padStart(2,"0");return `${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}function Ae(e){let t=e;for(;;){let n=j(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=q(t);else return n}}function We(e,t,n=""){let s={};for(let r of Object.keys(t.shape)){let o=n?`${n}.${r}`:r,a=e[r];if(a===null){s[o]="__null__";continue}if(a===void 0)continue;let f=t.shape[r];for(;;){let d=j(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=q(f);else break}let g=j(f);if(g==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let d=We(a,f,o);Object.assign(s,d);}else if(g==="ZodDate"){let d=Je(a);d!==null&&(s[o]=d);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let d=Je(a);s[o]=d??JSON.stringify(a,null,2);}else typeof a=="object"?s[o]=JSON.stringify(a,null,2):s[o]=String(a);}return s}function ke(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?ke(n.nested,t):void 0}))}function Ot(e,t){let n=new Set(["==","!=","<","<=",">",">=","array-contains","array-contains-any"]),s=[];for(let[r,o]of Object.entries(e)){if(!r.startsWith("fv_"))continue;let a=r.slice(3);if(!t.has(a))continue;let f=(o??"").trim();if(!f)continue;let g=e[`fo_${a}`]??"==",d=n.has(g)?g:"==";s.push({field:a,op:d,value:f});}return s}function kt(e){let t=n=>n==="true"?true:n==="false"?false:n!==""&&!isNaN(Number(n))?Number(n):n;return e.map(n=>{if(n.op==="array-contains-any"){let s=n.value.split(",").map(r=>t(r.trim())).filter(r=>r!=="");return [n.field,n.op,s]}return [n.field,n.op,t(n.value)]})}function Ge(e,t,n=""){let s=[];for(let r of e){let o=n?`${n}.${r}`:r,a=t.shape[r];if(!a){s.push({name:o,zodType:"ZodString"});continue}let f=Ae(a);if(f==="ZodObject"){let g=a;for(;;){let l=j(g);if(l==="ZodOptional"||l==="ZodNullable"||l==="ZodDefault")g=q(g);else break}let d=ae(g);s.push(...Ge(Object.keys(d),g,o));}else s.push({name:o,zodType:f});}return s}function At(e,t){let n=t.split("."),s=e;for(let r of n){for(;;){let a=j(s);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")s=q(s);else break}let o=ae(s);if(!(r in o))return null;s=o[r];}return s}function ne(e,t){if(!t||t.length===0)return e;let n=[],s=new Map;for(let o of t){let a=o.indexOf(".");if(a===-1)n.push(o);else {let f=o.slice(0,a),g=o.slice(a+1);s.has(f)||s.set(f,[]),s.get(f).push(g);}}let r={};for(let o of n)o in e.shape&&(r[o]=e.shape[o]);for(let[o,a]of s){if(!(o in e.shape))continue;let f=e.shape[o];for(;;){let g=j(f);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")f=q(f);else break}if(j(f)!=="ZodObject"){r[o]=e.shape[o];continue}r[o]=ne(f,a);}return z.object(r)}function te(e,t){let n=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let o=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${a}/${f}${n}`}let s=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return s&&r.includes("cloudfunctions.net")?`/${s.toLowerCase()}${n}`:n}function Xe(e,t){return {handleDashboard:(d,l)=>{let R=te(d,t),u=Object.values(e).map(c=>({name:c.name,path:c.path}));A(l,we(u,R));},handleList:async(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=u.pageSize??25,p=d.query??{},b=p.cursor,m=p.dir==="prev"?"prev":"next",i=p.ob??"",y=p.od==="desc"?"desc":"asc",v=i?{field:i,dir:y}:void 0,h=parseInt(p.ps??""),x=Number.isFinite(h)&&h>0?Math.min(h,200):c,w=u.listColumns??Object.keys(u.schema.shape),S=u.documentKey??"docId",C=[S,...w.filter(I=>I!==S)],O=u.filterableFields?(()=>{let I=[];for(let H of u.filterableFields)(H.includes(".")||w.includes(H))&&I.push(H);return I})():w,T=(()=>{let I=[];for(let H of O)if(H.includes(".")){let _e=At(u.schema,H);I.push({name:H,zodType:_e?Ae(_e):"ZodString"});}else I.push(...Ge([H],u.schema));return I})(),z=new Set(T.map(I=>I.name)),Z=Ot(p,z),re=kt(Z),_;if(b)try{let I=u.repo.ref;typeof I.doc=="function"&&(_=await I.doc(b).get());}catch{}let K=await u.repo.query.paginate({pageSize:x,cursor:_,direction:m,...re.length>0?{where:re}:{},...v?{orderBy:[{field:v.field,direction:v.dir}]}:{}}),ot=K.nextCursor?.id??"",it=K.prevCursor?.id??"",lt=te(d,t);A(l,Se(u.name,K.data,C,lt,{hasPrev:K.hasPrevPage,hasNext:K.hasNextPage,prevCursor:it,nextCursor:ot},void 0,T,Z,u.allowDelete??false,u.relationalMeta,v,x));},handleCreateForm:(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=te(d,t),p=ne(u.schema,u.createFields),b=U(p),m=`${c}/${u.name}/create`,i=V(b,m,"POST","Create document");A(l,X(u.name,i,"create",null,c));},handleCreateSubmit:async(d,l)=>{let R=d.params.repoName;if(!R){A(l,"Bad request",400);return}let u=e[R];if(!u){A(l,"Repository not found",404);return}let c=te(d,t),p=d.body??{},b=Oe(p,u.schema),m=ne(u.schema,u.createFields),i=m.safeParse(b);if(!i.success){let y=U(m),v=`${c}/${u.name}/create`,h=V(y,v,"POST","Create document"),x=i.error.issues.map(w=>`${w.path.join(".")}: ${w.message}`).join(", ");A(l,X(u.name,h,"create",null,c,{type:"error",message:`Validation error: ${x}`}),422);return}try{if(u.isGroup&&u.parentKeys&&u.parentKeys.length>0){let y={...i.data};u.createdKey&&(y[u.createdKey]=new Date);let v=u.parentKeys.filter(S=>!y[S]);if(v.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${v.join(", ")}`);let h=u.parentKeys.map(S=>y[S]),x=u.documentKey??"docId",w=y[x]||Ct();await u.repo.set(...h,w,y);}else await u.repo.create(i.data);Ce(l,`${c}/${u.name}?flash=created`);}catch(y){let v=ne(u.schema,u.createFields),h=U(v),x=`${c}/${u.name}/create`,w=V(h,x,"POST","Create document");A(l,X(u.name,w,"create",null,c,{type:"error",message:`Save error: ${y.message}`}),500);}},handleEditForm:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}let p=null;try{p=await $e(c,u);}catch(x){A(l,`Error fetching document: ${x.message}`,500);return}if(!p){A(l,"Document not found",404);return}let b=We(p,c.schema),m=ne(c.schema,c.mutableFields),i=ke(U(m),b),y=te(d,t),v=`${y}/${c.name}/${encodeURIComponent(u)}/edit`,h=V(i,v,"POST","Save changes");A(l,X(c.name,h,"edit",u,y));},handleEditSubmit:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}let p=te(d,t),b=d.body??{},m=Oe(b,c.schema),i=ne(c.schema,c.mutableFields),v=i.partial().safeParse(m);if(!v.success){let h=Object.fromEntries(Object.entries(b).map(([O,T])=>[O,Array.isArray(T)?T.join(","):T??""])),x=ke(U(i),h),w=`${p}/${c.name}/${encodeURIComponent(u)}/edit`,S=V(x,w,"POST","Save changes"),C=v.error.issues.map(O=>`${O.path.join(".")}: ${O.message}`).join(", ");A(l,X(c.name,S,"edit",u,p,{type:"error",message:`Validation error: ${C}`}),422);return}try{let h=await $e(c,u),x=(h&&Ve(h,c.pathKey))??[u];await c.repo.update(...x,v.data),Ce(l,`${p}/${c.name}?flash=updated`);}catch(h){let x=ne(c.schema,c.mutableFields),w=U(x),S=`${p}/${c.name}/${encodeURIComponent(u)}/edit`,C=V(w,S,"POST","Save changes");A(l,X(c.name,C,"edit",u,p,{type:"error",message:`Save error: ${h.message}`}),500);}},handleDelete:async(d,l)=>{let R=d.params.repoName,u=d.params.id;if(!R||!u){A(l,"Bad request",400);return}let c=e[R];if(!c){A(l,"Repository not found",404);return}if(!c.allowDelete){A(l,"Delete is not allowed for this repository",403);return}let p=te(d,t);try{let b=await $e(c,u),m=(b&&Ve(b,c.pathKey))??[u];await c.repo.delete(...m),Ce(l,`${p}/${c.name}?flash=deleted`);}catch(b){A(l,`Delete error: ${b.message}`,500);}}}}function Tt(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,s=>s===":"?s:`\\${s}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(s,r)=>(t.push(r),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function Pt(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var Q=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,n)=>{n.status(404).send("Not Found");};this.errorHandler=(t,n,s)=>{console.error("[MiniRouter]",t),s.status(500).send("Internal Server Error");};}use(t){return this.middlewares.push(t),this}get(t,n){return this.addRoute("GET",t,n)}post(t,n){return this.addRoute("POST",t,n)}put(t,n){return this.addRoute("PUT",t,n)}patch(t,n){return this.addRoute("PATCH",t,n)}delete(t,n){return this.addRoute("DELETE",t,n)}onNotFound(t){return this.notFoundHandler=t,this}onError(t){return this.errorHandler=t,this}addRoute(t,n,s){let{pattern:r,paramNames:o}=Tt(n);return this.routes.push({method:t.toUpperCase(),pattern:r,paramNames:o,handler:s}),this}async handle(t,n){let s=(t.method??"GET").toUpperCase(),r=Pt(t),o=null,a={};for(let d of this.routes){if(d.method!==s)continue;let l=r.match(d.pattern);if(l){o=d,a={},d.paramNames.forEach((R,u)=>{a[R]=decodeURIComponent(l[u+1]??"");});break}}let f=Object.assign(t,{params:a}),g=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,n,g);}catch(d){this.errorHandler(d,t,n);}}async runMiddlewareChain(t,n,s){let r=0,o=async()=>{if(r<this.middlewares.length){let a=this.middlewares[r++];await a(t,n,o);}else await s(t,n);};await o();}};async function Et(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function _t(e){let t={};if(!e)return t;for(let n of e.split("&")){let s=n.indexOf("=");if(s===-1)continue;let r=decodeURIComponent(n.slice(0,s).replace(/\+/g," ")),o=decodeURIComponent(n.slice(s+1).replace(/\+/g," ")),a=t[r];a===void 0?t[r]=o:Array.isArray(a)?a.push(o):t[r]=[a,o];}return t}function Zt(e){let{basePath:t="/",repos:n,parseBody:s=true,auth:r,middleware:o=[],httpsOptions:a}=e,f=t==="/"?"":t.replace(/\/$/,""),g={};for(let[u,c]of Object.entries(n)){let p=c.schema??c.repo.schema??null;if(!p)throw new Error(`[createAdminServer] Repository "${u}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let b,m,i;if(c.fieldsConfig){let h=c.fieldsConfig;b=[],m=[],i=[];for(let[x,w]of Object.entries(h))for(let S of w)S==="filterable"?b.push(x):S==="mutable"?m.push(x):S==="create"&&i.push(x);b.length===0&&(b=void 0),m.length===0&&(m=void 0),i.length===0&&(i=void 0);}let y=(()=>{let h=c.repo._parentKeys;return h&&h.length>0?h:void 0})();if(y&&i)for(let h of y)i.includes(h)||i.push(h);let v={name:u,path:c.path,repo:c.repo,schema:p,documentKey:c.documentKey??"docId",pathKey:c.repo._pathKey??void 0,isGroup:!!c.repo._isGroup,parentKeys:y,createdKey:c.repo._createdKey??void 0,listColumns:c.listColumns,pageSize:c.pageSize,filterableFields:b,mutableFields:m,createFields:i,allowDelete:c.allowDelete??false,relationalMeta:(()=>{if(!c.relationalFields||c.relationalFields.length===0)return;let h=c.repo.relationalKeys??{},x=[];for(let w of c.relationalFields){let S=h[w.key];S&&x.push({key:w.key,column:w.column,targetRepo:String(S.repo),targetKey:String(S.key),type:S.type});}return x.length>0?x:void 0})()};g[u]=v;}let d=Xe(g,f),l=new Q;if(s&&l.use(async(u,c,p)=>{let b=u,m=String(b.headers?.["content-type"]??"");if(m.includes("application/x-www-form-urlencoded")){let i=await Et(b);u.body=_t(i);}else if(m.includes("application/json")&&typeof b.body=="string")try{u.body=JSON.parse(b.body);}catch{}await p();}),r)if(typeof r=="function")l.use(r);else {let u=r.realm??"Admin",c="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");l.use((p,b,m)=>{if((p.headers?.authorization??"")!==c){b.status(401).set("WWW-Authenticate",`Basic realm="${u}"`).set("Content-Type","text/plain").send("Unauthorized");return}m();});}for(let u of o)l.use(u);l.get(`${f}/`,d.handleDashboard),l.get(`${f}`,d.handleDashboard),l.get(`${f}/:repoName`,d.handleList),l.get(`${f}/:repoName/create`,d.handleCreateForm),l.post(`${f}/:repoName/create`,d.handleCreateSubmit),l.get(`${f}/:repoName/:id/edit`,d.handleEditForm),l.post(`${f}/:repoName/:id/edit`,d.handleEditSubmit),l.post(`${f}/:repoName/:id/delete`,d.handleDelete);let R=async(u,c)=>{await l.handle(u,c);};return a&&(R.httpsOptions=a),R}function rt(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function se(e,t,n,s=200){rt(e,{success:true,data:t,meta:n},s);}function P(e,t,n=400){rt(e,{success:false,error:t},n);}var Qe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Dt(){let e="";for(let t=0;t<20;t++)e+=Qe.charAt(Math.floor(Math.random()*Qe.length));return e}function Ft(e,t,n=[]){let s=e.shape,r={},o=t&&t.length>0?t:Object.keys(s);for(let a of o){if(n.includes(a))continue;let f=a.split(".")[0];f&&s[f]&&(r[f]=s[f]);}return z.object(r)}function Ye(e,t,n,s=false,r=[]){try{let o=Ft(e,n,r);return {success:!0,data:(s?o.partial():o).parse(t)}}catch(o){return o instanceof z.ZodError?{success:false,error:`Validation failed: ${o.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function It(e,t){let n=[],s=t?new Set(t):null,r={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[o,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(o))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let g=o.match(/^(\w+)__(\w+)$/),d,l="==";if(g&&g[1]&&g[2]){d=g[1];let u=g[2];if(r[u])l=r[u];else continue}else if(!g)d=o;else continue;if(s&&!s.has(d))continue;let R=f;l==="in"||l==="not-in"||l==="array-contains-any"?R=f.split(",").map(u=>et(u.trim())):R=et(f),n.push({field:d,op:l,value:R});}return n}function et(e){if(e==="true")return true;if(e==="false")return false;if(e==="null")return null;let t=Number(e);return !isNaN(t)&&e!==""?t:e}function ue(e){return e?{docId:e.id}:null}async function tt(e,t){if(!t||typeof t!="object")return;let n=t.docId;if(typeof n=="string")try{let s=e.repo.ref;if(typeof s.doc!="function")return;let r=await s.doc(n).get();return r.exists?r:void 0}catch{return}}function st(e,t,n){function s(c,p){return !c||!e[c]?(P(p,`Repository "${c}" not found`,404),null):e[c]}function r(c,p){if(!p)return;let b=c[p];if(typeof b!="string"||!b)return;let m=b.split("/").filter(Boolean),i=[];for(let y=1;y<m.length;y+=2)i.push(m[y]);return i.length>0?i:void 0}async function o(c,p){let b=`by${c.documentKey.charAt(0).toUpperCase()}${c.documentKey.slice(1)}`,m=c.repo.get[b];if(typeof m=="function")try{let y=await m(p);if(y)return y}catch{}return (await c.repo.query.by({where:[[c.documentKey,"==",p]],limit:1}))[0]??null}async function a(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.query??{},y=Math.min(Number(i.pageSize)||m.pageSize,100),v=i.cursor,h=i.direction?.toLowerCase()==="prev"?"prev":"next",x=i.orderBy,w=i.orderDir?.toLowerCase()==="desc"?"desc":"asc",S=i.select,C=S?S.split(",").map(_=>_.trim()):void 0,O;m.allowedIncludes&&i.includes&&(O=(typeof i.includes=="string"?i.includes.split(",").map(K=>K.trim()):Array.isArray(i.includes)?i.includes:[]).filter(K=>typeof K=="string"&&m.allowedIncludes.includes(K)),O?.length===0&&(O=void 0));let T=It(i,m.filterableFields),z={pageSize:y,direction:h};if(v)try{let _=typeof v=="string"?JSON.parse(v):v;z.cursor=await tt(m,_);}catch{}x&&(z.orderBy=[{field:x,direction:w}]),T.length>0&&(z.where=T.map(_=>[_.field,_.op,_.value])),C&&(z.select=C),O&&(z.include=O);let Z=await m.repo.query.paginate(z),re={items:Z.data,hasNextPage:Z.hasNextPage,hasPrevPage:Z.hasPrevPage,nextCursor:ue(Z.nextCursor),prevCursor:ue(Z.prevCursor)};se(p,re,{pageSize:y,hasMore:Z.hasNextPage});}catch(i){let y=n&&i instanceof Error?i.message:"Failed to fetch documents";P(p,y,500);}}async function f(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.body??{},y=Math.min(i.pageSize||m.pageSize,100),v=i.direction==="prev"?"prev":"next",h={pageSize:y,direction:v};if(i.cursor)try{let S=typeof i.cursor=="string"?JSON.parse(i.cursor):i.cursor;h.cursor=await tt(m,S);}catch{}if(m.allowedIncludes&&i.includes&&i.includes.length>0){let S=i.includes.filter(C=>typeof C=="string"?m.allowedIncludes.includes(C):typeof C=="object"&&C!==null&&"relation"in C&&typeof C.relation=="string"?m.allowedIncludes.includes(C.relation):!1);S.length>0&&(h.include=S);}if(i.where&&i.where.length>0){if(m.filterableFields){let S=new Set(m.filterableFields),C=i.where.filter(O=>!S.has(O[0]));if(C.length>0){P(p,`Fields not filterable: ${C.map(O=>O[0]).join(", ")}`,400);return}}h.where=i.where;}if(i.orWhere&&i.orWhere.length>0){if(m.filterableFields){let S=new Set(m.filterableFields),C=i.orWhere.filter(O=>!S.has(O[0]));if(C.length>0){P(p,`Fields not filterable: ${C.map(O=>O[0]).join(", ")}`,400);return}}h.orWhere=i.orWhere;}if(i.orWhereGroups&&i.orWhereGroups.length>0){if(m.filterableFields){let S=new Set(m.filterableFields);for(let C of i.orWhereGroups){let O=C.filter(T=>!S.has(T[0]));if(O.length>0){P(p,`Fields not filterable: ${O.map(T=>T[0]).join(", ")}`,400);return}}}h.orWhereGroups=i.orWhereGroups;}i.orderBy&&i.orderBy.length>0&&(h.orderBy=i.orderBy),i.select&&i.select.length>0&&(h.select=i.select);let x=await m.repo.query.paginate(h),w={items:x.data,hasNextPage:x.hasNextPage,hasPrevPage:x.hasPrevPage,nextCursor:ue(x.nextCursor),prevCursor:ue(x.prevCursor)};se(p,w,{pageSize:y,hasMore:x.hasNextPage});}catch(i){let y=n&&i instanceof Error?i.message:"Failed to query documents";P(p,y,500);}}async function g(c,p){let b=c.params||{},m=s(b.repoName,p);if(!m)return;let i=b.id;if(!i){P(p,"Document ID required",400);return}try{let y=await o(m,i);if(!y){P(p,"Document not found",404);return}se(p,y);}catch(y){let v=n&&y instanceof Error?y.message:"Failed to fetch document";P(p,v,500);}}async function d(c,p){let b=c.params||{},m=s(b.repoName,p);if(m)try{let i=c.body??{},y=Ye(m.schema,i,m.createFields,!1,m.systemKeys);if(!y.success){P(p,y.error,400);return}if(m.validate){let h=await m.validate(y.data,"create");if(h){P(p,h,400);return}}let v;if(m.isGroup&&m.parentKeys&&m.parentKeys.length>0){let h={...y.data};m.createdKey&&(h[m.createdKey]=new Date);let x=m.parentKeys.filter(C=>!h[C]);if(x.length>0){P(p,`Missing parent key(s) for subcollection create: ${x.join(", ")}`,400);return}let w=m.parentKeys.map(C=>h[C]),S=h[m.documentKey]||Dt();v=await m.repo.set(...w,S,h);}else v=await m.repo.create(y.data);se(p,v,void 0,201);}catch(i){let y=n&&i instanceof Error?i.message:"Failed to create document";P(p,y,500);}}async function l(c,p,b){let m=c.params||{},i=s(m.repoName,p);if(!i)return;let y=m.id;if(!y){P(p,"Document ID required",400);return}try{let v=c.body??{},h=Ye(i.schema,v,i.mutableFields,b,i.systemKeys);if(!h.success){P(p,h.error,400);return}if(i.validate){let C=await i.validate(h.data,"update");if(C){P(p,C,400);return}}let x=await o(i,y),w=(x&&r(x,i.pathKey))??[y],S=await i.repo.update(...w,h.data);se(p,S);}catch(v){let h=n&&v instanceof Error?v.message:"Failed to update document";P(p,h,500);}}async function R(c,p){let b=c.params||{},m=s(b.repoName,p);if(!m)return;if(!m.allowDelete){P(p,"Delete not allowed for this repository",403);return}let i=b.id;if(!i){P(p,"Document ID required",400);return}try{let y=await o(m,i),v=(y&&r(y,m.pathKey))??[i];await m.repo.delete(...v),se(p,{deleted:!0});}catch(y){let v=n&&y instanceof Error?y.message:"Failed to delete document";P(p,v,500);}}function u(c,p){p.status(204).set("Access-Control-Allow-Methods","GET, POST, PUT, PATCH, DELETE, OPTIONS").set("Access-Control-Allow-Headers","Content-Type, Authorization").set("Access-Control-Max-Age","86400").send("");}return {handleList:a,handleQuery:f,handleGet:g,handleCreate:d,handleUpdate:l,handleDelete:R,handleOptions:u}}function Te(e){try{return z.toJSONSchema(e,{target:"openapi-3.1"})}catch{return {type:"object"}}}function M(e){return {$ref:`#/components/schemas/${e}`}}function F(e){return {description:e,content:{"application/json":{schema:M("ErrorResponse")}}}}function ce(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function at(e){return {description:"Paginated list of documents",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:{type:"object",properties:{items:{type:"array",items:e},nextCursor:{oneOf:[{type:"object"},{type:"null"}]},prevCursor:{oneOf:[{type:"object"},{type:"null"}]},hasNextPage:{type:"boolean"},hasPrevPage:{type:"boolean"}},required:["items","hasNextPage","hasPrevPage"]},meta:{type:"object",properties:{pageSize:{type:"integer"},hasMore:{type:"boolean"},cursor:{oneOf:[{type:"string"},{type:"null"}]}}}},required:["success","data"]}}}}}function jt(e){return [{name:"pageSize",in:"query",schema:{type:"integer",default:e.pageSize,maximum:100},description:"Number of items per page"},{name:"cursor",in:"query",schema:{type:"string"},description:"Base64 pagination cursor"},{name:"orderBy",in:"query",schema:{type:"string"},description:"Field name to order by"},{name:"orderDir",in:"query",schema:{type:"string",enum:["asc","desc"]},description:"Order direction"},{name:"select",in:"query",schema:{type:"string"},description:"Comma-separated list of fields to return"}]}function Nt(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],s=[];for(let r of t){s.push({name:r,in:"query",schema:{type:"string"},description:`Filter by ${r} (equality)`});for(let o of n)s.push({name:`${r}__${o}`,in:"query",schema:{type:"string"},description:`Filter ${r} with operator ${o}`});}return s}function zt(){return {type:"object",properties:{where:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"AND conditions: [field, operator, value][]"},orWhere:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"Simple OR conditions (each independently OR'd)"},orWhereGroups:{type:"array",items:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3}},description:"Advanced OR groups (AND within, OR across groups)"},orderBy:{type:"array",items:{type:"object",properties:{field:{type:"string"},direction:{type:"string",enum:["asc","desc"]}},required:["field"]}},select:{type:"array",items:{type:"string"},description:"Fields to select (projection)"},pageSize:{type:"integer",maximum:100,description:"Number of items per page"},cursor:{oneOf:[{type:"string"},{type:"object"}],description:"Pagination cursor"},direction:{type:"string",enum:["next","prev"],description:"Pagination direction"},includes:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{relation:{type:"string"},select:{type:"array",items:{type:"string"}}},required:["relation"]}]},description:"Relations to include (populate)"}}}}function qt(e,t,n,s,r){let o={},a=e.name,f=`${t}/${e.name}`,g=`${f}/{${e.documentKey}}`,d={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};o[f]={get:{operationId:`list${Y(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...jt(e),...Nt(e)],responses:{200:at(M(n)),500:F("Internal server error")}},post:{operationId:`create${Y(e.name)}`,summary:`Create a ${L(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:M(s??n)}}},responses:{201:ce("Document created",M(n)),400:F("Validation error"),500:F("Internal server error")}}},o[`${f}/query`]={post:{operationId:`query${Y(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:M("QueryRequestBody")}}},responses:{200:at(M(n)),400:F("Invalid query"),500:F("Internal server error")}}};let l={};return l.get={operationId:`get${Y(L(e.name))}`,summary:`Get a single ${L(e.name)}`,tags:[a],parameters:[d],responses:{200:ce("Document found",M(n)),404:F("Document not found"),500:F("Internal server error")}},l.put={operationId:`update${Y(L(e.name))}`,summary:`Update a ${L(e.name)} (full replace)`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:M(r??n)}}},responses:{200:ce("Document updated",M(n)),400:F("Validation error"),404:F("Document not found"),500:F("Internal server error")}},l.patch={operationId:`patch${Y(L(e.name))}`,summary:`Partially update a ${L(e.name)}`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:{allOf:[M(r??n)],description:"All fields are optional for partial updates"}}}},responses:{200:ce("Document patched",M(n)),400:F("Validation error"),404:F("Document not found"),500:F("Internal server error")}},e.allowDelete&&(l.delete={operationId:`delete${Y(L(e.name))}`,summary:`Delete a ${L(e.name)}`,tags:[a],parameters:[d],responses:{200:ce("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:F("Document not found"),500:F("Internal server error")}}),o[g]=l,o}function Ee(e,t,n={}){let{title:s="CRUD API",version:r="1.0.0",description:o,servers:a,auth:f=false}=n,g=t==="/"?"":t.replace(/\/$/,""),d={},l={},R=[];d.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},d.QueryRequestBody=zt();for(let[b,m]of Object.entries(e)){let i=Y(L(b)),y=`${i}Create`,v=`${i}Update`;d[i]=Te(m.schema);let h=T=>{let z=T&&T.length>0?T:Object.keys(m.schema.shape),Z={};for(let re of z){let _=re.split(".")[0];_&&m.schema.shape[_]&&!m.systemKeys.includes(_)&&(Z[_]=m.schema.shape[_]);}return Z},x=null,w=h(m.createFields);Object.keys(w).length>0&&(d[y]=Te(z.object(w)),x=y);let S=null,C=h(m.mutableFields);Object.keys(C).length>0&&(d[v]=Te(z.object(C)),S=v);let O=qt(m,g,i,x,S);Object.assign(l,O),R.push({name:b,description:`Operations on ${b} (collection: ${m.path})`});}let u={},c;return f==="basic"?(u.basicAuth={type:"http",scheme:"basic"},c=[{basicAuth:[]}]):f==="bearer"&&(u.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},c=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:s,version:r,...o?{description:o}:{}},...a&&a.length>0?{servers:a}:{},paths:l,components:{schemas:d,...Object.keys(u).length>0?{securitySchemes:u}:{}},...c?{security:c}:{},tags:R}}function Y(e){return e.charAt(0).toUpperCase()+e.slice(1)}function L(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}function Bt(e,t){return `<!DOCTYPE html>
556
556
  <html lang="en">
557
557
  <head>
558
558
  <meta charset="utf-8" />
@@ -563,5 +563,5 @@ function initColumnReorder(table) {
563
563
  <script id="api-reference" data-url="${t}"></script>
564
564
  <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
565
565
  </body>
566
- </html>`}function Mt(e){let t=e==="/"?"":e.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let n=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",s=process.env.FUNCTION_REGION??"us-central1",r=process.env.FUNCTION_TARGET??"";return `/${n}/${s}/${r}${t}`}return t}async function Kt(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Ut(e){let{basePath:t="/",repos:n,parseBody:s=true,auth:r,middleware:o=[],verbose:a=false,httpsOptions:f}=e,g=t==="/"?"":t.replace(/\/$/,""),d={};for(let[i,y]of Object.entries(n)){let v=y.schema??y.repo.schema??null;if(!v)throw new Error(`[createCrudServer] Repository "${i}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let h,x,w;if(y.fieldsConfig){let O=y.fieldsConfig;h=[],x=[],w=[];for(let[T,z]of Object.entries(O))for(let Z of z)Z==="filterable"?h.push(T):Z==="mutable"?x.push(T):Z==="create"&&w.push(T);h.length===0&&(h=void 0),x.length===0&&(x=void 0),w.length===0&&(w=void 0);}let S=(()=>{let O=y.repo._parentKeys;return O&&O.length>0?O:void 0})();if(S&&w)for(let O of S)w.includes(O)||w.push(O);let C={name:i,path:y.path,repo:y.repo,schema:v,systemKeys:y.repo._systemKeys??[y.documentKey??"docId"],documentKey:y.documentKey??"docId",pathKey:y.repo._pathKey??void 0,isGroup:!!y.repo._isGroup,parentKeys:S,createdKey:y.repo._createdKey??void 0,pageSize:y.pageSize??25,filterableFields:h,mutableFields:x,createFields:w,allowDelete:y.allowDelete??false,allowedIncludes:y.allowedIncludes,validate:y.validate};d[i]=C;}let l=st(d,g,a),R=e.openapi,u=R&&typeof R=="object"?R:{},c=null;function p(){if(!c){let i=r&&typeof r!="function"?"basic":r?"bearer":false;c=_e(d,g,{...u,auth:u.auth??i});}return c}let b=new Q;if(b.use((i,y,v)=>{y.set("Access-Control-Allow-Origin","*"),y.set("Access-Control-Allow-Credentials","true"),v();}),s&&b.use(async(i,y,v)=>{let h=i;if(String(h.headers?.["content-type"]??"").includes("application/json")){if(typeof h.body=="string")try{i.body=JSON.parse(h.body);}catch{}else if(Buffer.isBuffer(i.rawBody))try{let w=await Kt(h);i.body=JSON.parse(w);}catch{}}await v();}),r)if(typeof r=="function")b.use(r);else {let i=r.realm??"API",y="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");b.use((v,h,x)=>{if((v.headers?.authorization??"")!==y){h.status(401).set("WWW-Authenticate",`Basic realm="${i}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}x();});}for(let i of o)b.use(i);if(R!==false){let i=`${g}/__spec.json`,y=`${g}/__docs`;b.get(i,(v,h)=>{let x=p();h.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(x,null,2));}),b.get(y,(v,h)=>{let x=Mt(g)+"/__spec.json",w=Bt(u.title??"CRUD API",x);h.status(200).set("Content-Type","text/html; charset=utf-8").send(w);});}b.use((i,y,v)=>{if(i.method==="OPTIONS"){l.handleOptions(i,y);return}v();}),b.get(`${g}/:repoName`,l.handleList),b.post(`${g}/:repoName/query`,l.handleQuery),b.get(`${g}/:repoName/:id`,l.handleGet),b.post(`${g}/:repoName`,l.handleCreate),b.put(`${g}/:repoName/:id`,(i,y)=>l.handleUpdate(i,y,false)),b.patch(`${g}/:repoName/:id`,(i,y)=>l.handleUpdate(i,y,true)),b.delete(`${g}/:repoName/:id`,l.handleDelete);let m=async(i,y)=>{await b.handle(i,y);};return m.spec=p,f&&(m.httpsOptions=f),m}export{wt as CSS,ie as ClientScript,Q as MiniRouter,Zt as createAdminServer,Ut as createCrudServer,we as renderDashboard,me as renderField,V as renderForm,X as renderFormPage,Se as renderList,St as renderPage,U as zodToFields};//# sourceMappingURL=index.js.map
566
+ </html>`}function Mt(e,t){let n=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let o=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=process.env.FUNCTION_TARGET??"";return `/${o}/${a}/${f}${n}`}let s=process.env.K_SERVICE,r=e?.hostname??e?.headers?.host??"";return s&&r.includes("cloudfunctions.net")?`/${s.toLowerCase()}${n}`:n}async function Kt(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Ut(e){let{basePath:t="/",repos:n,parseBody:s=true,auth:r,middleware:o=[],verbose:a=false,httpsOptions:f}=e,g=t==="/"?"":t.replace(/\/$/,""),d={};for(let[i,y]of Object.entries(n)){let v=y.schema??y.repo.schema??null;if(!v)throw new Error(`[createCrudServer] Repository "${i}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let h,x,w;if(y.fieldsConfig){let O=y.fieldsConfig;h=[],x=[],w=[];for(let[T,z]of Object.entries(O))for(let Z of z)Z==="filterable"?h.push(T):Z==="mutable"?x.push(T):Z==="create"&&w.push(T);h.length===0&&(h=void 0),x.length===0&&(x=void 0),w.length===0&&(w=void 0);}let S=(()=>{let O=y.repo._parentKeys;return O&&O.length>0?O:void 0})();if(S&&w)for(let O of S)w.includes(O)||w.push(O);let C={name:i,path:y.path,repo:y.repo,schema:v,systemKeys:y.repo._systemKeys??[y.documentKey??"docId"],documentKey:y.documentKey??"docId",pathKey:y.repo._pathKey??void 0,isGroup:!!y.repo._isGroup,parentKeys:S,createdKey:y.repo._createdKey??void 0,pageSize:y.pageSize??25,filterableFields:h,mutableFields:x,createFields:w,allowDelete:y.allowDelete??false,allowedIncludes:y.allowedIncludes,validate:y.validate};d[i]=C;}let l=st(d,g,a),R=e.openapi,u=R&&typeof R=="object"?R:{},c=null;function p(){if(!c){let i=r&&typeof r!="function"?"basic":r?"bearer":false;c=Ee(d,g,{...u,auth:u.auth??i});}return c}let b=new Q;if(b.use((i,y,v)=>{y.set("Access-Control-Allow-Origin","*"),y.set("Access-Control-Allow-Credentials","true"),v();}),s&&b.use(async(i,y,v)=>{let h=i;if(String(h.headers?.["content-type"]??"").includes("application/json")){if(typeof h.body=="string")try{i.body=JSON.parse(h.body);}catch{}else if(Buffer.isBuffer(i.rawBody))try{let w=await Kt(h);i.body=JSON.parse(w);}catch{}}await v();}),r)if(typeof r=="function")b.use(r);else {let i=r.realm??"API",y="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");b.use((v,h,x)=>{if((v.headers?.authorization??"")!==y){h.status(401).set("WWW-Authenticate",`Basic realm="${i}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}x();});}for(let i of o)b.use(i);if(R!==false){let i=`${g}/__spec.json`,y=`${g}/__docs`;b.get(i,(v,h)=>{let x=p();h.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(x,null,2));}),b.get(y,(v,h)=>{let x=Mt(v,g)+"/__spec.json",w=Bt(u.title??"CRUD API",x);h.status(200).set("Content-Type","text/html; charset=utf-8").send(w);});}b.use((i,y,v)=>{if(i.method==="OPTIONS"){l.handleOptions(i,y);return}v();}),b.get(`${g}/:repoName`,l.handleList),b.post(`${g}/:repoName/query`,l.handleQuery),b.get(`${g}/:repoName/:id`,l.handleGet),b.post(`${g}/:repoName`,l.handleCreate),b.put(`${g}/:repoName/:id`,(i,y)=>l.handleUpdate(i,y,false)),b.patch(`${g}/:repoName/:id`,(i,y)=>l.handleUpdate(i,y,true)),b.delete(`${g}/:repoName/:id`,l.handleDelete);let m=async(i,y)=>{await b.handle(i,y);};return m.spec=p,f&&(m.httpsOptions=f),m}export{wt as CSS,ie as ClientScript,Q as MiniRouter,Zt as createAdminServer,Ut as createCrudServer,we as renderDashboard,me as renderField,V as renderForm,X as renderFormPage,Se as renderList,St as renderPage,U as zodToFields};//# sourceMappingURL=index.js.map
567
567
  //# sourceMappingURL=index.js.map