@lpdjs/firestore-repo-service 2.2.8 → 2.2.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{create-servers-BGtAS0oG.d.cts → create-servers-CfLtucbQ.d.cts} +27 -3
  2. package/dist/{create-servers-DMszgNtg.d.ts → create-servers-xx0m3wwM.d.ts} +27 -3
  3. package/dist/history/index.cjs +1 -1
  4. package/dist/history/index.cjs.map +1 -1
  5. package/dist/history/index.d.cts +2 -2
  6. package/dist/history/index.d.ts +2 -2
  7. package/dist/history/index.js +1 -1
  8. package/dist/history/index.js.map +1 -1
  9. package/dist/{index-D7oj3Pft.d.cts → index-BvKyjs6k.d.cts} +9 -1
  10. package/dist/{index-BSZP0Gz9.d.ts → index-Njwf8jvu.d.ts} +9 -1
  11. package/dist/index.cjs +93 -93
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +6 -6
  14. package/dist/index.d.ts +6 -6
  15. package/dist/index.js +93 -93
  16. package/dist/index.js.map +1 -1
  17. package/dist/{openapi-BdqIkSjO.d.ts → openapi-BHZ2XHgn.d.ts} +1 -1
  18. package/dist/{openapi-lY43PZXy.d.cts → openapi-DXUE_MEP.d.cts} +1 -1
  19. package/dist/{read-DfXXxhO4.d.cts → read-D4xAmsbE.d.cts} +139 -9
  20. package/dist/{read-DfXXxhO4.d.ts → read-D4xAmsbE.d.ts} +139 -9
  21. package/dist/servers/admin/index.cjs +45 -45
  22. package/dist/servers/admin/index.cjs.map +1 -1
  23. package/dist/servers/admin/index.d.cts +3 -3
  24. package/dist/servers/admin/index.d.ts +3 -3
  25. package/dist/servers/admin/index.js +45 -45
  26. package/dist/servers/admin/index.js.map +1 -1
  27. package/dist/servers/crud/index.d.cts +5 -5
  28. package/dist/servers/crud/index.d.ts +5 -5
  29. package/dist/servers/index.cjs +88 -88
  30. package/dist/servers/index.cjs.map +1 -1
  31. package/dist/servers/index.d.cts +7 -7
  32. package/dist/servers/index.d.ts +7 -7
  33. package/dist/servers/index.js +88 -88
  34. package/dist/servers/index.js.map +1 -1
  35. package/dist/{types-BESS89Fu.d.cts → types-C822D0dX.d.ts} +2 -2
  36. package/dist/{types-BVUFVcpl.d.ts → types-Z1Zy-2hs.d.cts} +2 -2
  37. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- 'use strict';var jsxRuntime=require('hono/jsx/jsx-runtime'),zod=require('zod'),server=require('hono/jsx/dom/server'),firestore=require('firebase-admin/firestore');var An=Object.defineProperty;var Me=(e,t)=>()=>(e&&(t=e(e=0)),t);var En=(e,t)=>{for(var n in t)An(e,n,{get:t[n],enumerable:true});};function q(e){let t=e,n=t._zod?.def?.type;if(n)return In[n]??`Zod${n.charAt(0).toUpperCase()}${n.slice(1)}`;let r=t._def?.typeName;return r||""}function U(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function Ot(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function Tt(e){let t=e;if(t._zod?.def?.defaultValue!==void 0)return t._zod.def.defaultValue;let n=t._def?.defaultValue;return typeof n=="function"?n():n}function Q(e){let t=e;return t.shape&&typeof t.shape=="object"?t.shape:t._zod?.def?.shape&&typeof t._zod.def.shape=="object"?t._zod.def.shape:t._def?.shape?typeof t._def.shape=="function"?t._def.shape():t._def.shape:{}}function Ae(e){let t=e;return Array.isArray(t.options)?t.options:t._zod?.def?.entries?Object.values(t._zod.def.entries):Array.isArray(t._def?.values)?t._def.values:[]}function Ee(e){let t=e;return t._zod?.def?.entries?t._zod.def.entries:t.enum&&typeof t.enum=="object"?t.enum:t._def?.values&&typeof t._def.values=="object"?t._def.values:{}}function Ue(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function At(e){let t=e,n=[],r=t._zod?.def?.checks;if(Array.isArray(r)){for(let o of r)o.format&&n.push(o.format);if(n.length>0)return n}let s=t._def?.checks;if(Array.isArray(s))for(let o of s)o.kind&&n.push(o.kind);return n}var In,Pe=Me(()=>{In={string:"ZodString",number:"ZodNumber",bigint:"ZodBigInt",boolean:"ZodBoolean",date:"ZodDate",enum:"ZodEnum",nativeEnum:"ZodNativeEnum",literal:"ZodLiteral",object:"ZodObject",array:"ZodArray",optional:"ZodOptional",nullable:"ZodNullable",default:"ZodDefault",coerce:"ZodCoerce",union:"ZodUnion",undefined:"ZodUndefined",unknown:"ZodUnknown",any:"ZodAny",record:"ZodRecord"};});function Ut({val:e}){return jsxRuntime.jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function Un({message:e}){return jsxRuntime.jsx("span",{class:"tooltip tooltip-warning tooltip-right inline-flex align-middle ml-1 text-warning","data-tip":e,role:"img","aria-label":e,children:jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",class:"size-3.5",children:jsxRuntime.jsx("path",{d:"M12 2 1 22h22L12 2zm0 6 7.5 13h-15L12 8zm-1 4v4h2v-4h-2zm0 5v2h2v-2h-2z"})})})}function Se({val:e,mismatch:t}){let n=Ln(e);return t?jsxRuntime.jsxs("span",{class:"inline-flex items-start gap-0.5",children:[n,jsxRuntime.jsx(Un,{message:t})]}):n}function Ln(e){if(e==null)return jsxRuntime.jsx("span",{class:"opacity-30 italic text-xs",children:"\u2014"});if(typeof e=="boolean")return e?jsxRuntime.jsx("span",{class:"badge badge-success badge-sm",children:"true"}):jsxRuntime.jsx("span",{class:"badge badge-error badge-sm",children:"false"});if(e instanceof Date)return jsxRuntime.jsx(Ut,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsxRuntime.jsx(Ut,{val:e.toDate()});if(typeof e=="number")return jsxRuntime.jsx("span",{class:"text-sm font-mono tabular-nums",children:String(e)});if(Array.isArray(e))return e.length===0?jsxRuntime.jsx("span",{class:"text-xs text-base-content/30",children:"[]"}):jsxRuntime.jsxs("ul",{class:"list-none p-0 m-0 space-y-0.5 text-xs",children:[e.slice(0,8).map((n,r)=>jsxRuntime.jsx("li",{class:"break-all",children:typeof n=="object"?JSON.stringify(n):String(n)},r)),e.length>8&&jsxRuntime.jsxs("li",{class:"text-base-content/40 italic",children:["+",e.length-8," more\u2026"]})]});if(typeof e=="object"&&e!==null){let n=Object.entries(e);return n.length===0?jsxRuntime.jsx("span",{class:"text-xs text-base-content/30",children:"{}"}):jsxRuntime.jsxs("dl",{class:"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-xs m-0",children:[n.slice(0,8).map(([r,s])=>jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:r}),jsxRuntime.jsx("dd",{class:"break-all",children:String(s??"")})]})),n.length>8&&jsxRuntime.jsxs("dt",{class:"col-span-2 text-base-content/40 italic",children:["+",n.length-8," more\u2026"]})]})}let t=String(e);return jsxRuntime.jsx("span",{class:"text-sm break-all",children:t})}var Ke=Me(()=>{});function ke(e){if(!e)return "unknown";let t=Xe(e);switch(q(t)){case "ZodString":return "string";case "ZodNumber":return "number";case "ZodBigInt":return "bigint";case "ZodBoolean":return "boolean";case "ZodDate":return "date";case "ZodArray":return "array";case "ZodObject":case "ZodRecord":return "object";case "ZodEnum":case "ZodNativeEnum":return "enum";case "ZodLiteral":return "literal";default:return "unknown"}}function Xe(e){let t=q(e);if(t==="ZodOptional"||t==="ZodNullable"||t==="ZodDefault"){let n=U(e);return n?Xe(n):e}return e}function $e(e,t){if(!e)return;let n=t.split("."),r=e;for(let s of n){if(!r)return;let o=Xe(r);if(q(o)!=="ZodObject")return;r=Q(o)[s];}return r}function Gn(e){return e==null?"null":e instanceof Date?"date":Array.isArray(e)?"array":typeof e=="string"?"string":typeof e=="boolean"?"boolean":typeof e=="bigint"?"bigint":typeof e=="number"?"number":typeof e=="object"?typeof e.toDate=="function"?"date":"object":"unknown"}function De(e,t){if(e==="unknown")return null;let n=Gn(t);return n==="null"?null:e==="enum"||e==="literal"?n==="string"||n==="number"?null:`Expected ${e} (string/number), got ${n}`:e===n||e==="number"&&n==="bigint"||e==="bigint"&&n==="number"?null:`Expected ${e}, got ${n}`}var Ye=Me(()=>{Pe();});var Kt={};En(Kt,{PanelMany:()=>Qn,PanelOne:()=>Jn,RightPanel:()=>et});function Jn({doc:e,repoName:t,basePath:n,schema:r,columns:s}){if(!e)return jsxRuntime.jsx("div",{class:"text-center py-12 text-base-content/50",children:"Document not found."});let o=String(e.docId??e.id??""),l=`${n}/${t}/${encodeURIComponent(o)}/edit`,p=Ht(r,s);return jsxRuntime.jsxs("div",{class:"space-y-4",children:[jsxRuntime.jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxRuntime.jsxs("div",{class:"text-xs text-base-content/60",children:[jsxRuntime.jsx("span",{class:"font-mono",children:t}),jsxRuntime.jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxRuntime.jsx("span",{class:"font-mono break-all",children:o})]}),jsxRuntime.jsx("a",{href:l,class:"btn btn-sm btn-primary",children:"Edit \u2192"})]}),jsxRuntime.jsx("dl",{class:"grid grid-cols-[max-content_1fr] gap-x-4 gap-y-2 border border-base-300 rounded-box p-4 bg-base-100",children:s.map(u=>{let g=e[u],h=p[u],k=h?De(h,g):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("dt",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide pt-0.5",children:u}),jsxRuntime.jsx("dd",{class:"min-w-0",children:jsxRuntime.jsx(Se,{val:g,mismatch:k})})]})})})]})}function Qn({docs:e,repoName:t,basePath:n,fk:r,fv:s,columns:o,schema:l,pagination:p}){let u=`${n}/${t}?fv_${r}=${encodeURIComponent(s)}`,g=Ht(l,o);return jsxRuntime.jsxs("div",{class:"space-y-4",children:[jsxRuntime.jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxRuntime.jsxs("div",{class:"text-xs text-base-content/60",children:[jsxRuntime.jsx("span",{class:"font-mono",children:t}),jsxRuntime.jsx("span",{class:"opacity-50",children:" where "}),jsxRuntime.jsx("span",{class:"font-mono",children:r}),jsxRuntime.jsx("span",{class:"opacity-50",children:" = "}),jsxRuntime.jsx("span",{class:"font-mono break-all",children:s}),jsxRuntime.jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxRuntime.jsxs("span",{children:[e.length," doc",e.length!==1?"s":""]})]}),jsxRuntime.jsx("a",{href:u,class:"btn btn-sm btn-outline",children:"Full view \u2192"})]}),jsxRuntime.jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100",children:jsxRuntime.jsxs("table",{class:"table table-xs w-full",children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{class:"bg-base-200/50",children:[o.map((h,k)=>jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:h},k)),jsxRuntime.jsx("th",{})]})}),jsxRuntime.jsx("tbody",{children:e.length===0?jsxRuntime.jsx("tr",{children:jsxRuntime.jsx("td",{colspan:o.length+1,class:"text-center py-10 text-base-content/40",children:"No related documents"})}):e.map((h,k)=>{let w=String(h.docId??h.id??""),b=`${n}/${t}/${encodeURIComponent(w)}/edit`;return jsxRuntime.jsxs("tr",{class:"hover",children:[o.map((m,y)=>{let i=h[m],d=g[m],c=d?De(d,i):null;return jsxRuntime.jsx("td",{class:"align-top py-1.5",children:jsxRuntime.jsx(Se,{val:i,mismatch:c})},y)}),jsxRuntime.jsx("td",{class:"text-right py-1.5",children:jsxRuntime.jsx("a",{href:b,class:"btn btn-xs btn-ghost",children:"Edit"})})]},k)})})]})}),(p.hasPrev||p.hasNext)&&jsxRuntime.jsxs("div",{class:"flex justify-center items-center gap-2",children:[p.hasPrev?jsxRuntime.jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"prev","data-cursor":p.prevCursor,children:"\u2190 Previous"}):jsxRuntime.jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"\u2190 Previous"}),p.hasNext?jsxRuntime.jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"next","data-cursor":p.nextCursor,children:"Next \u2192"}):jsxRuntime.jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"Next \u2192"})]})]})}function Ht(e,t){if(!e)return {};let n={};for(let r of t)n[r]=ke($e(e,r));return n}var et,tt=Me(()=>{Ke();Ye();et=({basePath:e=""})=>jsxRuntime.jsxs("div",{class:"fixed inset-0 z-[100] hidden pointer-events-none","data-frs-panel-root":true,"data-frs-base-path":e,"aria-hidden":"true",children:[jsxRuntime.jsx("div",{class:"absolute inset-0 bg-black/30 opacity-0 transition-opacity duration-200 pointer-events-auto","data-frs-panel-backdrop":true}),jsxRuntime.jsxs("aside",{class:"absolute top-0 right-0 h-full w-full md:w-1/2 bg-base-100 shadow-2xl border-l border-base-300 translate-x-full transition-transform duration-200 pointer-events-auto flex flex-col","data-frs-panel":true,role:"dialog","aria-label":"Relation preview",children:[jsxRuntime.jsxs("header",{class:"flex items-center justify-between px-5 py-3 border-b border-base-300 bg-base-200/40 shrink-0",children:[jsxRuntime.jsx("h2",{class:"font-semibold text-base truncate","data-frs-panel-title":true,children:"Relation"}),jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-ghost btn-circle","data-frs-panel-close":true,"aria-label":"Close panel",children:"\u2715"})]}),jsxRuntime.jsx("div",{class:"flex-1 overflow-auto p-5 text-sm","data-frs-panel-body":true,children:jsxRuntime.jsx("div",{class:"flex items-center justify-center py-12 text-base-content/40",children:jsxRuntime.jsx("span",{class:"loading loading-spinner loading-md"})})})]})]});});function Pn(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,r=>r===":"?r:`\\${r}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(r,s)=>(t.push(s),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function Nn(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var Y=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,n)=>{n.status(404).send("Not Found");};this.errorHandler=(t,n,r)=>{console.error("[MiniRouter]",t),r.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,r){let{pattern:s,paramNames:o}=Pn(n);return this.routes.push({method:t.toUpperCase(),pattern:s,paramNames:o,handler:r}),this}async handle(t,n){let r=(t.method??"GET").toUpperCase(),s=Nn(t),o=null,l={};for(let g of this.routes){if(g.method!==r)continue;let h=s.match(g.pattern);if(h){o=g,l={},g.paramNames.forEach((k,w)=>{l[k]=decodeURIComponent(h[w+1]??"");});break}}let p=Object.assign(t,{params:l}),u=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(p,n,u);}catch(g){this.errorHandler(g,t,n);}}async runMiddlewareChain(t,n,r){let s=0,o=async()=>{if(s<this.middlewares.length){let l=this.middlewares[s++];await l(t,n,o);}else await r(t,n);};await o();}};Pe();var ae="__sync_version";var _n=new Set(["ZodOptional","ZodNullable","ZodDefault"]);function Dn(e){let t=e,n=false;for(;;){let r=q(t);if(!_n.has(r))break;(r==="ZodOptional"||r==="ZodNullable")&&(n=true);let s=U(t);if(!s)break;t=s;}return {inner:t,nullable:n}}var jn={ZodString:"string",ZodNumber:"number",ZodBigInt:"bigint",ZodBoolean:"boolean",ZodDate:"timestamp",ZodEnum:"string",ZodNativeEnum:"string",ZodLiteral:"string"};function Et(e,t,n,r,s,o,l,p){for(let[u,g]of Object.entries(e)){let h=n?`${n}__${u}`:u;if(s.has(u)||s.has(h))continue;let{inner:k,nullable:w}=Dn(g),b=q(k),m=r||w;if(b==="ZodObject"){let c=Q(k);Et(c,t,h,m,s,o,l,p);continue}let y=jn[b]??"json",i=h===l||u===l,d=o[h]??o[u]??h;p.push({name:d,sqlType:t.mapType(y),nullable:i?false:m,isPrimaryKey:i});}}function Le(e,t,n={}){let{primaryKey:r,exclude:s=[],columnMap:o={}}=n,l=new Set(s),p=Q(e),u=[];return Et(p,t,"",false,l,o,r,u),u.some(g=>g.name===ae)||u.push({name:ae,sqlType:t.mapType("bigint"),nullable:true,isPrimaryKey:false,description:"Monotonic publish version (Date.now() ms). Internal."}),u}function Pt(e){if(e==null)return null;if(typeof e=="object"&&typeof e.toDate=="function")return e.toDate().toISOString();if(e instanceof Date)return e.toISOString();if(Buffer.isBuffer(e))return e.toString("base64");if(e instanceof Uint8Array)return Buffer.from(e).toString("base64");if(typeof e=="object"&&"latitude"in e&&"longitude"in e){let t=e;return JSON.stringify({lat:t.latitude,lng:t.longitude})}return Array.isArray(e)?JSON.stringify(e.map(Pt)):e}function Nt(e,t,n){for(let[r,s]of Object.entries(e)){let o=t?`${t}__${r}`:r;s!=null&&typeof s=="object"&&!Array.isArray(s)&&!(s instanceof Date)&&!Buffer.isBuffer(s)&&!(s instanceof Uint8Array)&&typeof s.toDate!="function"&&!("latitude"in s&&"longitude"in s)?Nt(s,o,n):n[o]=Pt(s);}}function Ne(e,t){let n=new Set(t?.exclude),r=t?.columnMap??{},s={};Nt(e,"",s);let o={};for(let[l,p]of Object.entries(s)){if(n.has(l))continue;let u=l.split("__")[0];if(u!==l&&n.has(u))continue;let g=r[l]??(l.includes("__")?r[l.split("__").pop()]:void 0)??l;o[g]=p;}return o}function ye(e,t){if(process.env.FUNCTIONS_EMULATOR==="true"){let s=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",o=process.env.FUNCTION_REGION??"us-central1",l=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${s}/${o}/${l}${t}`}let n=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return n&&r.includes("cloudfunctions.net")?`/${n.toLowerCase()}${t}`:t}function ee(e,t,n){return `<!DOCTYPE html>
1
+ 'use strict';var jsxRuntime=require('hono/jsx/jsx-runtime'),firestore=require('firebase-admin/firestore'),crypto=require('crypto'),zod=require('zod'),server=require('hono/jsx/dom/server');var Bn=Object.defineProperty;var Ke=(e,t)=>()=>(e&&(t=e(e=0)),t);var Mn=(e,t)=>{for(var n in t)Bn(e,n,{get:t[n],enumerable:true});};function q(e){let t=e,n=t._zod?.def?.type;if(n)return Gn[n]??`Zod${n.charAt(0).toUpperCase()}${n.slice(1)}`;let r=t._def?.typeName;return r||""}function L(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function Zt(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function Bt(e){let t=e;if(t._zod?.def?.defaultValue!==void 0)return t._zod.def.defaultValue;let n=t._def?.defaultValue;return typeof n=="function"?n():n}function Y(e){let t=e;return t.shape&&typeof t.shape=="object"?t.shape:t._zod?.def?.shape&&typeof t._zod.def.shape=="object"?t._zod.def.shape:t._def?.shape?typeof t._def.shape=="function"?t._def.shape():t._def.shape:{}}function Ne(e){let t=e;return Array.isArray(t.options)?t.options:t._zod?.def?.entries?Object.values(t._zod.def.entries):Array.isArray(t._def?.values)?t._def.values:[]}function _e(e){let t=e;return t._zod?.def?.entries?t._zod.def.entries:t.enum&&typeof t.enum=="object"?t.enum:t._def?.values&&typeof t._def.values=="object"?t._def.values:{}}function Ve(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function Mt(e){let t=e,n=[],r=t._zod?.def?.checks;if(Array.isArray(r)){for(let o of r)o.format&&n.push(o.format);if(n.length>0)return n}let s=t._def?.checks;if(Array.isArray(s))for(let o of s)o.kind&&n.push(o.kind);return n}var Gn,De=Ke(()=>{Gn={string:"ZodString",number:"ZodNumber",bigint:"ZodBigInt",boolean:"ZodBoolean",date:"ZodDate",enum:"ZodEnum",nativeEnum:"ZodNativeEnum",literal:"ZodLiteral",object:"ZodObject",array:"ZodArray",optional:"ZodOptional",nullable:"ZodNullable",default:"ZodDefault",coerce:"ZodCoerce",union:"ZodUnion",undefined:"ZodUndefined",unknown:"ZodUnknown",any:"ZodAny",record:"ZodRecord"};});function tn({val:e}){return jsxRuntime.jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function sr({message:e}){return jsxRuntime.jsx("span",{class:"tooltip tooltip-warning tooltip-right inline-flex align-middle ml-1 text-warning","data-tip":e,role:"img","aria-label":e,children:jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",class:"size-3.5",children:jsxRuntime.jsx("path",{d:"M12 2 1 22h22L12 2zm0 6 7.5 13h-15L12 8zm-1 4v4h2v-4h-2zm0 5v2h2v-2h-2z"})})})}function Ce({val:e,mismatch:t}){let n=or(e);return t?jsxRuntime.jsxs("span",{class:"inline-flex items-start gap-0.5",children:[n,jsxRuntime.jsx(sr,{message:t})]}):n}function or(e){if(e==null)return jsxRuntime.jsx("span",{class:"opacity-30 italic text-xs",children:"\u2014"});if(typeof e=="boolean")return e?jsxRuntime.jsx("span",{class:"badge badge-success badge-sm",children:"true"}):jsxRuntime.jsx("span",{class:"badge badge-error badge-sm",children:"false"});if(e instanceof Date)return jsxRuntime.jsx(tn,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsxRuntime.jsx(tn,{val:e.toDate()});if(typeof e=="number")return jsxRuntime.jsx("span",{class:"text-sm font-mono tabular-nums",children:String(e)});if(Array.isArray(e))return e.length===0?jsxRuntime.jsx("span",{class:"text-xs text-base-content/30",children:"[]"}):jsxRuntime.jsxs("ul",{class:"list-none p-0 m-0 space-y-0.5 text-xs",children:[e.slice(0,8).map((n,r)=>jsxRuntime.jsx("li",{class:"break-all",children:typeof n=="object"?JSON.stringify(n):String(n)},r)),e.length>8&&jsxRuntime.jsxs("li",{class:"text-base-content/40 italic",children:["+",e.length-8," more\u2026"]})]});if(typeof e=="object"&&e!==null){let n=Object.entries(e);return n.length===0?jsxRuntime.jsx("span",{class:"text-xs text-base-content/30",children:"{}"}):jsxRuntime.jsxs("dl",{class:"grid grid-cols-[auto_1fr] gap-x-2 gap-y-0.5 text-xs m-0",children:[n.slice(0,8).map(([r,s])=>jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:r}),jsxRuntime.jsx("dd",{class:"break-all",children:String(s??"")})]})),n.length>8&&jsxRuntime.jsxs("dt",{class:"col-span-2 text-base-content/40 italic",children:["+",n.length-8," more\u2026"]})]})}let t=String(e);return jsxRuntime.jsx("span",{class:"text-sm break-all",children:t})}var We=Ke(()=>{});function Oe(e){if(!e)return "unknown";let t=st(e);switch(q(t)){case "ZodString":return "string";case "ZodNumber":return "number";case "ZodBigInt":return "bigint";case "ZodBoolean":return "boolean";case "ZodDate":return "date";case "ZodArray":return "array";case "ZodObject":case "ZodRecord":return "object";case "ZodEnum":case "ZodNativeEnum":return "enum";case "ZodLiteral":return "literal";default:return "unknown"}}function st(e){let t=q(e);if(t==="ZodOptional"||t==="ZodNullable"||t==="ZodDefault"){let n=L(e);return n?st(n):e}return e}function Te(e,t){if(!e)return;let n=t.split("."),r=e;for(let s of n){if(!r)return;let o=st(r);if(q(o)!=="ZodObject")return;r=Y(o)[s];}return r}function cr(e){return e==null?"null":e instanceof Date?"date":Array.isArray(e)?"array":typeof e=="string"?"string":typeof e=="boolean"?"boolean":typeof e=="bigint"?"bigint":typeof e=="number"?"number":typeof e=="object"?typeof e.toDate=="function"?"date":"object":"unknown"}function Ze(e,t){if(e==="unknown")return null;let n=cr(t);return n==="null"?null:e==="enum"||e==="literal"?n==="string"||n==="number"?null:`Expected ${e} (string/number), got ${n}`:e===n||e==="number"&&n==="bigint"||e==="bigint"&&n==="number"?null:`Expected ${e}, got ${n}`}var ot=Ke(()=>{De();});var sn={};Mn(sn,{PanelMany:()=>ur,PanelOne:()=>dr,RightPanel:()=>at});function dr({doc:e,repoName:t,basePath:n,schema:r,columns:s}){if(!e)return jsxRuntime.jsx("div",{class:"text-center py-12 text-base-content/50",children:"Document not found."});let o=String(e.docId??e.id??""),i=`${n}/${t}/${encodeURIComponent(o)}/edit`,u=rn(r,s);return jsxRuntime.jsxs("div",{class:"space-y-4",children:[jsxRuntime.jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxRuntime.jsxs("div",{class:"text-xs text-base-content/60",children:[jsxRuntime.jsx("span",{class:"font-mono",children:t}),jsxRuntime.jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxRuntime.jsx("span",{class:"font-mono break-all",children:o})]}),jsxRuntime.jsx("a",{href:i,class:"btn btn-sm btn-primary",children:"Edit \u2192"})]}),jsxRuntime.jsx("dl",{class:"grid grid-cols-[max-content_1fr] gap-x-4 gap-y-2 border border-base-300 rounded-box p-4 bg-base-100",children:s.map(c=>{let g=e[c],h=u[c],k=h?Ze(h,g):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("dt",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide pt-0.5",children:c}),jsxRuntime.jsx("dd",{class:"min-w-0",children:jsxRuntime.jsx(Ce,{val:g,mismatch:k})})]})})})]})}function ur({docs:e,repoName:t,basePath:n,fk:r,fv:s,columns:o,schema:i,pagination:u}){let c=`${n}/${t}?fv_${r}=${encodeURIComponent(s)}`,g=rn(i,o);return jsxRuntime.jsxs("div",{class:"space-y-4",children:[jsxRuntime.jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxRuntime.jsxs("div",{class:"text-xs text-base-content/60",children:[jsxRuntime.jsx("span",{class:"font-mono",children:t}),jsxRuntime.jsx("span",{class:"opacity-50",children:" where "}),jsxRuntime.jsx("span",{class:"font-mono",children:r}),jsxRuntime.jsx("span",{class:"opacity-50",children:" = "}),jsxRuntime.jsx("span",{class:"font-mono break-all",children:s}),jsxRuntime.jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxRuntime.jsxs("span",{children:[e.length," doc",e.length!==1?"s":""]})]}),jsxRuntime.jsx("a",{href:c,class:"btn btn-sm btn-outline",children:"Full view \u2192"})]}),jsxRuntime.jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100",children:jsxRuntime.jsxs("table",{class:"table table-xs w-full",children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{class:"bg-base-200/50",children:[o.map((h,k)=>jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:h},k)),jsxRuntime.jsx("th",{})]})}),jsxRuntime.jsx("tbody",{children:e.length===0?jsxRuntime.jsx("tr",{children:jsxRuntime.jsx("td",{colspan:o.length+1,class:"text-center py-10 text-base-content/40",children:"No related documents"})}):e.map((h,k)=>{let w=String(h.docId??h.id??""),x=`${n}/${t}/${encodeURIComponent(w)}/edit`;return jsxRuntime.jsxs("tr",{class:"hover",children:[o.map((m,y)=>{let f=h[m],d=g[m],a=d?Ze(d,f):null;return jsxRuntime.jsx("td",{class:"align-top py-1.5",children:jsxRuntime.jsx(Ce,{val:f,mismatch:a})},y)}),jsxRuntime.jsx("td",{class:"text-right py-1.5",children:jsxRuntime.jsx("a",{href:x,class:"btn btn-xs btn-ghost",children:"Edit"})})]},k)})})]})}),(u.hasPrev||u.hasNext)&&jsxRuntime.jsxs("div",{class:"flex justify-center items-center gap-2",children:[u.hasPrev?jsxRuntime.jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"prev","data-cursor":u.prevCursor,children:"\u2190 Previous"}):jsxRuntime.jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"\u2190 Previous"}),u.hasNext?jsxRuntime.jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"next","data-cursor":u.nextCursor,children:"Next \u2192"}):jsxRuntime.jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"Next \u2192"})]})]})}function rn(e,t){if(!e)return {};let n={};for(let r of t)n[r]=Oe(Te(e,r));return n}var at,it=Ke(()=>{We();ot();at=({basePath:e=""})=>jsxRuntime.jsxs("div",{class:"fixed inset-0 z-[100] hidden pointer-events-none","data-frs-panel-root":true,"data-frs-base-path":e,"aria-hidden":"true",children:[jsxRuntime.jsx("div",{class:"absolute inset-0 bg-black/30 opacity-0 transition-opacity duration-200 pointer-events-auto","data-frs-panel-backdrop":true}),jsxRuntime.jsxs("aside",{class:"absolute top-0 right-0 h-full w-full md:w-1/2 bg-base-100 shadow-2xl border-l border-base-300 translate-x-full transition-transform duration-200 pointer-events-auto flex flex-col","data-frs-panel":true,role:"dialog","aria-label":"Relation preview",children:[jsxRuntime.jsxs("header",{class:"flex items-center justify-between px-5 py-3 border-b border-base-300 bg-base-200/40 shrink-0",children:[jsxRuntime.jsx("h2",{class:"font-semibold text-base truncate","data-frs-panel-title":true,children:"Relation"}),jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-ghost btn-circle","data-frs-panel-close":true,"aria-label":"Close panel",children:"\u2715"})]}),jsxRuntime.jsx("div",{class:"flex-1 overflow-auto p-5 text-sm","data-frs-panel-body":true,children:jsxRuntime.jsx("div",{class:"flex items-center justify-center py-12 text-base-content/40",children:jsxRuntime.jsx("span",{class:"loading loading-spinner loading-md"})})})]})]});});function Pt(e){if(e===null)return "null";if(e===void 0)return "undefined";if(e instanceof firestore.Timestamp)return "timestamp";if(e instanceof Date)return "date";if(Array.isArray(e))return "array";let t=typeof e;return t==="string"||t==="number"||t==="boolean"?t:"object"}function It(e,t){if(e===t)return true;if(e===null||t===null||e===void 0||t===void 0)return e===t;if(e instanceof firestore.Timestamp&&t instanceof firestore.Timestamp)return e.isEqual(t);if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return false;for(let n=0;n<e.length;n++)if(!It(e[n],t[n]))return false;return true}if(typeof e=="object"&&typeof t=="object")try{return JSON.stringify(e)===JSON.stringify(t)}catch{return false}return false}function Nt(e,t,n={}){let r=new Set([...n.exclude??[],...n.metaFields??[],...n.systemKeys??[]]),s=n.include?new Set(n.include):null,o=e??{},i=t??{},u=new Set([...Object.keys(o),...Object.keys(i)]),c={};for(let g of u){if(r.has(g)||s&&!s.has(g))continue;let h=o[g],k=i[g];It(h,k)||(c[g]={oldValue:h===void 0?null:h,newValue:k===void 0?null:k,type:{old:Pt(h),new:Pt(k)}});}return c}var Hn=7e5;function _t(e){let t=e.ttlOverride??e.config.ttl,r={schemaVersion:2,historyDocId:crypto.randomUUID(),historyToObjectId:e.entityId,historySetAt:firestore.Timestamp.now(),operation:e.operation,meta:e.meta,changes:e.changes};t&&(r.expiresAt=firestore.Timestamp.fromMillis(Date.now()+t.days*24*60*60*1e3));let s=o=>{try{return Buffer.byteLength(JSON.stringify(o,(i,u)=>u instanceof firestore.Timestamp?u.toMillis():u),"utf8")}catch{return 0}};if(s(r.changes)>Hn){let o={};for(let[i,u]of Object.entries(r.changes)){let c=s(u.oldValue),g=s(u.newValue);o[i]={oldValue:c>5e4?"[truncated]":u.oldValue,newValue:g>5e4?"[truncated]":u.newValue,type:u.type};}r.changes=o,r._truncated=true;}return r}async function Dt(e,t,n,r){let s=t;return n.onBeforeWrite&&(s=await n.onBeforeWrite(t,r)),s?(await e.doc(s.historyDocId).set(s),{written:true,entry:s}):{written:false,reason:"dropped-by-onBeforeWrite"}}function jt(e,t){let n=e??{},r={},s=t.meta;if(!s)return r;let o=h=>{if(!h)return;let k=n[h];return k===void 0||k===null?null:String(k)},i=o(s.userId);i!==void 0&&(r.userId=i);let u=o(s.userEmail);u!==void 0&&(r.userEmail=u);let c=o(s.reason);c!==void 0&&(r.reason=c);let g=o(s.comment);if(g!==void 0&&(r.comment=g),s.extras&&s.extras.length>0){let h={},k=false;for(let w of s.extras)w in n&&(h[w]=n[w],k=true);k&&(r.extras=h);}return r}function Ft(e){let t=e.meta;if(!t)return [];let n=[];return t.userId&&n.push(t.userId),t.userEmail&&n.push(t.userEmail),t.reason&&n.push(t.reason),t.comment&&n.push(t.comment),t.extras&&n.push(...t.extras),n}var Un="history";function Ln(e,t){let n=t.ref?.path??void 0;return n?`${n}/{docId}`:(console.warn(`[HistoryTriggers] Cannot determine collection path for "${e}". Skipping.`),null)}function zt(e,t){let{onDocumentWritten:n}=t.deps,r={};for(let[s,o]of Object.entries(e)){let i=o._historyConfig??(typeof o.history=="object"&&o.history!==null&&"enabled"in o.history?o.history:void 0);if(!i?.enabled)continue;let u=i.subcollection??Un,c=i.ttl??t.defaults?.ttl,g=t.repos?.[s],h;if(o._isGroup){if(!g?.triggerPath){console.warn(`[HistoryTriggers] Skipping collection-group repo "${s}". Provide a triggerPath in the history triggers repos override.`);continue}h=g.triggerPath;}else h=g?.triggerPath??Ln(s,o);if(!h)continue;let k=o._systemKeys??[],w=k[0]??"docId",x=Ft(i);r[`${s}_onHistory`]=n(h,async m=>{try{let y=m.data?.before?.data(),f=m.data?.after?.data(),d;if(!y&&f)d="create";else if(y&&!f)d="delete";else if(y&&f)d="update";else return;let a=String(f?.[w]??y?.[w]??m.params?.docId??m.data?.after?.id??m.data?.before?.id??"");if(!a)return;let p=Nt(y??{},f??{},{include:i.include,exclude:i.exclude,metaFields:x,systemKeys:k});if(d==="update"&&Object.keys(p).length===0)return;let l=jt(f??y??null,i),b=_t({entityId:a,operation:d,changes:p,meta:l,config:i,ttlOverride:c}),v=m.data?.after?.ref??m.data?.before?.ref;if(!v)return;let C=v.collection(u);await Dt(C,b,i,{repoName:s,docId:a,before:y??null,after:f??null});}catch(y){console.error(`[HistoryTriggers] Failed to record history for "${s}":`,y);}});}return r}function Kn(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,r=>r===":"?r:`\\${r}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(r,s)=>(t.push(s),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function Vn(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var ne=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,n)=>{n.status(404).send("Not Found");};this.errorHandler=(t,n,r)=>{console.error("[MiniRouter]",t),r.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,r){let{pattern:s,paramNames:o}=Kn(n);return this.routes.push({method:t.toUpperCase(),pattern:s,paramNames:o,handler:r}),this}async handle(t,n){let r=(t.method??"GET").toUpperCase(),s=Vn(t),o=null,i={};for(let g of this.routes){if(g.method!==r)continue;let h=s.match(g.pattern);if(h){o=g,i={},g.paramNames.forEach((k,w)=>{i[k]=decodeURIComponent(h[w+1]??"");});break}}let u=Object.assign(t,{params:i}),c=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(u,n,c);}catch(g){this.errorHandler(g,t,n);}}async runMiddlewareChain(t,n,r){let s=0,o=async()=>{if(s<this.middlewares.length){let i=this.middlewares[s++];await i(t,n,o);}else await r(t,n);};await o();}};De();var de="__sync_version";var Jn=new Set(["ZodOptional","ZodNullable","ZodDefault"]);function Wn(e){let t=e,n=false;for(;;){let r=q(t);if(!Jn.has(r))break;(r==="ZodOptional"||r==="ZodNullable")&&(n=true);let s=L(t);if(!s)break;t=s;}return {inner:t,nullable:n}}var Qn={ZodString:"string",ZodNumber:"number",ZodBigInt:"bigint",ZodBoolean:"boolean",ZodDate:"timestamp",ZodEnum:"string",ZodNativeEnum:"string",ZodLiteral:"string"};function qt(e,t,n,r,s,o,i,u){for(let[c,g]of Object.entries(e)){let h=n?`${n}__${c}`:c;if(s.has(c)||s.has(h))continue;let{inner:k,nullable:w}=Wn(g),x=q(k),m=r||w;if(x==="ZodObject"){let a=Y(k);qt(a,t,h,m,s,o,i,u);continue}let y=Qn[x]??"json",f=h===i||c===i,d=o[h]??o[c]??h;u.push({name:d,sqlType:t.mapType(y),nullable:f?false:m,isPrimaryKey:f});}}function Ge(e,t,n={}){let{primaryKey:r,exclude:s=[],columnMap:o={}}=n,i=new Set(s),u=Y(e),c=[];return qt(u,t,"",false,i,o,r,c),c.some(g=>g.name===de)||c.push({name:de,sqlType:t.mapType("bigint"),nullable:true,isPrimaryKey:false,description:"Monotonic publish version (Date.now() ms). Internal."}),c}function Ht(e){if(e==null)return null;if(typeof e=="object"&&typeof e.toDate=="function")return e.toDate().toISOString();if(e instanceof Date)return e.toISOString();if(Buffer.isBuffer(e))return e.toString("base64");if(e instanceof Uint8Array)return Buffer.from(e).toString("base64");if(typeof e=="object"&&"latitude"in e&&"longitude"in e){let t=e;return JSON.stringify({lat:t.latitude,lng:t.longitude})}return Array.isArray(e)?JSON.stringify(e.map(Ht)):e}function Ut(e,t,n){for(let[r,s]of Object.entries(e)){let o=t?`${t}__${r}`:r;s!=null&&typeof s=="object"&&!Array.isArray(s)&&!(s instanceof Date)&&!Buffer.isBuffer(s)&&!(s instanceof Uint8Array)&&typeof s.toDate!="function"&&!("latitude"in s&&"longitude"in s)?Ut(s,o,n):n[o]=Ht(s);}}function je(e,t){let n=new Set(t?.exclude),r=t?.columnMap??{},s={};Ut(e,"",s);let o={};for(let[i,u]of Object.entries(s)){if(n.has(i))continue;let c=i.split("__")[0];if(c!==i&&n.has(c))continue;let g=r[i]??(i.includes("__")?r[i.split("__").pop()]:void 0)??i;o[g]=u;}return o}function be(e,t){if(process.env.FUNCTIONS_EMULATOR==="true"){let s=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",o=process.env.FUNCTION_REGION??"us-central1",i=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${s}/${o}/${i}${t}`}let n=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return n&&r.includes("cloudfunctions.net")?`/${n.toLowerCase()}${t}`:t}function re(e,t,n){return `<!DOCTYPE html>
2
2
  <html lang="en"><head>
3
3
  <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
4
4
  <title>${e} \u2014 Sync Admin</title>
@@ -28,70 +28,70 @@
28
28
  <nav><a href="${t}/">\u2190 Dashboard</a></nav>
29
29
  <h1>${e}</h1>
30
30
  ${n}
31
- </body></html>`}function te(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function ge(e,t,n=200){e.status(n).set("Content-Type","application/json").send(JSON.stringify(t,null,2));}function Ie(e){return (e.headers?.accept??"").includes("application/json")}function It(e,t,n,r,s,o,l,p){let u=(s.basePath??"/").replace(/\/$/,"")||"",g=s.featuresFlag??{},h=[];for(let[w,b]of Object.entries(e)){let m=o[w];h.push({name:w,schema:b.schema??null,documentKey:b._systemKeys?.[0]??b.documentKey??"docId",tableName:m?.tableName??w,isGroup:!!b._isGroup,repoCfg:m,repo:b});}let k=new Y;if(s.auth)if(typeof s.auth=="function")k.use(s.auth);else {let w=s.auth.realm??"Sync Admin",b="Basic "+Buffer.from(`${s.auth.username}:${s.auth.password}`).toString("base64");k.use((m,y,i)=>{if((m.headers?.authorization??"")!==b){y.status(401).set("WWW-Authenticate",`Basic realm="${w}"`).set("Content-Type","text/plain").send("Unauthorized");return}i();});}return k.get(`${u}/`,(w,b)=>{let m=ye(w,u),y=h.map(a=>{let f=[];return g.healthCheck&&f.push(`<a class="btn" href="${m}/${a.name}/health">Health</a>`),g.manualSync&&f.push(`<a class="btn btn-primary" href="${m}/${a.name}/force-sync">Force Sync</a>`),`<tr>
32
- <td><strong>${a.name}</strong></td>
33
- <td>${a.tableName}</td>
34
- <td>${a.isGroup?'<span class="badge badge-warn">group</span>':'<span class="badge badge-ok">collection</span>'}</td>
35
- <td>${a.schema?"\u2713":"\u2717"}</td>
36
- <td>${f.join(" ")}</td>
31
+ </body></html>`}function se(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function ve(e,t,n=200){e.status(n).set("Content-Type","application/json").send(JSON.stringify(t,null,2));}function Fe(e){return (e.headers?.accept??"").includes("application/json")}function Lt(e,t,n,r,s,o,i,u){let c=(s.basePath??"/").replace(/\/$/,"")||"",g=s.featuresFlag??{},h=[];for(let[w,x]of Object.entries(e)){let m=o[w];h.push({name:w,schema:x.schema??null,documentKey:x._systemKeys?.[0]??x.documentKey??"docId",tableName:m?.tableName??w,isGroup:!!x._isGroup,repoCfg:m,repo:x});}let k=new ne;if(s.auth)if(typeof s.auth=="function")k.use(s.auth);else {let w=s.auth.realm??"Sync Admin",x="Basic "+Buffer.from(`${s.auth.username}:${s.auth.password}`).toString("base64");k.use((m,y,f)=>{if((m.headers?.authorization??"")!==x){y.status(401).set("WWW-Authenticate",`Basic realm="${w}"`).set("Content-Type","text/plain").send("Unauthorized");return}f();});}return k.get(`${c}/`,(w,x)=>{let m=be(w,c),y=h.map(p=>{let l=[];return g.healthCheck&&l.push(`<a class="btn" href="${m}/${p.name}/health">Health</a>`),g.manualSync&&l.push(`<a class="btn btn-primary" href="${m}/${p.name}/force-sync">Force Sync</a>`),`<tr>
32
+ <td><strong>${p.name}</strong></td>
33
+ <td>${p.tableName}</td>
34
+ <td>${p.isGroup?'<span class="badge badge-warn">group</span>':'<span class="badge badge-ok">collection</span>'}</td>
35
+ <td>${p.schema?"\u2713":"\u2717"}</td>
36
+ <td>${l.join(" ")}</td>
37
37
  </tr>`}).join(`
38
- `),i=g.viewQueue?`<p><a class="btn" href="${m}/queues">View Queues</a></p>`:"",d=g.configCheck?`<p style="margin-top:.5rem"><a class="btn" href="${m}/config-check">\u2699 Config Check</a></p>`:"",c=ee("Sync Dashboard",m,`<div class="card">
38
+ `),f=g.viewQueue?`<p><a class="btn" href="${m}/queues">View Queues</a></p>`:"",d=g.configCheck?`<p style="margin-top:.5rem"><a class="btn" href="${m}/config-check">\u2699 Config Check</a></p>`:"",a=re("Sync Dashboard",m,`<div class="card">
39
39
  <table>
40
40
  <thead><tr><th>Repository</th><th>Table</th><th>Type</th><th>Schema</th><th>Actions</th></tr></thead>
41
41
  <tbody>${y}</tbody>
42
42
  </table>
43
- ${i}
43
+ ${f}
44
44
  ${d}
45
- </div>`);te(b,c);}),k.get(`${u}`,(w,b)=>{let m=ye(w,u);b.status(302).set("Location",`${m}/`).send("");}),g.healthCheck&&k.get(`${u}/:repoName/health`,async(w,b)=>{let m=ye(w,u),y=h.find(C=>C.name===w.params.repoName);if(!y){te(b,ee("Not Found",m,`<p>Unknown repo: ${w.params.repoName}</p>`),404);return}if(!y.schema){te(b,ee("Health Check",m,`<p class="badge badge-warn">No Zod schema attached to "${y.name}"</p>`));return}let i=Le(y.schema,t.dialect,{primaryKey:y.documentKey,exclude:y.repoCfg?.exclude,columnMap:y.repoCfg?.columnMap}),d=[],c=false,a=null;try{c=await t.tableExists(y.tableName),c&&(d=await t.getTableColumns(y.tableName));}catch(C){a=C?.message??String(C);}let f=new Set(d),v=new Set(i.map(C=>C.name)),S=i.filter(C=>!f.has(C.name)),O=d.filter(C=>!v.has(C)),A=i.filter(C=>f.has(C.name)),x=c&&S.length===0&&!a;if(Ie(w)){ge(b,{repo:y.name,table:y.tableName,tableExists:c,healthy:x,error:a,columns:{expected:i.map(C=>({name:C.name,type:C.sqlType,nullable:C.nullable,isPrimaryKey:C.isPrimaryKey})),actual:d,matched:A.map(C=>C.name),missing:S.map(C=>({name:C.name,type:C.sqlType})),extra:O}});return}let R=x?'<span class="badge badge-ok">Healthy</span>':'<span class="badge badge-err">Unhealthy</span>',$=i.map(C=>{let B=f.has(C.name)?'<span class="badge badge-ok">OK</span>':'<span class="badge badge-err">MISSING</span>';return `<tr><td>${C.name}</td><td>${C.sqlType}</td><td>${C.nullable?"Yes":"No"}</td><td>${C.isPrimaryKey?"\u2713":""}</td><td>${B}</td></tr>`}).join(`
46
- `),T=O.map(C=>`<tr><td>${C}</td><td colspan="3" class="muted">not in schema</td><td><span class="badge badge-warn">EXTRA</span></td></tr>`).join(`
47
- `),P=ee(`Health: ${y.name}`,m,`<div class="card">
48
- <p>Table: <code>${y.tableName}</code> ${c?R:'<span class="badge badge-err">NOT FOUND</span>'}</p>
49
- ${a?`<p class="badge badge-err">Error: ${a}</p>`:""}
45
+ </div>`);se(x,a);}),k.get(`${c}`,(w,x)=>{let m=be(w,c);x.status(302).set("Location",`${m}/`).send("");}),g.healthCheck&&k.get(`${c}/:repoName/health`,async(w,x)=>{let m=be(w,c),y=h.find(T=>T.name===w.params.repoName);if(!y){se(x,re("Not Found",m,`<p>Unknown repo: ${w.params.repoName}</p>`),404);return}if(!y.schema){se(x,re("Health Check",m,`<p class="badge badge-warn">No Zod schema attached to "${y.name}"</p>`));return}let f=Ge(y.schema,t.dialect,{primaryKey:y.documentKey,exclude:y.repoCfg?.exclude,columnMap:y.repoCfg?.columnMap}),d=[],a=false,p=null;try{a=await t.tableExists(y.tableName),a&&(d=await t.getTableColumns(y.tableName));}catch(T){p=T?.message??String(T);}let l=new Set(d),b=new Set(f.map(T=>T.name)),v=f.filter(T=>!l.has(T.name)),C=d.filter(T=>!b.has(T)),E=f.filter(T=>l.has(T.name)),R=a&&v.length===0&&!p;if(Fe(w)){ve(x,{repo:y.name,table:y.tableName,tableExists:a,healthy:R,error:p,columns:{expected:f.map(T=>({name:T.name,type:T.sqlType,nullable:T.nullable,isPrimaryKey:T.isPrimaryKey})),actual:d,matched:E.map(T=>T.name),missing:v.map(T=>({name:T.name,type:T.sqlType})),extra:C}});return}let S=R?'<span class="badge badge-ok">Healthy</span>':'<span class="badge badge-err">Unhealthy</span>',$=f.map(T=>{let D=l.has(T.name)?'<span class="badge badge-ok">OK</span>':'<span class="badge badge-err">MISSING</span>';return `<tr><td>${T.name}</td><td>${T.sqlType}</td><td>${T.nullable?"Yes":"No"}</td><td>${T.isPrimaryKey?"\u2713":""}</td><td>${D}</td></tr>`}).join(`
46
+ `),O=C.map(T=>`<tr><td>${T}</td><td colspan="3" class="muted">not in schema</td><td><span class="badge badge-warn">EXTRA</span></td></tr>`).join(`
47
+ `),A=re(`Health: ${y.name}`,m,`<div class="card">
48
+ <p>Table: <code>${y.tableName}</code> ${a?S:'<span class="badge badge-err">NOT FOUND</span>'}</p>
49
+ ${p?`<p class="badge badge-err">Error: ${p}</p>`:""}
50
50
  <h2>Columns</h2>
51
51
  <table>
52
52
  <thead><tr><th>Column</th><th>SQL Type</th><th>Nullable</th><th>PK</th><th>Status</th></tr></thead>
53
- <tbody>${$}${T}</tbody>
53
+ <tbody>${$}${O}</tbody>
54
54
  </table>
55
- </div>`);te(b,P);}),g.manualSync&&(k.get(`${u}/:repoName/force-sync`,(w,b)=>{let m=ye(w,u),y=h.find(d=>d.name===w.params.repoName);if(!y){te(b,ee("Not Found",m,`<p>Unknown repo: ${w.params.repoName}</p>`),404);return}let i=ee(`Force Sync: ${y.name}`,m,`<div class="card">
55
+ </div>`);se(x,A);}),g.manualSync&&(k.get(`${c}/:repoName/force-sync`,(w,x)=>{let m=be(w,c),y=h.find(d=>d.name===w.params.repoName);if(!y){se(x,re("Not Found",m,`<p>Unknown repo: ${w.params.repoName}</p>`),404);return}let f=re(`Force Sync: ${y.name}`,m,`<div class="card">
56
56
  <p>This will read <strong>all</strong> documents from the <code>${y.name}</code> Firestore collection
57
57
  and upsert them into the <code>${y.tableName}</code> SQL table.</p>
58
58
  <p class="muted" style="margin:.75rem 0">This may take a while for large collections.</p>
59
59
  <form method="POST" action="${m}/${y.name}/force-sync">
60
60
  <button type="submit" class="btn btn-primary">Start Force Sync</button>
61
61
  </form>
62
- </div>`);te(b,i);}),k.post(`${u}/:repoName/force-sync`,async(w,b)=>{let m=ye(w,u),y=h.find(x=>x.name===w.params.repoName);if(!y){ge(b,{error:`Unknown repo: ${w.params.repoName}`},404);return}let i=y.repo.ref;if(!i){ge(b,{error:`No collection reference for "${y.name}"`},400);return}let d=0,c=0,a=[],f=500,v=i.limit(f),S=null;try{for(;;){let $=await(S?v.startAfter(S):v).get();if($.empty)break;for(let T of $.docs){let P=T.data(),C=String(P[y.documentKey]??T.id),B=Ne(P,{exclude:y.repoCfg?.exclude,columnMap:y.repoCfg?.columnMap});try{await r({operation:"UPSERT",repoName:y.name,docId:C,data:B,timestamp:new Date().toISOString()}),d++;}catch(I){c++;let D=I?.message??String(I);console.error(`[ForceSync:${y.name}] doc=${C} failed:`,I),a.length<5&&a.push(`${C}: ${D}`);}}if(S=$.docs[$.docs.length-1],$.docs.length<f)break}let x=n.get(y.name);x&&await x.flush();}catch(x){if(Ie(w)){ge(b,{error:x?.message??String(x),synced:d,errors:c},500);return}te(b,ee(`Force Sync: ${y.name}`,m,`<div class="card">
63
- <p class="badge badge-err">Error: ${x?.message??String(x)}</p>
64
- <p>Synced ${d} docs before failure (${c} errors).</p>
65
- </div>`),500);return}if(Ie(w)){ge(b,{repo:y.name,table:y.tableName,synced:d,errors:c,...a.length>0&&{errorSamples:a}});return}let O=a.length>0?`<details style="margin-top:1rem"><summary>First ${a.length} error(s)</summary>
66
- <pre style="white-space:pre-wrap">${a.map(x=>x.replace(/[<>&]/g,R=>`&#${R.charCodeAt(0)};`)).join(`
62
+ </div>`);se(x,f);}),k.post(`${c}/:repoName/force-sync`,async(w,x)=>{let m=be(w,c),y=h.find(R=>R.name===w.params.repoName);if(!y){ve(x,{error:`Unknown repo: ${w.params.repoName}`},404);return}let f=y.repo.ref;if(!f){ve(x,{error:`No collection reference for "${y.name}"`},400);return}let d=0,a=0,p=[],l=500,b=f.limit(l),v=null;try{for(;;){let $=await(v?b.startAfter(v):b).get();if($.empty)break;for(let O of $.docs){let A=O.data(),T=String(A[y.documentKey]??O.id),D=je(A,{exclude:y.repoCfg?.exclude,columnMap:y.repoCfg?.columnMap});try{await r({operation:"UPSERT",repoName:y.name,docId:T,data:D,timestamp:new Date().toISOString()}),d++;}catch(Z){a++;let N=Z?.message??String(Z);console.error(`[ForceSync:${y.name}] doc=${T} failed:`,Z),p.length<5&&p.push(`${T}: ${N}`);}}if(v=$.docs[$.docs.length-1],$.docs.length<l)break}let R=n.get(y.name);R&&await R.flush();}catch(R){if(Fe(w)){ve(x,{error:R?.message??String(R),synced:d,errors:a},500);return}se(x,re(`Force Sync: ${y.name}`,m,`<div class="card">
63
+ <p class="badge badge-err">Error: ${R?.message??String(R)}</p>
64
+ <p>Synced ${d} docs before failure (${a} errors).</p>
65
+ </div>`),500);return}if(Fe(w)){ve(x,{repo:y.name,table:y.tableName,synced:d,errors:a,...p.length>0&&{errorSamples:p}});return}let C=p.length>0?`<details style="margin-top:1rem"><summary>First ${p.length} error(s)</summary>
66
+ <pre style="white-space:pre-wrap">${p.map(R=>R.replace(/[<>&]/g,S=>`&#${S.charCodeAt(0)};`)).join(`
67
67
 
68
- `)}</pre></details>`:"",A=ee(`Force Sync: ${y.name}`,m,`<div class="card">
69
- <p class="badge ${c>0?"badge-warn":"badge-ok"}">${c>0?"Completed with errors":"Complete"}</p>
68
+ `)}</pre></details>`:"",E=re(`Force Sync: ${y.name}`,m,`<div class="card">
69
+ <p class="badge ${a>0?"badge-warn":"badge-ok"}">${a>0?"Completed with errors":"Complete"}</p>
70
70
  <p>Synced <strong>${d}</strong> documents to <code>${y.tableName}</code>.</p>
71
- ${c>0?`<p class="badge badge-warn">${c} error(s)</p>`:""}
72
- ${O}
73
- </div>`);te(b,A);})),g.viewQueue&&k.get(`${u}/queues`,(w,b)=>{let m=ye(w,u),y=[];for(let c of h){let a=n.get(c.name);y.push({repo:c.name,table:c.tableName,pending:a?a.size:0});}if(Ie(w)){ge(b,{queues:y});return}let i=y.map(c=>`<tr><td>${c.repo}</td><td>${c.table}</td><td>${c.pending===0?'<span class="badge badge-ok">0</span>':`<span class="badge badge-warn">${c.pending}</span>`}</td></tr>`).join(`
74
- `),d=ee("Sync Queues",m,`<div class="card">
71
+ ${a>0?`<p class="badge badge-warn">${a} error(s)</p>`:""}
72
+ ${C}
73
+ </div>`);se(x,E);})),g.viewQueue&&k.get(`${c}/queues`,(w,x)=>{let m=be(w,c),y=[];for(let a of h){let p=n.get(a.name);y.push({repo:a.name,table:a.tableName,pending:p?p.size:0});}if(Fe(w)){ve(x,{queues:y});return}let f=y.map(a=>`<tr><td>${a.repo}</td><td>${a.table}</td><td>${a.pending===0?'<span class="badge badge-ok">0</span>':`<span class="badge badge-warn">${a.pending}</span>`}</td></tr>`).join(`
74
+ `),d=re("Sync Queues",m,`<div class="card">
75
75
  <table>
76
76
  <thead><tr><th>Repository</th><th>Table</th><th>Pending</th></tr></thead>
77
- <tbody>${i}</tbody>
77
+ <tbody>${f}</tbody>
78
78
  </table>
79
- </div>`);te(b,d);}),g.configCheck&&k.get(`${u}/config-check`,async(w,b)=>{let m=ye(w,u),y=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??process.env.GCP_PROJECT??"unknown",i="https://console.cloud.google.com",d=p??"firestore-sync",c=[];try{await t.tableExists("__nonexistent_health_check__"),c.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable"});}catch(x){let R=x?.message??String(x),$=R.toLowerCase(),T=$.includes("disabled")||$.includes("has not been used")||$.includes("accessnotconfigured"),P=$.includes("permission")||R.includes("403")||$.includes("access denied"),C=$.includes("project")&&$.includes("not found"),B=$.includes("not found")||R.includes("404");T?c.push({name:"BigQuery API",category:"bigquery",status:"error",message:"BigQuery API is not enabled",fix:{gcloud:`gcloud services enable bigquery.googleapis.com --project=${y}`,console:`${i}/apis/library/bigquery.googleapis.com?project=${y}`}}):C?c.push({name:"BigQuery Project",category:"bigquery",status:"error",message:R,fix:{hint:"The GCP project does not exist or the credentials don't have access to it. In the Firebase emulator, GCLOUD_PROJECT may override the configured projectId. Ensure you pass the correct projectId to the BigQuery constructor and have valid credentials.",console:`${i}/home/dashboard`}}):P?c.push({name:"BigQuery API",category:"bigquery",status:"error",message:`Permission denied: ${R}`,fix:{hint:"Grant the service account BigQuery Data Editor + BigQuery Job User roles",gcloud:[`SA=$(gcloud run services describe YOUR_SERVICE --region=YOUR_REGION --format="value(spec.template.spec.serviceAccountName)" --project=${y})`,`gcloud projects add-iam-policy-binding ${y} --member="serviceAccount:$SA" --role="roles/bigquery.dataEditor"`,`gcloud projects add-iam-policy-binding ${y} --member="serviceAccount:$SA" --role="roles/bigquery.jobUser"`].join(`
80
- `),console:`${i}/iam-admin/iam?project=${y}`}}):B?c.push({name:"BigQuery Dataset",category:"bigquery",status:"error",message:`Dataset not found: ${R}`,fix:{hint:"Create the dataset first",gcloud:`bq mk --dataset ${y}:YOUR_DATASET_ID`,console:`${i}/bigquery?project=${y}`}}):c.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable (table lookup returned expected error)"});}for(let x of h)try{let R=await t.tableExists(x.tableName);c.push({name:`Table: ${x.tableName}`,category:"bigquery",status:R?"ok":"warn",message:R?`Table \`${x.tableName}\` exists`:`Table \`${x.tableName}\` does not exist yet`,...!R&&{fix:{hint:"Table will be auto-created on first sync if autoMigrate is enabled. Or create it manually."}}});}catch(R){c.push({name:`Table: ${x.tableName}`,category:"bigquery",status:"error",message:R?.message??String(R)});}if(l)for(let x of h){let R=`${d}-${x.name}`;try{let $=l.topic(R);if(typeof $.exists=="function"){let[T]=await $.exists();c.push({name:`Topic: ${R}`,category:"pubsub",status:T?"ok":"error",message:T?`Topic \`${R}\` exists`:`Topic \`${R}\` does not exist`,...!T&&{fix:{gcloud:`gcloud pubsub topics create ${R} --project=${y}`,console:`${i}/cloudpubsub/topic/list?project=${y}`}}});}else c.push({name:`Topic: ${R}`,category:"pubsub",status:"warn",message:"Cannot verify topic existence (PubSub client doesn't expose .exists())",fix:{gcloud:`gcloud pubsub topics create ${R} --project=${y}`,console:`${i}/cloudpubsub/topic/list?project=${y}`,hint:"Ensure the topic exists. It is auto-created by the Firebase emulator but must exist in production."}});}catch($){let T=$?.message??String($),P=T.includes("disabled")||T.includes("has not been used");if(c.push({name:P?"Pub/Sub API":`Topic: ${R}`,category:"pubsub",status:"error",message:P?"Pub/Sub API is not enabled":T,fix:P?{gcloud:`gcloud services enable pubsub.googleapis.com --project=${y}`,console:`${i}/apis/library/pubsub.googleapis.com?project=${y}`}:{gcloud:`gcloud pubsub topics create ${R} --project=${y}`,console:`${i}/cloudpubsub/topic/list?project=${y}`}}),P)break}}else c.push({name:"Pub/Sub Client",category:"pubsub",status:"warn",message:"PubSub client not available for config check"});if(Ie(w)){let x=c.every(R=>R.status==="ok");ge(b,{project:y,healthy:x,checks:c});return}let a=x=>x==="ok"?'<span class="badge badge-ok">OK</span>':x==="warn"?'<span class="badge badge-warn">WARN</span>':'<span class="badge badge-err">ERROR</span>',f={bigquery:c.filter(x=>x.category==="bigquery"),pubsub:c.filter(x=>x.category==="pubsub"),firestore:c.filter(x=>x.category==="firestore")},v=(x,R)=>{if(R.length===0)return "";let $=R.map(T=>{let P="";if(T.fix){let C=[];T.fix.hint&&C.push(`<p class="muted">${T.fix.hint}</p>`),T.fix.gcloud&&C.push(`<pre>$ ${T.fix.gcloud}</pre>`),T.fix.console&&C.push(`<p><a href="${T.fix.console}" target="_blank">Open GCP Console \u2192</a></p>`),P=`<div style="margin-top:.5rem">${C.join("")}</div>`;}return `<tr>
81
- <td>${a(T.status)}</td>
82
- <td><strong>${T.name}</strong><br><span class="muted">${T.message}</span>${P}</td>
79
+ </div>`);se(x,d);}),g.configCheck&&k.get(`${c}/config-check`,async(w,x)=>{let m=be(w,c),y=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??process.env.GCP_PROJECT??"unknown",f="https://console.cloud.google.com",d=u??"firestore-sync",a=[];try{await t.tableExists("__nonexistent_health_check__"),a.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable"});}catch(R){let S=R?.message??String(R),$=S.toLowerCase(),O=$.includes("disabled")||$.includes("has not been used")||$.includes("accessnotconfigured"),A=$.includes("permission")||S.includes("403")||$.includes("access denied"),T=$.includes("project")&&$.includes("not found"),D=$.includes("not found")||S.includes("404");O?a.push({name:"BigQuery API",category:"bigquery",status:"error",message:"BigQuery API is not enabled",fix:{gcloud:`gcloud services enable bigquery.googleapis.com --project=${y}`,console:`${f}/apis/library/bigquery.googleapis.com?project=${y}`}}):T?a.push({name:"BigQuery Project",category:"bigquery",status:"error",message:S,fix:{hint:"The GCP project does not exist or the credentials don't have access to it. In the Firebase emulator, GCLOUD_PROJECT may override the configured projectId. Ensure you pass the correct projectId to the BigQuery constructor and have valid credentials.",console:`${f}/home/dashboard`}}):A?a.push({name:"BigQuery API",category:"bigquery",status:"error",message:`Permission denied: ${S}`,fix:{hint:"Grant the service account BigQuery Data Editor + BigQuery Job User roles",gcloud:[`SA=$(gcloud run services describe YOUR_SERVICE --region=YOUR_REGION --format="value(spec.template.spec.serviceAccountName)" --project=${y})`,`gcloud projects add-iam-policy-binding ${y} --member="serviceAccount:$SA" --role="roles/bigquery.dataEditor"`,`gcloud projects add-iam-policy-binding ${y} --member="serviceAccount:$SA" --role="roles/bigquery.jobUser"`].join(`
80
+ `),console:`${f}/iam-admin/iam?project=${y}`}}):D?a.push({name:"BigQuery Dataset",category:"bigquery",status:"error",message:`Dataset not found: ${S}`,fix:{hint:"Create the dataset first",gcloud:`bq mk --dataset ${y}:YOUR_DATASET_ID`,console:`${f}/bigquery?project=${y}`}}):a.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable (table lookup returned expected error)"});}for(let R of h)try{let S=await t.tableExists(R.tableName);a.push({name:`Table: ${R.tableName}`,category:"bigquery",status:S?"ok":"warn",message:S?`Table \`${R.tableName}\` exists`:`Table \`${R.tableName}\` does not exist yet`,...!S&&{fix:{hint:"Table will be auto-created on first sync if autoMigrate is enabled. Or create it manually."}}});}catch(S){a.push({name:`Table: ${R.tableName}`,category:"bigquery",status:"error",message:S?.message??String(S)});}if(i)for(let R of h){let S=`${d}-${R.name}`;try{let $=i.topic(S);if(typeof $.exists=="function"){let[O]=await $.exists();a.push({name:`Topic: ${S}`,category:"pubsub",status:O?"ok":"error",message:O?`Topic \`${S}\` exists`:`Topic \`${S}\` does not exist`,...!O&&{fix:{gcloud:`gcloud pubsub topics create ${S} --project=${y}`,console:`${f}/cloudpubsub/topic/list?project=${y}`}}});}else a.push({name:`Topic: ${S}`,category:"pubsub",status:"warn",message:"Cannot verify topic existence (PubSub client doesn't expose .exists())",fix:{gcloud:`gcloud pubsub topics create ${S} --project=${y}`,console:`${f}/cloudpubsub/topic/list?project=${y}`,hint:"Ensure the topic exists. It is auto-created by the Firebase emulator but must exist in production."}});}catch($){let O=$?.message??String($),A=O.includes("disabled")||O.includes("has not been used");if(a.push({name:A?"Pub/Sub API":`Topic: ${S}`,category:"pubsub",status:"error",message:A?"Pub/Sub API is not enabled":O,fix:A?{gcloud:`gcloud services enable pubsub.googleapis.com --project=${y}`,console:`${f}/apis/library/pubsub.googleapis.com?project=${y}`}:{gcloud:`gcloud pubsub topics create ${S} --project=${y}`,console:`${f}/cloudpubsub/topic/list?project=${y}`}}),A)break}}else a.push({name:"Pub/Sub Client",category:"pubsub",status:"warn",message:"PubSub client not available for config check"});if(Fe(w)){let R=a.every(S=>S.status==="ok");ve(x,{project:y,healthy:R,checks:a});return}let p=R=>R==="ok"?'<span class="badge badge-ok">OK</span>':R==="warn"?'<span class="badge badge-warn">WARN</span>':'<span class="badge badge-err">ERROR</span>',l={bigquery:a.filter(R=>R.category==="bigquery"),pubsub:a.filter(R=>R.category==="pubsub"),firestore:a.filter(R=>R.category==="firestore")},b=(R,S)=>{if(S.length===0)return "";let $=S.map(O=>{let A="";if(O.fix){let T=[];O.fix.hint&&T.push(`<p class="muted">${O.fix.hint}</p>`),O.fix.gcloud&&T.push(`<pre>$ ${O.fix.gcloud}</pre>`),O.fix.console&&T.push(`<p><a href="${O.fix.console}" target="_blank">Open GCP Console \u2192</a></p>`),A=`<div style="margin-top:.5rem">${T.join("")}</div>`;}return `<tr>
81
+ <td>${p(O.status)}</td>
82
+ <td><strong>${O.name}</strong><br><span class="muted">${O.message}</span>${A}</td>
83
83
  </tr>`}).join(`
84
- `);return `<h2>${x}</h2>
84
+ `);return `<h2>${R}</h2>
85
85
  <table><thead><tr><th style="width:80px">Status</th><th>Check</th></tr></thead>
86
- <tbody>${$}</tbody></table>`},O=c.every(x=>x.status==="ok")?'<span class="badge badge-ok">All checks passed</span>':'<span class="badge badge-warn">Some issues found</span>',A=ee("Config Check",m,`<div class="card">
87
- <p>Project: <code>${y}</code> ${O}</p>
88
- ${v("BigQuery",f.bigquery)}
89
- ${v("Pub/Sub",f.pubsub)}
90
- ${v("Firestore",f.firestore)}
91
- </div>`);te(b,A);}),async(w,b)=>{await k.handle(w,b);}}var zn="firestore-sync";function Zn(e,t){let n=t.ref?.path??void 0;return n?`${n}/{docId}`:(console.warn(`[SyncTriggers] Cannot determine collection path for "${e}". Skipping.`),null)}function _t(e,t){let{onDocumentCreated:n,onDocumentUpdated:r,onDocumentDeleted:s}=t.deps.firestoreTriggers,o=t.deps.pubsub,l=t?.topicPrefix??zn,p={},u=new Map;function g(k){let w=u.get(k);return w||(w=o.topic(k),u.set(k,w),w)}async function h(k,w){await g(k).publishMessage({json:w});}for(let[k,w]of Object.entries(e)){let b=t?.repos?.[k],m;if(w._isGroup){if(!b?.triggerPath){console.warn(`[SyncTriggers] Skipping collection-group repo "${k}". Provide a triggerPath in the sync repos config for group collections.`);continue}m=b.triggerPath;}else m=b?.triggerPath??Zn(k,w);if(!m)continue;let y=w._systemKeys?.[0]??"docId",i=`${l}-${k}`;p[`${k}_onCreate`]=n(m,async d=>{let c=d.data;if(!c)return;let a=c.data();if(!a)return;let f=String(a[y]??c.id),v=Ne(a,{exclude:b?.exclude,columnMap:b?.columnMap}),S={operation:"INSERT",repoName:k,docId:f,data:v,timestamp:new Date().toISOString(),version:Date.now()};await h(i,S);}),p[`${k}_onUpdate`]=r(m,async d=>{let c=d.data?.after;if(!c)return;let a=c.data();if(!a)return;let f=String(a[y]??c.id),v=Ne(a,{exclude:b?.exclude,columnMap:b?.columnMap}),S={operation:"UPSERT",repoName:k,docId:f,data:v,timestamp:new Date().toISOString(),version:Date.now()};await h(i,S);}),p[`${k}_onDelete`]=s(m,async d=>{let c=d.data;if(!c)return;let a=c.data(),f=String(a?.[y]??c.id),v={operation:"DELETE",repoName:k,docId:f,data:null,timestamp:new Date().toISOString(),version:Date.now()};await h(i,v);});}return p}var He=class{constructor(t){this.buffer=[];this.flushing=false;this.timer=null;this.adapter=t.adapter,this.tableName=t.tableName,this.primaryKey=t.primaryKey,this.batchSize=t.batchSize??100,this.onFlushError=t.onFlushError;let n=t.flushIntervalMs??5e3;n>0&&(this.timer=setInterval(()=>{this.flush();},n),typeof this.timer=="object"&&"unref"in this.timer&&this.timer.unref());}get size(){return this.buffer.length}enqueue(...t){this.buffer.push(...t),this.buffer.length>=this.batchSize&&this.flush();}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=true;let t=this.buffer.splice(0,this.batchSize);try{let n=new Map,r=[];for(let o of t)if(o.operation==="DELETE")r.push(o.docId),n.delete(o.docId);else if(o.data){let l=n.get(o.docId);if(!l)n.set(o.docId,o.data);else {let p=Number(l[ae]??0);Number(o.data[ae]??0)>=p&&n.set(o.docId,o.data);}}let s=Array.from(n.values());s.length>0&&await this.adapter.upsertRows(this.tableName,s,this.primaryKey),r.length>0&&await this.adapter.deleteRows(this.tableName,this.primaryKey,r);}catch(n){this.onFlushError?await this.onFlushError(t,n).catch(r=>{console.error(`[SyncQueue] Flush error for ${this.tableName}:`,n),console.error("[SyncQueue] Error handler also failed:",r);}):(this.buffer.unshift(...t),console.error(`[SyncQueue] Flush failed for ${this.tableName}:`,n));}finally{this.flushing=false;}}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.flush();}};var Dt=new Set;async function Fn(e,t,n,r,s,o,l){if(Dt.has(e))return;let p=Le(n,t.dialect,{primaryKey:s,exclude:o,columnMap:l});if(!await t.tableExists(r))await t.createTable({tableName:r,columns:p});else {let g=new Set(await t.getTableColumns(r)),h=p.filter(k=>!g.has(k.name));h.length>0&&await t.addColumns(r,h);}Dt.add(e);}function jt(e,t){let{deps:n,adapter:r,batchSize:s=100,flushIntervalMs:o=5e3,autoMigrate:l=false,topicPrefix:p="firestore-sync",workerOptions:u,repos:g={}}=t,h=new Map;function k(m,y){let i=h.get(m);if(i)return i;let c=g[m]?.tableName??m,a=async(f,v)=>{console.error(`[SyncWorker] Flush failed for "${m}" (${f.length} events):`,v);try{let S=`${p}-${m}-dlq`,O=n.pubsub.topic(S),[A]=await O.exists();A||(await O.create(),console.info(`[SyncWorker] Created DLQ topic "${S}"`));for(let x of f)await O.publishMessage({json:x});}catch(S){console.error(`[SyncWorker] Dead-letter publish also failed for ${m}:`,S);}};return i=new He({adapter:r,tableName:c,primaryKey:y,batchSize:s,flushIntervalMs:o,onFlushError:a}),h.set(m,i),i}async function w(m){let{repoName:y}=m,i=e[y];if(!i){console.warn(`[SyncWorker] Unknown repo "${y}", skipping event`);return}let d=i._systemKeys?.[0]??i.documentKey??"docId",c=g[y],a=c?.columnMap,f=a?.[d]??d;if(l){let S=i.schema??void 0;if(S){let O=c?.tableName??y;await Fn(y,r,S,O,d,c?.exclude,a);}}let v=k(y,f);m.data&&(m.data[ae]=m.version??Date.now()),v.enqueue(m);}function b(m){let y=async i=>{let d=i.data?.message?.json??i.data?.json;if(!d){console.warn("[SyncWorker] Received empty PubSub message");return}await w(d);let c=h.get(d.repoName);c&&await c.flush();};return u?n.pubsubHandler.onMessagePublished({topic:m,...u},y):n.pubsubHandler.onMessagePublished(m,y)}return {handleMessage:w,createHandler:b,queues:h,async shutdown(){let m=[];for(let y of h.values())m.push(y.shutdown());await Promise.all(m);}}}var qn="firestore-sync";function zt(e){if(typeof e!="function")return e;let t=e,n;return new Proxy({},{get(r,s){return n||(n=t()),n[s]},has(r,s){return n||(n=t()),s in n}})}function Zt(e,t){let{deps:n,adapter:r,topicPrefix:s=qn,batchSize:o,flushIntervalMs:l,autoMigrate:p,admin:u,workerOptions:g,repos:h}=t,k=zt(n.pubsub),w=zt(r),b=_t(e,{deps:{firestoreTriggers:n.firestoreTriggers,pubsub:k},topicPrefix:s,repos:h}),m=jt(e,{deps:{pubsubHandler:n.pubsubHandler,pubsub:k},adapter:w,batchSize:o,flushIntervalMs:l,autoMigrate:p,topicPrefix:s,workerOptions:g,repos:h}),y={};for(let c of Object.keys(e))y[`sync_${c}`]=m.createHandler(`${s}-${c}`);let i=null;u&&(i=It(e,w,m.queues,m.handleMessage,u,h??{},k,s),y.adminsync=u.onRequest?u.httpsOptions?u.onRequest(u.httpsOptions,i):u.onRequest(i):i);let d={functions:{...b,...y},adminHandler:i,handleMessage:m.handleMessage,queues:m.queues,shutdown:m.shutdown};for(let c of ["adminHandler","handleMessage","queues","shutdown"])Object.defineProperty(d,c,{enumerable:false});return d}Pe();Pe();function Bn(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function Ft(e){let t=e,n=true,r=false,s;for(;;){let o=q(t);if(o==="ZodOptional")n=false,t=U(t);else if(o==="ZodNullable")n=false,r=true,t=U(t);else if(o==="ZodDefault")n=false,s=Tt(t),t=U(t);else break}return {inner:t,required:n,nullable:r,defaultValue:s}}function ne(e,t=""){if(q(e)==="ZodObject"){let r=Q(e);return Object.entries(r).map(([s,o])=>qt(t?`${t}.${s}`:s,s,o))}return [qt(t||"value",t||"value",e)]}function qt(e,t,n){let{inner:r,required:s,nullable:o,defaultValue:l}=Ft(n),p=q(r),u=Bn(t.split(".").pop()??t);switch(p){case "ZodString":{let g=At(r),h=g.includes("email"),k=g.includes("url");return {name:e,label:u,type:"text",required:s,nullable:o,defaultValue:l,hint:h?"email":k?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:u,type:"number",required:s,nullable:o,defaultValue:l};case "ZodBoolean":return {name:e,label:u,type:"checkbox",required:s,nullable:o,defaultValue:l};case "ZodDate":case "ZodCoerce":return {name:e,label:u,type:"datetime-local",required:s,nullable:o,defaultValue:l};case "ZodEnum":{let g=Ae(r);return {name:e,label:u,type:"select",required:s,nullable:o,defaultValue:l,options:g}}case "ZodNativeEnum":{let g=Ee(r),h=Object.values(g).filter(k=>typeof k=="string");return {name:e,label:u,type:"select",required:s,nullable:o,defaultValue:l,options:h}}case "ZodLiteral":{let g=String(Ue(r)??"");return {name:e,label:u,type:"select",required:s,nullable:o,defaultValue:l,options:[g]}}case "ZodObject":{let g=ne(r,e);return {name:e,label:u,type:"textarea",required:s,nullable:o,defaultValue:l,nested:g,hint:"JSON object"}}case "ZodArray":{let g=Ot(r);if(!g)return {name:e,label:u,type:"textarea",required:s,nullable:o,defaultValue:l,hint:"JSON array"};let{inner:h}=Ft(g),k=q(h),w,b,m;switch(k){case "ZodString":w="text";break;case "ZodNumber":case "ZodBigInt":w="number";break;case "ZodBoolean":w="checkbox";break;case "ZodDate":w="datetime-local";break;case "ZodEnum":w="select",b=Ae(h);break;case "ZodNativeEnum":w="select",b=Object.values(Ee(h)).filter(y=>typeof y=="string");break;case "ZodObject":w="object",m=ne(h);break;default:return {name:e,label:u,type:"textarea",required:s,nullable:o,defaultValue:l,hint:"JSON array"}}return {name:e,label:u,type:"textarea",required:s,nullable:o,defaultValue:l,arrayElementType:w,arrayElementOptions:b,arrayElementFields:m}}default:return {name:e,label:u,type:"textarea",required:s,nullable:o,defaultValue:l,hint:"JSON"}}}function We(e,t=0){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,s=e.name,o=e.required?" required":"",l=e.defaultValue==="__null__",p=!l&&e.defaultValue!=null?String(e.defaultValue):"",u=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
92
- <input type="hidden" id="${r}__isnull" name="${s}__isnull" value="${l?"1":""}">
86
+ <tbody>${$}</tbody></table>`},C=a.every(R=>R.status==="ok")?'<span class="badge badge-ok">All checks passed</span>':'<span class="badge badge-warn">Some issues found</span>',E=re("Config Check",m,`<div class="card">
87
+ <p>Project: <code>${y}</code> ${C}</p>
88
+ ${b("BigQuery",l.bigquery)}
89
+ ${b("Pub/Sub",l.pubsub)}
90
+ ${b("Firestore",l.firestore)}
91
+ </div>`);se(x,E);}),async(w,x)=>{await k.handle(w,x);}}var Xn="firestore-sync";function Yn(e,t){let n=t.ref?.path??void 0;return n?`${n}/{docId}`:(console.warn(`[SyncTriggers] Cannot determine collection path for "${e}". Skipping.`),null)}function Kt(e,t){let{onDocumentCreated:n,onDocumentUpdated:r,onDocumentDeleted:s}=t.deps.firestoreTriggers,o=t.deps.pubsub,i=t?.topicPrefix??Xn,u={},c=new Map;function g(k){let w=c.get(k);return w||(w=o.topic(k),c.set(k,w),w)}async function h(k,w){await g(k).publishMessage({json:w});}for(let[k,w]of Object.entries(e)){let x=t?.repos?.[k],m;if(w._isGroup){if(!x?.triggerPath){console.warn(`[SyncTriggers] Skipping collection-group repo "${k}". Provide a triggerPath in the sync repos config for group collections.`);continue}m=x.triggerPath;}else m=x?.triggerPath??Yn(k,w);if(!m)continue;let y=w._systemKeys?.[0]??"docId",f=`${i}-${k}`;u[`${k}_onCreate`]=n(m,async d=>{let a=d.data;if(!a)return;let p=a.data();if(!p)return;let l=String(p[y]??a.id),b=je(p,{exclude:x?.exclude,columnMap:x?.columnMap}),v={operation:"INSERT",repoName:k,docId:l,data:b,timestamp:new Date().toISOString(),version:Date.now()};await h(f,v);}),u[`${k}_onUpdate`]=r(m,async d=>{let a=d.data?.after;if(!a)return;let p=a.data();if(!p)return;let l=String(p[y]??a.id),b=je(p,{exclude:x?.exclude,columnMap:x?.columnMap}),v={operation:"UPSERT",repoName:k,docId:l,data:b,timestamp:new Date().toISOString(),version:Date.now()};await h(f,v);}),u[`${k}_onDelete`]=s(m,async d=>{let a=d.data;if(!a)return;let p=a.data(),l=String(p?.[y]??a.id),b={operation:"DELETE",repoName:k,docId:l,data:null,timestamp:new Date().toISOString(),version:Date.now()};await h(f,b);});}return u}var Je=class{constructor(t){this.buffer=[];this.flushing=false;this.timer=null;this.adapter=t.adapter,this.tableName=t.tableName,this.primaryKey=t.primaryKey,this.batchSize=t.batchSize??100,this.onFlushError=t.onFlushError;let n=t.flushIntervalMs??5e3;n>0&&(this.timer=setInterval(()=>{this.flush();},n),typeof this.timer=="object"&&"unref"in this.timer&&this.timer.unref());}get size(){return this.buffer.length}enqueue(...t){this.buffer.push(...t),this.buffer.length>=this.batchSize&&this.flush();}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=true;let t=this.buffer.splice(0,this.batchSize);try{let n=new Map,r=[];for(let o of t)if(o.operation==="DELETE")r.push(o.docId),n.delete(o.docId);else if(o.data){let i=n.get(o.docId);if(!i)n.set(o.docId,o.data);else {let u=Number(i[de]??0);Number(o.data[de]??0)>=u&&n.set(o.docId,o.data);}}let s=Array.from(n.values());s.length>0&&await this.adapter.upsertRows(this.tableName,s,this.primaryKey),r.length>0&&await this.adapter.deleteRows(this.tableName,this.primaryKey,r);}catch(n){this.onFlushError?await this.onFlushError(t,n).catch(r=>{console.error(`[SyncQueue] Flush error for ${this.tableName}:`,n),console.error("[SyncQueue] Error handler also failed:",r);}):(this.buffer.unshift(...t),console.error(`[SyncQueue] Flush failed for ${this.tableName}:`,n));}finally{this.flushing=false;}}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.flush();}};var Vt=new Set;async function er(e,t,n,r,s,o,i){if(Vt.has(e))return;let u=Ge(n,t.dialect,{primaryKey:s,exclude:o,columnMap:i});if(!await t.tableExists(r))await t.createTable({tableName:r,columns:u});else {let g=new Set(await t.getTableColumns(r)),h=u.filter(k=>!g.has(k.name));h.length>0&&await t.addColumns(r,h);}Vt.add(e);}function Gt(e,t){let{deps:n,adapter:r,batchSize:s=100,flushIntervalMs:o=5e3,autoMigrate:i=false,topicPrefix:u="firestore-sync",workerOptions:c,repos:g={}}=t,h=new Map;function k(m,y){let f=h.get(m);if(f)return f;let a=g[m]?.tableName??m,p=async(l,b)=>{console.error(`[SyncWorker] Flush failed for "${m}" (${l.length} events):`,b);try{let v=`${u}-${m}-dlq`,C=n.pubsub.topic(v),[E]=await C.exists();E||(await C.create(),console.info(`[SyncWorker] Created DLQ topic "${v}"`));for(let R of l)await C.publishMessage({json:R});}catch(v){console.error(`[SyncWorker] Dead-letter publish also failed for ${m}:`,v);}};return f=new Je({adapter:r,tableName:a,primaryKey:y,batchSize:s,flushIntervalMs:o,onFlushError:p}),h.set(m,f),f}async function w(m){let{repoName:y}=m,f=e[y];if(!f){console.warn(`[SyncWorker] Unknown repo "${y}", skipping event`);return}let d=f._systemKeys?.[0]??f.documentKey??"docId",a=g[y],p=a?.columnMap,l=p?.[d]??d;if(i){let v=f.schema??void 0;if(v){let C=a?.tableName??y;await er(y,r,v,C,d,a?.exclude,p);}}let b=k(y,l);m.data&&(m.data[de]=m.version??Date.now()),b.enqueue(m);}function x(m){let y=async f=>{let d=f.data?.message?.json??f.data?.json;if(!d){console.warn("[SyncWorker] Received empty PubSub message");return}await w(d);let a=h.get(d.repoName);a&&await a.flush();};return c?n.pubsubHandler.onMessagePublished({topic:m,...c},y):n.pubsubHandler.onMessagePublished(m,y)}return {handleMessage:w,createHandler:x,queues:h,async shutdown(){let m=[];for(let y of h.values())m.push(y.shutdown());await Promise.all(m);}}}var tr="firestore-sync";function Jt(e){if(typeof e!="function")return e;let t=e,n;return new Proxy({},{get(r,s){return n||(n=t()),n[s]},has(r,s){return n||(n=t()),s in n}})}function Wt(e,t){let{deps:n,adapter:r,topicPrefix:s=tr,batchSize:o,flushIntervalMs:i,autoMigrate:u,admin:c,workerOptions:g,repos:h}=t,k=Jt(n.pubsub),w=Jt(r),x=Kt(e,{deps:{firestoreTriggers:n.firestoreTriggers,pubsub:k},topicPrefix:s,repos:h}),m=Gt(e,{deps:{pubsubHandler:n.pubsubHandler,pubsub:k},adapter:w,batchSize:o,flushIntervalMs:i,autoMigrate:u,topicPrefix:s,workerOptions:g,repos:h}),y={};for(let a of Object.keys(e))y[`sync_${a}`]=m.createHandler(`${s}-${a}`);let f=null;c&&(f=Lt(e,w,m.queues,m.handleMessage,c,h??{},k,s),y.adminsync=c.onRequest?c.httpsOptions?c.onRequest(c.httpsOptions,f):c.onRequest(f):f);let d={functions:{...x,...y},adminHandler:f,handleMessage:m.handleMessage,queues:m.queues,shutdown:m.shutdown};for(let a of ["adminHandler","handleMessage","queues","shutdown"])Object.defineProperty(d,a,{enumerable:false});return d}De();De();function nr(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function Qt(e){let t=e,n=true,r=false,s;for(;;){let o=q(t);if(o==="ZodOptional")n=false,t=L(t);else if(o==="ZodNullable")n=false,r=true,t=L(t);else if(o==="ZodDefault")n=false,s=Bt(t),t=L(t);else break}return {inner:t,required:n,nullable:r,defaultValue:s}}function oe(e,t=""){if(q(e)==="ZodObject"){let r=Y(e);return Object.entries(r).map(([s,o])=>Xt(t?`${t}.${s}`:s,s,o))}return [Xt(t||"value",t||"value",e)]}function Xt(e,t,n){let{inner:r,required:s,nullable:o,defaultValue:i}=Qt(n),u=q(r),c=nr(t.split(".").pop()??t);switch(u){case "ZodString":{let g=Mt(r),h=g.includes("email"),k=g.includes("url");return {name:e,label:c,type:"text",required:s,nullable:o,defaultValue:i,hint:h?"email":k?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:c,type:"number",required:s,nullable:o,defaultValue:i};case "ZodBoolean":return {name:e,label:c,type:"checkbox",required:s,nullable:o,defaultValue:i};case "ZodDate":case "ZodCoerce":return {name:e,label:c,type:"datetime-local",required:s,nullable:o,defaultValue:i};case "ZodEnum":{let g=Ne(r);return {name:e,label:c,type:"select",required:s,nullable:o,defaultValue:i,options:g}}case "ZodNativeEnum":{let g=_e(r),h=Object.values(g).filter(k=>typeof k=="string");return {name:e,label:c,type:"select",required:s,nullable:o,defaultValue:i,options:h}}case "ZodLiteral":{let g=String(Ve(r)??"");return {name:e,label:c,type:"select",required:s,nullable:o,defaultValue:i,options:[g]}}case "ZodObject":{let g=oe(r,e);return {name:e,label:c,type:"textarea",required:s,nullable:o,defaultValue:i,nested:g,hint:"JSON object"}}case "ZodArray":{let g=Zt(r);if(!g)return {name:e,label:c,type:"textarea",required:s,nullable:o,defaultValue:i,hint:"JSON array"};let{inner:h}=Qt(g),k=q(h),w,x,m;switch(k){case "ZodString":w="text";break;case "ZodNumber":case "ZodBigInt":w="number";break;case "ZodBoolean":w="checkbox";break;case "ZodDate":w="datetime-local";break;case "ZodEnum":w="select",x=Ne(h);break;case "ZodNativeEnum":w="select",x=Object.values(_e(h)).filter(y=>typeof y=="string");break;case "ZodObject":w="object",m=oe(h);break;default:return {name:e,label:c,type:"textarea",required:s,nullable:o,defaultValue:i,hint:"JSON array"}}return {name:e,label:c,type:"textarea",required:s,nullable:o,defaultValue:i,arrayElementType:w,arrayElementOptions:x,arrayElementFields:m}}default:return {name:e,label:c,type:"textarea",required:s,nullable:o,defaultValue:i,hint:"JSON"}}}function rt(e,t=0){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,s=e.name,o=e.required?" required":"",i=e.defaultValue==="__null__",u=!i&&e.defaultValue!=null?String(e.defaultValue):"",c=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
92
+ <input type="hidden" id="${r}__isnull" name="${s}__isnull" value="${i?"1":""}">
93
93
  <label class="flex items-center gap-1 cursor-pointer select-none text-xs text-base-content/40 hover:text-base-content/70 border border-base-300 rounded px-2 py-1">
94
- <input type="checkbox" class="checkbox checkbox-xs" ${l?"checked":""}
94
+ <input type="checkbox" class="checkbox checkbox-xs" ${i?"checked":""}
95
95
  onchange="(function(cb){
96
96
  var inp = document.getElementById('${r}');
97
97
  var h = document.getElementById('${r}__isnull');
@@ -100,11 +100,11 @@ ${n}
100
100
  })(this)">
101
101
  <span>null</span>
102
102
  </label>
103
- </span>`:"",g;switch(e.type){case "checkbox":if(e.nullable){let h=l?"__null__":p==="true"?"true":p==="false"?"false":"__null__";return `
103
+ </span>`:"",g;switch(e.type){case "checkbox":if(e.nullable){let h=i?"__null__":u==="true"?"true":u==="false"?"false":"__null__";return `
104
104
  <div class="form-control mb-3 ${n}">
105
105
  <label for="${r}" class="label pb-1">
106
106
  <span class="label-text font-medium">
107
- ${N(e.label)}
107
+ ${_(e.label)}
108
108
  <span class="text-base-content/40 text-xs ml-1">(nullable)</span>
109
109
  </span>
110
110
  </label>
@@ -116,43 +116,43 @@ ${n}
116
116
  </div>`}return `
117
117
  <div class="form-control ${n}">
118
118
  <label class="label cursor-pointer justify-start gap-3">
119
- <input type="checkbox" id="${r}" name="${s}" value="true"${p==="true"?" checked":""} class="checkbox checkbox-primary checkbox-sm">
119
+ <input type="checkbox" id="${r}" name="${s}" value="true"${u==="true"?" checked":""} class="checkbox checkbox-primary checkbox-sm">
120
120
  <span class="label-text font-medium">
121
- ${N(e.label)}${e.required?' <span class="text-error">*</span>':""}
121
+ ${_(e.label)}${e.required?' <span class="text-error">*</span>':""}
122
122
  </span>
123
123
  </label>
124
- </div>`;case "select":g=`<select id="${r}" name="${s}"${o}${l?' disabled style="opacity:0.35"':""} class="select select-bordered select-sm w-full">
124
+ </div>`;case "select":g=`<select id="${r}" name="${s}"${o}${i?' disabled style="opacity:0.35"':""} class="select select-bordered select-sm w-full">
125
125
  ${e.required&&!e.nullable?"":'<option value="">\u2014 optional \u2014</option>'}
126
- ${(e.options??[]).map(h=>`<option value="${N(h)}"${p===h?" selected":""}>${N(h)}</option>`).join(`
126
+ ${(e.options??[]).map(h=>`<option value="${_(h)}"${u===h?" selected":""}>${_(h)}</option>`).join(`
127
127
  `)}
128
- </select>`;break;case "textarea":if(e.arrayElementType)return Mn(e,t);if(e.nested&&e.nested.length>0){let h=e.nested.map(k=>We(k,t+1)).join(`
128
+ </select>`;break;case "textarea":if(e.arrayElementType)return rr(e,t);if(e.nested&&e.nested.length>0){let h=e.nested.map(k=>rt(k,t+1)).join(`
129
129
  `);return `
130
130
  <fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}">
131
131
  <legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
132
- ${N(e.label)}${e.required?' <span class="text-error">*</span>':""}
132
+ ${_(e.label)}${e.required?' <span class="text-error">*</span>':""}
133
133
  </legend>
134
134
  ${h}
135
- </fieldset>`}g=`<textarea id="${r}" name="${s}"${o} rows="3"${l?' disabled style="opacity:0.35"':""}
135
+ </fieldset>`}g=`<textarea id="${r}" name="${s}"${o} rows="3"${i?' disabled style="opacity:0.35"':""}
136
136
  data-json
137
137
  class="textarea textarea-bordered textarea-sm w-full font-mono text-xs"
138
- placeholder="${N(e.hint??"JSON")}">${N(p)}</textarea>`;break;default:g=`<input type="${e.type}" id="${r}" name="${s}"${o}${l?' disabled style="opacity:0.35"':""}
139
- value="${N(p)}"
138
+ placeholder="${_(e.hint??"JSON")}">${_(u)}</textarea>`;break;default:g=`<input type="${e.type}" id="${r}" name="${s}"${o}${i?' disabled style="opacity:0.35"':""}
139
+ value="${_(u)}"
140
140
  class="input input-bordered input-sm w-full"${e.hint==="email"?' autocomplete="email"':e.hint==="url"?' autocomplete="url"':""}>`;}return `
141
141
  <div class="form-control mb-3 ${n}">
142
142
  <label for="${r}" class="label pb-1">
143
143
  <span class="label-text font-medium">
144
- ${N(e.label)}${e.required?' <span class="text-error">*</span>':""}
145
- ${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${N(e.hint)})</span>`:""}
144
+ ${_(e.label)}${e.required?' <span class="text-error">*</span>':""}
145
+ ${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${_(e.hint)})</span>`:""}
146
146
  </span>
147
147
  </label>
148
148
  <div class="flex items-center gap-2">
149
149
  <div class="flex-1 min-w-0">${g}</div>
150
- ${u}
150
+ ${c}
151
151
  </div>
152
- </div>`}function N(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Mn(e,t){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,s=e.defaultValue==="__null__",o=e.arrayElementType==="object",l=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{l=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(l)||(l=[]);let p=o?l.map(h=>Mt(e,h??{})).join(`
153
- `):l.map(h=>Bt(e,h)).join(`
154
- `),u=o?Mt(e,{}):Bt(e,""),g=e.nullable?`<span class="flex items-center gap-1 mt-2">
155
- <input type="hidden" id="${r}__isnull" name="${N(e.name)}__isnull" value="${s?"1":""}">
152
+ </div>`}function _(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function rr(e,t){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,s=e.defaultValue==="__null__",o=e.arrayElementType==="object",i=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{i=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(i)||(i=[]);let u=o?i.map(h=>en(e,h??{})).join(`
153
+ `):i.map(h=>Yt(e,h)).join(`
154
+ `),c=o?en(e,{}):Yt(e,""),g=e.nullable?`<span class="flex items-center gap-1 mt-2">
155
+ <input type="hidden" id="${r}__isnull" name="${_(e.name)}__isnull" value="${s?"1":""}">
156
156
  <label class="flex items-center gap-1 cursor-pointer select-none text-xs text-base-content/40 hover:text-base-content/70 border border-base-300 rounded px-2 py-1">
157
157
  <input type="checkbox" class="checkbox checkbox-xs" ${s?"checked":""}
158
158
  onchange="(function(cb){
@@ -166,64 +166,64 @@ ${n}
166
166
  </label>
167
167
  </span>`:"";return `
168
168
  <fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}"
169
- data-frs-array="${N(e.name)}" data-frs-array-type="${N(e.arrayElementType??"text")}">
169
+ data-frs-array="${_(e.name)}" data-frs-array-type="${_(e.arrayElementType??"text")}">
170
170
  <legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
171
- ${N(e.label)}${e.required?' <span class="text-error">*</span>':""}
171
+ ${_(e.label)}${e.required?' <span class="text-error">*</span>':""}
172
172
  </legend>
173
- <input type="hidden" id="${r}" name="${N(e.name)}" value="${N(JSON.stringify(l))}"${s?" disabled":""}>
173
+ <input type="hidden" id="${r}" name="${_(e.name)}" value="${_(JSON.stringify(i))}"${s?" disabled":""}>
174
174
  <div data-frs-array-items${s?' style="opacity:0.35"':""}>
175
- ${p}
175
+ ${u}
176
176
  </div>
177
- <template data-frs-array-tpl>${u}</template>
177
+ <template data-frs-array-tpl>${c}</template>
178
178
  <button type="button" class="btn btn-xs btn-outline mt-1" data-frs-array-add>+ Add</button>
179
179
  ${g}
180
- </fieldset>`}function Bt(e,t){let n=t!=null?String(t):"",r;switch(e.arrayElementType){case "select":r=`<select data-frs-val class="select select-bordered select-sm flex-1">
180
+ </fieldset>`}function Yt(e,t){let n=t!=null?String(t):"",r;switch(e.arrayElementType){case "select":r=`<select data-frs-val class="select select-bordered select-sm flex-1">
181
181
  <option value="">\u2014</option>
182
- ${(e.arrayElementOptions??[]).map(s=>`<option value="${N(s)}"${n===s?" selected":""}>${N(s)}</option>`).join("")}
182
+ ${(e.arrayElementOptions??[]).map(s=>`<option value="${_(s)}"${n===s?" selected":""}>${_(s)}</option>`).join("")}
183
183
  </select>`;break;case "checkbox":r=`<label class="flex items-center gap-2 flex-1 cursor-pointer">
184
184
  <input type="checkbox" data-frs-val class="checkbox checkbox-sm checkbox-primary"${n==="true"?" checked":""}>
185
185
  <span class="text-sm">true</span>
186
- </label>`;break;case "number":r=`<input type="number" data-frs-val value="${N(n)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":r=`<input type="datetime-local" data-frs-val value="${N(n)}" class="input input-bordered input-sm flex-1">`;break;default:r=`<input type="text" data-frs-val value="${N(n)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
186
+ </label>`;break;case "number":r=`<input type="number" data-frs-val value="${_(n)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":r=`<input type="datetime-local" data-frs-val value="${_(n)}" class="input input-bordered input-sm flex-1">`;break;default:r=`<input type="text" data-frs-val value="${_(n)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
187
187
  ${r}
188
188
  <button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>&times;</button>
189
- </div>`}function Mt(e,t){return `<div class="border border-base-200 rounded p-3 mb-2" data-frs-array-item>
189
+ </div>`}function en(e,t){return `<div class="border border-base-200 rounded p-3 mb-2" data-frs-array-item>
190
190
  <div class="flex justify-end mb-1">
191
191
  <button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>&times;</button>
192
192
  </div>
193
- ${(e.arrayElementFields??[]).map(s=>{let o=t[s.name],l=o==null?"":typeof o=="object"?JSON.stringify(o):String(o);switch(s.type){case "checkbox":return `<div class="form-control mb-2">
193
+ ${(e.arrayElementFields??[]).map(s=>{let o=t[s.name],i=o==null?"":typeof o=="object"?JSON.stringify(o):String(o);switch(s.type){case "checkbox":return `<div class="form-control mb-2">
194
194
  <label class="label cursor-pointer justify-start gap-3">
195
- <input type="checkbox" data-frs-key="${N(s.name)}" class="checkbox checkbox-sm checkbox-primary"${l==="true"?" checked":""}>
196
- <span class="label-text text-sm">${N(s.label)}</span>
195
+ <input type="checkbox" data-frs-key="${_(s.name)}" class="checkbox checkbox-sm checkbox-primary"${i==="true"?" checked":""}>
196
+ <span class="label-text text-sm">${_(s.label)}</span>
197
197
  </label>
198
198
  </div>`;case "select":return `<div class="form-control mb-2">
199
- <label class="label pb-1"><span class="label-text text-sm">${N(s.label)}</span></label>
200
- <select data-frs-key="${N(s.name)}" class="select select-bordered select-sm w-full">
199
+ <label class="label pb-1"><span class="label-text text-sm">${_(s.label)}</span></label>
200
+ <select data-frs-key="${_(s.name)}" class="select select-bordered select-sm w-full">
201
201
  ${s.required?"":'<option value="">\u2014</option>'}
202
- ${(s.options??[]).map(p=>`<option value="${N(p)}"${l===p?" selected":""}>${N(p)}</option>`).join("")}
202
+ ${(s.options??[]).map(u=>`<option value="${_(u)}"${i===u?" selected":""}>${_(u)}</option>`).join("")}
203
203
  </select>
204
204
  </div>`;case "number":return `<div class="form-control mb-2">
205
- <label class="label pb-1"><span class="label-text text-sm">${N(s.label)}</span></label>
206
- <input type="number" data-frs-key="${N(s.name)}" value="${N(l)}" class="input input-bordered input-sm w-full">
205
+ <label class="label pb-1"><span class="label-text text-sm">${_(s.label)}</span></label>
206
+ <input type="number" data-frs-key="${_(s.name)}" value="${_(i)}" class="input input-bordered input-sm w-full">
207
207
  </div>`;case "datetime-local":return `<div class="form-control mb-2">
208
- <label class="label pb-1"><span class="label-text text-sm">${N(s.label)}</span></label>
209
- <input type="datetime-local" data-frs-key="${N(s.name)}" value="${N(l)}" class="input input-bordered input-sm w-full">
208
+ <label class="label pb-1"><span class="label-text text-sm">${_(s.label)}</span></label>
209
+ <input type="datetime-local" data-frs-key="${_(s.name)}" value="${_(i)}" class="input input-bordered input-sm w-full">
210
210
  </div>`;case "textarea":return `<div class="form-control mb-2">
211
- <label class="label pb-1"><span class="label-text text-sm">${N(s.label)}</span></label>
212
- <textarea data-frs-key="${N(s.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${N(l)}</textarea>
211
+ <label class="label pb-1"><span class="label-text text-sm">${_(s.label)}</span></label>
212
+ <textarea data-frs-key="${_(s.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${_(i)}</textarea>
213
213
  </div>`;default:return `<div class="form-control mb-2">
214
- <label class="label pb-1"><span class="label-text text-sm">${N(s.label)}</span></label>
215
- <input type="text" data-frs-key="${N(s.name)}" value="${N(l)}" class="input input-bordered input-sm w-full">
214
+ <label class="label pb-1"><span class="label-text text-sm">${_(s.label)}</span></label>
215
+ <input type="text" data-frs-key="${_(s.name)}" value="${_(i)}" class="input input-bordered input-sm w-full">
216
216
  </div>`}}).join(`
217
217
  `)}
218
- </div>`}function ie(e,t,n,r="Save"){let s=e.map(o=>We(o)).join(`
218
+ </div>`}function ue(e,t,n,r="Save"){let s=e.map(o=>rt(o)).join(`
219
219
  `);return `
220
- <form action="${N(t)}" method="${n}" novalidate data-frs-form>
220
+ <form action="${_(t)}" method="${n}" novalidate data-frs-form>
221
221
  ${s}
222
222
  <div class="flex gap-2 mt-4 pt-4 border-t border-base-200">
223
- <button type="submit" class="btn btn-primary btn-sm">${N(r)}</button>
223
+ <button type="submit" class="btn btn-primary btn-sm">${_(r)}</button>
224
224
  <button type="button" class="btn btn-ghost btn-sm" onclick="history.back()">Cancel</button>
225
225
  </div>
226
- </form>`}Ke();var Lt=`// \u2500\u2500 Shared helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
226
+ </form>`}We();var nn=`// \u2500\u2500 Shared helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
227
227
  function frsGetBasePath() {
228
228
  var root = document.querySelector("[data-frs-panel-root]");
229
229
  var bp = root && root.getAttribute("data-frs-base-path");
@@ -1132,7 +1132,7 @@ function initColumnReorder(table) {
1132
1132
  });
1133
1133
  });
1134
1134
  }
1135
- `;function _e(){return jsxRuntime.jsx("script",{dangerouslySetInnerHTML:{__html:Lt}})}tt();function le(e){return "<!DOCTYPE html>"+server.renderToString(e)}var Yn=["corporate","silk","dark"],er=()=>jsxRuntime.jsxs("div",{class:"dropdown dropdown-end","data-frs-theme-switcher":true,children:[jsxRuntime.jsxs("button",{type:"button",tabIndex:0,class:"btn btn-sm btn-ghost text-neutral-content gap-1.5","aria-label":"Switch theme",children:[jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",class:"size-4",children:[jsxRuntime.jsx("circle",{cx:"12",cy:"12",r:"4"}),jsxRuntime.jsx("path",{d:"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"})]}),jsxRuntime.jsx("span",{class:"text-xs hidden sm:inline","data-frs-theme-current":true,children:"Theme"})]}),jsxRuntime.jsx("ul",{tabIndex:0,class:"dropdown-content menu menu-sm bg-base-100 text-base-content rounded-box z-50 mt-2 w-40 p-1 shadow-lg border border-base-300",children:Yn.map(e=>jsxRuntime.jsx("li",{children:jsxRuntime.jsxs("button",{type:"button","data-frs-theme":e,class:"capitalize justify-between",children:[jsxRuntime.jsx("span",{children:e}),jsxRuntime.jsx("span",{class:"hidden text-primary","data-frs-theme-check":e,children:"\u2713"})]})},e))})]}),ce=({opts:e,children:t})=>{let{title:n,breadcrumb:r,flash:s,basePath:o="/"}=e;return jsxRuntime.jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxRuntime.jsxs("head",{children:[jsxRuntime.jsx("meta",{charset:"UTF-8"}),jsxRuntime.jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxRuntime.jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsxRuntime.jsx("script",{dangerouslySetInnerHTML:{__html:"(function(){try{var t=localStorage.getItem('frs-admin-theme');if(t){document.documentElement.setAttribute('data-theme',t);}}catch(_){}})();"}}),jsxRuntime.jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsxRuntime.jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsxRuntime.jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxRuntime.jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsxRuntime.jsxs("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:[jsxRuntime.jsx("div",{class:"flex-1",children:jsxRuntime.jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})}),jsxRuntime.jsx("div",{class:"flex-none",children:jsxRuntime.jsx(er,{})})]}),jsxRuntime.jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[r&&r.length>0&&jsxRuntime.jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsxRuntime.jsx("ul",{children:r.map((l,p)=>l.href?jsxRuntime.jsx("li",{children:jsxRuntime.jsx("a",{href:l.href,children:l.label})},p):jsxRuntime.jsx("li",{class:"text-base-content/60",children:l.label},p))})}),jsxRuntime.jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),s&&jsxRuntime.jsxs("div",{role:"alert",class:`alert ${s.type==="success"?"alert-success":s.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsxRuntime.jsx("span",{class:"flex-1",children:s.message}),s.action&&jsxRuntime.jsx("a",{href:s.action.href,...s.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:s.action.label})]}),t]}),jsxRuntime.jsx(et,{basePath:o}),jsxRuntime.jsx(_e,{})]})]})};function nt(e,t){return le(jsxRuntime.jsx(ce,{opts:t,children:jsxRuntime.jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function rt(e,t){return le(jsxRuntime.jsx(ce,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxRuntime.jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsxRuntime.jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsxRuntime.jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsxRuntime.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=>jsxRuntime.jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxRuntime.jsxs("div",{class:"card-body p-5",children:[jsxRuntime.jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsxRuntime.jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var Gt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],tr=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"<",label:"<"},{value:"<=",label:"\u2264"},{value:">",label:">"},{value:">=",label:"\u2265"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],nr=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function rr(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return tr;case "ZodBoolean":return Gt;case "ZodArray":return nr;default:return Gt}}var de="__null__";function sr(e){return `(function(cb){var i=document.getElementById('${e}');if(!i)return;if(cb.checked){i.dataset._prev=i.value;if(i.tagName==='SELECT'){var o=i.querySelector('option[value="${de}"]');if(!o){o=document.createElement('option');o.value='${de}';o.textContent='\u2205 null';o.dataset._auto='1';i.appendChild(o);}o.selected=true;}else{if(i.type==='number'||i.type==='datetime-local'){i.dataset._type=i.type;i.type='text';}i.value='${de}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${de}"][data-_auto="1"]');if(o2)o2.remove();var prev=i.dataset._prev||'';for(var k=0;k<i.options.length;k++)i.options[k].selected=(i.options[k].value===prev);}else{if(i.dataset._type){i.type=i.dataset._type;delete i.dataset._type;}i.readOnly=false;i.value=(i.dataset._prev&&i.dataset._prev!=='${de}')?i.dataset._prev:'';}}})(this)`}function or(e,t){return `(function(){var h=document.getElementById('${e}');var boxes=document.querySelectorAll('input[data-enum-group="${t}"]');h.value=Array.from(boxes).filter(function(b){return b.checked;}).map(function(b){return b.value;}).join(',');})()`}function je({inputId:e,active:t}){return jsxRuntime.jsxs("label",{class:"flex items-center gap-1 cursor-pointer select-none text-xs text-base-content/60 hover:text-base-content border border-base-300 rounded-md px-1.5 py-1 shrink-0 leading-none h-8",title:"Filter where field IS NULL",children:[jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",checked:t,onchange:sr(e)}),jsxRuntime.jsx("span",{children:"\u2205"})]})}function ar({col:e,active:t}){let n=t?.value??"",r=n===de,s=`fv_input_${e.name.replace(/\./g,"__")}`,o=t?.op,l=o==="in"||o==="not-in";if(e.enumValues&&e.enumValues.length>0){if(l){let p=new Set(n.split(",").map(g=>g.trim()).filter(Boolean)),u=`eg_${e.name.replace(/\./g,"__")}`;return jsxRuntime.jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{type:"hidden",id:s,name:`fv_${e.name}`,value:n}),e.enumValues.map(g=>jsxRuntime.jsxs("label",{class:"flex items-center gap-1 text-xs border border-base-300 rounded px-2 cursor-pointer hover:bg-base-200",children:[jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",value:g,checked:p.has(g),"data-enum-group":u,onchange:or(s,u)}),jsxRuntime.jsx("span",{children:g})]},g))]})}return jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsxs("select",{id:s,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsxRuntime.jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),e.enumValues.map(p=>jsxRuntime.jsx("option",{value:p,selected:n===p,children:p},p)),e.nullable&&jsxRuntime.jsx("option",{value:de,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsxRuntime.jsx(je,{inputId:s,active:r})]})}if(e.zodType==="ZodBoolean")return jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsxs("select",{id:s,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsxRuntime.jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),jsxRuntime.jsx("option",{value:"true",selected:n==="true",children:"true"}),jsxRuntime.jsx("option",{value:"false",selected:n==="false",children:"false"}),e.nullable&&jsxRuntime.jsx("option",{value:de,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsxRuntime.jsx(je,{inputId:s,active:r})]});if(e.zodType==="ZodArray"){let p=t?.op==="array-contains-any";return jsxRuntime.jsx("input",{id:s,type:"text",name:`fv_${e.name}`,value:n,placeholder:p?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:r?"text":"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0,"data-_type":r?"number":void 0}),e.nullable&&jsxRuntime.jsx(je,{inputId:s,active:r})]}):e.zodType==="ZodDate"?jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:r?"text":"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0,"data-_type":r?"datetime-local":void 0}),e.nullable&&jsxRuntime.jsx(je,{inputId:s,active:r})]}):jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0}),e.nullable&&jsxRuntime.jsx(je,{inputId:s,active:r})]})}function st({action:e,columnMeta:t,activeFilters:n,isGroup:r}){let s=Object.fromEntries(n.map(u=>[u.field,u])),o=n.length>0,l=n.length>=2||r&&o,p=t.filter(u=>u.zodType!=="ZodObject"&&u.zodType!=="ZodRecord");return jsxRuntime.jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:o?true:void 0,children:[jsxRuntime.jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",o&&jsxRuntime.jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsxRuntime.jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxRuntime.jsxs("form",{method:"get",action:e,children:[jsxRuntime.jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:p.map(u=>{let g=rr(u.zodType),h=s[u.name],k=h?.op??g[0].value;return jsxRuntime.jsxs("div",{class:"flex flex-col gap-1.5",children:[jsxRuntime.jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:u.name}),jsxRuntime.jsxs("div",{class:"flex gap-1.5",children:[g.length>1?jsxRuntime.jsx("select",{name:`fo_${u.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:g.map(w=>jsxRuntime.jsx("option",{value:w.value,selected:w.value===k,children:w.label},w.value))}):jsxRuntime.jsx("input",{type:"hidden",name:`fo_${u.name}`,value:g[0].value}),jsxRuntime.jsx(ar,{col:u,active:h})]})]},u.name)})}),jsxRuntime.jsxs("div",{class:"flex flex-wrap gap-2 mt-4 pt-3 border-t border-base-200 items-center",children:[jsxRuntime.jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),o&&jsxRuntime.jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),l&&jsxRuntime.jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),r?"Collection group queries require a composite index":"Multiple filters may require a composite index"]})]})]})})]})}function ot(e,t,n,r,s,o){let l=n==="create"?`Create ${e}`:`Edit ${e} / ${r??""}`,p=n==="create"?[{label:"Repositories",href:s},{label:e,href:`${s}/${e}`},{label:"New document"}]:[{label:"Repositories",href:s},{label:e,href:`${s}/${e}`},{label:`Edit ${r??""}`}];return le(jsxRuntime.jsx(ce,{opts:{title:l,breadcrumb:p,basePath:s,flash:o},children:jsxRuntime.jsx("div",{class:"card bg-base-100 border border-base-300",children:jsxRuntime.jsx("div",{class:"card-body p-6",children:jsxRuntime.jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}Ke();Ye();function at(e,t,n){let r=new URLSearchParams;for(let s of e)r.set(`fv_${s.field}`,s.value),r.set(`fo_${s.field}`,s.op);return t&&(r.set("ob",t.field),r.set("od",t.dir)),n&&r.set("ps",String(n)),r}function Jt(e,t,n,r,s){let o=at(e,r,s);return o.set("cursor",t),o.set("dir",n),`?${o.toString()}`}function ir(e,t,n,r){let s=at(n,void 0,r);return t?.field===e?t.dir==="asc"&&(s.set("ob",e),s.set("od","desc")):(s.set("ob",e),s.set("od","asc")),`?${s.toString()}`}function lr(e,t,n){return `?${at(t,n,e).toString()}`}function it(e,t,n,r,s,o,l=[],p=[],u=false,g=[],h,k,w,b,m,y,i){let d=`${r}/${e}`,c=`${d}/create`,a={};if(i)for(let x of n)a[x]=ke($e(i,x));let f=(y??[]).filter(x=>{let R=a[x]??ke($e(i,x));return R==="string"||R==="number"||R==="bigint"||R==="boolean"||R==="enum"||R==="literal"}),v=f.length>0,S=u,O=S||v,A=f.map(x=>{let R=$e(i,x),$=ke(R),T=l.find(P=>P.name===x);return {name:x,type:$,enumValues:T?.enumValues??null,nullable:T?.nullable??false}});return le(jsxRuntime.jsxs(ce,{opts:{title:e,breadcrumb:[{label:"Repositories",href:r},{label:e}],basePath:r,flash:o},children:[l.length>0&&jsxRuntime.jsx(st,{action:d,columnMeta:l,activeFilters:p,isGroup:b}),w&&jsxRuntime.jsxs("div",{role:"alert",class:`alert ${w.type==="index"?"alert-warning":"alert-error"} mb-6 shadow-sm`,children:[jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 shrink-0 stroke-current",fill:"none",viewBox:"0 0 24 24",children:w.type==="index"?jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"}):jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"})}),jsxRuntime.jsxs("div",{class:"flex-1",children:[jsxRuntime.jsx("h3",{class:"font-bold",children:w.type==="index"?"Composite index required":"Query failed"}),jsxRuntime.jsx("div",{class:"text-sm",children:w.message})]}),w.indexUrl&&jsxRuntime.jsx("a",{href:w.indexUrl,target:"_blank",rel:"noopener noreferrer",class:"btn btn-sm btn-outline",children:"Create Index \u2192"})]}),jsxRuntime.jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3","data-frs-toolbar":true,children:[jsxRuntime.jsxs("div",{class:"flex items-center gap-3",children:[jsxRuntime.jsxs("span",{class:"text-sm text-base-content/60",children:[t.length,typeof m=="number"&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[" ","of ",jsxRuntime.jsx("span",{class:"font-semibold text-base-content/80",children:m})]})," ","document",(typeof m=="number"?m:t.length)!==1&&"s"]}),jsxRuntime.jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsxRuntime.jsx("span",{children:"Rows"}),jsxRuntime.jsx("div",{class:"join",children:[10,25,50,100].map(x=>jsxRuntime.jsx("a",{href:lr(x,p,h),class:`join-item btn btn-xs ${k===x?"btn-active btn-primary":"btn-outline"}`,children:x},x))})]})]}),jsxRuntime.jsx("a",{href:c,class:"btn btn-primary btn-sm",children:"+ New"})]}),O&&jsxRuntime.jsxs("div",{class:"hidden mb-3 alert alert-info py-2 px-3","data-frs-bulk-bar":true,"data-frs-repo":e,"data-frs-total":typeof m=="number"?String(m):"","data-frs-page-size":String(k??t.length),"data-frs-allow-delete":S?"1":"0","data-frs-allow-update":v?"1":"0","data-frs-fields":JSON.stringify(A),"data-frs-filters":JSON.stringify(p),children:[jsxRuntime.jsxs("div",{class:"flex-1 text-sm",children:[jsxRuntime.jsx("span",{"data-frs-bulk-summary":true,children:"0 selected"}),typeof m=="number"&&m>t.length&&jsxRuntime.jsxs("button",{type:"button",class:"ml-3 link link-primary text-sm hidden","data-frs-bulk-select-all":true,children:["Select all ",m," matching documents"]}),jsxRuntime.jsxs("span",{class:"hidden ml-3 italic","data-frs-bulk-all-active":true,children:["All ",m??"?"," matching documents are selected."," ",jsxRuntime.jsx("button",{type:"button",class:"link","data-frs-bulk-clear":true,children:"Clear selection"})]})]}),jsxRuntime.jsxs("div",{class:"flex gap-2",children:[v&&jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-outline","data-frs-bulk-action":"update",children:"Update field\u2026"}),S&&jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-error btn-outline","data-frs-bulk-action":"delete",children:"Delete"})]})]}),jsxRuntime.jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxRuntime.jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{class:"bg-base-200/50",children:[O&&jsxRuntime.jsx("th",{class:"w-8",children:jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-page":true,"aria-label":"Select all on this page"})}),[...n].map((x,R)=>{let $=h?.field===x,T=$?h.dir==="asc"?" \u25B2":" \u25BC":"";return jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxRuntime.jsxs("a",{href:ir(x,h,p,k),class:`hover:text-base-content inline-flex items-center gap-0.5${$?" text-primary font-bold":""}`,children:[x,T]})},R)}),g.map((x,R)=>jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:x.column},`rel-${R}`)),jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsxRuntime.jsx("tbody",{children:t.length===0?jsxRuntime.jsx("tr",{children:jsxRuntime.jsx("td",{colspan:n.length+g.length+1+(O?1:0),class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((x,R)=>{let $=String(x.docId??x.id??""),T=`${r}/${e}/${encodeURIComponent($)}/edit`,P=`${r}/${e}/${encodeURIComponent($)}/delete`;return jsxRuntime.jsxs("tr",{class:"hover","data-frs-row-id":$,children:[O&&jsxRuntime.jsx("td",{class:"align-middle py-2",children:jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-row":true,value:$,"aria-label":`Select ${$}`})}),n.map((C,B)=>{let I=x[C],D=a[C],se=D?De(D,I):null;return jsxRuntime.jsx("td",{class:"align-top py-2",children:jsxRuntime.jsx(Se,{val:I,mismatch:se})},B)}),g.map((C,B)=>{let I=x[C.key];if(I==null||I==="")return jsxRuntime.jsx("td",{class:"py-2"},`rel-${B}`);let D=C.type==="one"?`${r}/${C.targetRepo}/${encodeURIComponent(String(I))}/edit`:`${r}/${C.targetRepo}?fv_${C.targetKey}=${encodeURIComponent(String(I))}`;return jsxRuntime.jsx("td",{class:"align-middle py-2",children:jsxRuntime.jsx("a",{href:D,class:"btn btn-xs btn-ghost btn-outline","data-frs-relation":true,"data-frs-rel-type":C.type,"data-frs-rel-repo":C.targetRepo,"data-frs-rel-fk":C.targetKey,"data-frs-rel-val":String(I),"data-frs-rel-label":C.column,children:C.column})},`rel-${B}`)}),jsxRuntime.jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxRuntime.jsxs("div",{class:"flex gap-1 justify-end",children:[jsxRuntime.jsx("a",{href:T,class:"btn btn-xs btn-outline",children:"Edit"}),u&&jsxRuntime.jsx("form",{method:"post",action:P,onsubmit:"return confirm('Delete this document?')",children:jsxRuntime.jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},R)})})]})}),(s.hasPrev||s.hasNext)&&jsxRuntime.jsxs("div",{class:"flex flex-col items-center mt-6 gap-2",children:[jsxRuntime.jsxs("div",{class:"flex justify-center items-center gap-2",children:[s.hasPrev?jsxRuntime.jsx("a",{href:Jt(p,s.prevCursor,"prev",h,k),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsxRuntime.jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),s.hasNext?jsxRuntime.jsx("a",{href:Jt(p,s.nextCursor,"next",h,k),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsxRuntime.jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]}),typeof m=="number"&&jsxRuntime.jsxs("div",{class:"text-xs text-base-content/50",children:[m," total document",m!==1?"s":"",p.length>0?" matching filters":""]})]}),O&&v&&jsxRuntime.jsxs("dialog",{id:"frs-bulk-update-modal",class:"modal",children:[jsxRuntime.jsxs("div",{class:"modal-box",children:[jsxRuntime.jsx("h3",{class:"font-bold text-lg mb-3",children:"Bulk update field"}),jsxRuntime.jsx("p",{class:"text-sm text-base-content/60 mb-4","data-frs-bulk-update-summary":true,children:"Update one field on the selected documents."}),jsxRuntime.jsxs("form",{method:"dialog","data-frs-bulk-update-form":true,children:[jsxRuntime.jsxs("label",{class:"form-control w-full mb-3",children:[jsxRuntime.jsx("div",{class:"label",children:jsxRuntime.jsx("span",{class:"label-text text-xs uppercase tracking-wide",children:"Field"})}),jsxRuntime.jsxs("select",{class:"select select-bordered select-sm w-full",name:"field",required:true,"data-frs-bulk-field-select":true,children:[jsxRuntime.jsx("option",{value:"",children:"\u2014 Select a field \u2014"}),f.map(x=>jsxRuntime.jsx("option",{value:x,children:x},x))]})]}),jsxRuntime.jsx("div",{class:"mb-4","data-frs-bulk-value-container":true}),jsxRuntime.jsxs("div",{class:"modal-action",children:[jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-ghost","data-frs-bulk-update-cancel":true,children:"Cancel"}),jsxRuntime.jsx("button",{type:"submit",class:"btn btn-sm btn-primary","data-frs-bulk-update-submit":true,children:"Apply"})]})]})]}),jsxRuntime.jsx("form",{method:"dialog",class:"modal-backdrop",children:jsxRuntime.jsx("button",{children:"close"})})]})]}))}var dr="";function Ge(e,t){return nt(e,t)}function lt(e,t){return rt(e,t)}function ct(e,t,n,r,s,o,l,p,u,g,h,k,w,b,m,y,i){return it(e,t,n,r,s,o,l,p,u,g,h,k,w,b,m,y,i)}function ue(e,t,n,r,s,o){return ot(e,t,n,r,s,o)}var ur=new Set(["<","<=",">",">=","!="]),pr=new Set(["array-contains","array-contains-any"]);function dt(e){return e==="desc"?"DESCENDING":"ASCENDING"}function fr(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function mr(e,t,n,r,s){let o=[],l=new Set;for(let u of r)if(u.op==="=="||u.op==="in"||u.op==="not-in"){if(l.has(u.field))continue;l.add(u.field),o.push({fieldPath:u.field,order:"ASCENDING"});}for(let u of r)if(pr.has(u.op)){if(l.has(u.field))continue;l.add(u.field),o.push({fieldPath:u.field,arrayConfig:"CONTAINS"});}for(let u of r)if(ur.has(u.op)){if(l.has(u.field))continue;l.add(u.field);let g=s?.field===u.field?dt(s.dir):"ASCENDING";o.push({fieldPath:u.field,order:g});}if(s&&!l.has(s.field)&&o.push({fieldPath:s.field,order:dt(s.dir)}),o.length===1&&n)return br(e,t,o[0]);let p=s&&o.some(u=>u.fieldPath===s.field)?dt(s.dir):"ASCENDING";return o.push({fieldPath:"__name__",order:p}),yr(e,t,n,o)}function yr(e,t,n,r,s="(default)"){let o=`projects/${e}/databases/${s}/collectionGroups/${t}/indexes/_`,l=[...ft(1,o),...Je(2,n?2:1)];for(let g of r)l.push(...Qt(3,Wt(g)));let p=s==="(default)"?"-default-":s,u=encodeURIComponent(Xt(l));return `https://console.firebase.google.com/project/${e}/firestore/databases/${p}/indexes?create_composite=${u}`}function gr(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function ut(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function pt(e,t){return e<<3|t}function ft(e,t){let n=Array.from(new TextEncoder().encode(t));return [pt(e,2),...ut(n.length),...n]}function Je(e,t){return [pt(e,0),...ut(t)]}function Qt(e,t){return [pt(e,2),...ut(t.length),...t]}function Wt(e){let t=[...ft(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...Je(3,1)):t.push(...Je(2,e.order==="DESCENDING"?2:1)),t}function Xt(e){let t=String.fromCharCode(...e),n;if(typeof Buffer<"u")n=Buffer.from(e).toString("base64");else if(typeof btoa<"u")n=btoa(t);else throw new Error("No base64 encoder available");return n.replace(/=+$/,"")}function br(e,t,n,r="(default)"){let s=`projects/${e}/databases/${r}/collectionGroups/${t}/fields/${n.fieldPath}`,o=[...ft(1,s),...Je(2,2),...Qt(3,Wt(n))],l=r==="(default)"?"-default-":r,p=encodeURIComponent(Xt(o));return `https://console.firebase.google.com/project/${e}/firestore/databases/${l}/indexes/automatic?create_exemption=${p}`}function hr(e){let t=e,n=[t?.firestore?.projectId,t?.firestore?.app?.options?.projectId,t?.firestore?._settings?.projectId,t?.firestore?.databaseId?.projectId,t?._firestore?.projectId];for(let s of n)if(typeof s=="string"&&s.length>0)return s;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function he(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function ze(e,t){let n=e??{},r=he(e),s;if(r&&(s=n.message?gr(n.message):void 0,!s)){let o=hr(t.ref);if(o){let l=fr(t.path);s=mr(o,l,t.isGroup,t.filters,t.sort);}}return {type:r?"index":"error",message:r?"This query requires a composite index that does not exist yet.":n.message??"Query failed",indexUrl:s}}var Yt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function xr(){let e="";for(let t=0;t<20;t++)e+=Yt.charAt(Math.floor(Math.random()*Yt.length));return e}function mt(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let r=n.split("/").filter(Boolean),s=[];for(let o=1;o<r.length;o+=2)s.push(r[o]);return s.length>0?s:void 0}async function Ze(e,t){let n=e.documentKey??"docId",r=`by${n.charAt(0).toUpperCase()}${n.slice(1)}`;if(typeof e.repo.get[r]=="function")try{let o=await e.repo.get[r](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function yt(e,t,n){let r=e.documentKey??"docId",s=ze(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:r,op:"==",value:t}]});return s.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...s.indexUrl?{action:{href:s.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:s.message}}function z(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function gt(e,t){e.status(302).set("Location",t).send("");}function bt(e,t){let n=t.shape,r={};for(let[s,o]of Object.entries(n)){let l=vt(o);if(l==="ZodObject"){if(e[s+"__isnull"]==="1"){r[s]=null;continue}let g={},h=false;for(let[b,m]of Object.entries(e))b.startsWith(`${s}.`)&&(g[b.slice(s.length+1)]=m,h=true);if(h){let b=o;for(;;){let m=q(b);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")b=U(b);else break}r[s]=bt(g,b);continue}let k=e[s],w=Array.isArray(k)?k[k.length-1]:k;if(w)try{r[s]=JSON.parse(w);}catch{r[s]=w;}continue}let p=e[s],u=Array.isArray(p)?p[p.length-1]:p;if(e[s+"__isnull"]==="1"){r[s]=null;continue}if(u===void 0||u===""){l==="ZodBoolean"&&(r[s]=false);continue}switch(l){case "ZodBoolean":u==="__null__"?r[s]=null:r[s]=u==="true"||u==="on"||u==="1";break;case "ZodNumber":case "ZodBigInt":r[s]=Number(u);break;case "ZodDate":r[s]=new Date(u);break;case "ZodArray":try{r[s]=JSON.parse(u);}catch{r[s]=u;}break;default:if(u.startsWith("{")||u.startsWith("["))try{r[s]=JSON.parse(u);break}catch{}r[s]=u;}}return r}function en(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 r=new Date(e);isNaN(r.getTime())||(t=r);}if(!t||isNaN(t.getTime()))return null;let n=r=>String(r).padStart(2,"0");return `${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}function vt(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=U(t);else return n}}function wr(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=U(t);else return t}}function nn(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable")return true;if(n==="ZodDefault"){t=U(t);continue}return false}}function rn(e){let t=wr(e),n=q(t);if(n==="ZodEnum"){let r=Ae(t);return r.length>0?r:void 0}if(n==="ZodNativeEnum"){let r=Ee(t),s=Object.values(r).filter(o=>typeof o=="string");return s.length>0?s:void 0}if(n==="ZodLiteral"){let r=Ue(t);return typeof r=="string"?[r]:void 0}}function sn(e,t,n=""){let r={};for(let s of Object.keys(t.shape)){let o=n?`${n}.${s}`:s,l=e[s];if(l===null){r[o]="__null__";continue}if(l===void 0)continue;let p=t.shape[s];for(;;){let g=q(p);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")p=U(p);else break}let u=q(p);if(u==="ZodObject"&&typeof l=="object"&&l!==null&&!Array.isArray(l)){let g=sn(l,p,o);Object.assign(r,g);}else if(u==="ZodDate"){let g=en(l);g!==null&&(r[o]=g);}else if(typeof l=="object"&&l!==null&&!Array.isArray(l)&&("_seconds"in l||typeof l.toDate=="function")){let g=en(l);r[o]=g??JSON.stringify(l,null,2);}else typeof l=="object"?r[o]=JSON.stringify(l,null,2):r[o]=String(l);}return r}function ht(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?ht(n.nested,t):void 0}))}function Rr(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),r=[];for(let[s,o]of Object.entries(e)){if(!s.startsWith("fv_"))continue;let l=s.slice(3);if(!t.has(l))continue;let p=(o??"").trim();if(!p)continue;let u=e[`fo_${l}`]??"==",g=n.has(u)?u:"==";r.push({field:l,op:g,value:p});}return r}function tn(e){let t="__null__",n=r=>r===t?null:r==="true"?true:r==="false"?false:r!==""&&!isNaN(Number(r))?Number(r):r;return e.map(r=>{if(r.op==="array-contains-any"||r.op==="in"||r.op==="not-in"){let s=r.value.split(",").map(o=>o.trim()).filter(o=>o!==""&&o!==t).map(o=>n(o));return [r.field,r.op,s]}return [r.field,r.op,n(r.value)]})}function on(e,t,n=""){let r=[];for(let s of e){let o=n?`${n}.${s}`:s,l=t.shape[s];if(!l){r.push({name:o,zodType:"ZodString"});continue}let p=vt(l);if(p==="ZodObject"){let u=l;for(;;){let h=q(u);if(h==="ZodOptional"||h==="ZodNullable"||h==="ZodDefault")u=U(u);else break}let g=Q(u);r.push(...on(Object.keys(g),u,o));}else r.push({name:o,zodType:p,nullable:nn(l),enumValues:rn(l)});}return r}function Sr(e,t){let n=t.split("."),r=e;for(let s of n){for(;;){let l=q(r);if(l==="ZodOptional"||l==="ZodNullable"||l==="ZodDefault")r=U(r);else break}let o=Q(r);if(!(s in o))return null;r=o[s];}return r}function ve(e,t){if(!t||t.length===0)return e;let n=[],r=new Map;for(let o of t){let l=o.indexOf(".");if(l===-1)n.push(o);else {let p=o.slice(0,l),u=o.slice(l+1);r.has(p)||r.set(p,[]),r.get(p).push(u);}}let s={};for(let o of n)o in e.shape&&(s[o]=e.shape[o]);for(let[o,l]of r){if(!(o in e.shape))continue;let p=e.shape[o];for(;;){let u=q(p);if(u==="ZodOptional"||u==="ZodNullable"||u==="ZodDefault")p=U(p);else break}if(q(p)!=="ZodObject"){s[o]=e.shape[o];continue}s[o]=ve(p,l);}return zod.z.object(s)}function pe(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",l=process.env.FUNCTION_REGION??"us-central1",p=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${l}/${p}${n}`}let r=process.env.K_SERVICE,s=e.hostname??e.headers?.host??"";return r&&s.includes("cloudfunctions.net")?`/${r.toLowerCase()}${n}`:n}function an(e,t){let n=(i,d)=>{let c=pe(i,t),a=Object.values(e).map(f=>({name:f.name,path:f.path}));z(d,lt(a,c));},r=async(i,d)=>{let c=i.params.repoName;if(!c){z(d,"Bad request",400);return}let a=e[c];if(!a){z(d,"Repository not found",404);return}let f=a.pageSize??25,v=i.query??{},S=v.cursor,O=v.dir==="prev"?"prev":"next",A=v.ob??"",x=v.od==="desc"?"desc":"asc",R=A?{field:A,dir:x}:void 0,$=parseInt(v.ps??""),T=Number.isFinite($)&&$>0?Math.min($,200):f,P=a.listColumns??Object.keys(a.schema.shape),C=a.documentKey??"docId",B=[C,...P.filter(K=>K!==C)],I=a.filterableFields?(()=>{let K=[];for(let oe of a.filterableFields)(oe.includes(".")||P.includes(oe))&&K.push(oe);return K})():P,D=(()=>{let K=[];for(let oe of I)if(oe.includes(".")){let we=Sr(a.schema,oe);K.push({name:oe,zodType:we?vt(we):"ZodString",nullable:we?nn(we):false,enumValues:we?rn(we):void 0});}else K.push(...on([oe],a.schema));return K})(),se=new Set(D.map(K=>K.name)),Te=Rr(v,se),Be=tn(Te),Ct;if(S)try{let K=a.repo.ref;typeof K.doc=="function"&&(Ct=await K.doc(S).get());}catch{}let[me,Sn]=await Promise.all([a.repo.query.paginate({pageSize:T,cursor:Ct,direction:O,...Be.length>0?{where:Be}:{},...R?{orderBy:[{field:R.field,direction:R.dir}]}:{}}).catch(K=>({queryError:ze(K,{ref:a.repo.ref,path:a.path,isGroup:!!a.isGroup,filters:Te,sort:R})})),a.repo.aggregate.count(Be.length>0?{where:Be}:{}).catch(()=>{})]),xe="queryError"in me,kn=xe?[]:me.data,$n=xe?"":me.nextCursor?.id??"",Cn=xe?"":me.prevCursor?.id??"",On=xe?me.queryError:void 0,Tn=pe(i,t);z(d,ct(a.name,kn,B,Tn,{hasPrev:xe?false:me.hasPrevPage,hasNext:xe?false:me.hasNextPage,prevCursor:Cn,nextCursor:$n},void 0,D,Te,a.allowDelete??false,a.relationalMeta,R,T,On,a.isGroup,Sn,a.mutableFields,a.schema));},s=(i,d)=>{let c=i.params.repoName;if(!c){z(d,"Bad request",400);return}let a=e[c];if(!a){z(d,"Repository not found",404);return}let f=pe(i,t),v=ve(a.schema,a.createFields),S=ne(v),O=`${f}/${a.name}/create`,A=ie(S,O,"POST","Create document");z(d,ue(a.name,A,"create",null,f));},o=async(i,d)=>{let c=i.params.repoName;if(!c){z(d,"Bad request",400);return}let a=e[c];if(!a){z(d,"Repository not found",404);return}let f=pe(i,t),v=i.body??{},S=bt(v,a.schema),O=ve(a.schema,a.createFields),A=O.safeParse(S);if(!A.success){let x=ne(O),R=`${f}/${a.name}/create`,$=ie(x,R,"POST","Create document"),T=A.error.issues.map(P=>`${P.path.join(".")}: ${P.message}`).join(", ");z(d,ue(a.name,$,"create",null,f,{type:"error",message:`Validation error: ${T}`}),422);return}try{if(a.isGroup&&a.parentKeys&&a.parentKeys.length>0){let x={...A.data};a.createdKey&&(x[a.createdKey]=new Date);let R=a.parentKeys.filter(C=>!x[C]);if(R.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${R.join(", ")}`);let $=a.parentKeys.map(C=>x[C]),T=a.documentKey??"docId",P=x[T]||xr();await a.repo.set(...$,P,x);}else await a.repo.create(A.data);gt(d,`${f}/${a.name}?flash=created`);}catch(x){let R=ve(a.schema,a.createFields),$=ne(R),T=`${f}/${a.name}/create`,P=ie($,T,"POST","Create document");z(d,ue(a.name,P,"create",null,f,{type:"error",message:`Save error: ${x.message}`}),500);}},l=async(i,d)=>{let c=i.params.repoName,a=i.params.id;if(!c||!a){z(d,"Bad request",400);return}let f=e[c];if(!f){z(d,"Repository not found",404);return}let v=pe(i,t),S=null;try{S=await Ze(f,a);}catch(T){let P=yt(f,a,T),C=he(T)?424:500;z(d,Ge("",{title:`Edit ${f.name} / ${a}`,basePath:v,breadcrumb:[{label:"Repositories",href:v},{label:f.name,href:`${v}/${f.name}`},{label:`Edit ${a}`}],flash:P}),C);return}if(!S){z(d,"Document not found",404);return}let O=sn(S,f.schema),A=ve(f.schema,f.mutableFields),x=ht(ne(A),O),R=`${v}/${f.name}/${encodeURIComponent(a)}/edit`,$=ie(x,R,"POST","Save changes");z(d,ue(f.name,$,"edit",a,v));},p=async(i,d)=>{let c=i.params.repoName,a=i.params.id;if(!c||!a){z(d,"Bad request",400);return}let f=e[c];if(!f){z(d,"Repository not found",404);return}let v=pe(i,t),S=i.body??{},O=bt(S,f.schema),A=ve(f.schema,f.mutableFields),R=A.partial().safeParse(O);if(!R.success){let $=Object.fromEntries(Object.entries(S).map(([I,D])=>[I,Array.isArray(D)?D.join(","):D??""])),T=ht(ne(A),$),P=`${v}/${f.name}/${encodeURIComponent(a)}/edit`,C=ie(T,P,"POST","Save changes"),B=R.error.issues.map(I=>`${I.path.join(".")}: ${I.message}`).join(", ");z(d,ue(f.name,C,"edit",a,v,{type:"error",message:`Validation error: ${B}`}),422);return}try{let $=await Ze(f,a),T=($&&mt($,f.pathKey))??[a];await f.repo.update(...T,R.data),gt(d,`${v}/${f.name}?flash=updated`);}catch($){let T=ve(f.schema,f.mutableFields),P=ne(T),C=`${v}/${f.name}/${encodeURIComponent(a)}/edit`,B=ie(P,C,"POST","Save changes"),I=he($)?yt(f,a,$):{type:"error",message:`Save error: ${$.message}`},D=he($)?424:500;z(d,ue(f.name,B,"edit",a,v,I),D);}},u=async(i,d)=>{let c=i.params.repoName,a=i.params.id;if(!c||!a){z(d,"Bad request",400);return}let f=e[c];if(!f){z(d,"Repository not found",404);return}if(!f.allowDelete){z(d,"Delete is not allowed for this repository",403);return}let v=pe(i,t);try{let S=await Ze(f,a),O=(S&&mt(S,f.pathKey))??[a];await f.repo.delete(...O),gt(d,`${v}/${f.name}?flash=deleted`);}catch(S){let O=he(S)?yt(f,a,S):{type:"error",message:`Delete error: ${S.message}`},A=he(S)?424:500;z(d,Ge("",{title:`Delete ${f.name} / ${a}`,basePath:v,breadcrumb:[{label:"Repositories",href:v},{label:f.name,href:`${v}/${f.name}`},{label:`Delete ${a}`}],flash:O}),A);}},g=async(i,d)=>{let c=i.params.repoName;if(!c){z(d,"Bad request",400);return}let a=e[c];if(!a){z(d,"Repository not found",404);return}let f=pe(i,t),v=i.query,S=v?.type==="many"?"many":"one",O=Math.max(1,Math.min(100,Number(v?.ps??25)||25)),A=a.listColumns??Object.keys(Q(a.schema)),{PanelOne:x,PanelMany:R}=await Promise.resolve().then(()=>(tt(),Kt)),{renderToString:$}=await import('hono/jsx/dom/server');if(S==="one"){let D=String(v?.id??"");if(!D){z(d,"<div class='p-6 text-error'>Missing id parameter.</div>",400);return}try{let se=await Ze(a,D),Te=$(x({doc:se,repoName:a.name,basePath:f,schema:a.schema,columns:A}));z(d,Te);}catch(se){z(d,`<div class='p-6 text-error text-sm'>Error: ${se.message}</div>`,500);}return}let T=String(v?.fk??""),P=String(v?.fv??"");if(!T||!P){z(d,"<div class='p-6 text-error'>Missing fk/fv parameters.</div>",400);return}let C=v?.cursor??"",B=v?.dir==="prev"?"prev":"next",I;if(C)try{let D=a.repo.ref;typeof D.doc=="function"&&(I=await D.doc(C).get());}catch{}try{let D=await a.repo.query.paginate({pageSize:O,cursor:I,direction:B,where:[[T,"==",kr(P)]]}),se=$(R({docs:D.data,repoName:a.name,basePath:f,fk:T,fv:P,columns:A,schema:a.schema,pagination:{hasPrev:D.hasPrevPage,hasNext:D.hasNextPage,prevCursor:D.prevCursor?.id??"",nextCursor:D.nextCursor?.id??"",pageSize:O}}));z(d,se);}catch(D){z(d,`<div class='p-6 text-error text-sm'>Error: ${D.message}</div>`,500);}},h=async(i,d)=>{let c=[];for(let a of d){let f;if(i.isGroup||i.parentKeys?.length){let v=await Ze(i,a);f=v?mt(v,i.pathKey):void 0;}f||(f=[a]);try{let v=i.repo.documentRef(...f);v&&c.push(v);}catch{}}return c},k=async(i,d)=>{let c=tn(d),a=i.documentKey??"docId",f=[],v;for(;;){let S=await i.repo.query.paginate({pageSize:500,cursor:v,direction:"next",...c.length>0?{where:c}:{}});for(let O of S.data){let A=String(O[a]??O.id??"");A&&f.push(A);}if(!S.hasNextPage||!S.nextCursor)break;v=S.nextCursor;}return f},w=async(i,d)=>{let c=i.params.repoName;if(!c){J(d,{error:"Bad request"},400);return}let a=e[c];if(!a){J(d,{error:"Repository not found"},404);return}if(!a.allowDelete){J(d,{error:"Delete is not allowed for this repository"},403);return}let f=i.body??{};try{let v=await m(a,f);if(v.length===0){J(d,{deleted:0});return}let S=await h(a,v);for(let O=0;O<S.length;O+=500)await a.repo.bulk.delete(S.slice(O,O+500));J(d,{deleted:S.length});}catch(v){J(d,{error:v.message},500);}},b=async(i,d)=>{let c=i.params.repoName;if(!c){J(d,{error:"Bad request"},400);return}let a=e[c];if(!a){J(d,{error:"Repository not found"},404);return}let f=i.body??{},v=String(f.field??"");if(!v){J(d,{error:"Missing 'field'"},400);return}if(!a.mutableFields||!a.mutableFields.includes(v)){J(d,{error:`Field '${v}' is not bulk-updatable`},403);return}let S=a.schema.shape?.[v],O=f.value;if(S){let A=S.safeParse(f.value);if(!A.success){J(d,{error:`Invalid value for '${v}': ${A.error.message}`},400);return}O=A.data;}try{let A=await m(a,f);if(A.length===0){J(d,{updated:0});return}let R=(await h(a,A)).map($=>({docRef:$,data:{[v]:O}}));for(let $=0;$<R.length;$+=500)await a.repo.bulk.update(R.slice($,$+500));J(d,{updated:R.length});}catch(A){J(d,{error:A.message},500);}};async function m(i,d){if(d.selectAll){let c=y(d.filters,i);return await k(i,c)}return Array.isArray(d.ids)?d.ids.filter(c=>typeof c=="string"&&!!c):[]}function y(i,d){if(!Array.isArray(i))return [];let c=new Set((d.filterableFields??Object.keys(Q(d.schema))).map(v=>String(v))),a=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),f=[];for(let v of i)v&&typeof v=="object"&&typeof v.field=="string"&&c.has(v.field)&&typeof v.value=="string"&&a.has(String(v.op))&&f.push({field:v.field,op:v.op,value:v.value});return f}return {handleDashboard:n,handleList:r,handleCreateForm:s,handleCreateSubmit:o,handleEditForm:l,handleEditSubmit:p,handleDelete:u,handlePanel:g,handleBulkDelete:w,handleBulkUpdate:b}}function J(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function kr(e){return e==="true"?true:e==="false"?false:e!==""&&!isNaN(Number(e))?Number(e):e}async function $r(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Cr(e){let t={};if(!e)return t;for(let n of e.split("&")){let r=n.indexOf("=");if(r===-1)continue;let s=decodeURIComponent(n.slice(0,r).replace(/\+/g," ")),o=decodeURIComponent(n.slice(r+1).replace(/\+/g," ")),l=t[s];l===void 0?t[s]=o:Array.isArray(l)?l.push(o):t[s]=[l,o];}return t}function ln(e){let{basePath:t="/",repos:n,parseBody:r=true,auth:s,middleware:o=[],httpsOptions:l}=e,p=t==="/"?"":t.replace(/\/$/,""),u={};for(let[w,b]of Object.entries(n)){let m=b.schema??b.repo.schema??null;if(!m)throw new Error(`[createAdminServer] Repository "${w}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let y,i,d;if(b.fieldsConfig){let f=b.fieldsConfig;y=[],i=[],d=[];for(let[v,S]of Object.entries(f))for(let O of S)O==="filterable"?y.push(v):O==="mutable"?i.push(v):O==="create"&&d.push(v);y.length===0&&(y=void 0),i.length===0&&(i=void 0),d.length===0&&(d=void 0);}let c=(()=>{let f=b.repo._parentKeys;return f&&f.length>0?f:void 0})();if(c&&d)for(let f of c)d.includes(f)||d.push(f);let a={name:w,path:b.path,repo:b.repo,schema:m,documentKey:b.documentKey??"docId",pathKey:b.repo._pathKey??void 0,isGroup:!!b.repo._isGroup,parentKeys:c,createdKey:b.repo._createdKey??void 0,listColumns:b.listColumns,pageSize:b.pageSize,filterableFields:y,mutableFields:i,createFields:d,allowDelete:b.allowDelete??false,relationalMeta:(()=>{if(!b.relationalFields||b.relationalFields.length===0)return;let f=b.repo.relationalKeys??{},v=[];for(let S of b.relationalFields){let O=f[S.key];O&&v.push({key:S.key,column:S.column,targetRepo:String(O.repo),targetKey:String(O.key),type:O.type});}return v.length>0?v:void 0})()};u[w]=a;}let g=an(u,p),h=new Y;if(r&&h.use(async(w,b,m)=>{let y=w,i=String(y.headers?.["content-type"]??"");if(i.includes("application/x-www-form-urlencoded")){let d=await $r(y);w.body=Cr(d);}else if(i.includes("application/json")&&typeof y.body=="string")try{w.body=JSON.parse(y.body);}catch{}await m();}),s)if(typeof s=="function")h.use(s);else {let w=s.realm??"Admin",b="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");h.use((m,y,i)=>{if((m.headers?.authorization??"")!==b){y.status(401).set("WWW-Authenticate",`Basic realm="${w}"`).set("Content-Type","text/plain").send("Unauthorized");return}i();});}for(let w of o)h.use(w);h.get(`${p}/`,g.handleDashboard),h.get(`${p}`,g.handleDashboard),h.get(`${p}/:repoName/_panel`,g.handlePanel),h.post(`${p}/:repoName/_bulk/delete`,g.handleBulkDelete),h.post(`${p}/:repoName/_bulk/update`,g.handleBulkUpdate),h.get(`${p}/:repoName`,g.handleList),h.get(`${p}/:repoName/create`,g.handleCreateForm),h.post(`${p}/:repoName/create`,g.handleCreateSubmit),h.get(`${p}/:repoName/:id/edit`,g.handleEditForm),h.post(`${p}/:repoName/:id/edit`,g.handleEditSubmit),h.post(`${p}/:repoName/:id/delete`,g.handleDelete);let k=async(w,b)=>{await h.handle(w,b);};return l&&(k.httpsOptions=l),k}var dn="preserve";function un(){return dn}function Or(e){return typeof e=="object"&&e!==null&&typeof e._seconds=="number"&&typeof e._nanoseconds=="number"}function pn(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(e instanceof firestore.Timestamp)return e.toDate();if(Or(e))return new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));if(typeof e=="string"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}if(typeof e=="number"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}return null}function fn(e){return e}function Rt(e,t,n=200){let r=fn(t);e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(r));}function Ce(e,t,n,r=200){Rt(e,{success:true,data:t,meta:n},r);}function H(e,t,n=400){Rt(e,{success:false,error:t},n);}function wt(e,t,n,r,s){let o=ze(t,n),l=o.type==="index",p=l?424:500,g={success:false,error:l?o.message:s&&t instanceof Error?t.message:r};l&&(g.errorType="index",o.indexUrl&&(g.indexUrl=o.indexUrl)),Rt(e,g,p);}var mn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Ar(){let e="";for(let t=0;t<20;t++)e+=mn.charAt(Math.floor(Math.random()*mn.length));return e}function Oe(e){let t=e._def??e.def;if(!t)return e;let n=t.typeName??t.type;if(n==="ZodDate"||n==="date")return zod.z.preprocess(r=>pn(r)??r,e);if(n==="ZodObject"||n==="object"){let r=e.shape,s={};for(let[o,l]of Object.entries(r))s[o]=Oe(l);return zod.z.object(s)}if(n==="ZodArray"||n==="array"){let r=t.element??t.type;if(r)return zod.z.array(Oe(r))}if(n==="ZodOptional"||n==="optional"){let r=t.innerType;if(r)return Oe(r).optional()}if(n==="ZodNullable"||n==="nullable"){let r=t.innerType;if(r)return Oe(r).nullable()}if(n==="ZodDefault"||n==="default"){let r=t.innerType,s=t.defaultValue;if(r){let o=Oe(r);return typeof s=="function"?o.default(s()):o.default(s)}}return e}function Er(e,t,n=[]){let r=e.shape,s={},o=t&&t.length>0?t:Object.keys(r);for(let l of o){if(n.includes(l))continue;let p=l.split(".")[0];p&&r[p]&&(s[p]=r[p]);}return zod.z.object(s)}function yn(e,t,n,r=false,s=[]){try{let o=Er(e,n,s),l=r?o.partial():o;return {success:!0,data:(un()==="normalize"?Oe(l):l).parse(t)}}catch(o){return o instanceof zod.z.ZodError?{success:false,error:`Validation failed: ${o.issues.map(p=>`${p.path.join(".")}: ${p.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function Pr(e,t){let n=[],r=t?new Set(t):null,s={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[o,l]of Object.entries(e)){if(l===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(o))continue;let p=Array.isArray(l)?l[0]:l;if(p===void 0||p==="")continue;let u=o.match(/^(\w+)__(\w+)$/),g,h="==";if(u&&u[1]&&u[2]){g=u[1];let w=u[2];if(s[w])h=s[w];else continue}else if(!u)g=o;else continue;if(r&&!r.has(g))continue;let k=p;h==="in"||h==="not-in"||h==="array-contains-any"?k=p.split(",").map(w=>gn(w.trim())):k=gn(p),n.push({field:g,op:h,value:k});}return n}function gn(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 Qe(e){return e?{docId:e.id}:null}async function bn(e,t){if(!t||typeof t!="object")return;let n=t.docId;if(typeof n=="string")try{let r=e.repo.ref;if(typeof r.doc!="function")return;let s=await r.doc(n).get();return s.exists?s:void 0}catch{return}}function hn(e,t,n){function r(b,m){return !b||!e[b]?(H(m,`Repository "${b}" not found`,404),null):e[b]}function s(b,m){if(!m)return;let y=b[m];if(typeof y!="string"||!y)return;let i=y.split("/").filter(Boolean),d=[];for(let c=1;c<i.length;c+=2)d.push(i[c]);return d.length>0?d:void 0}async function o(b,m){let y=`by${b.documentKey.charAt(0).toUpperCase()}${b.documentKey.slice(1)}`,i=b.repo.get[y];if(typeof i=="function")try{let c=await i(m);if(c)return c}catch{}return (await b.repo.query.by({where:[[b.documentKey,"==",m]],limit:1}))[0]??null}async function l(b,m){let y=b.params||{},i=r(y.repoName,m);if(!i)return;let d=[],c;try{let a=b.query??{},f=Math.min(Number(a.pageSize)||i.pageSize,100),v=a.cursor,S=a.direction?.toLowerCase()==="prev"?"prev":"next",O=a.orderBy,A=a.orderDir?.toLowerCase()==="desc"?"desc":"asc",x=a.select,R=x?x.split(",").map(I=>I.trim()):void 0,$;i.allowedIncludes&&a.includes&&($=(typeof a.includes=="string"?a.includes.split(",").map(D=>D.trim()):Array.isArray(a.includes)?a.includes:[]).filter(D=>typeof D=="string"&&i.allowedIncludes.includes(D)),$?.length===0&&($=void 0));let T=Pr(a,i.filterableFields);d=T.map(I=>({field:I.field,op:I.op,value:String(I.value??"")})),O&&(c={field:O,dir:A});let P={pageSize:f,direction:S};if(v)try{let I=typeof v=="string"?JSON.parse(v):v;P.cursor=await bn(i,I);}catch{}O&&(P.orderBy=[{field:O,direction:A}]),T.length>0&&(P.where=T.map(I=>[I.field,I.op,I.value])),R&&(P.select=R),$&&(P.include=$);let C=await i.repo.query.paginate(P),B={items:C.data,hasNextPage:C.hasNextPage,hasPrevPage:C.hasPrevPage,nextCursor:Qe(C.nextCursor),prevCursor:Qe(C.prevCursor)};Ce(m,B,{pageSize:f,hasMore:C.hasNextPage});}catch(a){wt(m,a,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:d,sort:c},"Failed to fetch documents",n);}}async function p(b,m){let y=b.params||{},i=r(y.repoName,m);if(!i)return;let d=[],c;try{let a=b.body??{},f=Math.min(a.pageSize||i.pageSize,100),v=a.direction==="prev"?"prev":"next";a.where&&(d=a.where.map(x=>({field:String(x[0]),op:x[1],value:String(x[2]??"")}))),a.orderBy&&a.orderBy[0]&&(c={field:a.orderBy[0].field,dir:a.orderBy[0].direction==="desc"?"desc":"asc"});let S={pageSize:f,direction:v};if(a.cursor)try{let x=typeof a.cursor=="string"?JSON.parse(a.cursor):a.cursor;S.cursor=await bn(i,x);}catch{}if(i.allowedIncludes&&a.includes&&a.includes.length>0){let x=a.includes.filter(R=>typeof R=="string"?i.allowedIncludes.includes(R):typeof R=="object"&&R!==null&&"relation"in R&&typeof R.relation=="string"?i.allowedIncludes.includes(R.relation):!1);x.length>0&&(S.include=x);}if(a.where&&a.where.length>0){if(i.filterableFields){let x=new Set(i.filterableFields),R=a.where.filter($=>!x.has($[0]));if(R.length>0){H(m,`Fields not filterable: ${R.map($=>$[0]).join(", ")}`,400);return}}S.where=a.where;}if(a.orWhere&&a.orWhere.length>0){if(i.filterableFields){let x=new Set(i.filterableFields),R=a.orWhere.filter($=>!x.has($[0]));if(R.length>0){H(m,`Fields not filterable: ${R.map($=>$[0]).join(", ")}`,400);return}}S.orWhere=a.orWhere;}if(a.orWhereGroups&&a.orWhereGroups.length>0){if(i.filterableFields){let x=new Set(i.filterableFields);for(let R of a.orWhereGroups){let $=R.filter(T=>!x.has(T[0]));if($.length>0){H(m,`Fields not filterable: ${$.map(T=>T[0]).join(", ")}`,400);return}}}S.orWhereGroups=a.orWhereGroups;}a.orderBy&&a.orderBy.length>0&&(S.orderBy=a.orderBy),a.select&&a.select.length>0&&(S.select=a.select);let O=await i.repo.query.paginate(S),A={items:O.data,hasNextPage:O.hasNextPage,hasPrevPage:O.hasPrevPage,nextCursor:Qe(O.nextCursor),prevCursor:Qe(O.prevCursor)};Ce(m,A,{pageSize:f,hasMore:O.hasNextPage});}catch(a){wt(m,a,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:d,sort:c},"Failed to query documents",n);}}async function u(b,m){let y=b.params||{},i=r(y.repoName,m);if(!i)return;let d=y.id;if(!d){H(m,"Document ID required",400);return}try{let c=await o(i,d);if(!c){H(m,"Document not found",404);return}Ce(m,c);}catch(c){wt(m,c,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:[{field:i.documentKey,op:"==",value:d}]},"Failed to fetch document",n);}}async function g(b,m){let y=b.params||{},i=r(y.repoName,m);if(i)try{let d=b.body??{},c=yn(i.schema,d,i.createFields,!1,i.systemKeys);if(!c.success){H(m,c.error,400);return}if(i.validate){let f=await i.validate(c.data,"create");if(f){H(m,f,400);return}}let a;if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let f={...c.data};i.createdKey&&(f[i.createdKey]=new Date);let v=i.parentKeys.filter(A=>!f[A]);if(v.length>0){H(m,`Missing parent key(s) for subcollection create: ${v.join(", ")}`,400);return}let S=i.parentKeys.map(A=>f[A]),O=f[i.documentKey]||Ar();a=await i.repo.set(...S,O,f);}else a=await i.repo.create(c.data);Ce(m,a,void 0,201);}catch(d){let c=n&&d instanceof Error?d.message:"Failed to create document";H(m,c,500);}}async function h(b,m,y){let i=b.params||{},d=r(i.repoName,m);if(!d)return;let c=i.id;if(!c){H(m,"Document ID required",400);return}try{let a=b.body??{},f=yn(d.schema,a,d.mutableFields,y,d.systemKeys);if(!f.success){H(m,f.error,400);return}if(d.validate){let A=await d.validate(f.data,"update");if(A){H(m,A,400);return}}let v=await o(d,c),S=(v&&s(v,d.pathKey))??[c],O=await d.repo.update(...S,f.data);Ce(m,O);}catch(a){let f=n&&a instanceof Error?a.message:"Failed to update document";H(m,f,500);}}async function k(b,m){let y=b.params||{},i=r(y.repoName,m);if(!i)return;if(!i.allowDelete){H(m,"Delete not allowed for this repository",403);return}let d=y.id;if(!d){H(m,"Document ID required",400);return}try{let c=await o(i,d),a=(c&&s(c,i.pathKey))??[d];await i.repo.delete(...a),Ce(m,{deleted:!0});}catch(c){let a=n&&c instanceof Error?c.message:"Failed to delete document";H(m,a,500);}}function w(b,m){m.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:l,handleQuery:p,handleGet:u,handleCreate:g,handleUpdate:h,handleDelete:k,handleOptions:w}}function St(e){try{return zod.z.toJSONSchema(e,{target:"openapi-3.1",unrepresentable:"any",override:t=>{let n=t.zodSchema?._zod?.def;n&&(n.type==="date"?(t.jsonSchema.type="string",t.jsonSchema.format="date-time"):n.type==="bigint"&&(t.jsonSchema.type="string",t.jsonSchema.format="int64"));}})}catch(t){return typeof console<"u"&&console.warn&&console.warn("[generateOpenAPISpec] Failed to convert Zod schema to JSON Schema; falling back to {type:object}.",t),{type:"object"}}}function X(e){return {$ref:`#/components/schemas/${e}`}}function G(e){return {description:e,content:{"application/json":{schema:X("ErrorResponse")}}}}function qe(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function vn(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 Nr(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 Ir(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],r=[];for(let s of t){r.push({name:s,in:"query",schema:{type:"string"},description:`Filter by ${s} (equality)`});for(let o of n)r.push({name:`${s}__${o}`,in:"query",schema:{type:"string"},description:`Filter ${s} with operator ${o}`});}return r}function _r(){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 Dr(e,t,n,r,s){let o={},l=e.name,p=`${t}/${e.name}`,u=`${p}/{${e.documentKey}}`,g={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};o[p]={get:{operationId:`list${fe(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[l],parameters:[...Nr(e),...Ir(e)],responses:{200:vn(X(n)),500:G("Internal server error")}},post:{operationId:`create${fe(e.name)}`,summary:`Create a ${re(e.name)}`,tags:[l],requestBody:{required:true,content:{"application/json":{schema:X(r??n)}}},responses:{201:qe("Document created",X(n)),400:G("Validation error"),500:G("Internal server error")}}},o[`${p}/query`]={post:{operationId:`query${fe(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[l],requestBody:{required:true,content:{"application/json":{schema:X("QueryRequestBody")}}},responses:{200:vn(X(n)),400:G("Invalid query"),500:G("Internal server error")}}};let h={};return h.get={operationId:`get${fe(re(e.name))}`,summary:`Get a single ${re(e.name)}`,tags:[l],parameters:[g],responses:{200:qe("Document found",X(n)),404:G("Document not found"),500:G("Internal server error")}},h.put={operationId:`update${fe(re(e.name))}`,summary:`Update a ${re(e.name)} (full replace)`,tags:[l],parameters:[g],requestBody:{required:true,content:{"application/json":{schema:X(s??n)}}},responses:{200:qe("Document updated",X(n)),400:G("Validation error"),404:G("Document not found"),500:G("Internal server error")}},h.patch={operationId:`patch${fe(re(e.name))}`,summary:`Partially update a ${re(e.name)}`,tags:[l],parameters:[g],requestBody:{required:true,content:{"application/json":{schema:{allOf:[X(s??n)],description:"All fields are optional for partial updates"}}}},responses:{200:qe("Document patched",X(n)),400:G("Validation error"),404:G("Document not found"),500:G("Internal server error")}},e.allowDelete&&(h.delete={operationId:`delete${fe(re(e.name))}`,summary:`Delete a ${re(e.name)}`,tags:[l],parameters:[g],responses:{200:qe("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:G("Document not found"),500:G("Internal server error")}}),o[u]=h,o}function $t(e,t,n={}){let{title:r="CRUD API",version:s="1.0.0",description:o,servers:l,auth:p=false}=n,u=t==="/"?"":t.replace(/\/$/,""),g={},h={},k=[];g.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},g.QueryRequestBody=_r();for(let[y,i]of Object.entries(e)){let d=fe(re(y)),c=`${d}Create`,a=`${d}Update`;g[d]=St(i.schema);let f=R=>{let $=R&&R.length>0?R:Object.keys(i.schema.shape),T={};for(let P of $){let C=P.split(".")[0];C&&i.schema.shape[C]&&!i.systemKeys.includes(C)&&(T[C]=i.schema.shape[C]);}return T},v=null,S=f(i.createFields);Object.keys(S).length>0&&(g[c]=St(zod.z.object(S)),v=c);let O=null,A=f(i.mutableFields);Object.keys(A).length>0&&(g[a]=St(zod.z.object(A)),O=a);let x=Dr(i,u,d,v,O);Object.assign(h,x),k.push({name:y,description:`Operations on ${y} (collection: ${i.path})`});}let w={},b;return p==="basic"?(w.basicAuth={type:"http",scheme:"basic"},b=[{basicAuth:[]}]):p==="bearer"&&(w.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},b=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:r,version:s,...o?{description:o}:{}},...l&&l.length>0?{servers:l}:{},paths:h,components:{schemas:g,...Object.keys(w).length>0?{securitySchemes:w}:{}},...b?{security:b}:{},tags:k}}function fe(e){return e.charAt(0).toUpperCase()+e.slice(1)}function re(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 jr(e,t){return `<!DOCTYPE html>
1135
+ `;function ze(){return jsxRuntime.jsx("script",{dangerouslySetInnerHTML:{__html:nn}})}it();function pe(e){return "<!DOCTYPE html>"+server.renderToString(e)}var mr=["corporate","silk","dark"],yr=()=>jsxRuntime.jsxs("div",{class:"dropdown dropdown-end","data-frs-theme-switcher":true,children:[jsxRuntime.jsxs("button",{type:"button",tabIndex:0,class:"btn btn-sm btn-ghost text-neutral-content gap-1.5","aria-label":"Switch theme",children:[jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2",class:"size-4",children:[jsxRuntime.jsx("circle",{cx:"12",cy:"12",r:"4"}),jsxRuntime.jsx("path",{d:"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"})]}),jsxRuntime.jsx("span",{class:"text-xs hidden sm:inline","data-frs-theme-current":true,children:"Theme"})]}),jsxRuntime.jsx("ul",{tabIndex:0,class:"dropdown-content menu menu-sm bg-base-100 text-base-content rounded-box z-50 mt-2 w-40 p-1 shadow-lg border border-base-300",children:mr.map(e=>jsxRuntime.jsx("li",{children:jsxRuntime.jsxs("button",{type:"button","data-frs-theme":e,class:"capitalize justify-between",children:[jsxRuntime.jsx("span",{children:e}),jsxRuntime.jsx("span",{class:"hidden text-primary","data-frs-theme-check":e,children:"\u2713"})]})},e))})]}),fe=({opts:e,children:t})=>{let{title:n,breadcrumb:r,flash:s,basePath:o="/"}=e;return jsxRuntime.jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxRuntime.jsxs("head",{children:[jsxRuntime.jsx("meta",{charset:"UTF-8"}),jsxRuntime.jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxRuntime.jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsxRuntime.jsx("script",{dangerouslySetInnerHTML:{__html:"(function(){try{var t=localStorage.getItem('frs-admin-theme');if(t){document.documentElement.setAttribute('data-theme',t);}}catch(_){}})();"}}),jsxRuntime.jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsxRuntime.jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsxRuntime.jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxRuntime.jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsxRuntime.jsxs("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:[jsxRuntime.jsx("div",{class:"flex-1",children:jsxRuntime.jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})}),jsxRuntime.jsx("div",{class:"flex-none",children:jsxRuntime.jsx(yr,{})})]}),jsxRuntime.jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[r&&r.length>0&&jsxRuntime.jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsxRuntime.jsx("ul",{children:r.map((i,u)=>i.href?jsxRuntime.jsx("li",{children:jsxRuntime.jsx("a",{href:i.href,children:i.label})},u):jsxRuntime.jsx("li",{class:"text-base-content/60",children:i.label},u))})}),jsxRuntime.jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),s&&jsxRuntime.jsxs("div",{role:"alert",class:`alert ${s.type==="success"?"alert-success":s.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsxRuntime.jsx("span",{class:"flex-1",children:s.message}),s.action&&jsxRuntime.jsx("a",{href:s.action.href,...s.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:s.action.label})]}),t]}),jsxRuntime.jsx(at,{basePath:o}),jsxRuntime.jsx(ze,{})]})]})};function lt(e,t){return pe(jsxRuntime.jsx(fe,{opts:t,children:jsxRuntime.jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function ct(e,t){return pe(jsxRuntime.jsx(fe,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxRuntime.jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsxRuntime.jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsxRuntime.jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsxRuntime.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=>jsxRuntime.jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxRuntime.jsxs("div",{class:"card-body p-5",children:[jsxRuntime.jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsxRuntime.jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var an=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],gr=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"<",label:"<"},{value:"<=",label:"\u2264"},{value:">",label:">"},{value:">=",label:"\u2265"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],hr=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function br(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return gr;case "ZodBoolean":return an;case "ZodArray":return hr;default:return an}}var me="__null__";function vr(e){return `(function(cb){var i=document.getElementById('${e}');if(!i)return;if(cb.checked){i.dataset._prev=i.value;if(i.tagName==='SELECT'){var o=i.querySelector('option[value="${me}"]');if(!o){o=document.createElement('option');o.value='${me}';o.textContent='\u2205 null';o.dataset._auto='1';i.appendChild(o);}o.selected=true;}else{if(i.type==='number'||i.type==='datetime-local'){i.dataset._type=i.type;i.type='text';}i.value='${me}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${me}"][data-_auto="1"]');if(o2)o2.remove();var prev=i.dataset._prev||'';for(var k=0;k<i.options.length;k++)i.options[k].selected=(i.options[k].value===prev);}else{if(i.dataset._type){i.type=i.dataset._type;delete i.dataset._type;}i.readOnly=false;i.value=(i.dataset._prev&&i.dataset._prev!=='${me}')?i.dataset._prev:'';}}})(this)`}function xr(e,t){return `(function(){var h=document.getElementById('${e}');var boxes=document.querySelectorAll('input[data-enum-group="${t}"]');h.value=Array.from(boxes).filter(function(b){return b.checked;}).map(function(b){return b.value;}).join(',');})()`}function Be({inputId:e,active:t}){return jsxRuntime.jsxs("label",{class:"flex items-center gap-1 cursor-pointer select-none text-xs text-base-content/60 hover:text-base-content border border-base-300 rounded-md px-1.5 py-1 shrink-0 leading-none h-8",title:"Filter where field IS NULL",children:[jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",checked:t,onchange:vr(e)}),jsxRuntime.jsx("span",{children:"\u2205"})]})}function wr({col:e,active:t}){let n=t?.value??"",r=n===me,s=`fv_input_${e.name.replace(/\./g,"__")}`,o=t?.op,i=o==="in"||o==="not-in";if(e.enumValues&&e.enumValues.length>0){if(i){let u=new Set(n.split(",").map(g=>g.trim()).filter(Boolean)),c=`eg_${e.name.replace(/\./g,"__")}`;return jsxRuntime.jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{type:"hidden",id:s,name:`fv_${e.name}`,value:n}),e.enumValues.map(g=>jsxRuntime.jsxs("label",{class:"flex items-center gap-1 text-xs border border-base-300 rounded px-2 cursor-pointer hover:bg-base-200",children:[jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",value:g,checked:u.has(g),"data-enum-group":c,onchange:xr(s,c)}),jsxRuntime.jsx("span",{children:g})]},g))]})}return jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsxs("select",{id:s,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsxRuntime.jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),e.enumValues.map(u=>jsxRuntime.jsx("option",{value:u,selected:n===u,children:u},u)),e.nullable&&jsxRuntime.jsx("option",{value:me,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsxRuntime.jsx(Be,{inputId:s,active:r})]})}if(e.zodType==="ZodBoolean")return jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsxs("select",{id:s,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsxRuntime.jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),jsxRuntime.jsx("option",{value:"true",selected:n==="true",children:"true"}),jsxRuntime.jsx("option",{value:"false",selected:n==="false",children:"false"}),e.nullable&&jsxRuntime.jsx("option",{value:me,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsxRuntime.jsx(Be,{inputId:s,active:r})]});if(e.zodType==="ZodArray"){let u=t?.op==="array-contains-any";return jsxRuntime.jsx("input",{id:s,type:"text",name:`fv_${e.name}`,value:n,placeholder:u?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:r?"text":"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r||void 0,style:r?"opacity:0.55":void 0,"data-_type":r?"number":void 0}),e.nullable&&jsxRuntime.jsx(Be,{inputId:s,active:r})]}):e.zodType==="ZodDate"?jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:r?"text":"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full",readOnly:r||void 0,style:r?"opacity:0.55":void 0,"data-_type":r?"datetime-local":void 0}),e.nullable&&jsxRuntime.jsx(Be,{inputId:s,active:r})]}):jsxRuntime.jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxRuntime.jsx("input",{id:s,type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r||void 0,style:r?"opacity:0.55":void 0}),e.nullable&&jsxRuntime.jsx(Be,{inputId:s,active:r})]})}function dt({action:e,columnMeta:t,activeFilters:n,isGroup:r}){let s=Object.fromEntries(n.map(c=>[c.field,c])),o=n.length>0,i=n.length>=2||r&&o,u=t.filter(c=>c.zodType!=="ZodObject"&&c.zodType!=="ZodRecord");return jsxRuntime.jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:o?true:void 0,children:[jsxRuntime.jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",o&&jsxRuntime.jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsxRuntime.jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxRuntime.jsxs("form",{method:"get",action:e,children:[jsxRuntime.jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:u.map(c=>{let g=br(c.zodType),h=s[c.name],k=h?.op??g[0].value;return jsxRuntime.jsxs("div",{class:"flex flex-col gap-1.5",children:[jsxRuntime.jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:c.name}),jsxRuntime.jsxs("div",{class:"flex gap-1.5",children:[g.length>1?jsxRuntime.jsx("select",{name:`fo_${c.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:g.map(w=>jsxRuntime.jsx("option",{value:w.value,selected:w.value===k,children:w.label},w.value))}):jsxRuntime.jsx("input",{type:"hidden",name:`fo_${c.name}`,value:g[0].value}),jsxRuntime.jsx(wr,{col:c,active:h})]})]},c.name)})}),jsxRuntime.jsxs("div",{class:"flex flex-wrap gap-2 mt-4 pt-3 border-t border-base-200 items-center",children:[jsxRuntime.jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),o&&jsxRuntime.jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),i&&jsxRuntime.jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),r?"Collection group queries require a composite index":"Multiple filters may require a composite index"]})]})]})})]})}function ut(e,t,n,r,s,o){let i=n==="create"?`Create ${e}`:`Edit ${e} / ${r??""}`,u=n==="create"?[{label:"Repositories",href:s},{label:e,href:`${s}/${e}`},{label:"New document"}]:[{label:"Repositories",href:s},{label:e,href:`${s}/${e}`},{label:`Edit ${r??""}`}];return pe(jsxRuntime.jsx(fe,{opts:{title:i,breadcrumb:u,basePath:s,flash:o},children:jsxRuntime.jsx("div",{class:"card bg-base-100 border border-base-300",children:jsxRuntime.jsx("div",{class:"card-body p-6",children:jsxRuntime.jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}We();ot();function pt(e,t,n){let r=new URLSearchParams;for(let s of e)r.set(`fv_${s.field}`,s.value),r.set(`fo_${s.field}`,s.op);return t&&(r.set("ob",t.field),r.set("od",t.dir)),n&&r.set("ps",String(n)),r}function ln(e,t,n,r,s){let o=pt(e,r,s);return o.set("cursor",t),o.set("dir",n),`?${o.toString()}`}function Sr(e,t,n,r){let s=pt(n,void 0,r);return t?.field===e?t.dir==="asc"&&(s.set("ob",e),s.set("od","desc")):(s.set("ob",e),s.set("od","asc")),`?${s.toString()}`}function Rr(e,t,n){return `?${pt(t,n,e).toString()}`}function ft(e,t,n,r,s,o,i=[],u=[],c=false,g=[],h,k,w,x,m,y,f,d=false){let a=`${r}/${e}`,p=`${a}/create`,l={};if(f)for(let S of n)l[S]=Oe(Te(f,S));let b=(y??[]).filter(S=>{let $=l[S]??Oe(Te(f,S));return $==="string"||$==="number"||$==="bigint"||$==="boolean"||$==="enum"||$==="literal"}),v=b.length>0,C=c,E=C||v,R=b.map(S=>{let $=Te(f,S),O=Oe($),A=i.find(T=>T.name===S);return {name:S,type:O,enumValues:A?.enumValues??null,nullable:A?.nullable??false}});return pe(jsxRuntime.jsxs(fe,{opts:{title:e,breadcrumb:[{label:"Repositories",href:r},{label:e}],basePath:r,flash:o},children:[i.length>0&&jsxRuntime.jsx(dt,{action:a,columnMeta:i,activeFilters:u,isGroup:x}),w&&jsxRuntime.jsxs("div",{role:"alert",class:`alert ${w.type==="index"?"alert-warning":"alert-error"} mb-6 shadow-sm`,children:[jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-6 w-6 shrink-0 stroke-current",fill:"none",viewBox:"0 0 24 24",children:w.type==="index"?jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"}):jsxRuntime.jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"})}),jsxRuntime.jsxs("div",{class:"flex-1",children:[jsxRuntime.jsx("h3",{class:"font-bold",children:w.type==="index"?"Composite index required":"Query failed"}),jsxRuntime.jsx("div",{class:"text-sm",children:w.message})]}),w.indexUrl&&jsxRuntime.jsx("a",{href:w.indexUrl,target:"_blank",rel:"noopener noreferrer",class:"btn btn-sm btn-outline",children:"Create Index \u2192"})]}),jsxRuntime.jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3","data-frs-toolbar":true,children:[jsxRuntime.jsxs("div",{class:"flex items-center gap-3",children:[jsxRuntime.jsxs("span",{class:"text-sm text-base-content/60",children:[t.length,typeof m=="number"&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[" ","of ",jsxRuntime.jsx("span",{class:"font-semibold text-base-content/80",children:m})]})," ","document",(typeof m=="number"?m:t.length)!==1&&"s"]}),jsxRuntime.jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsxRuntime.jsx("span",{children:"Rows"}),jsxRuntime.jsx("div",{class:"join",children:[10,25,50,100].map(S=>jsxRuntime.jsx("a",{href:Rr(S,u,h),class:`join-item btn btn-xs ${k===S?"btn-active btn-primary":"btn-outline"}`,children:S},S))})]})]}),jsxRuntime.jsx("a",{href:p,class:"btn btn-primary btn-sm",children:"+ New"})]}),E&&jsxRuntime.jsxs("div",{class:"hidden mb-3 alert alert-info py-2 px-3","data-frs-bulk-bar":true,"data-frs-repo":e,"data-frs-total":typeof m=="number"?String(m):"","data-frs-page-size":String(k??t.length),"data-frs-allow-delete":C?"1":"0","data-frs-allow-update":v?"1":"0","data-frs-fields":JSON.stringify(R),"data-frs-filters":JSON.stringify(u),children:[jsxRuntime.jsxs("div",{class:"flex-1 text-sm",children:[jsxRuntime.jsx("span",{"data-frs-bulk-summary":true,children:"0 selected"}),typeof m=="number"&&m>t.length&&jsxRuntime.jsxs("button",{type:"button",class:"ml-3 link link-primary text-sm hidden","data-frs-bulk-select-all":true,children:["Select all ",m," matching documents"]}),jsxRuntime.jsxs("span",{class:"hidden ml-3 italic","data-frs-bulk-all-active":true,children:["All ",m??"?"," matching documents are selected."," ",jsxRuntime.jsx("button",{type:"button",class:"link","data-frs-bulk-clear":true,children:"Clear selection"})]})]}),jsxRuntime.jsxs("div",{class:"flex gap-2",children:[v&&jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-outline","data-frs-bulk-action":"update",children:"Update field\u2026"}),C&&jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-error btn-outline","data-frs-bulk-action":"delete",children:"Delete"})]})]}),jsxRuntime.jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxRuntime.jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{class:"bg-base-200/50",children:[E&&jsxRuntime.jsx("th",{class:"w-8",children:jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-page":true,"aria-label":"Select all on this page"})}),[...n].map((S,$)=>{let O=h?.field===S,A=O?h.dir==="asc"?" \u25B2":" \u25BC":"";return jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxRuntime.jsxs("a",{href:Sr(S,h,u,k),class:`hover:text-base-content inline-flex items-center gap-0.5${O?" text-primary font-bold":""}`,children:[S,A]})},$)}),g.map((S,$)=>jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:S.column},`rel-${$}`)),jsxRuntime.jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsxRuntime.jsx("tbody",{children:t.length===0?jsxRuntime.jsx("tr",{children:jsxRuntime.jsx("td",{colspan:n.length+g.length+1+(E?1:0),class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((S,$)=>{let O=String(S.docId??S.id??""),A=`${r}/${e}/${encodeURIComponent(O)}/edit`,T=`${r}/${e}/${encodeURIComponent(O)}/delete`;return jsxRuntime.jsxs("tr",{class:"hover","data-frs-row-id":O,children:[E&&jsxRuntime.jsx("td",{class:"align-middle py-2",children:jsxRuntime.jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-row":true,value:O,"aria-label":`Select ${O}`})}),n.map((D,Z)=>{let N=S[D],P=l[D],H=P?Ze(P,N):null;return jsxRuntime.jsx("td",{class:"align-top py-2",children:jsxRuntime.jsx(Ce,{val:N,mismatch:H})},Z)}),g.map((D,Z)=>{let N=S[D.key];if(N==null||N==="")return jsxRuntime.jsx("td",{class:"py-2"},`rel-${Z}`);let P=D.type==="one"?`${r}/${D.targetRepo}/${encodeURIComponent(String(N))}/edit`:`${r}/${D.targetRepo}?fv_${D.targetKey}=${encodeURIComponent(String(N))}`;return jsxRuntime.jsx("td",{class:"align-middle py-2",children:jsxRuntime.jsx("a",{href:P,class:"btn btn-xs btn-ghost btn-outline","data-frs-relation":true,"data-frs-rel-type":D.type,"data-frs-rel-repo":D.targetRepo,"data-frs-rel-fk":D.targetKey,"data-frs-rel-val":String(N),"data-frs-rel-label":D.column,children:D.column})},`rel-${Z}`)}),jsxRuntime.jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxRuntime.jsxs("div",{class:"flex gap-1 justify-end",children:[jsxRuntime.jsx("a",{href:A,class:"btn btn-xs btn-outline",children:"Edit"}),d&&jsxRuntime.jsx("a",{href:`${r}/${e}/${encodeURIComponent(O)}/history`,class:"btn btn-xs btn-outline",title:"View change history",children:"History"}),c&&jsxRuntime.jsx("form",{method:"post",action:T,onsubmit:"return confirm('Delete this document?')",children:jsxRuntime.jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},$)})})]})}),(s.hasPrev||s.hasNext)&&jsxRuntime.jsxs("div",{class:"flex flex-col items-center mt-6 gap-2",children:[jsxRuntime.jsxs("div",{class:"flex justify-center items-center gap-2",children:[s.hasPrev?jsxRuntime.jsx("a",{href:ln(u,s.prevCursor,"prev",h,k),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsxRuntime.jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),s.hasNext?jsxRuntime.jsx("a",{href:ln(u,s.nextCursor,"next",h,k),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsxRuntime.jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]}),typeof m=="number"&&jsxRuntime.jsxs("div",{class:"text-xs text-base-content/50",children:[m," total document",m!==1?"s":"",u.length>0?" matching filters":""]})]}),E&&v&&jsxRuntime.jsxs("dialog",{id:"frs-bulk-update-modal",class:"modal",children:[jsxRuntime.jsxs("div",{class:"modal-box",children:[jsxRuntime.jsx("h3",{class:"font-bold text-lg mb-3",children:"Bulk update field"}),jsxRuntime.jsx("p",{class:"text-sm text-base-content/60 mb-4","data-frs-bulk-update-summary":true,children:"Update one field on the selected documents."}),jsxRuntime.jsxs("form",{method:"dialog","data-frs-bulk-update-form":true,children:[jsxRuntime.jsxs("label",{class:"form-control w-full mb-3",children:[jsxRuntime.jsx("div",{class:"label",children:jsxRuntime.jsx("span",{class:"label-text text-xs uppercase tracking-wide",children:"Field"})}),jsxRuntime.jsxs("select",{class:"select select-bordered select-sm w-full",name:"field",required:true,"data-frs-bulk-field-select":true,children:[jsxRuntime.jsx("option",{value:"",children:"\u2014 Select a field \u2014"}),b.map(S=>jsxRuntime.jsx("option",{value:S,children:S},S))]})]}),jsxRuntime.jsx("div",{class:"mb-4","data-frs-bulk-value-container":true}),jsxRuntime.jsxs("div",{class:"modal-action",children:[jsxRuntime.jsx("button",{type:"button",class:"btn btn-sm btn-ghost","data-frs-bulk-update-cancel":true,children:"Cancel"}),jsxRuntime.jsx("button",{type:"submit",class:"btn btn-sm btn-primary","data-frs-bulk-update-submit":true,children:"Apply"})]})]})]}),jsxRuntime.jsx("form",{method:"dialog",class:"modal-backdrop",children:jsxRuntime.jsx("button",{children:"close"})})]})]}))}var $r="";function Me(e,t){return lt(e,t)}function mt(e,t){return ct(e,t)}function yt(e,t,n,r,s,o,i,u,c,g,h,k,w,x,m,y,f,d){return ft(e,t,n,r,s,o,i,u,c,g,h,k,w,x,m,y,f,d)}function ye(e,t,n,r,s,o){return ut(e,t,n,r,s,o)}var Cr=new Set(["<","<=",">",">=","!="]),Or=new Set(["array-contains","array-contains-any"]);function gt(e){return e==="desc"?"DESCENDING":"ASCENDING"}function Tr(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function Ar(e,t,n,r,s){let o=[],i=new Set;for(let c of r)if(c.op==="=="||c.op==="in"||c.op==="not-in"){if(i.has(c.field))continue;i.add(c.field),o.push({fieldPath:c.field,order:"ASCENDING"});}for(let c of r)if(Or.has(c.op)){if(i.has(c.field))continue;i.add(c.field),o.push({fieldPath:c.field,arrayConfig:"CONTAINS"});}for(let c of r)if(Cr.has(c.op)){if(i.has(c.field))continue;i.add(c.field);let g=s?.field===c.field?gt(s.dir):"ASCENDING";o.push({fieldPath:c.field,order:g});}if(s&&!i.has(s.field)&&o.push({fieldPath:s.field,order:gt(s.dir)}),o.length===1&&n)return Ir(e,t,o[0]);let u=s&&o.some(c=>c.fieldPath===s.field)?gt(s.dir):"ASCENDING";return o.push({fieldPath:"__name__",order:u}),Er(e,t,n,o)}function Er(e,t,n,r,s="(default)"){let o=`projects/${e}/databases/${s}/collectionGroups/${t}/indexes/_`,i=[...vt(1,o),...Xe(2,n?2:1)];for(let g of r)i.push(...cn(3,dn(g)));let u=s==="(default)"?"-default-":s,c=encodeURIComponent(un(i));return `https://console.firebase.google.com/project/${e}/firestore/databases/${u}/indexes?create_composite=${c}`}function Pr(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function ht(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function bt(e,t){return e<<3|t}function vt(e,t){let n=Array.from(new TextEncoder().encode(t));return [bt(e,2),...ht(n.length),...n]}function Xe(e,t){return [bt(e,0),...ht(t)]}function cn(e,t){return [bt(e,2),...ht(t.length),...t]}function dn(e){let t=[...vt(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...Xe(3,1)):t.push(...Xe(2,e.order==="DESCENDING"?2:1)),t}function un(e){let t=String.fromCharCode(...e),n;if(typeof Buffer<"u")n=Buffer.from(e).toString("base64");else if(typeof btoa<"u")n=btoa(t);else throw new Error("No base64 encoder available");return n.replace(/=+$/,"")}function Ir(e,t,n,r="(default)"){let s=`projects/${e}/databases/${r}/collectionGroups/${t}/fields/${n.fieldPath}`,o=[...vt(1,s),...Xe(2,2),...cn(3,dn(n))],i=r==="(default)"?"-default-":r,u=encodeURIComponent(un(o));return `https://console.firebase.google.com/project/${e}/firestore/databases/${i}/indexes/automatic?create_exemption=${u}`}function Nr(e){let t=e,n=[t?.firestore?.projectId,t?.firestore?.app?.options?.projectId,t?.firestore?._settings?.projectId,t?.firestore?.databaseId?.projectId,t?._firestore?.projectId];for(let s of n)if(typeof s=="string"&&s.length>0)return s;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function we(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function qe(e,t){let n=e??{},r=we(e),s;if(r&&(s=n.message?Pr(n.message):void 0,!s)){let o=Nr(t.ref);if(o){let i=Tr(t.path);s=Ar(o,i,t.isGroup,t.filters,t.sort);}}return {type:r?"index":"error",message:r?"This query requires a composite index that does not exist yet.":n.message??"Query failed",indexUrl:s}}var pn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Dr(){let e="";for(let t=0;t<20;t++)e+=pn.charAt(Math.floor(Math.random()*pn.length));return e}function Ye(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let r=n.split("/").filter(Boolean),s=[];for(let o=1;o<r.length;o+=2)s.push(r[o]);return s.length>0?s:void 0}async function Ae(e,t){let n=e.documentKey??"docId",r=`by${n.charAt(0).toUpperCase()}${n.slice(1)}`;if(typeof e.repo.get[r]=="function")try{let o=await e.repo.get[r](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function xt(e,t,n){let r=e.documentKey??"docId",s=qe(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:r,op:"==",value:t}]});return s.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...s.indexUrl?{action:{href:s.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:s.message}}function F(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function wt(e,t){e.status(302).set("Location",t).send("");}function St(e,t){let n=t.shape,r={};for(let[s,o]of Object.entries(n)){let i=kt(o);if(i==="ZodObject"){if(e[s+"__isnull"]==="1"){r[s]=null;continue}let g={},h=false;for(let[x,m]of Object.entries(e))x.startsWith(`${s}.`)&&(g[x.slice(s.length+1)]=m,h=true);if(h){let x=o;for(;;){let m=q(x);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")x=L(x);else break}r[s]=St(g,x);continue}let k=e[s],w=Array.isArray(k)?k[k.length-1]:k;if(w)try{r[s]=JSON.parse(w);}catch{r[s]=w;}continue}let u=e[s],c=Array.isArray(u)?u[u.length-1]:u;if(e[s+"__isnull"]==="1"){r[s]=null;continue}if(c===void 0||c===""){i==="ZodBoolean"&&(r[s]=false);continue}switch(i){case "ZodBoolean":c==="__null__"?r[s]=null:r[s]=c==="true"||c==="on"||c==="1";break;case "ZodNumber":case "ZodBigInt":r[s]=Number(c);break;case "ZodDate":r[s]=new Date(c);break;case "ZodArray":try{r[s]=JSON.parse(c);}catch{r[s]=c;}break;default:if(c.startsWith("{")||c.startsWith("["))try{r[s]=JSON.parse(c);break}catch{}r[s]=c;}}return r}function fn(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 r=new Date(e);isNaN(r.getTime())||(t=r);}if(!t||isNaN(t.getTime()))return null;let n=r=>String(r).padStart(2,"0");return `${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}function kt(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=L(t);else return n}}function jr(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=L(t);else return t}}function yn(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable")return true;if(n==="ZodDefault"){t=L(t);continue}return false}}function gn(e){let t=jr(e),n=q(t);if(n==="ZodEnum"){let r=Ne(t);return r.length>0?r:void 0}if(n==="ZodNativeEnum"){let r=_e(t),s=Object.values(r).filter(o=>typeof o=="string");return s.length>0?s:void 0}if(n==="ZodLiteral"){let r=Ve(t);return typeof r=="string"?[r]:void 0}}function hn(e,t,n=""){let r={};for(let s of Object.keys(t.shape)){let o=n?`${n}.${s}`:s,i=e[s];if(i===null){r[o]="__null__";continue}if(i===void 0)continue;let u=t.shape[s];for(;;){let g=q(u);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")u=L(u);else break}let c=q(u);if(c==="ZodObject"&&typeof i=="object"&&i!==null&&!Array.isArray(i)){let g=hn(i,u,o);Object.assign(r,g);}else if(c==="ZodDate"){let g=fn(i);g!==null&&(r[o]=g);}else if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&("_seconds"in i||typeof i.toDate=="function")){let g=fn(i);r[o]=g??JSON.stringify(i,null,2);}else typeof i=="object"?r[o]=JSON.stringify(i,null,2):r[o]=String(i);}return r}function Rt(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?Rt(n.nested,t):void 0}))}function Fr(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),r=[];for(let[s,o]of Object.entries(e)){if(!s.startsWith("fv_"))continue;let i=s.slice(3);if(!t.has(i))continue;let u=(o??"").trim();if(!u)continue;let c=e[`fo_${i}`]??"==",g=n.has(c)?c:"==";r.push({field:i,op:g,value:u});}return r}function mn(e){let t="__null__",n=r=>r===t?null:r==="true"?true:r==="false"?false:r!==""&&!isNaN(Number(r))?Number(r):r;return e.map(r=>{if(r.op==="array-contains-any"||r.op==="in"||r.op==="not-in"){let s=r.value.split(",").map(o=>o.trim()).filter(o=>o!==""&&o!==t).map(o=>n(o));return [r.field,r.op,s]}return [r.field,r.op,n(r.value)]})}function bn(e,t,n=""){let r=[];for(let s of e){let o=n?`${n}.${s}`:s,i=t.shape[s];if(!i){r.push({name:o,zodType:"ZodString"});continue}let u=kt(i);if(u==="ZodObject"){let c=i;for(;;){let h=q(c);if(h==="ZodOptional"||h==="ZodNullable"||h==="ZodDefault")c=L(c);else break}let g=Y(c);r.push(...bn(Object.keys(g),c,o));}else r.push({name:o,zodType:u,nullable:yn(i),enumValues:gn(i)});}return r}function zr(e,t){let n=t.split("."),r=e;for(let s of n){for(;;){let i=q(r);if(i==="ZodOptional"||i==="ZodNullable"||i==="ZodDefault")r=L(r);else break}let o=Y(r);if(!(s in o))return null;r=o[s];}return r}function Se(e,t){if(!t||t.length===0)return e;let n=[],r=new Map;for(let o of t){let i=o.indexOf(".");if(i===-1)n.push(o);else {let u=o.slice(0,i),c=o.slice(i+1);r.has(u)||r.set(u,[]),r.get(u).push(c);}}let s={};for(let o of n)o in e.shape&&(s[o]=e.shape[o]);for(let[o,i]of r){if(!(o in e.shape))continue;let u=e.shape[o];for(;;){let c=q(u);if(c==="ZodOptional"||c==="ZodNullable"||c==="ZodDefault")u=L(u);else break}if(q(u)!=="ZodObject"){s[o]=e.shape[o];continue}s[o]=Se(u,i);}return zod.z.object(s)}function le(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",i=process.env.FUNCTION_REGION??"us-central1",u=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${i}/${u}${n}`}let r=process.env.K_SERVICE,s=e.hostname??e.headers?.host??"";return r&&s.includes("cloudfunctions.net")?`/${r.toLowerCase()}${n}`:n}function vn(e,t){let n=(d,a)=>{let p=le(d,t),l=Object.values(e).map(b=>({name:b.name,path:b.path}));F(a,mt(l,p));},r=async(d,a)=>{let p=d.params.repoName;if(!p){F(a,"Bad request",400);return}let l=e[p];if(!l){F(a,"Repository not found",404);return}let b=l.pageSize??25,v=d.query??{},C=v.cursor,E=v.dir==="prev"?"prev":"next",R=v.ob??"",S=v.od==="desc"?"desc":"asc",$=R?{field:R,dir:S}:void 0,O=parseInt(v.ps??""),A=Number.isFinite(O)&&O>0?Math.min(O,200):b,T=l.listColumns??Object.keys(l.schema.shape),D=l.documentKey??"docId",Z=[D,...T.filter(G=>G!==D)],N=l.filterableFields?(()=>{let G=[];for(let ie of l.filterableFields)(ie.includes(".")||T.includes(ie))&&G.push(ie);return G})():T,P=(()=>{let G=[];for(let ie of N)if(ie.includes(".")){let ke=zr(l.schema,ie);G.push({name:ie,zodType:ke?kt(ke):"ZodString",nullable:ke?yn(ke):false,enumValues:ke?gn(ke):void 0});}else G.push(...bn([ie],l.schema));return G})(),H=new Set(P.map(G=>G.name)),he=Fr(v,H),ce=mn(he),Ie;if(C)try{let G=l.repo.ref;typeof G.doc=="function"&&(Ie=await G.doc(C).get());}catch{}let[J,Le]=await Promise.all([l.repo.query.paginate({pageSize:A,cursor:Ie,direction:E,...ce.length>0?{where:ce}:{},...$?{orderBy:[{field:$.field,direction:$.dir}]}:{}}).catch(G=>({queryError:qe(G,{ref:l.repo.ref,path:l.path,isGroup:!!l.isGroup,filters:he,sort:$})})),l.repo.aggregate.count(ce.length>0?{where:ce}:{}).catch(()=>{})]),Re="queryError"in J,Dn=Re?[]:J.data,jn=Re?"":J.nextCursor?.id??"",Fn=Re?"":J.prevCursor?.id??"",zn=Re?J.queryError:void 0,Zn=le(d,t);F(a,yt(l.name,Dn,Z,Zn,{hasPrev:Re?false:J.hasPrevPage,hasNext:Re?false:J.hasNextPage,prevCursor:Fn,nextCursor:jn},void 0,P,he,l.allowDelete??false,l.relationalMeta,$,A,zn,l.isGroup,Le,l.mutableFields,l.schema,l.historyEnabled));},s=(d,a)=>{let p=d.params.repoName;if(!p){F(a,"Bad request",400);return}let l=e[p];if(!l){F(a,"Repository not found",404);return}let b=le(d,t),v=Se(l.schema,l.createFields),C=oe(v),E=`${b}/${l.name}/create`,R=ue(C,E,"POST","Create document");F(a,ye(l.name,R,"create",null,b));},o=async(d,a)=>{let p=d.params.repoName;if(!p){F(a,"Bad request",400);return}let l=e[p];if(!l){F(a,"Repository not found",404);return}let b=le(d,t),v=d.body??{},C=St(v,l.schema),E=Se(l.schema,l.createFields),R=E.safeParse(C);if(!R.success){let S=oe(E),$=`${b}/${l.name}/create`,O=ue(S,$,"POST","Create document"),A=R.error.issues.map(T=>`${T.path.join(".")}: ${T.message}`).join(", ");F(a,ye(l.name,O,"create",null,b,{type:"error",message:`Validation error: ${A}`}),422);return}try{if(l.isGroup&&l.parentKeys&&l.parentKeys.length>0){let S={...R.data};l.createdKey&&(S[l.createdKey]=new Date);let $=l.parentKeys.filter(D=>!S[D]);if($.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${$.join(", ")}`);let O=l.parentKeys.map(D=>S[D]),A=l.documentKey??"docId",T=S[A]||Dr();await l.repo.set(...O,T,S);}else await l.repo.create(R.data);wt(a,`${b}/${l.name}?flash=created`);}catch(S){let $=Se(l.schema,l.createFields),O=oe($),A=`${b}/${l.name}/create`,T=ue(O,A,"POST","Create document");F(a,ye(l.name,T,"create",null,b,{type:"error",message:`Save error: ${S.message}`}),500);}},i=async(d,a)=>{let p=d.params.repoName,l=d.params.id;if(!p||!l){F(a,"Bad request",400);return}let b=e[p];if(!b){F(a,"Repository not found",404);return}let v=le(d,t),C=null;try{C=await Ae(b,l);}catch(A){let T=xt(b,l,A),D=we(A)?424:500;F(a,Me("",{title:`Edit ${b.name} / ${l}`,basePath:v,breadcrumb:[{label:"Repositories",href:v},{label:b.name,href:`${v}/${b.name}`},{label:`Edit ${l}`}],flash:T}),D);return}if(!C){F(a,"Document not found",404);return}let E=hn(C,b.schema),R=Se(b.schema,b.mutableFields),S=Rt(oe(R),E),$=`${v}/${b.name}/${encodeURIComponent(l)}/edit`,O=ue(S,$,"POST","Save changes");F(a,ye(b.name,O,"edit",l,v));},u=async(d,a)=>{let p=d.params.repoName,l=d.params.id;if(!p||!l){F(a,"Bad request",400);return}let b=e[p];if(!b){F(a,"Repository not found",404);return}let v=le(d,t),C=d.body??{},E=St(C,b.schema),R=Se(b.schema,b.mutableFields),$=R.partial().safeParse(E);if(!$.success){let O=Object.fromEntries(Object.entries(C).map(([N,P])=>[N,Array.isArray(P)?P.join(","):P??""])),A=Rt(oe(R),O),T=`${v}/${b.name}/${encodeURIComponent(l)}/edit`,D=ue(A,T,"POST","Save changes"),Z=$.error.issues.map(N=>`${N.path.join(".")}: ${N.message}`).join(", ");F(a,ye(b.name,D,"edit",l,v,{type:"error",message:`Validation error: ${Z}`}),422);return}try{let O=await Ae(b,l),A=(O&&Ye(O,b.pathKey))??[l];await b.repo.update(...A,$.data),wt(a,`${v}/${b.name}?flash=updated`);}catch(O){let A=Se(b.schema,b.mutableFields),T=oe(A),D=`${v}/${b.name}/${encodeURIComponent(l)}/edit`,Z=ue(T,D,"POST","Save changes"),N=we(O)?xt(b,l,O):{type:"error",message:`Save error: ${O.message}`},P=we(O)?424:500;F(a,ye(b.name,Z,"edit",l,v,N),P);}},c=async(d,a)=>{let p=d.params.repoName,l=d.params.id;if(!p||!l){F(a,"Bad request",400);return}let b=e[p];if(!b){F(a,"Repository not found",404);return}if(!b.allowDelete){F(a,"Delete is not allowed for this repository",403);return}let v=le(d,t);try{let C=await Ae(b,l),E=(C&&Ye(C,b.pathKey))??[l];await b.repo.delete(...E),wt(a,`${v}/${b.name}?flash=deleted`);}catch(C){let E=we(C)?xt(b,l,C):{type:"error",message:`Delete error: ${C.message}`},R=we(C)?424:500;F(a,Me("",{title:`Delete ${b.name} / ${l}`,basePath:v,breadcrumb:[{label:"Repositories",href:v},{label:b.name,href:`${v}/${b.name}`},{label:`Delete ${l}`}],flash:E}),R);}},g=async(d,a)=>{let p=d.params.repoName;if(!p){F(a,"Bad request",400);return}let l=e[p];if(!l){F(a,"Repository not found",404);return}let b=le(d,t),v=d.query,C=v?.type==="many"?"many":"one",E=Math.max(1,Math.min(100,Number(v?.ps??25)||25)),R=l.listColumns??Object.keys(Y(l.schema)),{PanelOne:S,PanelMany:$}=await Promise.resolve().then(()=>(it(),sn)),{renderToString:O}=await import('hono/jsx/dom/server');if(C==="one"){let P=String(v?.id??"");if(!P){F(a,"<div class='p-6 text-error'>Missing id parameter.</div>",400);return}try{let H=await Ae(l,P),he=O(S({doc:H,repoName:l.name,basePath:b,schema:l.schema,columns:R}));F(a,he);}catch(H){F(a,`<div class='p-6 text-error text-sm'>Error: ${H.message}</div>`,500);}return}let A=String(v?.fk??""),T=String(v?.fv??"");if(!A||!T){F(a,"<div class='p-6 text-error'>Missing fk/fv parameters.</div>",400);return}let D=v?.cursor??"",Z=v?.dir==="prev"?"prev":"next",N;if(D)try{let P=l.repo.ref;typeof P.doc=="function"&&(N=await P.doc(D).get());}catch{}try{let P=await l.repo.query.paginate({pageSize:E,cursor:N,direction:Z,where:[[A,"==",Zr(T)]]}),H=O($({docs:P.data,repoName:l.name,basePath:b,fk:A,fv:T,columns:R,schema:l.schema,pagination:{hasPrev:P.hasPrevPage,hasNext:P.hasNextPage,prevCursor:P.prevCursor?.id??"",nextCursor:P.nextCursor?.id??"",pageSize:E}}));F(a,H);}catch(P){F(a,`<div class='p-6 text-error text-sm'>Error: ${P.message}</div>`,500);}},h=async(d,a)=>{let p=[];for(let l of a){let b;if(d.isGroup||d.parentKeys?.length){let v=await Ae(d,l);b=v?Ye(v,d.pathKey):void 0;}b||(b=[l]);try{let v=d.repo.documentRef(...b);v&&p.push(v);}catch{}}return p},k=async(d,a)=>{let p=mn(a),l=d.documentKey??"docId",b=[],v;for(;;){let C=await d.repo.query.paginate({pageSize:500,cursor:v,direction:"next",...p.length>0?{where:p}:{}});for(let E of C.data){let R=String(E[l]??E.id??"");R&&b.push(R);}if(!C.hasNextPage||!C.nextCursor)break;v=C.nextCursor;}return b},w=async(d,a)=>{let p=d.params.repoName;if(!p){X(a,{error:"Bad request"},400);return}let l=e[p];if(!l){X(a,{error:"Repository not found"},404);return}if(!l.allowDelete){X(a,{error:"Delete is not allowed for this repository"},403);return}let b=d.body??{};try{let v=await m(l,b);if(v.length===0){X(a,{deleted:0});return}let C=await h(l,v);for(let E=0;E<C.length;E+=500)await l.repo.bulk.delete(C.slice(E,E+500));X(a,{deleted:C.length});}catch(v){X(a,{error:v.message},500);}},x=async(d,a)=>{let p=d.params.repoName;if(!p){X(a,{error:"Bad request"},400);return}let l=e[p];if(!l){X(a,{error:"Repository not found"},404);return}let b=d.body??{},v=String(b.field??"");if(!v){X(a,{error:"Missing 'field'"},400);return}if(!l.mutableFields||!l.mutableFields.includes(v)){X(a,{error:`Field '${v}' is not bulk-updatable`},403);return}let C=l.schema.shape?.[v],E=b.value;if(C){let R=C.safeParse(b.value);if(!R.success){X(a,{error:`Invalid value for '${v}': ${R.error.message}`},400);return}E=R.data;}try{let R=await m(l,b);if(R.length===0){X(a,{updated:0});return}let $=(await h(l,R)).map(O=>({docRef:O,data:{[v]:E}}));for(let O=0;O<$.length;O+=500)await l.repo.bulk.update($.slice(O,O+500));X(a,{updated:$.length});}catch(R){X(a,{error:R.message},500);}};async function m(d,a){if(a.selectAll){let p=y(a.filters,d);return await k(d,p)}return Array.isArray(a.ids)?a.ids.filter(p=>typeof p=="string"&&!!p):[]}function y(d,a){if(!Array.isArray(d))return [];let p=new Set((a.filterableFields??Object.keys(Y(a.schema))).map(v=>String(v))),l=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),b=[];for(let v of d)v&&typeof v=="object"&&typeof v.field=="string"&&p.has(v.field)&&typeof v.value=="string"&&l.has(String(v.op))&&b.push({field:v.field,op:v.op,value:v.value});return b}return {handleDashboard:n,handleList:r,handleCreateForm:s,handleCreateSubmit:o,handleEditForm:i,handleEditSubmit:u,handleDelete:c,handlePanel:g,handleBulkDelete:w,handleBulkUpdate:x,handleHistory:async(d,a)=>{let p=d.params.repoName,l=d.params.id;if(!p||!l){F(a,"Bad request",400);return}let b=e[p];if(!b){F(a,"Repository not found",404);return}if(!b.historyEnabled||!b.repo.history){F(a,"History not enabled for this repository",404);return}let v=le(d,t),C=b.historySubcollection??"history",E=[l];try{let P=await Ae(b,l),H=P?Ye(P,b.pathKey):void 0;H&&H.length>0&&(E=H);}catch{}let R=parseInt(String(d.query?.limit??"")),S=Number.isFinite(R)&&R>0?Math.min(R,500):100,$=[],O;try{$=await b.repo.history.list(...E,{limit:S});}catch(P){O=P.message;}let A=P=>String(P??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),T=P=>{if(P===void 0)return '<span class="opacity-40">undefined</span>';if(P===null)return '<span class="opacity-40">null</span>';if(typeof P=="object")try{return `<code class="text-xs">${A(JSON.stringify(P))}</code>`}catch{return A(String(P))}return A(String(P))},D=P=>P?typeof P.toDate=="function"?P.toDate().toISOString():P instanceof Date?P.toISOString():A(String(P)):"",Z=P=>`<span class="badge badge-sm ${P==="create"?"badge-success":P==="delete"?"badge-error":"badge-info"}">${A(P)}</span>`,N="";if(N+='<div class="flex items-center justify-between mb-4">',N+=`<h1 class="text-2xl font-semibold">History \u2014 ${A(b.name)} / ${A(l)}</h1>`,N+=`<a href="${v}/${b.name}/${encodeURIComponent(l)}/edit" class="btn btn-sm btn-outline">\u2190 Back to edit</a>`,N+="</div>",N+=`<p class="text-sm text-base-content/60 mb-4">Subcollection: <code>${A(C)}</code> \xB7 Showing up to ${S} entries.</p>`,O)N+=`<div class="alert alert-error mb-4">${A(O)}</div>`;else if($.length===0)N+='<div class="alert">No history entries found.</div>';else {N+='<div class="overflow-x-auto"><table class="table table-zebra table-sm">',N+="<thead><tr><th>When</th><th>Op</th><th>User</th><th>Reason / Comment</th><th>Changes</th></tr></thead><tbody>";for(let P of $){let H=P.meta??{},he=[H.reason,H.comment].filter(J=>J!=null&&J!=="").map(J=>A(String(J))).join(" \u2014 "),ce="",Ie=Object.keys(P.changes??{});Ie.length===0?ce='<span class="opacity-40">\u2014</span>':ce='<ul class="space-y-1">'+Ie.map(J=>{let Le=P.changes[J];return `<li><strong>${A(J)}</strong>: ${T(Le.oldValue)} \u2192 ${T(Le.newValue)}</li>`}).join("")+"</ul>",N+="<tr>",N+=`<td class="whitespace-nowrap text-xs font-mono">${A(D(P.historySetAt))}</td>`,N+=`<td>${Z(P.operation??"update")}</td>`,N+=`<td class="text-xs">${A(H.userEmail??H.userId??"")}</td>`,N+=`<td class="text-xs">${he}</td>`,N+=`<td>${ce}</td>`,N+="</tr>";}N+="</tbody></table></div>";}F(a,Me(N,{title:`History \u2014 ${b.name} / ${l}`,basePath:v,breadcrumb:[{label:"Repositories",href:v},{label:b.name,href:`${v}/${b.name}`},{label:`History ${l}`}]}));}}}function X(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function Zr(e){return e==="true"?true:e==="false"?false:e!==""&&!isNaN(Number(e))?Number(e):e}async function Br(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Mr(e){let t={};if(!e)return t;for(let n of e.split("&")){let r=n.indexOf("=");if(r===-1)continue;let s=decodeURIComponent(n.slice(0,r).replace(/\+/g," ")),o=decodeURIComponent(n.slice(r+1).replace(/\+/g," ")),i=t[s];i===void 0?t[s]=o:Array.isArray(i)?i.push(o):t[s]=[i,o];}return t}function xn(e){let{basePath:t="/",repos:n,parseBody:r=true,auth:s,middleware:o=[],httpsOptions:i}=e,u=t==="/"?"":t.replace(/\/$/,""),c={};for(let[w,x]of Object.entries(n)){let m=x.schema??x.repo.schema??null;if(!m)throw new Error(`[createAdminServer] Repository "${w}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let y,f,d;if(x.fieldsConfig){let l=x.fieldsConfig;y=[],f=[],d=[];for(let[b,v]of Object.entries(l))for(let C of v)C==="filterable"?y.push(b):C==="mutable"?f.push(b):C==="create"&&d.push(b);y.length===0&&(y=void 0),f.length===0&&(f=void 0),d.length===0&&(d=void 0);}let a=(()=>{let l=x.repo._parentKeys;return l&&l.length>0?l:void 0})();if(a&&d)for(let l of a)d.includes(l)||d.push(l);let p={name:w,path:x.path,repo:x.repo,schema:m,documentKey:x.documentKey??"docId",pathKey:x.repo._pathKey??void 0,isGroup:!!x.repo._isGroup,parentKeys:a,createdKey:x.repo._createdKey??void 0,listColumns:x.listColumns,pageSize:x.pageSize,filterableFields:y,mutableFields:f,createFields:d,allowDelete:x.allowDelete??false,historyEnabled:!!x.repo.history,historySubcollection:(x.repo.history&&x.repo._historySubcollection)??void 0,relationalMeta:(()=>{if(!x.relationalFields||x.relationalFields.length===0)return;let l=x.repo.relationalKeys??{},b=[];for(let v of x.relationalFields){let C=l[v.key];C&&b.push({key:v.key,column:v.column,targetRepo:String(C.repo),targetKey:String(C.key),type:C.type});}return b.length>0?b:void 0})()};c[w]=p;}let g=vn(c,u),h=new ne;if(r&&h.use(async(w,x,m)=>{let y=w,f=String(y.headers?.["content-type"]??"");if(f.includes("application/x-www-form-urlencoded")){let d=await Br(y);w.body=Mr(d);}else if(f.includes("application/json")&&typeof y.body=="string")try{w.body=JSON.parse(y.body);}catch{}await m();}),s)if(typeof s=="function")h.use(s);else {let w=s.realm??"Admin",x="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");h.use((m,y,f)=>{if((m.headers?.authorization??"")!==x){y.status(401).set("WWW-Authenticate",`Basic realm="${w}"`).set("Content-Type","text/plain").send("Unauthorized");return}f();});}for(let w of o)h.use(w);h.get(`${u}/`,g.handleDashboard),h.get(`${u}`,g.handleDashboard),h.get(`${u}/:repoName/_panel`,g.handlePanel),h.post(`${u}/:repoName/_bulk/delete`,g.handleBulkDelete),h.post(`${u}/:repoName/_bulk/update`,g.handleBulkUpdate),h.get(`${u}/:repoName`,g.handleList),h.get(`${u}/:repoName/create`,g.handleCreateForm),h.post(`${u}/:repoName/create`,g.handleCreateSubmit),h.get(`${u}/:repoName/:id/edit`,g.handleEditForm),h.post(`${u}/:repoName/:id/edit`,g.handleEditSubmit),h.get(`${u}/:repoName/:id/history`,g.handleHistory),h.post(`${u}/:repoName/:id/delete`,g.handleDelete);let k=async(w,x)=>{await h.handle(w,x);};return i&&(k.httpsOptions=i),k}var Sn="preserve";function Rn(){return Sn}function qr(e){return typeof e=="object"&&e!==null&&typeof e._seconds=="number"&&typeof e._nanoseconds=="number"}function kn(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(e instanceof firestore.Timestamp)return e.toDate();if(qr(e))return new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));if(typeof e=="string"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}if(typeof e=="number"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}return null}function $n(e){return e}function Ot(e,t,n=200){let r=$n(t);e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(r));}function Ee(e,t,n,r=200){Ot(e,{success:true,data:t,meta:n},r);}function V(e,t,n=400){Ot(e,{success:false,error:t},n);}function Ct(e,t,n,r,s){let o=qe(t,n),i=o.type==="index",u=i?424:500,g={success:false,error:i?o.message:s&&t instanceof Error?t.message:r};i&&(g.errorType="index",o.indexUrl&&(g.indexUrl=o.indexUrl)),Ot(e,g,u);}var Cn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Ur(){let e="";for(let t=0;t<20;t++)e+=Cn.charAt(Math.floor(Math.random()*Cn.length));return e}function Pe(e){let t=e._def??e.def;if(!t)return e;let n=t.typeName??t.type;if(n==="ZodDate"||n==="date")return zod.z.preprocess(r=>kn(r)??r,e);if(n==="ZodObject"||n==="object"){let r=e.shape,s={};for(let[o,i]of Object.entries(r))s[o]=Pe(i);return zod.z.object(s)}if(n==="ZodArray"||n==="array"){let r=t.element??t.type;if(r)return zod.z.array(Pe(r))}if(n==="ZodOptional"||n==="optional"){let r=t.innerType;if(r)return Pe(r).optional()}if(n==="ZodNullable"||n==="nullable"){let r=t.innerType;if(r)return Pe(r).nullable()}if(n==="ZodDefault"||n==="default"){let r=t.innerType,s=t.defaultValue;if(r){let o=Pe(r);return typeof s=="function"?o.default(s()):o.default(s)}}return e}function Lr(e,t,n=[]){let r=e.shape,s={},o=t&&t.length>0?t:Object.keys(r);for(let i of o){if(n.includes(i))continue;let u=i.split(".")[0];u&&r[u]&&(s[u]=r[u]);}return zod.z.object(s)}function On(e,t,n,r=false,s=[]){try{let o=Lr(e,n,s),i=r?o.partial():o;return {success:!0,data:(Rn()==="normalize"?Pe(i):i).parse(t)}}catch(o){return o instanceof zod.z.ZodError?{success:false,error:`Validation failed: ${o.issues.map(u=>`${u.path.join(".")}: ${u.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function Kr(e,t){let n=[],r=t?new Set(t):null,s={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[o,i]of Object.entries(e)){if(i===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(o))continue;let u=Array.isArray(i)?i[0]:i;if(u===void 0||u==="")continue;let c=o.match(/^(\w+)__(\w+)$/),g,h="==";if(c&&c[1]&&c[2]){g=c[1];let w=c[2];if(s[w])h=s[w];else continue}else if(!c)g=o;else continue;if(r&&!r.has(g))continue;let k=u;h==="in"||h==="not-in"||h==="array-contains-any"?k=u.split(",").map(w=>Tn(w.trim())):k=Tn(u),n.push({field:g,op:h,value:k});}return n}function Tn(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 et(e){return e?{docId:e.id}:null}async function An(e,t){if(!t||typeof t!="object")return;let n=t.docId;if(typeof n=="string")try{let r=e.repo.ref;if(typeof r.doc!="function")return;let s=await r.doc(n).get();return s.exists?s:void 0}catch{return}}function En(e,t,n){function r(x,m){return !x||!e[x]?(V(m,`Repository "${x}" not found`,404),null):e[x]}function s(x,m){if(!m)return;let y=x[m];if(typeof y!="string"||!y)return;let f=y.split("/").filter(Boolean),d=[];for(let a=1;a<f.length;a+=2)d.push(f[a]);return d.length>0?d:void 0}async function o(x,m){let y=`by${x.documentKey.charAt(0).toUpperCase()}${x.documentKey.slice(1)}`,f=x.repo.get[y];if(typeof f=="function")try{let a=await f(m);if(a)return a}catch{}return (await x.repo.query.by({where:[[x.documentKey,"==",m]],limit:1}))[0]??null}async function i(x,m){let y=x.params||{},f=r(y.repoName,m);if(!f)return;let d=[],a;try{let p=x.query??{},l=Math.min(Number(p.pageSize)||f.pageSize,100),b=p.cursor,v=p.direction?.toLowerCase()==="prev"?"prev":"next",C=p.orderBy,E=p.orderDir?.toLowerCase()==="desc"?"desc":"asc",R=p.select,S=R?R.split(",").map(Z=>Z.trim()):void 0,$;f.allowedIncludes&&p.includes&&($=(typeof p.includes=="string"?p.includes.split(",").map(N=>N.trim()):Array.isArray(p.includes)?p.includes:[]).filter(N=>typeof N=="string"&&f.allowedIncludes.includes(N)),$?.length===0&&($=void 0));let O=Kr(p,f.filterableFields);d=O.map(Z=>({field:Z.field,op:Z.op,value:String(Z.value??"")})),C&&(a={field:C,dir:E});let A={pageSize:l,direction:v};if(b)try{let Z=typeof b=="string"?JSON.parse(b):b;A.cursor=await An(f,Z);}catch{}C&&(A.orderBy=[{field:C,direction:E}]),O.length>0&&(A.where=O.map(Z=>[Z.field,Z.op,Z.value])),S&&(A.select=S),$&&(A.include=$);let T=await f.repo.query.paginate(A),D={items:T.data,hasNextPage:T.hasNextPage,hasPrevPage:T.hasPrevPage,nextCursor:et(T.nextCursor),prevCursor:et(T.prevCursor)};Ee(m,D,{pageSize:l,hasMore:T.hasNextPage});}catch(p){Ct(m,p,{ref:f.repo.ref,path:f.path,isGroup:!!f.isGroup,filters:d,sort:a},"Failed to fetch documents",n);}}async function u(x,m){let y=x.params||{},f=r(y.repoName,m);if(!f)return;let d=[],a;try{let p=x.body??{},l=Math.min(p.pageSize||f.pageSize,100),b=p.direction==="prev"?"prev":"next";p.where&&(d=p.where.map(R=>({field:String(R[0]),op:R[1],value:String(R[2]??"")}))),p.orderBy&&p.orderBy[0]&&(a={field:p.orderBy[0].field,dir:p.orderBy[0].direction==="desc"?"desc":"asc"});let v={pageSize:l,direction:b};if(p.cursor)try{let R=typeof p.cursor=="string"?JSON.parse(p.cursor):p.cursor;v.cursor=await An(f,R);}catch{}if(f.allowedIncludes&&p.includes&&p.includes.length>0){let R=p.includes.filter(S=>typeof S=="string"?f.allowedIncludes.includes(S):typeof S=="object"&&S!==null&&"relation"in S&&typeof S.relation=="string"?f.allowedIncludes.includes(S.relation):!1);R.length>0&&(v.include=R);}if(p.where&&p.where.length>0){if(f.filterableFields){let R=new Set(f.filterableFields),S=p.where.filter($=>!R.has($[0]));if(S.length>0){V(m,`Fields not filterable: ${S.map($=>$[0]).join(", ")}`,400);return}}v.where=p.where;}if(p.orWhere&&p.orWhere.length>0){if(f.filterableFields){let R=new Set(f.filterableFields),S=p.orWhere.filter($=>!R.has($[0]));if(S.length>0){V(m,`Fields not filterable: ${S.map($=>$[0]).join(", ")}`,400);return}}v.orWhere=p.orWhere;}if(p.orWhereGroups&&p.orWhereGroups.length>0){if(f.filterableFields){let R=new Set(f.filterableFields);for(let S of p.orWhereGroups){let $=S.filter(O=>!R.has(O[0]));if($.length>0){V(m,`Fields not filterable: ${$.map(O=>O[0]).join(", ")}`,400);return}}}v.orWhereGroups=p.orWhereGroups;}p.orderBy&&p.orderBy.length>0&&(v.orderBy=p.orderBy),p.select&&p.select.length>0&&(v.select=p.select);let C=await f.repo.query.paginate(v),E={items:C.data,hasNextPage:C.hasNextPage,hasPrevPage:C.hasPrevPage,nextCursor:et(C.nextCursor),prevCursor:et(C.prevCursor)};Ee(m,E,{pageSize:l,hasMore:C.hasNextPage});}catch(p){Ct(m,p,{ref:f.repo.ref,path:f.path,isGroup:!!f.isGroup,filters:d,sort:a},"Failed to query documents",n);}}async function c(x,m){let y=x.params||{},f=r(y.repoName,m);if(!f)return;let d=y.id;if(!d){V(m,"Document ID required",400);return}try{let a=await o(f,d);if(!a){V(m,"Document not found",404);return}Ee(m,a);}catch(a){Ct(m,a,{ref:f.repo.ref,path:f.path,isGroup:!!f.isGroup,filters:[{field:f.documentKey,op:"==",value:d}]},"Failed to fetch document",n);}}async function g(x,m){let y=x.params||{},f=r(y.repoName,m);if(f)try{let d=x.body??{},a=On(f.schema,d,f.createFields,!1,f.systemKeys);if(!a.success){V(m,a.error,400);return}if(f.validate){let l=await f.validate(a.data,"create");if(l){V(m,l,400);return}}let p;if(f.isGroup&&f.parentKeys&&f.parentKeys.length>0){let l={...a.data};f.createdKey&&(l[f.createdKey]=new Date);let b=f.parentKeys.filter(E=>!l[E]);if(b.length>0){V(m,`Missing parent key(s) for subcollection create: ${b.join(", ")}`,400);return}let v=f.parentKeys.map(E=>l[E]),C=l[f.documentKey]||Ur();p=await f.repo.set(...v,C,l);}else p=await f.repo.create(a.data);Ee(m,p,void 0,201);}catch(d){let a=n&&d instanceof Error?d.message:"Failed to create document";V(m,a,500);}}async function h(x,m,y){let f=x.params||{},d=r(f.repoName,m);if(!d)return;let a=f.id;if(!a){V(m,"Document ID required",400);return}try{let p=x.body??{},l=On(d.schema,p,d.mutableFields,y,d.systemKeys);if(!l.success){V(m,l.error,400);return}if(d.validate){let E=await d.validate(l.data,"update");if(E){V(m,E,400);return}}let b=await o(d,a),v=(b&&s(b,d.pathKey))??[a],C=await d.repo.update(...v,l.data);Ee(m,C);}catch(p){let l=n&&p instanceof Error?p.message:"Failed to update document";V(m,l,500);}}async function k(x,m){let y=x.params||{},f=r(y.repoName,m);if(!f)return;if(!f.allowDelete){V(m,"Delete not allowed for this repository",403);return}let d=y.id;if(!d){V(m,"Document ID required",400);return}try{let a=await o(f,d),p=(a&&s(a,f.pathKey))??[d];await f.repo.delete(...p),Ee(m,{deleted:!0});}catch(a){let p=n&&a instanceof Error?a.message:"Failed to delete document";V(m,p,500);}}function w(x,m){m.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:i,handleQuery:u,handleGet:c,handleCreate:g,handleUpdate:h,handleDelete:k,handleOptions:w}}function Tt(e){try{return zod.z.toJSONSchema(e,{target:"openapi-3.1",unrepresentable:"any",override:t=>{let n=t.zodSchema?._zod?.def;n&&(n.type==="date"?(t.jsonSchema.type="string",t.jsonSchema.format="date-time"):n.type==="bigint"&&(t.jsonSchema.type="string",t.jsonSchema.format="int64"));}})}catch(t){return typeof console<"u"&&console.warn&&console.warn("[generateOpenAPISpec] Failed to convert Zod schema to JSON Schema; falling back to {type:object}.",t),{type:"object"}}}function te(e){return {$ref:`#/components/schemas/${e}`}}function Q(e){return {description:e,content:{"application/json":{schema:te("ErrorResponse")}}}}function Ue(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function Pn(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 Vr(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 Gr(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],r=[];for(let s of t){r.push({name:s,in:"query",schema:{type:"string"},description:`Filter by ${s} (equality)`});for(let o of n)r.push({name:`${s}__${o}`,in:"query",schema:{type:"string"},description:`Filter ${s} with operator ${o}`});}return r}function Jr(){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 Wr(e,t,n,r,s){let o={},i=e.name,u=`${t}/${e.name}`,c=`${u}/{${e.documentKey}}`,g={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};o[u]={get:{operationId:`list${ge(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[i],parameters:[...Vr(e),...Gr(e)],responses:{200:Pn(te(n)),500:Q("Internal server error")}},post:{operationId:`create${ge(e.name)}`,summary:`Create a ${ae(e.name)}`,tags:[i],requestBody:{required:true,content:{"application/json":{schema:te(r??n)}}},responses:{201:Ue("Document created",te(n)),400:Q("Validation error"),500:Q("Internal server error")}}},o[`${u}/query`]={post:{operationId:`query${ge(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[i],requestBody:{required:true,content:{"application/json":{schema:te("QueryRequestBody")}}},responses:{200:Pn(te(n)),400:Q("Invalid query"),500:Q("Internal server error")}}};let h={};return h.get={operationId:`get${ge(ae(e.name))}`,summary:`Get a single ${ae(e.name)}`,tags:[i],parameters:[g],responses:{200:Ue("Document found",te(n)),404:Q("Document not found"),500:Q("Internal server error")}},h.put={operationId:`update${ge(ae(e.name))}`,summary:`Update a ${ae(e.name)} (full replace)`,tags:[i],parameters:[g],requestBody:{required:true,content:{"application/json":{schema:te(s??n)}}},responses:{200:Ue("Document updated",te(n)),400:Q("Validation error"),404:Q("Document not found"),500:Q("Internal server error")}},h.patch={operationId:`patch${ge(ae(e.name))}`,summary:`Partially update a ${ae(e.name)}`,tags:[i],parameters:[g],requestBody:{required:true,content:{"application/json":{schema:{allOf:[te(s??n)],description:"All fields are optional for partial updates"}}}},responses:{200:Ue("Document patched",te(n)),400:Q("Validation error"),404:Q("Document not found"),500:Q("Internal server error")}},e.allowDelete&&(h.delete={operationId:`delete${ge(ae(e.name))}`,summary:`Delete a ${ae(e.name)}`,tags:[i],parameters:[g],responses:{200:Ue("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:Q("Document not found"),500:Q("Internal server error")}}),o[c]=h,o}function Et(e,t,n={}){let{title:r="CRUD API",version:s="1.0.0",description:o,servers:i,auth:u=false}=n,c=t==="/"?"":t.replace(/\/$/,""),g={},h={},k=[];g.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},g.QueryRequestBody=Jr();for(let[y,f]of Object.entries(e)){let d=ge(ae(y)),a=`${d}Create`,p=`${d}Update`;g[d]=Tt(f.schema);let l=S=>{let $=S&&S.length>0?S:Object.keys(f.schema.shape),O={};for(let A of $){let T=A.split(".")[0];T&&f.schema.shape[T]&&!f.systemKeys.includes(T)&&(O[T]=f.schema.shape[T]);}return O},b=null,v=l(f.createFields);Object.keys(v).length>0&&(g[a]=Tt(zod.z.object(v)),b=a);let C=null,E=l(f.mutableFields);Object.keys(E).length>0&&(g[p]=Tt(zod.z.object(E)),C=p);let R=Wr(f,c,d,b,C);Object.assign(h,R),k.push({name:y,description:`Operations on ${y} (collection: ${f.path})`});}let w={},x;return u==="basic"?(w.basicAuth={type:"http",scheme:"basic"},x=[{basicAuth:[]}]):u==="bearer"&&(w.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},x=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:r,version:s,...o?{description:o}:{}},...i&&i.length>0?{servers:i}:{},paths:h,components:{schemas:g,...Object.keys(w).length>0?{securitySchemes:w}:{}},...x?{security:x}:{},tags:k}}function ge(e){return e.charAt(0).toUpperCase()+e.slice(1)}function ae(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 Qr(e,t){return `<!DOCTYPE html>
1136
1136
  <html lang="en">
1137
1137
  <head>
1138
1138
  <meta charset="utf-8" />
@@ -1143,5 +1143,5 @@ function initColumnReorder(table) {
1143
1143
  <script id="api-reference" data-url="${t}"></script>
1144
1144
  <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
1145
1145
  </body>
1146
- </html>`}function zr(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",l=process.env.FUNCTION_REGION??"us-central1",p=process.env.FUNCTION_TARGET??"";return `/${o}/${l}/${p}${n}`}let r=process.env.K_SERVICE,s=e?.hostname??e?.headers?.host??"";return r&&s.includes("cloudfunctions.net")?`/${r.toLowerCase()}${n}`:n}async function Zr(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function xn(e){let{basePath:t="/",repos:n,parseBody:r=true,auth:s,middleware:o=[],verbose:l=false,httpsOptions:p}=e,u=t==="/"?"":t.replace(/\/$/,""),g={};for(let[d,c]of Object.entries(n)){let a=c.schema??c.repo.schema??null;if(!a)throw new Error(`[createCrudServer] Repository "${d}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let f,v,S;if(c.fieldsConfig){let x=c.fieldsConfig;f=[],v=[],S=[];for(let[R,$]of Object.entries(x))for(let T of $)T==="filterable"?f.push(R):T==="mutable"?v.push(R):T==="create"&&S.push(R);f.length===0&&(f=void 0),v.length===0&&(v=void 0),S.length===0&&(S=void 0);}let O=(()=>{let x=c.repo._parentKeys;return x&&x.length>0?x:void 0})();if(O&&S)for(let x of O)S.includes(x)||S.push(x);let A={name:d,path:c.path,repo:c.repo,schema:a,systemKeys:c.repo._systemKeys??[c.documentKey??"docId"],documentKey:c.documentKey??"docId",pathKey:c.repo._pathKey??void 0,isGroup:!!c.repo._isGroup,parentKeys:O,createdKey:c.repo._createdKey??void 0,pageSize:c.pageSize??25,filterableFields:f,mutableFields:v,createFields:S,allowDelete:c.allowDelete??false,allowedIncludes:c.allowedIncludes,validate:c.validate};g[d]=A;}let h=hn(g,u,l),k=e.openapi,w=k&&typeof k=="object"?k:{},b=null;function m(){if(!b){let d=s&&typeof s!="function"?"basic":s?"bearer":false;b=$t(g,u,{...w,auth:w.auth??d});}return b}let y=new Y;if(y.use((d,c,a)=>{c.set("Access-Control-Allow-Origin","*"),c.set("Access-Control-Allow-Credentials","true"),a();}),r&&y.use(async(d,c,a)=>{let f=d;if(String(f.headers?.["content-type"]??"").includes("application/json")){if(typeof f.body=="string")try{d.body=JSON.parse(f.body);}catch{}else if(Buffer.isBuffer(d.rawBody))try{let S=await Zr(f);d.body=JSON.parse(S);}catch{}}await a();}),s)if(typeof s=="function")y.use(s);else {let d=s.realm??"API",c="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");y.use((a,f,v)=>{if((a.headers?.authorization??"")!==c){f.status(401).set("WWW-Authenticate",`Basic realm="${d}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}v();});}for(let d of o)y.use(d);if(k!==false){let d=`${u}/__spec.json`,c=`${u}/__docs`;y.get(d,(a,f)=>{let v=m();f.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(v,null,2));}),y.get(c,(a,f)=>{let v=zr(a,u)+"/__spec.json",S=jr(w.title??"CRUD API",v);f.status(200).set("Content-Type","text/html; charset=utf-8").send(S);});}y.use((d,c,a)=>{if(d.method==="OPTIONS"){h.handleOptions(d,c);return}a();}),y.get(`${u}/:repoName`,h.handleList),y.post(`${u}/:repoName/query`,h.handleQuery),y.get(`${u}/:repoName/:id`,h.handleGet),y.post(`${u}/:repoName`,h.handleCreate),y.put(`${u}/:repoName/:id`,(d,c)=>h.handleUpdate(d,c,false)),y.patch(`${u}/:repoName/:id`,(d,c)=>h.handleUpdate(d,c,true)),y.delete(`${u}/:repoName/:id`,h.handleDelete);let i=async(d,c)=>{await y.handle(d,c);};return i.spec=m,p&&(i.httpsOptions=p),i}function wn(e,t){if(!t.onRequest)return e;let n=e.httpsOptions??t.httpsOptions;return n?t.onRequest(n,e):t.onRequest(e)}function Rn(e,t,n){let r={};for(let[s,o]of Object.entries(t)){if(!o)continue;let l=e[s];if(!l)throw new Error(`[createServers.${n}] Unknown repo "${s}" \u2014 not present in the registry passed to createServers().`);r[s]={...o,repo:l};}return r}function Fr(e,t={}){return {admin(n){let r=Rn(e,n.repos,"admin"),s=ln({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return wn(s,t)},crud(n){let r=Rn(e,n.repos,"crud"),s=xn({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return wn(s,t)},sync(n){let r={...n};return t.onRequest&&r.admin&&!r.admin.onRequest&&(r.admin={...r.admin,onRequest:t.onRequest,httpsOptions:r.admin.httpsOptions??t.httpsOptions}),Zt(e,r)}}}exports.CSS=dr;exports.ClientScript=_e;exports.MiniRouter=Y;exports.createServers=Fr;exports.renderDashboard=lt;exports.renderField=We;exports.renderForm=ie;exports.renderFormPage=ue;exports.renderList=ct;exports.renderPage=Ge;exports.zodToFields=ne;//# sourceMappingURL=index.cjs.map
1146
+ </html>`}function Xr(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",i=process.env.FUNCTION_REGION??"us-central1",u=process.env.FUNCTION_TARGET??"";return `/${o}/${i}/${u}${n}`}let r=process.env.K_SERVICE,s=e?.hostname??e?.headers?.host??"";return r&&s.includes("cloudfunctions.net")?`/${r.toLowerCase()}${n}`:n}async function Yr(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function In(e){let{basePath:t="/",repos:n,parseBody:r=true,auth:s,middleware:o=[],verbose:i=false,httpsOptions:u}=e,c=t==="/"?"":t.replace(/\/$/,""),g={};for(let[d,a]of Object.entries(n)){let p=a.schema??a.repo.schema??null;if(!p)throw new Error(`[createCrudServer] Repository "${d}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let l,b,v;if(a.fieldsConfig){let R=a.fieldsConfig;l=[],b=[],v=[];for(let[S,$]of Object.entries(R))for(let O of $)O==="filterable"?l.push(S):O==="mutable"?b.push(S):O==="create"&&v.push(S);l.length===0&&(l=void 0),b.length===0&&(b=void 0),v.length===0&&(v=void 0);}let C=(()=>{let R=a.repo._parentKeys;return R&&R.length>0?R:void 0})();if(C&&v)for(let R of C)v.includes(R)||v.push(R);let E={name:d,path:a.path,repo:a.repo,schema:p,systemKeys:a.repo._systemKeys??[a.documentKey??"docId"],documentKey:a.documentKey??"docId",pathKey:a.repo._pathKey??void 0,isGroup:!!a.repo._isGroup,parentKeys:C,createdKey:a.repo._createdKey??void 0,pageSize:a.pageSize??25,filterableFields:l,mutableFields:b,createFields:v,allowDelete:a.allowDelete??false,allowedIncludes:a.allowedIncludes,validate:a.validate};g[d]=E;}let h=En(g,c,i),k=e.openapi,w=k&&typeof k=="object"?k:{},x=null;function m(){if(!x){let d=s&&typeof s!="function"?"basic":s?"bearer":false;x=Et(g,c,{...w,auth:w.auth??d});}return x}let y=new ne;if(y.use((d,a,p)=>{a.set("Access-Control-Allow-Origin","*"),a.set("Access-Control-Allow-Credentials","true"),p();}),r&&y.use(async(d,a,p)=>{let l=d;if(String(l.headers?.["content-type"]??"").includes("application/json")){if(typeof l.body=="string")try{d.body=JSON.parse(l.body);}catch{}else if(Buffer.isBuffer(d.rawBody))try{let v=await Yr(l);d.body=JSON.parse(v);}catch{}}await p();}),s)if(typeof s=="function")y.use(s);else {let d=s.realm??"API",a="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");y.use((p,l,b)=>{if((p.headers?.authorization??"")!==a){l.status(401).set("WWW-Authenticate",`Basic realm="${d}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}b();});}for(let d of o)y.use(d);if(k!==false){let d=`${c}/__spec.json`,a=`${c}/__docs`;y.get(d,(p,l)=>{let b=m();l.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(b,null,2));}),y.get(a,(p,l)=>{let b=Xr(p,c)+"/__spec.json",v=Qr(w.title??"CRUD API",b);l.status(200).set("Content-Type","text/html; charset=utf-8").send(v);});}y.use((d,a,p)=>{if(d.method==="OPTIONS"){h.handleOptions(d,a);return}p();}),y.get(`${c}/:repoName`,h.handleList),y.post(`${c}/:repoName/query`,h.handleQuery),y.get(`${c}/:repoName/:id`,h.handleGet),y.post(`${c}/:repoName`,h.handleCreate),y.put(`${c}/:repoName/:id`,(d,a)=>h.handleUpdate(d,a,false)),y.patch(`${c}/:repoName/:id`,(d,a)=>h.handleUpdate(d,a,true)),y.delete(`${c}/:repoName/:id`,h.handleDelete);let f=async(d,a)=>{await y.handle(d,a);};return f.spec=m,u&&(f.httpsOptions=u),f}function Nn(e,t){if(!t.onRequest)return e;let n=e.httpsOptions??t.httpsOptions;return n?t.onRequest(n,e):t.onRequest(e)}function _n(e,t,n){let r={};for(let[s,o]of Object.entries(t)){if(!o)continue;let i=e[s];if(!i)throw new Error(`[createServers.${n}] Unknown repo "${s}" \u2014 not present in the registry passed to createServers().`);r[s]={...o,repo:i};}return r}function es(e,t={}){return {admin(n){let r=_n(e,n.repos,"admin"),s=xn({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Nn(s,t)},crud(n){let r=_n(e,n.repos,"crud"),s=In({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Nn(s,t)},sync(n){let r={...n};return t.onRequest&&r.admin&&!r.admin.onRequest&&(r.admin={...r.admin,onRequest:t.onRequest,httpsOptions:r.admin.httpsOptions??t.httpsOptions}),Wt(e,r)},history(n){return zt(e,n)}}}exports.CSS=$r;exports.ClientScript=ze;exports.MiniRouter=ne;exports.createServers=es;exports.renderDashboard=mt;exports.renderField=rt;exports.renderForm=ue;exports.renderFormPage=ye;exports.renderList=yt;exports.renderPage=Me;exports.zodToFields=oe;//# sourceMappingURL=index.cjs.map
1147
1147
  //# sourceMappingURL=index.cjs.map