@lpdjs/firestore-repo-service 2.6.16 → 2.6.18

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.
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {Timestamp}from'firebase-admin/firestore';import {randomUUID,randomBytes}from'crypto';import {z}from'zod';import {renderToString}from'hono/jsx/dom/server';var Xn=Object.defineProperty;var Je=(e,t)=>()=>(e&&(t=e(e=0)),t);var Yn=(e,t)=>{for(var n in t)Xn(e,n,{get:t[n],enumerable:true});};function L(e){let t=e,n=t._zod?.def?.type;if(n)return lr[n]??`Zod${n.charAt(0).toUpperCase()}${n.slice(1)}`;let r=t._def?.typeName;return r||""}function G(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function Kt(e){let t=e,n=t._zod?.def?.in;if(n)return n;if(t._def?.schema)return t._def.schema}function Vt(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function Wt(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 ne(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 Fe(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 je(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 ze(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function Gt(e){let t=e;return Array.isArray(t.options)?t.options:Array.isArray(t._zod?.def?.options)?t._zod.def.options:Array.isArray(t._def?.options)?t._def.options:[]}function Jt(e){let t=e,n=[],r=t._zod?.def?.checks;if(Array.isArray(r)){for(let s of r)s.format&&n.push(s.format);if(n.length>0)return n}let o=t._def?.checks;if(Array.isArray(o))for(let s of o)s.kind&&n.push(s.kind);return n}var lr,Ze=Je(()=>{lr={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 gn({val:e}){return jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function Tr({message:e}){return 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:jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",class:"size-3.5",children:jsx("path",{d:"M12 2 1 22h22L12 2zm0 6 7.5 13h-15L12 8zm-1 4v4h2v-4h-2zm0 5v2h2v-2h-2z"})})})}function Oe({val:e,mismatch:t}){let n=Or(e);return t?jsxs("span",{class:"inline-flex items-start gap-0.5",children:[n,jsx(Tr,{message:t})]}):n}function Or(e){if(e==null)return jsx("span",{class:"opacity-30 italic text-xs",children:"\u2014"});if(typeof e=="boolean")return e?jsx("span",{class:"badge badge-success badge-sm",children:"true"}):jsx("span",{class:"badge badge-error badge-sm",children:"false"});if(e instanceof Date)return jsx(gn,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsx(gn,{val:e.toDate()});if(typeof e=="number")return jsx("span",{class:"text-sm font-mono tabular-nums",children:String(e)});if(Array.isArray(e))return e.length===0?jsx("span",{class:"text-xs text-base-content/30",children:"[]"}):jsxs("ul",{class:"list-none p-0 m-0 space-y-0.5 text-xs",children:[e.slice(0,8).map((n,r)=>jsx("li",{class:"break-all",children:typeof n=="object"?JSON.stringify(n):String(n)},r)),e.length>8&&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?jsx("span",{class:"text-xs text-base-content/30",children:"{}"}):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,o])=>jsxs(Fragment,{children:[jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:r}),jsx("dd",{class:"break-all",children:String(o??"")})]})),n.length>8&&jsxs("dt",{class:"col-span-2 text-base-content/40 italic",children:["+",n.length-8," more\u2026"]})]})}let t=String(e);return jsx("span",{class:"text-sm break-all",children:t})}var tt=Je(()=>{});function Ee(e){if(!e)return "unknown";let t=ft(e);switch(L(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 ft(e){let t=L(e);if(t==="ZodOptional"||t==="ZodNullable"||t==="ZodDefault"){let n=G(e);return n?ft(n):e}return e}function Pe(e,t){if(!e)return;let n=t.split("."),r=e;for(let o of n){if(!r)return;let s=ft(r);if(L(s)!=="ZodObject")return;r=ne(s)[o];}return r}function _r(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 qe(e,t){if(e==="unknown")return null;let n=_r(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 mt=Je(()=>{Ze();});var vn={};Yn(vn,{PanelMany:()=>Dr,PanelOne:()=>Nr,RightPanel:()=>yt});function Nr({doc:e,repoName:t,basePath:n,schema:r,columns:o}){if(!e)return jsx("div",{class:"text-center py-12 text-base-content/50",children:"Document not found."});let s=String(e.docId??e.id??""),a=`${n}/${t}/${encodeURIComponent(s)}/edit`,f=bn(r,o);return jsxs("div",{class:"space-y-4",children:[jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxs("div",{class:"text-xs text-base-content/60",children:[jsx("span",{class:"font-mono",children:t}),jsx("span",{class:"opacity-50",children:" \xB7 "}),jsx("span",{class:"font-mono break-all",children:s})]}),jsx("a",{href:a,class:"btn btn-sm btn-primary",children:"Edit \u2192"})]}),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:o.map(d=>{let m=e[d],b=f[d],v=b?qe(b,m):null;return jsxs(Fragment,{children:[jsx("dt",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide pt-0.5",children:d}),jsx("dd",{class:"min-w-0",children:jsx(Oe,{val:m,mismatch:v})})]})})})]})}function Dr({docs:e,repoName:t,basePath:n,fk:r,fv:o,columns:s,schema:a,pagination:f}){let d=`${n}/${t}?fv_${r}=${encodeURIComponent(o)}`,m=bn(a,s);return jsxs("div",{class:"space-y-4",children:[jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxs("div",{class:"text-xs text-base-content/60",children:[jsx("span",{class:"font-mono",children:t}),jsx("span",{class:"opacity-50",children:" where "}),jsx("span",{class:"font-mono",children:r}),jsx("span",{class:"opacity-50",children:" = "}),jsx("span",{class:"font-mono break-all",children:o}),jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxs("span",{children:[e.length," doc",e.length!==1?"s":""]})]}),jsx("a",{href:d,class:"btn btn-sm btn-outline",children:"Full view \u2192"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100",children:jsxs("table",{class:"table table-xs w-full",children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[s.map((b,v)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:b},v)),jsx("th",{})]})}),jsx("tbody",{children:e.length===0?jsx("tr",{children:jsx("td",{colspan:s.length+1,class:"text-center py-10 text-base-content/40",children:"No related documents"})}):e.map((b,v)=>{let S=String(b.docId??b.id??""),C=`${n}/${t}/${encodeURIComponent(S)}/edit`;return jsxs("tr",{class:"hover",children:[s.map((k,x)=>{let $=b[k],g=m[k],i=g?qe(g,$):null;return jsx("td",{class:"align-top py-1.5",children:jsx(Oe,{val:$,mismatch:i})},x)}),jsx("td",{class:"text-right py-1.5",children:jsx("a",{href:C,class:"btn btn-xs btn-ghost",children:"Edit"})})]},v)})})]})}),(f.hasPrev||f.hasNext)&&jsxs("div",{class:"flex justify-center items-center gap-2",children:[f.hasPrev?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"prev","data-cursor":f.prevCursor,children:"\u2190 Previous"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"\u2190 Previous"}),f.hasNext?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"next","data-cursor":f.nextCursor,children:"Next \u2192"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"Next \u2192"})]})]})}function bn(e,t){if(!e)return {};let n={};for(let r of t)n[r]=Ee(Pe(e,r));return n}var yt,gt=Je(()=>{tt();mt();yt=({basePath:e=""})=>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:[jsx("div",{class:"absolute inset-0 bg-black/30 opacity-0 transition-opacity duration-200 pointer-events-auto","data-frs-panel-backdrop":true}),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:[jsxs("header",{class:"flex items-center justify-between px-5 py-3 border-b border-base-300 bg-base-200/40 shrink-0",children:[jsx("h2",{class:"font-semibold text-base truncate","data-frs-panel-title":true,children:"Relation"}),jsx("button",{type:"button",class:"btn btn-sm btn-ghost btn-circle","data-frs-panel-close":true,"aria-label":"Close panel",children:"\u2715"})]}),jsx("div",{class:"flex-1 overflow-auto p-5 text-sm","data-frs-panel-body":true,children:jsx("div",{class:"flex items-center justify-center py-12 text-base-content/40",children:jsx("span",{class:"loading loading-spinner loading-md"})})})]})]});});function zt(e){if(e===null)return "null";if(e===void 0)return "undefined";if(e instanceof 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 st(e,t,n=new WeakMap){if(e===t)return true;if(e===null||t===null||e===void 0||t===void 0)return e===t;if(e instanceof Timestamp&&t instanceof 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(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length)return false;if(n.get(e)===t)return true;n.set(e,t);for(let r=0;r<e.length;r++)if(!st(e[r],t[r],n))return false;return true}if(typeof e=="object"&&typeof t=="object"){if(e instanceof Date||t instanceof Date||e instanceof Timestamp||t instanceof Timestamp)return false;if(n.get(e)===t)return true;n.set(e,t);let r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return false;for(let s of r)if(!Object.prototype.hasOwnProperty.call(t,s)||!st(e[s],t[s],n))return false;return true}return false}function Zt(e,t,n={}){let r=new Set([...n.exclude??[],...n.metaFields??[],...n.systemKeys??[]]),o=n.include?new Set(n.include):null,s=e??{},a=t??{},f=new Set([...Object.keys(s),...Object.keys(a)]),d={};for(let m of f){if(r.has(m)||o&&!o.has(m))continue;let b=s[m],v=a[m];st(b,v)||(d[m]={oldValue:b===void 0?null:b,newValue:v===void 0?null:v,type:{old:zt(b),new:zt(v)}});}return d}var tr=7e5;function Bt(e){let t=e.ttlOverride??e.config.ttl,r={schemaVersion:2,historyDocId:randomUUID(),historyToObjectId:e.entityId,historySetAt:Timestamp.now(),operation:e.operation,meta:e.meta,changes:e.changes};t&&(r.expiresAt=Timestamp.fromMillis(Date.now()+t.days*24*60*60*1e3));let o=s=>{try{return Buffer.byteLength(JSON.stringify(s,(a,f)=>f instanceof Timestamp?f.toMillis():f),"utf8")}catch{return 0}};if(o(r.changes)>tr){let s={};for(let[a,f]of Object.entries(r.changes)){let d=o(f.oldValue),m=o(f.newValue);s[a]={oldValue:d>5e4?"[truncated]":f.oldValue,newValue:m>5e4?"[truncated]":f.newValue,type:f.type};}r.changes=s,r._truncated=true;}return r}async function Mt(e,t,n,r){let o=t;return n.onBeforeWrite&&(o=await n.onBeforeWrite(t,r)),o?(await e.doc(o.historyDocId).set(o),{written:true,entry:o}):{written:false,reason:"dropped-by-onBeforeWrite"}}function Ht(e,t){let n=e??{},r={},o=t.meta;if(!o)return r;let s=b=>{if(!b)return;let v=n[b];return v===void 0||v===null?null:String(v)},a=s(o.userId);a!==void 0&&(r.userId=a);let f=s(o.userEmail);f!==void 0&&(r.userEmail=f);let d=s(o.reason);d!==void 0&&(r.reason=d);let m=s(o.comment);if(m!==void 0&&(r.comment=m),o.extras&&o.extras.length>0){let b={},v=false;for(let S of o.extras)S in n&&(b[S]=n[S],v=true);v&&(r.extras=b);}return r}function qt(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 nr="history";function rr(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 Lt(e,t){let{onDocumentWritten:n}=t.deps,r={};for(let[o,s]of Object.entries(e)){let a=s._historyConfig??(typeof s.history=="object"&&s.history!==null&&"enabled"in s.history?s.history:void 0);if(!a?.enabled)continue;let f=a.subcollection??nr,d=a.ttl??t.defaults?.ttl,m=t.repos?.[o],b;if(s._isGroup){if(!m?.triggerPath){console.warn(`[HistoryTriggers] Skipping collection-group repo "${o}". Provide a triggerPath in the history triggers repos override.`);continue}b=m.triggerPath;}else b=m?.triggerPath??rr(o,s);if(!b)continue;let v=s._systemKeys??[],S=v[0]??"docId",C=qt(a);r[`${o}_onHistory`]=n(b,async k=>{try{let x=k.data?.before?.data(),$=k.data?.after?.data(),g;if(!x&&$)g="create";else if(x&&!$)g="delete";else if(x&&$)g="update";else return;let i=String($?.[S]??x?.[S]??k.params?.docId??k.data?.after?.id??k.data?.before?.id??"");if(!i)return;let u=Zt(x??{},$??{},{include:a.include,exclude:a.exclude,metaFields:C,systemKeys:v});if(g==="update"&&Object.keys(u).length===0)return;let c=Ht($??x??null,a),l=Bt({entityId:i,operation:g,changes:u,meta:c,config:a,ttlOverride:d}),p=k.data?.after?.ref??k.data?.before?.ref;if(!p)return;let y=p.collection(f);await Mt(y,l,a,{repoName:o,docId:i,before:x??null,after:$??null});}catch(x){console.error(`[HistoryTriggers] Failed to record history for "${o}":`,x);}});}return r}function or(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,r=>r===":"?r:`\\${r}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(r,o)=>(t.push(o),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function sr(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var ae=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:o,paramNames:s}=or(n);return this.routes.push({method:t.toUpperCase(),pattern:o,paramNames:s,handler:r}),this}async handle(t,n){let r=(t.method??"GET").toUpperCase(),o=sr(t),s=null,a={};for(let m of this.routes){if(m.method!==r)continue;let b=o.match(m.pattern);if(b){s=m,a={},m.paramNames.forEach((v,S)=>{a[v]=decodeURIComponent(b[S+1]??"");});break}}let f=Object.assign(t,{params:a}),d=s?s.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,n,d);}catch(m){this.errorHandler(m,t,n);}}async runMiddlewareChain(t,n,r){let o=0,s=async()=>{if(o<this.middlewares.length){let a=this.middlewares[o++];await a(t,n,s);}else await r(t,n);};await s();}};function te(e,t,n){let r=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let a=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",f=n??process.env.FUNCTION_REGION??"us-central1",d=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${a}/${f}/${d}${r}`}let o=process.env.K_SERVICE,s=e?.hostname??e?.headers?.host??"";return o&&typeof s=="string"&&s.includes("cloudfunctions.net")?`/${o.toLowerCase()}${r}`:r}function Ut(e){if(typeof e=="string")return e;if(Array.isArray(e)){let t=e[0];return typeof t=="string"?t:void 0}}function me(e){return !!e&&typeof e=="object"&&e.__authExtension===true}Ze();var ye="__sync_version";var cr=new Set(["ZodOptional","ZodNullable","ZodDefault"]);function dr(e){let t=e,n=false;for(;;){let r=L(t);if(!cr.has(r))break;(r==="ZodOptional"||r==="ZodNullable")&&(n=true);let o=G(t);if(!o)break;t=o;}return {inner:t,nullable:n}}var ur={ZodString:"string",ZodNumber:"number",ZodBigInt:"bigint",ZodBoolean:"boolean",ZodDate:"timestamp",ZodEnum:"string",ZodNativeEnum:"string",ZodLiteral:"string"};function Qt(e,t,n,r,o,s,a,f){for(let[d,m]of Object.entries(e)){let b=n?`${n}__${d}`:d;if(o.has(d)||o.has(b))continue;let{inner:v,nullable:S}=dr(m),C=L(v),k=r||S;if(C==="ZodObject"){let i=ne(v);Qt(i,t,b,k,o,s,a,f);continue}let x=ur[C]??"json",$=b===a||d===a,g=s[b]??s[d]??b;f.push({name:g,sqlType:t.mapType(x),nullable:$?false:k,isPrimaryKey:$});}}function Qe(e,t,n={}){let{primaryKey:r,exclude:o=[],columnMap:s={}}=n,a=new Set(o),f=ne(e),d=[];return Qt(f,t,"",false,a,s,r,d),d.some(m=>m.name===ye)||d.push({name:ye,sqlType:t.mapType("bigint"),nullable:true,isPrimaryKey:false,description:"Monotonic publish version (Date.now() ms). Internal."}),d}function Xt(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(Xt)):e}var pr=32,fr=5e3;function Yt(e,t,n,r=new WeakSet,o=0){if(o>pr){n[t||"_truncated"]=JSON.stringify({__truncated:true});return}if(r.has(e)){n[t||"_cycle"]=JSON.stringify({__cycle:true});return}r.add(e);for(let[s,a]of Object.entries(e)){if(Object.keys(n).length>=fr)break;let f=t?`${t}__${s}`:s;a!=null&&typeof a=="object"&&!Array.isArray(a)&&!(a instanceof Date)&&!Buffer.isBuffer(a)&&!(a instanceof Uint8Array)&&typeof a.toDate!="function"&&!("latitude"in a&&"longitude"in a)?Yt(a,f,n,r,o+1):n[f]=Xt(a);}r.delete(e);}function Be(e,t){let n=new Set(t?.exclude),r=t?.columnMap??{},o={};Yt(e,"",o);let s={};for(let[a,f]of Object.entries(o)){if(n.has(a))continue;let d=a.split("__")[0];if(d!==a&&n.has(d))continue;let m=r[a]??(a.includes("__")?r[a.split("__").pop()]:void 0)??a;s[m]=f;}return s}function ue(e,t,n){return `<!DOCTYPE html>
1
+ import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {Timestamp}from'firebase-admin/firestore';import {randomUUID,randomBytes}from'crypto';import {z}from'zod';import {renderToString}from'hono/jsx/dom/server';var tr=Object.defineProperty;var Je=(e,t)=>()=>(e&&(t=e(e=0)),t);var nr=(e,t)=>{for(var n in t)tr(e,n,{get:t[n],enumerable:true});};function q(e){let t=e,n=t._zod?.def?.type;if(n)return br[n]??`Zod${n.charAt(0).toUpperCase()}${n.slice(1)}`;let r=t._def?.typeName;return r||""}function W(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function en(e){let t=e,n=t._zod?.def?.in;if(n)return n;if(t._def?.schema)return t._def.schema}function tn(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function nn(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 ne(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 je(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 Me(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 He(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function rn(e){let t=e;return Array.isArray(t.options)?t.options:Array.isArray(t._zod?.def?.options)?t._zod.def.options:Array.isArray(t._def?.options)?t._def.options:[]}function on(e){let t=e,n=[],r=t._zod?.def?.checks;if(Array.isArray(r)){for(let s of r)s.format&&n.push(s.format);if(n.length>0)return n}let o=t._def?.checks;if(Array.isArray(o))for(let s of o)s.kind&&n.push(s.kind);return n}var br,Be=Je(()=>{br={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 kn({val:e}){return jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function Br({message:e}){return 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:jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",class:"size-3.5",children:jsx("path",{d:"M12 2 1 22h22L12 2zm0 6 7.5 13h-15L12 8zm-1 4v4h2v-4h-2zm0 5v2h2v-2h-2z"})})})}function Ee({val:e,mismatch:t}){let n=zr(e);return t?jsxs("span",{class:"inline-flex items-start gap-0.5",children:[n,jsx(Br,{message:t})]}):n}function zr(e){if(e==null)return jsx("span",{class:"opacity-30 italic text-xs",children:"\u2014"});if(typeof e=="boolean")return e?jsx("span",{class:"badge badge-success badge-sm",children:"true"}):jsx("span",{class:"badge badge-error badge-sm",children:"false"});if(e instanceof Date)return jsx(kn,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsx(kn,{val:e.toDate()});if(typeof e=="number")return jsx("span",{class:"text-sm font-mono tabular-nums",children:String(e)});if(Array.isArray(e))return e.length===0?jsx("span",{class:"text-xs text-base-content/30",children:"[]"}):jsxs("ul",{class:"list-none p-0 m-0 space-y-0.5 text-xs",children:[e.slice(0,8).map((n,r)=>jsx("li",{class:"break-all",children:typeof n=="object"?JSON.stringify(n):String(n)},r)),e.length>8&&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?jsx("span",{class:"text-xs text-base-content/30",children:"{}"}):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,o])=>jsxs(Fragment,{children:[jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:r}),jsx("dd",{class:"break-all",children:String(o??"")})]})),n.length>8&&jsxs("dt",{class:"col-span-2 text-base-content/40 italic",children:["+",n.length-8," more\u2026"]})]})}let t=String(e);return jsx("span",{class:"text-sm break-all",children:t})}var rt=Je(()=>{});function Pe(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=W(e);return n?St(n):e}return e}function De(e,t){if(!e)return;let n=t.split("."),r=e;for(let o of n){if(!r)return;let s=St(r);if(q(s)!=="ZodObject")return;r=ne(s)[o];}return r}function Ur(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 qe(e,t){if(e==="unknown")return null;let n=Ur(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 Rt=Je(()=>{Be();});var An={};nr(An,{PanelMany:()=>Vr,PanelOne:()=>Kr,RightPanel:()=>kt});function Kr({doc:e,repoName:t,basePath:n,schema:r,columns:o}){if(!e)return jsx("div",{class:"text-center py-12 text-base-content/50",children:"Document not found."});let s=String(e.docId??e.id??""),a=`${n}/${t}/${encodeURIComponent(s)}/edit`,f=Cn(r,o);return jsxs("div",{class:"space-y-4",children:[jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxs("div",{class:"text-xs text-base-content/60",children:[jsx("span",{class:"font-mono",children:t}),jsx("span",{class:"opacity-50",children:" \xB7 "}),jsx("span",{class:"font-mono break-all",children:s})]}),jsx("a",{href:a,class:"btn btn-sm btn-primary",children:"Edit \u2192"})]}),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:o.map(d=>{let m=e[d],v=f[d],R=v?qe(v,m):null;return jsxs(Fragment,{children:[jsx("dt",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide pt-0.5",children:d}),jsx("dd",{class:"min-w-0",children:jsx(Ee,{val:m,mismatch:R})})]})})})]})}function Vr({docs:e,repoName:t,basePath:n,fk:r,fv:o,columns:s,schema:a,pagination:f}){let d=`${n}/${t}?fv_${r}=${encodeURIComponent(o)}`,m=Cn(a,s);return jsxs("div",{class:"space-y-4",children:[jsxs("div",{class:"flex items-center justify-between gap-2",children:[jsxs("div",{class:"text-xs text-base-content/60",children:[jsx("span",{class:"font-mono",children:t}),jsx("span",{class:"opacity-50",children:" where "}),jsx("span",{class:"font-mono",children:r}),jsx("span",{class:"opacity-50",children:" = "}),jsx("span",{class:"font-mono break-all",children:o}),jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxs("span",{children:[e.length," doc",e.length!==1?"s":""]})]}),jsx("a",{href:d,class:"btn btn-sm btn-outline",children:"Full view \u2192"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100",children:jsxs("table",{class:"table table-xs w-full",children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[s.map((v,R)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:v},R)),jsx("th",{})]})}),jsx("tbody",{children:e.length===0?jsx("tr",{children:jsx("td",{colspan:s.length+1,class:"text-center py-10 text-base-content/40",children:"No related documents"})}):e.map((v,R)=>{let A=String(v.docId??v.id??""),S=`${n}/${t}/${encodeURIComponent(A)}/edit`;return jsxs("tr",{class:"hover",children:[s.map((w,C)=>{let b=v[w],g=m[w],u=g?qe(g,b):null;return jsx("td",{class:"align-top py-1.5",children:jsx(Ee,{val:b,mismatch:u})},C)}),jsx("td",{class:"text-right py-1.5",children:jsx("a",{href:S,class:"btn btn-xs btn-ghost",children:"Edit"})})]},R)})})]})}),(f.hasPrev||f.hasNext)&&jsxs("div",{class:"flex justify-center items-center gap-2",children:[f.hasPrev?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"prev","data-cursor":f.prevCursor,children:"\u2190 Previous"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"\u2190 Previous"}),f.hasNext?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"next","data-cursor":f.nextCursor,children:"Next \u2192"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"Next \u2192"})]})]})}function Cn(e,t){if(!e)return {};let n={};for(let r of t)n[r]=Pe(De(e,r));return n}var kt,Tt=Je(()=>{rt();Rt();kt=({basePath:e=""})=>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:[jsx("div",{class:"absolute inset-0 bg-black/30 opacity-0 transition-opacity duration-200 pointer-events-auto","data-frs-panel-backdrop":true}),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:[jsxs("header",{class:"flex items-center justify-between px-5 py-3 border-b border-base-300 bg-base-200/40 shrink-0",children:[jsx("h2",{class:"font-semibold text-base truncate","data-frs-panel-title":true,children:"Relation"}),jsx("button",{type:"button",class:"btn btn-sm btn-ghost btn-circle","data-frs-panel-close":true,"aria-label":"Close panel",children:"\u2715"})]}),jsx("div",{class:"flex-1 overflow-auto p-5 text-sm","data-frs-panel-body":true,children:jsx("div",{class:"flex items-center justify-center py-12 text-base-content/40",children:jsx("span",{class:"loading loading-spinner loading-md"})})})]})]});});function it(e){if(e===null)return "null";if(e===void 0)return "undefined";if(e instanceof 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 lt(e,t,n=new WeakMap){if(e===t)return true;if(e===null||t===null||e===void 0||t===void 0)return e===t;if(e instanceof Timestamp&&t instanceof 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(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length)return false;if(n.get(e)===t)return true;n.set(e,t);for(let r=0;r<e.length;r++)if(!lt(e[r],t[r],n))return false;return true}if(typeof e=="object"&&typeof t=="object"){if(e instanceof Date||t instanceof Date||e instanceof Timestamp||t instanceof Timestamp)return false;if(n.get(e)===t)return true;n.set(e,t);let r=Object.keys(e),o=Object.keys(t);if(r.length!==o.length)return false;for(let s of r)if(!Object.prototype.hasOwnProperty.call(t,s)||!lt(e[s],t[s],n))return false;return true}return false}function ct(e,t,n={}){let r=new Set([...n.exclude??[],...n.metaFields??[],...n.systemKeys??[]]),o=n.include?new Set(n.include):null,s=e??{},a=t??{},f=new Set([...Object.keys(s),...Object.keys(a)]),d={};for(let m of f){if(r.has(m)||o&&!o.has(m))continue;let v=s[m],R=a[m];lt(v,R)||(d[m]={oldValue:v===void 0?null:v,newValue:R===void 0?null:R,type:{old:it(v),new:it(R)}});}return d}var or=7e5;function ut(e){let t=e.ttlOverride??e.config.ttl,r={schemaVersion:2,historyDocId:randomUUID(),historyToObjectId:e.entityId,historySetAt:Timestamp.now(),operation:e.operation,meta:e.meta,changes:e.changes};t&&(r.expiresAt=Timestamp.fromMillis(Date.now()+t.days*24*60*60*1e3));let o=s=>{try{return Buffer.byteLength(JSON.stringify(s,(a,f)=>f instanceof Timestamp?f.toMillis():f),"utf8")}catch{return 0}};if(o(r.changes)>or){let s={};for(let[a,f]of Object.entries(r.changes)){let d=o(f.oldValue),m=o(f.newValue);s[a]={oldValue:d>5e4?"[truncated]":f.oldValue,newValue:m>5e4?"[truncated]":f.newValue,type:f.type};}r.changes=s,r._truncated=true;}return r}async function pt(e,t,n,r){let o=t;return n.onBeforeWrite&&(o=await n.onBeforeWrite(t,r)),o?(await e.doc(o.historyDocId).set(o),{written:true,entry:o}):{written:false,reason:"dropped-by-onBeforeWrite"}}function ft(e,t){let n=e??{},r={},o=t.meta;if(!o)return r;let s=v=>{if(!v)return;let R=n[v];return R===void 0||R===null?null:String(R)},a=s(o.userId);a!==void 0&&(r.userId=a);let f=s(o.userEmail);f!==void 0&&(r.userEmail=f);let d=s(o.reason);d!==void 0&&(r.reason=d);let m=s(o.comment);if(m!==void 0&&(r.comment=m),o.extras&&o.extras.length>0){let v={},R=false;for(let A of o.extras)A in n&&(v[A]=n[A],R=true);R&&(r.extras=v);}return r}function mt(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 sr="history";function ar(e){let t=e&&typeof e.history=="object"&&e.history!==null?e.history:void 0,n=[e?.documentKey,e?.pathKey,e?.createdKey,e?.updatedKey].filter(r=>typeof r=="string");return {historyConfig:t,systemKeys:n,isGroup:!!e?.isGroup,collectionPath:typeof e?.path=="string"?e.path:null}}function ir(e){return {historyConfig:e._historyConfig??(typeof e.history=="object"&&e.history!==null&&"enabled"in e.history?e.history:void 0),systemKeys:e._systemKeys??[],isGroup:!!e._isGroup,collectionPath:e.ref?.path??null}}function lr(e,t){return t?`${t}/{docId}`:(console.warn(`[HistoryTriggers] Cannot determine collection path for "${e}". Skipping.`),null)}function Kt(e,t){let{onDocumentWritten:n}=t.deps,r={},o=e?.rawMapping,s=o?Object.entries(o).map(([a,f])=>[a,ar(f)]):Object.entries(e).map(([a,f])=>[a,ir(f)]);for(let[a,f]of s){let d=f.historyConfig;if(!d?.enabled)continue;let m=d.subcollection??sr,v=d.ttl??t.defaults?.ttl,R=t.repos?.[a],A;if(f.isGroup){if(!R?.triggerPath){console.warn(`[HistoryTriggers] Skipping collection-group repo "${a}". Provide a triggerPath in the history triggers repos override.`);continue}A=R.triggerPath;}else A=R?.triggerPath??lr(a,f.collectionPath);if(!A)continue;let S=f.systemKeys,w=S[0]??"docId",C=mt(d);r[`${a}_onHistory`]=n(A,async b=>{try{let g=b.data?.before?.data(),u=b.data?.after?.data(),c;if(!g&&u)c="create";else if(g&&!u)c="delete";else if(g&&u)c="update";else return;let i=String(u?.[w]??g?.[w]??b.params?.docId??b.data?.after?.id??b.data?.before?.id??"");if(!i)return;let l=ct(g??{},u??{},{include:d.include,exclude:d.exclude,metaFields:C,systemKeys:S});if(c==="update"&&Object.keys(l).length===0)return;let p=ft(u??g??null,d),y=ut({entityId:i,operation:c,changes:l,meta:p,config:d,ttlOverride:v}),h=b.data?.after?.ref??b.data?.before?.ref;if(!h)return;let E=h.collection(m);await pt(E,y,d,{repoName:a,docId:i,before:g??null,after:u??null});}catch(g){console.error(`[HistoryTriggers] Failed to record history for "${a}":`,g);}});}return r}var Wt="preserve";function Gt(){return Wt}function cr(e){return typeof e=="object"&&e!==null&&typeof e._seconds=="number"&&typeof e._nanoseconds=="number"}function Jt(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(e instanceof Timestamp)return e.toDate();if(cr(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 Se(e){return e}function pr(e){if(typeof e!="function")return [];let n=e.toString().match(/^\s*(?:function\s*\w*\s*)?\(([^)]*)\)/);if(!n?.[1])return [];let r=n[1].split(",").map(o=>o.trim().replace(/\s*[:=].*$/,"").trim()).filter(Boolean);return r.length<=2?[]:r.slice(1,-1)}function fr(e){let t=[e?.documentKey,e?.pathKey,e?.createdKey,e?.updatedKey].filter(r=>typeof r=="string"),n=e?.history&&typeof e.history=="object"?e.history:void 0;return {schema:e?.schema,_systemKeys:t,_pathKey:e?.pathKey??null,_isGroup:!!e?.isGroup,_createdKey:e?.createdKey??null,_parentKeys:e?.isGroup?pr(e?.refCb):[],relationalKeys:e?.relationalKeys,_historyConfig:n,_historySubcollection:n?.enabled?n.subcollection??"history":void 0,_collectionPath:typeof e?.path=="string"?e.path:null}}function Xe(e,t){let n=fr(e),r,o=()=>r??(r=t());return new Proxy(n,{get(s,a){return typeof a=="string"&&a in n?n[a]:o()[a]},has(s,a){return typeof a=="string"&&a in n?true:a in o()}})}function mr(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,r=>r===":"?r:`\\${r}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(r,o)=>(t.push(o),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function yr(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var ae=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:o,paramNames:s}=mr(n);return this.routes.push({method:t.toUpperCase(),pattern:o,paramNames:s,handler:r}),this}async handle(t,n){let r=(t.method??"GET").toUpperCase(),o=yr(t),s=null,a={};for(let m of this.routes){if(m.method!==r)continue;let v=o.match(m.pattern);if(v){s=m,a={},m.paramNames.forEach((R,A)=>{a[R]=decodeURIComponent(v[A+1]??"");});break}}let f=Object.assign(t,{params:a}),d=s?s.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,n,d);}catch(m){this.errorHandler(m,t,n);}}async runMiddlewareChain(t,n,r){let o=0,s=async()=>{if(o<this.middlewares.length){let a=this.middlewares[o++];await a(t,n,s);}else await r(t,n);};await s();}};function te(e,t,n){let r=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let a=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",f=n??process.env.FUNCTION_REGION??"us-central1",d=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${a}/${f}/${d}${r}`}let o=process.env.K_SERVICE,s=e?.hostname??e?.headers?.host??"";return o&&typeof s=="string"&&s.includes("cloudfunctions.net")?`/${o.toLowerCase()}${r}`:r}function Yt(e){if(typeof e=="string")return e;if(Array.isArray(e)){let t=e[0];return typeof t=="string"?t:void 0}}function me(e){return !!e&&typeof e=="object"&&e.__authExtension===true}Be();var ye="__sync_version";var wr=new Set(["ZodOptional","ZodNullable","ZodDefault"]);function xr(e){let t=e,n=false;for(;;){let r=q(t);if(!wr.has(r))break;(r==="ZodOptional"||r==="ZodNullable")&&(n=true);let o=W(t);if(!o)break;t=o;}return {inner:t,nullable:n}}var vr={ZodString:"string",ZodNumber:"number",ZodBigInt:"bigint",ZodBoolean:"boolean",ZodDate:"timestamp",ZodEnum:"string",ZodNativeEnum:"string",ZodLiteral:"string"};function sn(e,t,n,r,o,s,a,f){for(let[d,m]of Object.entries(e)){let v=n?`${n}__${d}`:d;if(o.has(d)||o.has(v))continue;let{inner:R,nullable:A}=xr(m),S=q(R),w=r||A;if(S==="ZodObject"){let u=ne(R);sn(u,t,v,w,o,s,a,f);continue}let C=vr[S]??"json",b=v===a||d===a,g=s[v]??s[d]??v;f.push({name:g,sqlType:t.mapType(C),nullable:b?false:w,isPrimaryKey:b});}}function Ye(e,t,n={}){let{primaryKey:r,exclude:o=[],columnMap:s={}}=n,a=new Set(o),f=ne(e),d=[];return sn(f,t,"",false,a,s,r,d),d.some(m=>m.name===ye)||d.push({name:ye,sqlType:t.mapType("bigint"),nullable:true,isPrimaryKey:false,description:"Monotonic publish version (Date.now() ms). Internal."}),d}function an(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(an)):e}var Sr=32,Rr=5e3;function ln(e,t,n,r=new WeakSet,o=0){if(o>Sr){n[t||"_truncated"]=JSON.stringify({__truncated:true});return}if(r.has(e)){n[t||"_cycle"]=JSON.stringify({__cycle:true});return}r.add(e);for(let[s,a]of Object.entries(e)){if(Object.keys(n).length>=Rr)break;let f=t?`${t}__${s}`:s;a!=null&&typeof a=="object"&&!Array.isArray(a)&&!(a instanceof Date)&&!Buffer.isBuffer(a)&&!(a instanceof Uint8Array)&&typeof a.toDate!="function"&&!("latitude"in a&&"longitude"in a)?ln(a,f,n,r,o+1):n[f]=an(a);}r.delete(e);}function ze(e,t){let n=new Set(t?.exclude),r=t?.columnMap??{},o={};ln(e,"",o);let s={};for(let[a,f]of Object.entries(o)){if(n.has(a))continue;let d=a.split("__")[0];if(d!==a&&n.has(d))continue;let m=r[a]??(a.includes("__")?r[a.split("__").pop()]:void 0)??a;s[m]=f;}return s}function ue(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,60 +28,60 @@ import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {Timestamp}from'fire
28
28
  <nav><a href="${t}/">\u2190 Dashboard</a></nav>
29
29
  <h1>${e}</h1>
30
30
  ${n}
31
- </body></html>`}function pe(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function $e(e,t,n=200){e.status(n).set("Content-Type","application/json").send(JSON.stringify(t,null,2));}function Xe(e){return (e.headers?.accept??"").includes("application/json")}function en(e,t,n,r,o,s,a,f){let d=(o.basePath??"/").replace(/\/$/,"")||"",m=o.featuresFlag??{},b=[];for(let[S,C]of Object.entries(e)){let k=s[S];b.push({name:S,schema:C.schema??null,documentKey:C._systemKeys?.[0]??C.documentKey??"docId",tableName:k?.tableName??S,isGroup:!!C._isGroup,repoCfg:k,repo:C});}let v=new ae;if(o.auth)if(me(o.auth)){let S=o.auth;for(let C of S.routes){let k=`${d}${C.path}`;C.method==="GET"?v.get(k,C.handler):v.post(k,C.handler);}v.use(S.middleware);}else if(typeof o.auth=="function")v.use(o.auth);else {let S=o.auth.realm??"Sync Admin",C="Basic "+Buffer.from(`${o.auth.username}:${o.auth.password}`).toString("base64");v.use((k,x,$)=>{if((k.headers?.authorization??"")!==C){x.status(401).set("WWW-Authenticate",`Basic realm="${S}"`).set("Content-Type","text/plain").send("Unauthorized");return}$();});}return v.get(`${d}/`,(S,C)=>{let k=te(S,d),x=b.map(i=>{let u=[];return m.healthCheck&&u.push(`<a class="btn" href="${k}/${i.name}/health">Health</a>`),m.manualSync&&u.push(`<a class="btn btn-primary" href="${k}/${i.name}/force-sync">Force Sync</a>`),`<tr>
32
- <td><strong>${i.name}</strong></td>
33
- <td>${i.tableName}</td>
34
- <td>${i.isGroup?'<span class="badge badge-warn">group</span>':'<span class="badge badge-ok">collection</span>'}</td>
35
- <td>${i.schema?"\u2713":"\u2717"}</td>
36
- <td>${u.join(" ")}</td>
31
+ </body></html>`}function pe(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Oe(e,t,n=200){e.status(n).set("Content-Type","application/json").send(JSON.stringify(t,null,2));}function et(e){return (e.headers?.accept??"").includes("application/json")}function cn(e,t,n,r,o,s,a,f){let d=(o.basePath??"/").replace(/\/$/,"")||"",m=o.featuresFlag??{},v=e?.rawMapping,R=[];for(let S of Object.keys(e)){let w=s[S],C=v?Xe(v[S],()=>e[S]):e[S];R.push({name:S,schema:C.schema??null,documentKey:C._systemKeys?.[0]??C.documentKey??"docId",tableName:w?.tableName??S,isGroup:!!C._isGroup,repoCfg:w,repo:C});}let A=new ae;if(o.auth)if(me(o.auth)){let S=o.auth;for(let w of S.routes){let C=`${d}${w.path}`;w.method==="GET"?A.get(C,w.handler):A.post(C,w.handler);}A.use(S.middleware);}else if(typeof o.auth=="function")A.use(o.auth);else {let S=o.auth.realm??"Sync Admin",w="Basic "+Buffer.from(`${o.auth.username}:${o.auth.password}`).toString("base64");A.use((C,b,g)=>{if((C.headers?.authorization??"")!==w){b.status(401).set("WWW-Authenticate",`Basic realm="${S}"`).set("Content-Type","text/plain").send("Unauthorized");return}g();});}return A.get(`${d}/`,(S,w)=>{let C=te(S,d),b=R.map(c=>{let i=[];return m.healthCheck&&i.push(`<a class="btn" href="${C}/${c.name}/health">Health</a>`),m.manualSync&&i.push(`<a class="btn btn-primary" href="${C}/${c.name}/force-sync">Force Sync</a>`),`<tr>
32
+ <td><strong>${c.name}</strong></td>
33
+ <td>${c.tableName}</td>
34
+ <td>${c.isGroup?'<span class="badge badge-warn">group</span>':'<span class="badge badge-ok">collection</span>'}</td>
35
+ <td>${c.schema?"\u2713":"\u2717"}</td>
36
+ <td>${i.join(" ")}</td>
37
37
  </tr>`}).join(`
38
- `),$=m.configCheck?`<p style="margin-top:.5rem"><a class="btn" href="${k}/config-check">\u2699 Config Check</a></p>`:"",g=ue("Sync Dashboard",k,`<div class="card">
38
+ `),g=m.configCheck?`<p style="margin-top:.5rem"><a class="btn" href="${C}/config-check">\u2699 Config Check</a></p>`:"",u=ue("Sync Dashboard",C,`<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
- <tbody>${x}</tbody>
41
+ <tbody>${b}</tbody>
42
42
  </table>
43
- ${$}
44
- </div>`);pe(C,g);}),v.get(`${d}`,(S,C)=>{let k=te(S,d);C.status(302).set("Location",`${k}/`).send("");}),m.healthCheck&&v.get(`${d}/:repoName/health`,async(S,C)=>{let k=te(S,d),x=b.find(T=>T.name===S.params.repoName);if(!x){pe(C,ue("Not Found",k,`<p>Unknown repo: ${S.params.repoName}</p>`),404);return}if(!x.schema){pe(C,ue("Health Check",k,`<p class="badge badge-warn">No Zod schema attached to "${x.name}"</p>`));return}let $=Qe(x.schema,t.dialect,{primaryKey:x.documentKey,exclude:x.repoCfg?.exclude,columnMap:x.repoCfg?.columnMap}),g=[],i=false,u=null;try{i=await t.tableExists(x.tableName),i&&(g=await t.getTableColumns(x.tableName));}catch(T){u=T?.message??String(T);}let c=new Set(g),l=new Set($.map(T=>T.name)),p=$.filter(T=>!c.has(T.name)),y=g.filter(T=>!l.has(T)),h=$.filter(T=>c.has(T.name)),R=i&&p.length===0&&!u;if(Xe(S)){$e(C,{repo:x.name,table:x.tableName,tableExists:i,healthy:R,error:u,columns:{expected:$.map(T=>({name:T.name,type:T.sqlType,nullable:T.nullable,isPrimaryKey:T.isPrimaryKey})),actual:g,matched:h.map(T=>T.name),missing:p.map(T=>({name:T.name,type:T.sqlType})),extra:y}});return}let w=R?'<span class="badge badge-ok">Healthy</span>':'<span class="badge badge-err">Unhealthy</span>',O=$.map(T=>{let P=c.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>${P}</td></tr>`}).join(`
45
- `),A=y.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(`
46
- `),E=ue(`Health: ${x.name}`,k,`<div class="card">
47
- <p>Table: <code>${x.tableName}</code> ${i?w:'<span class="badge badge-err">NOT FOUND</span>'}</p>
48
- ${u?`<p class="badge badge-err">Error: ${u}</p>`:""}
43
+ ${g}
44
+ </div>`);pe(w,u);}),A.get(`${d}`,(S,w)=>{let C=te(S,d);w.status(302).set("Location",`${C}/`).send("");}),m.healthCheck&&A.get(`${d}/:repoName/health`,async(S,w)=>{let C=te(S,d),b=R.find(k=>k.name===S.params.repoName);if(!b){pe(w,ue("Not Found",C,`<p>Unknown repo: ${S.params.repoName}</p>`),404);return}if(!b.schema){pe(w,ue("Health Check",C,`<p class="badge badge-warn">No Zod schema attached to "${b.name}"</p>`));return}let g=Ye(b.schema,t.dialect,{primaryKey:b.documentKey,exclude:b.repoCfg?.exclude,columnMap:b.repoCfg?.columnMap}),u=[],c=false,i=null;try{c=await t.tableExists(b.tableName),c&&(u=await t.getTableColumns(b.tableName));}catch(k){i=k?.message??String(k);}let l=new Set(u),p=new Set(g.map(k=>k.name)),y=g.filter(k=>!l.has(k.name)),h=u.filter(k=>!p.has(k)),E=g.filter(k=>l.has(k.name)),x=c&&y.length===0&&!i;if(et(S)){Oe(w,{repo:b.name,table:b.tableName,tableExists:c,healthy:x,error:i,columns:{expected:g.map(k=>({name:k.name,type:k.sqlType,nullable:k.nullable,isPrimaryKey:k.isPrimaryKey})),actual:u,matched:E.map(k=>k.name),missing:y.map(k=>({name:k.name,type:k.sqlType})),extra:h}});return}let O=x?'<span class="badge badge-ok">Healthy</span>':'<span class="badge badge-err">Unhealthy</span>',T=g.map(k=>{let I=l.has(k.name)?'<span class="badge badge-ok">OK</span>':'<span class="badge badge-err">MISSING</span>';return `<tr><td>${k.name}</td><td>${k.sqlType}</td><td>${k.nullable?"Yes":"No"}</td><td>${k.isPrimaryKey?"\u2713":""}</td><td>${I}</td></tr>`}).join(`
45
+ `),$=h.map(k=>`<tr><td>${k}</td><td colspan="3" class="muted">not in schema</td><td><span class="badge badge-warn">EXTRA</span></td></tr>`).join(`
46
+ `),P=ue(`Health: ${b.name}`,C,`<div class="card">
47
+ <p>Table: <code>${b.tableName}</code> ${c?O:'<span class="badge badge-err">NOT FOUND</span>'}</p>
48
+ ${i?`<p class="badge badge-err">Error: ${i}</p>`:""}
49
49
  <h2>Columns</h2>
50
50
  <table>
51
51
  <thead><tr><th>Column</th><th>SQL Type</th><th>Nullable</th><th>PK</th><th>Status</th></tr></thead>
52
- <tbody>${O}${A}</tbody>
52
+ <tbody>${T}${$}</tbody>
53
53
  </table>
54
- </div>`);pe(C,E);}),m.manualSync&&(v.get(`${d}/:repoName/force-sync`,(S,C)=>{let k=te(S,d),x=b.find(g=>g.name===S.params.repoName);if(!x){pe(C,ue("Not Found",k,`<p>Unknown repo: ${S.params.repoName}</p>`),404);return}let $=ue(`Force Sync: ${x.name}`,k,`<div class="card">
55
- <p>This will read <strong>all</strong> documents from the <code>${x.name}</code> Firestore collection
56
- and upsert them into the <code>${x.tableName}</code> SQL table.</p>
54
+ </div>`);pe(w,P);}),m.manualSync&&(A.get(`${d}/:repoName/force-sync`,(S,w)=>{let C=te(S,d),b=R.find(u=>u.name===S.params.repoName);if(!b){pe(w,ue("Not Found",C,`<p>Unknown repo: ${S.params.repoName}</p>`),404);return}let g=ue(`Force Sync: ${b.name}`,C,`<div class="card">
55
+ <p>This will read <strong>all</strong> documents from the <code>${b.name}</code> Firestore collection
56
+ and upsert them into the <code>${b.tableName}</code> SQL table.</p>
57
57
  <p class="muted" style="margin:.75rem 0">This may take a while for large collections.</p>
58
- <form method="POST" action="${k}/${x.name}/force-sync">
58
+ <form method="POST" action="${C}/${b.name}/force-sync">
59
59
  <button type="submit" class="btn btn-primary">Start Force Sync</button>
60
60
  </form>
61
- </div>`);pe(C,$);}),v.post(`${d}/:repoName/force-sync`,async(S,C)=>{let k=te(S,d),x=b.find(R=>R.name===S.params.repoName);if(!x){$e(C,{error:`Unknown repo: ${S.params.repoName}`},404);return}let $=x.repo.ref;if(!$){$e(C,{error:`No collection reference for "${x.name}"`},400);return}let g=0,i=0,u=[],c=500,l=$.limit(c),p=null;try{for(;;){let O=await(p?l.startAfter(p):l).get();if(O.empty)break;for(let A of O.docs){let E=A.data(),T=String(E[x.documentKey]??A.id),P=Be(E,{exclude:x.repoCfg?.exclude,columnMap:x.repoCfg?.columnMap});try{await r({operation:"UPSERT",repoName:x.name,docId:T,data:P,timestamp:new Date().toISOString()}),g++;}catch(N){i++;let j=N?.message??String(N);console.error(`[ForceSync:${x.name}] doc=${T} failed:`,N),u.length<5&&u.push(`${T}: ${j}`);}}if(p=O.docs[O.docs.length-1],O.docs.length<c)break}let R=n.get(x.name);R&&await R.flush();}catch(R){if(Xe(S)){$e(C,{error:R?.message??String(R),synced:g,errors:i},500);return}pe(C,ue(`Force Sync: ${x.name}`,k,`<div class="card">
62
- <p class="badge badge-err">Error: ${R?.message??String(R)}</p>
63
- <p>Synced ${g} docs before failure (${i} errors).</p>
64
- </div>`),500);return}if(Xe(S)){$e(C,{repo:x.name,table:x.tableName,synced:g,errors:i,...u.length>0&&{errorSamples:u}});return}let y=u.length>0?`<details style="margin-top:1rem"><summary>First ${u.length} error(s)</summary>
65
- <pre style="white-space:pre-wrap">${u.map(R=>R.replace(/[<>&]/g,w=>`&#${w.charCodeAt(0)};`)).join(`
61
+ </div>`);pe(w,g);}),A.post(`${d}/:repoName/force-sync`,async(S,w)=>{let C=te(S,d),b=R.find(x=>x.name===S.params.repoName);if(!b){Oe(w,{error:`Unknown repo: ${S.params.repoName}`},404);return}let g=b.repo.ref;if(!g){Oe(w,{error:`No collection reference for "${b.name}"`},400);return}let u=0,c=0,i=[],l=500,p=g.limit(l),y=null;try{for(;;){let T=await(y?p.startAfter(y):p).get();if(T.empty)break;for(let $ of T.docs){let P=$.data(),k=String(P[b.documentKey]??$.id),I=ze(P,{exclude:b.repoCfg?.exclude,columnMap:b.repoCfg?.columnMap});try{await r({operation:"UPSERT",repoName:b.name,docId:k,data:I,timestamp:new Date().toISOString()}),u++;}catch(F){c++;let N=F?.message??String(F);console.error(`[ForceSync:${b.name}] doc=${k} failed:`,F),i.length<5&&i.push(`${k}: ${N}`);}}if(y=T.docs[T.docs.length-1],T.docs.length<l)break}let x=n.get(b.name);x&&await x.flush();}catch(x){if(et(S)){Oe(w,{error:x?.message??String(x),synced:u,errors:c},500);return}pe(w,ue(`Force Sync: ${b.name}`,C,`<div class="card">
62
+ <p class="badge badge-err">Error: ${x?.message??String(x)}</p>
63
+ <p>Synced ${u} docs before failure (${c} errors).</p>
64
+ </div>`),500);return}if(et(S)){Oe(w,{repo:b.name,table:b.tableName,synced:u,errors:c,...i.length>0&&{errorSamples:i}});return}let h=i.length>0?`<details style="margin-top:1rem"><summary>First ${i.length} error(s)</summary>
65
+ <pre style="white-space:pre-wrap">${i.map(x=>x.replace(/[<>&]/g,O=>`&#${O.charCodeAt(0)};`)).join(`
66
66
 
67
- `)}</pre></details>`:"",h=ue(`Force Sync: ${x.name}`,k,`<div class="card">
68
- <p class="badge ${i>0?"badge-warn":"badge-ok"}">${i>0?"Completed with errors":"Complete"}</p>
69
- <p>Synced <strong>${g}</strong> documents to <code>${x.tableName}</code>.</p>
70
- ${i>0?`<p class="badge badge-warn">${i} error(s)</p>`:""}
71
- ${y}
72
- </div>`);pe(C,h);})),m.configCheck&&v.get(`${d}/config-check`,async(S,C)=>{let k=te(S,d),x=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??process.env.GCP_PROJECT??"unknown",$="https://console.cloud.google.com",g=f??"firestore-sync",i=[];try{await t.tableExists("__nonexistent_health_check__"),i.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable"});}catch(R){let w=R?.message??String(R),O=w.toLowerCase(),A=O.includes("disabled")||O.includes("has not been used")||O.includes("accessnotconfigured"),E=O.includes("permission")||w.includes("403")||O.includes("access denied"),T=O.includes("project")&&O.includes("not found"),P=O.includes("not found")||w.includes("404");A?i.push({name:"BigQuery API",category:"bigquery",status:"error",message:"BigQuery API is not enabled",fix:{gcloud:`gcloud services enable bigquery.googleapis.com --project=${x}`,console:`${$}/apis/library/bigquery.googleapis.com?project=${x}`}}):T?i.push({name:"BigQuery Project",category:"bigquery",status:"error",message:w,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:`${$}/home/dashboard`}}):E?i.push({name:"BigQuery API",category:"bigquery",status:"error",message:`Permission denied: ${w}`,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=${x})`,`gcloud projects add-iam-policy-binding ${x} --member="serviceAccount:$SA" --role="roles/bigquery.dataEditor"`,`gcloud projects add-iam-policy-binding ${x} --member="serviceAccount:$SA" --role="roles/bigquery.jobUser"`].join(`
73
- `),console:`${$}/iam-admin/iam?project=${x}`}}):P?i.push({name:"BigQuery Dataset",category:"bigquery",status:"error",message:`Dataset not found: ${w}`,fix:{hint:"Create the dataset first",gcloud:`bq mk --dataset ${x}:YOUR_DATASET_ID`,console:`${$}/bigquery?project=${x}`}}):i.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable (table lookup returned expected error)"});}for(let R of b)try{let w=await t.tableExists(R.tableName);i.push({name:`Table: ${R.tableName}`,category:"bigquery",status:w?"ok":"warn",message:w?`Table \`${R.tableName}\` exists`:`Table \`${R.tableName}\` does not exist yet`,...!w&&{fix:{hint:"Table will be auto-created on first sync if autoMigrate is enabled. Or create it manually."}}});}catch(w){i.push({name:`Table: ${R.tableName}`,category:"bigquery",status:"error",message:w?.message??String(w)});}if(a)for(let R of b){let w=`${g}-${R.name}`;try{let O=a.topic(w);if(typeof O.exists=="function"){let[A]=await O.exists();i.push({name:`Topic: ${w}`,category:"pubsub",status:A?"ok":"error",message:A?`Topic \`${w}\` exists`:`Topic \`${w}\` does not exist`,...!A&&{fix:{gcloud:`gcloud pubsub topics create ${w} --project=${x}`,console:`${$}/cloudpubsub/topic/list?project=${x}`}}});}else i.push({name:`Topic: ${w}`,category:"pubsub",status:"warn",message:"Cannot verify topic existence (PubSub client doesn't expose .exists())",fix:{gcloud:`gcloud pubsub topics create ${w} --project=${x}`,console:`${$}/cloudpubsub/topic/list?project=${x}`,hint:"Ensure the topic exists. It is auto-created by the Firebase emulator but must exist in production."}});}catch(O){let A=O?.message??String(O),E=A.includes("disabled")||A.includes("has not been used");if(i.push({name:E?"Pub/Sub API":`Topic: ${w}`,category:"pubsub",status:"error",message:E?"Pub/Sub API is not enabled":A,fix:E?{gcloud:`gcloud services enable pubsub.googleapis.com --project=${x}`,console:`${$}/apis/library/pubsub.googleapis.com?project=${x}`}:{gcloud:`gcloud pubsub topics create ${w} --project=${x}`,console:`${$}/cloudpubsub/topic/list?project=${x}`}}),E)break}}else i.push({name:"Pub/Sub Client",category:"pubsub",status:"warn",message:"PubSub client not available for config check"});if(Xe(S)){let R=i.every(w=>w.status==="ok");$e(C,{project:x,healthy:R,checks:i});return}let u=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>',c={bigquery:i.filter(R=>R.category==="bigquery"),pubsub:i.filter(R=>R.category==="pubsub"),firestore:i.filter(R=>R.category==="firestore")},l=(R,w)=>{if(w.length===0)return "";let O=w.map(A=>{let E="";if(A.fix){let T=[];A.fix.hint&&T.push(`<p class="muted">${A.fix.hint}</p>`),A.fix.gcloud&&T.push(`<pre>$ ${A.fix.gcloud}</pre>`),A.fix.console&&T.push(`<p><a href="${A.fix.console}" target="_blank">Open GCP Console \u2192</a></p>`),E=`<div style="margin-top:.5rem">${T.join("")}</div>`;}return `<tr>
74
- <td>${u(A.status)}</td>
75
- <td><strong>${A.name}</strong><br><span class="muted">${A.message}</span>${E}</td>
67
+ `)}</pre></details>`:"",E=ue(`Force Sync: ${b.name}`,C,`<div class="card">
68
+ <p class="badge ${c>0?"badge-warn":"badge-ok"}">${c>0?"Completed with errors":"Complete"}</p>
69
+ <p>Synced <strong>${u}</strong> documents to <code>${b.tableName}</code>.</p>
70
+ ${c>0?`<p class="badge badge-warn">${c} error(s)</p>`:""}
71
+ ${h}
72
+ </div>`);pe(w,E);})),m.configCheck&&A.get(`${d}/config-check`,async(S,w)=>{let C=te(S,d),b=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??process.env.GCP_PROJECT??"unknown",g="https://console.cloud.google.com",u=f??"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 O=x?.message??String(x),T=O.toLowerCase(),$=T.includes("disabled")||T.includes("has not been used")||T.includes("accessnotconfigured"),P=T.includes("permission")||O.includes("403")||T.includes("access denied"),k=T.includes("project")&&T.includes("not found"),I=T.includes("not found")||O.includes("404");$?c.push({name:"BigQuery API",category:"bigquery",status:"error",message:"BigQuery API is not enabled",fix:{gcloud:`gcloud services enable bigquery.googleapis.com --project=${b}`,console:`${g}/apis/library/bigquery.googleapis.com?project=${b}`}}):k?c.push({name:"BigQuery Project",category:"bigquery",status:"error",message:O,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:`${g}/home/dashboard`}}):P?c.push({name:"BigQuery API",category:"bigquery",status:"error",message:`Permission denied: ${O}`,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=${b})`,`gcloud projects add-iam-policy-binding ${b} --member="serviceAccount:$SA" --role="roles/bigquery.dataEditor"`,`gcloud projects add-iam-policy-binding ${b} --member="serviceAccount:$SA" --role="roles/bigquery.jobUser"`].join(`
73
+ `),console:`${g}/iam-admin/iam?project=${b}`}}):I?c.push({name:"BigQuery Dataset",category:"bigquery",status:"error",message:`Dataset not found: ${O}`,fix:{hint:"Create the dataset first",gcloud:`bq mk --dataset ${b}:YOUR_DATASET_ID`,console:`${g}/bigquery?project=${b}`}}):c.push({name:"BigQuery API",category:"bigquery",status:"ok",message:"BigQuery API is reachable (table lookup returned expected error)"});}for(let x of R)try{let O=await t.tableExists(x.tableName);c.push({name:`Table: ${x.tableName}`,category:"bigquery",status:O?"ok":"warn",message:O?`Table \`${x.tableName}\` exists`:`Table \`${x.tableName}\` does not exist yet`,...!O&&{fix:{hint:"Table will be auto-created on first sync if autoMigrate is enabled. Or create it manually."}}});}catch(O){c.push({name:`Table: ${x.tableName}`,category:"bigquery",status:"error",message:O?.message??String(O)});}if(a)for(let x of R){let O=`${u}-${x.name}`;try{let T=a.topic(O);if(typeof T.exists=="function"){let[$]=await T.exists();c.push({name:`Topic: ${O}`,category:"pubsub",status:$?"ok":"error",message:$?`Topic \`${O}\` exists`:`Topic \`${O}\` does not exist`,...!$&&{fix:{gcloud:`gcloud pubsub topics create ${O} --project=${b}`,console:`${g}/cloudpubsub/topic/list?project=${b}`}}});}else c.push({name:`Topic: ${O}`,category:"pubsub",status:"warn",message:"Cannot verify topic existence (PubSub client doesn't expose .exists())",fix:{gcloud:`gcloud pubsub topics create ${O} --project=${b}`,console:`${g}/cloudpubsub/topic/list?project=${b}`,hint:"Ensure the topic exists. It is auto-created by the Firebase emulator but must exist in production."}});}catch(T){let $=T?.message??String(T),P=$.includes("disabled")||$.includes("has not been used");if(c.push({name:P?"Pub/Sub API":`Topic: ${O}`,category:"pubsub",status:"error",message:P?"Pub/Sub API is not enabled":$,fix:P?{gcloud:`gcloud services enable pubsub.googleapis.com --project=${b}`,console:`${g}/apis/library/pubsub.googleapis.com?project=${b}`}:{gcloud:`gcloud pubsub topics create ${O} --project=${b}`,console:`${g}/cloudpubsub/topic/list?project=${b}`}}),P)break}}else c.push({name:"Pub/Sub Client",category:"pubsub",status:"warn",message:"PubSub client not available for config check"});if(et(S)){let x=c.every(O=>O.status==="ok");Oe(w,{project:b,healthy:x,checks:c});return}let i=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>',l={bigquery:c.filter(x=>x.category==="bigquery"),pubsub:c.filter(x=>x.category==="pubsub"),firestore:c.filter(x=>x.category==="firestore")},p=(x,O)=>{if(O.length===0)return "";let T=O.map($=>{let P="";if($.fix){let k=[];$.fix.hint&&k.push(`<p class="muted">${$.fix.hint}</p>`),$.fix.gcloud&&k.push(`<pre>$ ${$.fix.gcloud}</pre>`),$.fix.console&&k.push(`<p><a href="${$.fix.console}" target="_blank">Open GCP Console \u2192</a></p>`),P=`<div style="margin-top:.5rem">${k.join("")}</div>`;}return `<tr>
74
+ <td>${i($.status)}</td>
75
+ <td><strong>${$.name}</strong><br><span class="muted">${$.message}</span>${P}</td>
76
76
  </tr>`}).join(`
77
- `);return `<h2>${R}</h2>
77
+ `);return `<h2>${x}</h2>
78
78
  <table><thead><tr><th style="width:80px">Status</th><th>Check</th></tr></thead>
79
- <tbody>${O}</tbody></table>`},y=i.every(R=>R.status==="ok")?'<span class="badge badge-ok">All checks passed</span>':'<span class="badge badge-warn">Some issues found</span>',h=ue("Config Check",k,`<div class="card">
80
- <p>Project: <code>${x}</code> ${y}</p>
81
- ${l("BigQuery",c.bigquery)}
82
- ${l("Pub/Sub",c.pubsub)}
83
- ${l("Firestore",c.firestore)}
84
- </div>`);pe(C,h);}),async(S,C)=>{await v.handle(S,C);}}var mr="firestore-sync";function yr(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 tn(e,t){let{onDocumentCreated:n,onDocumentUpdated:r,onDocumentDeleted:o}=t.deps.firestoreTriggers,s=t.deps.pubsub,a=t?.topicPrefix??mr,f={},d=new Map;function m(v){let S=d.get(v);return S||(S=s.topic(v),d.set(v,S),S)}async function b(v,S){await m(v).publishMessage({json:S});}for(let[v,S]of Object.entries(e)){let C=t?.repos?.[v],k;if(S._isGroup){if(!C?.triggerPath){console.warn(`[SyncTriggers] Skipping collection-group repo "${v}". Provide a triggerPath in the sync repos config for group collections.`);continue}k=C.triggerPath;}else k=C?.triggerPath??yr(v,S);if(!k)continue;let x=S._systemKeys?.[0]??"docId",$=`${a}-${v}`;f[`${v}_onCreate`]=n(k,async g=>{let i=g.data;if(!i)return;let u=i.data();if(!u)return;let c=String(u[x]??i.id),l=Be(u,{exclude:C?.exclude,columnMap:C?.columnMap}),p={operation:"INSERT",repoName:v,docId:c,data:l,timestamp:new Date().toISOString(),version:Date.now()};await b($,p);}),f[`${v}_onUpdate`]=r(k,async g=>{let i=g.data?.after;if(!i)return;let u=i.data();if(!u)return;let c=String(u[x]??i.id),l=Be(u,{exclude:C?.exclude,columnMap:C?.columnMap}),p={operation:"UPSERT",repoName:v,docId:c,data:l,timestamp:new Date().toISOString(),version:Date.now()};await b($,p);}),f[`${v}_onDelete`]=o(k,async g=>{let i=g.data;if(!i)return;let u=i.data(),c=String(u?.[x]??i.id),l={operation:"DELETE",repoName:v,docId:c,data:null,timestamp:new Date().toISOString(),version:Date.now()};await b($,l);});}return f}function nn(e){let t=e.toUpperCase();switch(t){case "INTEGER":return "INT64";case "FLOAT":return "FLOAT64";case "BOOLEAN":return "BOOL";default:return t}}function rn(e,t){let n=nn(e),r=nn(t);return n===r?true:{INT64:["NUMERIC","BIGNUMERIC","FLOAT64"],NUMERIC:["BIGNUMERIC","FLOAT64"],DATE:["DATETIME","TIMESTAMP"],DATETIME:["TIMESTAMP"]}[n]?.includes(r)??false}var Ye=class{constructor(t){this.buffer=[];this.flushing=false;this.flushPromise=null;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(){for(;this.flushPromise;)await this.flushPromise;this.buffer.length!==0&&(this.flushing=true,this.flushPromise=this._drain().finally(()=>{this.flushing=false,this.flushPromise=null;}),await this.flushPromise);}async _drain(){for(;this.buffer.length>0&&await this._doFlush(););}async _doFlush(){let t=this.buffer.splice(0,this.batchSize);try{let n=new Map,r=[];for(let s of t)if(s.operation==="DELETE")r.push(s.docId),n.delete(s.docId);else if(s.data){let a=n.get(s.docId);if(!a)n.set(s.docId,s.data);else {let f=Number(a[ye]??0);Number(s.data[ye]??0)>=f&&n.set(s.docId,s.data);}}let o=Array.from(n.values());o.length>0&&await this.adapter.upsertRows(this.tableName,o,this.primaryKey),r.length>0&&await this.adapter.deleteRows(this.tableName,this.primaryKey,r);}catch(n){if(this.onFlushError)await this.onFlushError(t,n);else return this.buffer.unshift(...t),console.error(`[SyncQueue] Flush failed for ${this.tableName}:`,n),false}return true}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.flush();}};var on=new Set,it=class extends Error{constructor(n,r,o,s){super(`Schema drift detected on \`${n}\`: column \`${r}\` has type ${o} in BigQuery but the current Zod schema maps it to ${s}. BigQuery cannot safely convert between these types \u2014 to resolve, either (a) keep the BigQuery type and add a transform in your repo to coerce values, (b) rename the field in your Zod schema (creates a new column), or (c) drop & recreate the table.`);this.tableName=n;this.column=r;this.existingType=o;this.desiredType=s;this.name="SchemaTypeMismatchError";}};async function gr(e,t,n,r,o,s,a){if(on.has(e))return;let f=Qe(n,t.dialect,{primaryKey:o,exclude:s,columnMap:a});if(!await t.tableExists(r))await t.createTable({tableName:r,columns:f});else if(t.getTableColumnsWithTypes){let m=await t.getTableColumnsWithTypes(r),b=[];for(let v of f){let S=m.get(v.name);if(S===void 0){b.push(v);continue}if(t.dialect.name==="bigquery"&&!rn(S,v.sqlType))throw new it(r,v.name,S,v.sqlType)}b.length>0&&(await t.addColumns(r,b),await t.onSchemaChange?.(r));}else {let m=new Set(await t.getTableColumns(r)),b=f.filter(v=>!m.has(v.name));b.length>0&&(await t.addColumns(r,b),await t.onSchemaChange?.(r));}on.add(e);}function sn(e,t){let{deps:n,adapter:r,batchSize:o=100,flushIntervalMs:s=5e3,autoMigrate:a=false,topicPrefix:f="firestore-sync",maxDlqAttempts:d=5,workerOptions:m,repos:b={}}=t,v=new Map;function S(x,$){let g=v.get(x);if(g)return g;let u=b[x]?.tableName??x,c=`${f}-${x}-dlq`,l=n.pubsub.topic(c),p=false,y=async()=>{if(!p){try{await l.create(),console.info(`[SyncWorker] Created DLQ topic "${c}"`);}catch(R){if(R?.code!==6)throw R}p=true;}},h=async(R,w)=>{console.error(`[SyncWorker] Flush failed for "${x}" (${R.length} events):`,w),await y(),await Promise.all(R.map(O=>{let A=(O.attempts??0)+1;if(d>0&&A>d)return console.error(`[SyncWorker] Dropping event for "${x}" after ${A-1} DLQ attempts:`,{docId:O.docId,operation:O.operation}),Promise.resolve();let E={...O,attempts:A,firstFailedAt:O.firstFailedAt??Date.now()};return l.publishMessage({json:E})}));};return g=new Ye({adapter:r,tableName:u,primaryKey:$,batchSize:o,flushIntervalMs:s,onFlushError:h}),v.set(x,g),g}async function C(x){let{repoName:$}=x,g=e[$];if(!g){console.warn(`[SyncWorker] Unknown repo "${$}", skipping event`);return}let i=g._systemKeys?.[0]??g.documentKey??"docId",u=b[$],c=u?.columnMap,l=c?.[i]??i;if(a){let y=g.schema??void 0;if(y){let h=u?.tableName??$;await gr($,r,y,h,i,u?.exclude,c);}}let p=S($,l);x.data&&(x.data[ye]=x.version??Date.now()),p.enqueue(x);}function k(x){let $=async g=>{let i=g.data?.message?.json??g.data?.json;if(!i){console.warn("[SyncWorker] Received empty PubSub message");return}await C(i);let u=v.get(i.repoName);u&&await u.flush();};return m?n.pubsubHandler.onMessagePublished({topic:x,...m},$):n.pubsubHandler.onMessagePublished(x,$)}return {handleMessage:C,createHandler:k,queues:v,async shutdown(){let x=[];for(let $ of v.values())x.push($.shutdown());await Promise.all(x);}}}var hr="firestore-sync";function an(e){if(typeof e!="function")return e;let t=e,n;return new Proxy({},{get(r,o){return n||(n=t()),n[o]},has(r,o){return n||(n=t()),o in n}})}function ln(e,t){let{deps:n,adapter:r,topicPrefix:o=hr,batchSize:s,flushIntervalMs:a,autoMigrate:f,admin:d,workerOptions:m,repos:b}=t,v=an(n.pubsub),S=an(r),C=tn(e,{deps:{firestoreTriggers:n.firestoreTriggers,pubsub:v},topicPrefix:o,repos:b}),k=sn(e,{deps:{pubsubHandler:n.pubsubHandler,pubsub:v},adapter:S,batchSize:s,flushIntervalMs:a,autoMigrate:f,topicPrefix:o,workerOptions:m,repos:b}),x={};for(let i of Object.keys(e))x[`sync_${i}`]=k.createHandler(`${o}-${i}`);let $=null;d&&($=en(e,S,k.queues,k.handleMessage,d,b??{},v,o),x.adminsync=d.onRequest?d.httpsOptions?d.onRequest(d.httpsOptions,$):d.onRequest($):$);let g={functions:{...C,...x},adminHandler:$,handleMessage:k.handleMessage,queues:k.queues,shutdown:k.shutdown};for(let i of ["adminHandler","handleMessage","queues","shutdown"])Object.defineProperty(g,i,{enumerable:false});return g}Ze();Ze();function br(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function cn(e){let t=e,n=true,r=false,o;for(;;){let s=L(t);if(s==="ZodOptional")n=false,t=G(t);else if(s==="ZodNullable")n=false,r=true,t=G(t);else if(s==="ZodDefault")n=false,o=Wt(t),t=G(t);else if(s==="ZodEffects"||s==="ZodPipe"||s==="ZodTransform"){let a=Kt(t);if(!a)break;t=a;}else break}return {inner:t,required:n,nullable:r,defaultValue:o}}function ie(e,t=""){if(L(e)==="ZodObject"){let r=ne(e);return Object.entries(r).map(([o,s])=>dn(t?`${t}.${o}`:o,o,s))}return [dn(t||"value",t||"value",e)]}function dn(e,t,n){let{inner:r,required:o,nullable:s,defaultValue:a}=cn(n),f=L(r),d=br(t.split(".").pop()??t);switch(f){case "ZodString":{let m=Jt(r),b=m.includes("email"),v=m.includes("url");return {name:e,label:d,type:"text",required:o,nullable:s,defaultValue:a,hint:b?"email":v?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:d,type:"number",required:o,nullable:s,defaultValue:a};case "ZodBoolean":return {name:e,label:d,type:"checkbox",required:o,nullable:s,defaultValue:a};case "ZodDate":case "ZodCoerce":return {name:e,label:d,type:"datetime-local",required:o,nullable:s,defaultValue:a};case "ZodEnum":{let m=Fe(r);return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:m}}case "ZodNativeEnum":{let m=je(r),b=Object.values(m).filter(v=>typeof v=="string");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:b}}case "ZodLiteral":{let m=String(ze(r)??"");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:[m]}}case "ZodUnion":{let m=Gt(r);if(m.length>0&&m.every(v=>L(v)==="ZodLiteral")){let v=m.map(S=>String(ze(S)??""));return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:v}}return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON"}}case "ZodObject":{let m=ie(r,e);return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,nested:m,hint:"JSON object"}}case "ZodArray":{let m=Vt(r);if(!m)return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"};let{inner:b}=cn(m),v=L(b),S,C,k;switch(v){case "ZodString":S="text";break;case "ZodNumber":case "ZodBigInt":S="number";break;case "ZodBoolean":S="checkbox";break;case "ZodDate":S="datetime-local";break;case "ZodEnum":S="select",C=Fe(b);break;case "ZodNativeEnum":S="select",C=Object.values(je(b)).filter(x=>typeof x=="string");break;case "ZodObject":S="object",k=ie(b);break;default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"}}return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,arrayElementType:S,arrayElementOptions:C,arrayElementFields:k}}default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON"}}}function lt(e,t=0){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,o=e.name,s=e.required?" required":"",a=e.defaultValue==="__null__",f=!a&&e.defaultValue!=null?String(e.defaultValue):"",d=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
79
+ <tbody>${T}</tbody></table>`},h=c.every(x=>x.status==="ok")?'<span class="badge badge-ok">All checks passed</span>':'<span class="badge badge-warn">Some issues found</span>',E=ue("Config Check",C,`<div class="card">
80
+ <p>Project: <code>${b}</code> ${h}</p>
81
+ ${p("BigQuery",l.bigquery)}
82
+ ${p("Pub/Sub",l.pubsub)}
83
+ ${p("Firestore",l.firestore)}
84
+ </div>`);pe(w,E);}),async(S,w)=>{await A.handle(S,w);}}var kr="firestore-sync";function Tr(e,t){return t?`${t}/{docId}`:(console.warn(`[SyncTriggers] Cannot determine collection path for "${e}". Skipping.`),null)}function Cr(e){let t=[e?.documentKey,e?.pathKey,e?.createdKey,e?.updatedKey].filter(n=>typeof n=="string");return {isGroup:!!e?.isGroup,documentKey:t[0]??"docId",collectionPath:typeof e?.path=="string"?e.path:null}}function Ar(e){return {isGroup:!!e?._isGroup,documentKey:e?._systemKeys?.[0]??"docId",collectionPath:e?.ref?.path??null}}function dn(e,t){let{onDocumentCreated:n,onDocumentUpdated:r,onDocumentDeleted:o}=t.deps.firestoreTriggers,s=t.deps.pubsub,a=t?.topicPrefix??kr,f={},d=new Map;function m(S){let w=d.get(S);return w||(w=s.topic(S),d.set(S,w),w)}async function v(S,w){await m(S).publishMessage({json:w});}let R=e?.rawMapping,A=R?Object.entries(R).map(([S,w])=>[S,Cr(w)]):Object.entries(e).map(([S,w])=>[S,Ar(w)]);for(let[S,w]of A){let C=t?.repos?.[S],b;if(w.isGroup){if(!C?.triggerPath){console.warn(`[SyncTriggers] Skipping collection-group repo "${S}". Provide a triggerPath in the sync repos config for group collections.`);continue}b=C.triggerPath;}else b=C?.triggerPath??Tr(S,w.collectionPath);if(!b)continue;let g=w.documentKey,u=`${a}-${S}`;f[`${S}_onCreate`]=n(b,async c=>{let i=c.data;if(!i)return;let l=i.data();if(!l)return;let p=String(l[g]??i.id),y=ze(l,{exclude:C?.exclude,columnMap:C?.columnMap}),h={operation:"INSERT",repoName:S,docId:p,data:y,timestamp:new Date().toISOString(),version:Date.now()};await v(u,h);}),f[`${S}_onUpdate`]=r(b,async c=>{let i=c.data?.after;if(!i)return;let l=i.data();if(!l)return;let p=String(l[g]??i.id),y=ze(l,{exclude:C?.exclude,columnMap:C?.columnMap}),h={operation:"UPSERT",repoName:S,docId:p,data:y,timestamp:new Date().toISOString(),version:Date.now()};await v(u,h);}),f[`${S}_onDelete`]=o(b,async c=>{let i=c.data;if(!i)return;let l=i.data(),p=String(l?.[g]??i.id),y={operation:"DELETE",repoName:S,docId:p,data:null,timestamp:new Date().toISOString(),version:Date.now()};await v(u,y);});}return f}function un(e){let t=e.toUpperCase();switch(t){case "INTEGER":return "INT64";case "FLOAT":return "FLOAT64";case "BOOLEAN":return "BOOL";default:return t}}function pn(e,t){let n=un(e),r=un(t);return n===r?true:{INT64:["NUMERIC","BIGNUMERIC","FLOAT64"],NUMERIC:["BIGNUMERIC","FLOAT64"],DATE:["DATETIME","TIMESTAMP"],DATETIME:["TIMESTAMP"]}[n]?.includes(r)??false}var tt=class{constructor(t){this.buffer=[];this.flushing=false;this.flushPromise=null;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(){for(;this.flushPromise;)await this.flushPromise;this.buffer.length!==0&&(this.flushing=true,this.flushPromise=this._drain().finally(()=>{this.flushing=false,this.flushPromise=null;}),await this.flushPromise);}async _drain(){for(;this.buffer.length>0&&await this._doFlush(););}async _doFlush(){let t=this.buffer.splice(0,this.batchSize);try{let n=new Map,r=[];for(let s of t)if(s.operation==="DELETE")r.push(s.docId),n.delete(s.docId);else if(s.data){let a=n.get(s.docId);if(!a)n.set(s.docId,s.data);else {let f=Number(a[ye]??0);Number(s.data[ye]??0)>=f&&n.set(s.docId,s.data);}}let o=Array.from(n.values());o.length>0&&await this.adapter.upsertRows(this.tableName,o,this.primaryKey),r.length>0&&await this.adapter.deleteRows(this.tableName,this.primaryKey,r);}catch(n){if(this.onFlushError)await this.onFlushError(t,n);else return this.buffer.unshift(...t),console.error(`[SyncQueue] Flush failed for ${this.tableName}:`,n),false}return true}async shutdown(){this.timer&&(clearInterval(this.timer),this.timer=null),await this.flush();}};var fn=new Set,gt=class extends Error{constructor(n,r,o,s){super(`Schema drift detected on \`${n}\`: column \`${r}\` has type ${o} in BigQuery but the current Zod schema maps it to ${s}. BigQuery cannot safely convert between these types \u2014 to resolve, either (a) keep the BigQuery type and add a transform in your repo to coerce values, (b) rename the field in your Zod schema (creates a new column), or (c) drop & recreate the table.`);this.tableName=n;this.column=r;this.existingType=o;this.desiredType=s;this.name="SchemaTypeMismatchError";}};async function Or(e,t,n,r,o,s,a){if(fn.has(e))return;let f=Ye(n,t.dialect,{primaryKey:o,exclude:s,columnMap:a});if(!await t.tableExists(r))await t.createTable({tableName:r,columns:f});else if(t.getTableColumnsWithTypes){let m=await t.getTableColumnsWithTypes(r),v=[];for(let R of f){let A=m.get(R.name);if(A===void 0){v.push(R);continue}if(t.dialect.name==="bigquery"&&!pn(A,R.sqlType))throw new gt(r,R.name,A,R.sqlType)}v.length>0&&(await t.addColumns(r,v),await t.onSchemaChange?.(r));}else {let m=new Set(await t.getTableColumns(r)),v=f.filter(R=>!m.has(R.name));v.length>0&&(await t.addColumns(r,v),await t.onSchemaChange?.(r));}fn.add(e);}function mn(e,t){let{deps:n,adapter:r,batchSize:o=100,flushIntervalMs:s=5e3,autoMigrate:a=false,topicPrefix:f="firestore-sync",maxDlqAttempts:d=5,workerOptions:m,repos:v={}}=t,R=new Map;function A(C,b){let g=R.get(C);if(g)return g;let c=v[C]?.tableName??C,i=`${f}-${C}-dlq`,l=n.pubsub.topic(i),p=false,y=async()=>{if(!p){try{await l.create(),console.info(`[SyncWorker] Created DLQ topic "${i}"`);}catch(E){if(E?.code!==6)throw E}p=true;}},h=async(E,x)=>{console.error(`[SyncWorker] Flush failed for "${C}" (${E.length} events):`,x),await y(),await Promise.all(E.map(O=>{let T=(O.attempts??0)+1;if(d>0&&T>d)return console.error(`[SyncWorker] Dropping event for "${C}" after ${T-1} DLQ attempts:`,{docId:O.docId,operation:O.operation}),Promise.resolve();let $={...O,attempts:T,firstFailedAt:O.firstFailedAt??Date.now()};return l.publishMessage({json:$})}));};return g=new tt({adapter:r,tableName:c,primaryKey:b,batchSize:o,flushIntervalMs:s,onFlushError:h}),R.set(C,g),g}async function S(C){let{repoName:b}=C,g=e[b];if(!g){console.warn(`[SyncWorker] Unknown repo "${b}", skipping event`);return}let u=g._systemKeys?.[0]??g.documentKey??"docId",c=v[b],i=c?.columnMap,l=i?.[u]??u;if(a){let y=g.schema??void 0;if(y){let h=c?.tableName??b;await Or(b,r,y,h,u,c?.exclude,i);}}let p=A(b,l);C.data&&(C.data[ye]=C.version??Date.now()),p.enqueue(C);}function w(C){let b=async g=>{let u=g.data?.message?.json??g.data?.json;if(!u){console.warn("[SyncWorker] Received empty PubSub message");return}await S(u);let c=R.get(u.repoName);c&&await c.flush();};return m?n.pubsubHandler.onMessagePublished({topic:C,...m},b):n.pubsubHandler.onMessagePublished(C,b)}return {handleMessage:S,createHandler:w,queues:R,async shutdown(){let C=[];for(let b of R.values())C.push(b.shutdown());await Promise.all(C);}}}var $r="firestore-sync";function yn(e){if(typeof e!="function")return e;let t=e,n;return new Proxy({},{get(r,o){return n||(n=t()),n[o]},has(r,o){return n||(n=t()),o in n}})}function gn(e,t){let{deps:n,adapter:r,topicPrefix:o=$r,batchSize:s,flushIntervalMs:a,autoMigrate:f,admin:d,workerOptions:m,repos:v}=t,R=yn(n.pubsub),A=yn(r),S=dn(e,{deps:{firestoreTriggers:n.firestoreTriggers,pubsub:R},topicPrefix:o,repos:v}),w=mn(e,{deps:{pubsubHandler:n.pubsubHandler,pubsub:R},adapter:A,batchSize:s,flushIntervalMs:a,autoMigrate:f,topicPrefix:o,workerOptions:m,repos:v}),C={};for(let u of Object.keys(e))C[`sync_${u}`]=w.createHandler(`${o}-${u}`);let b=null;d&&(b=cn(e,A,w.queues,w.handleMessage,d,v??{},R,o),C.adminsync=d.onRequest?d.httpsOptions?d.onRequest(d.httpsOptions,b):d.onRequest(b):b);let g={functions:{...S,...C},adminHandler:b,handleMessage:w.handleMessage,queues:w.queues,shutdown:w.shutdown};for(let u of ["adminHandler","handleMessage","queues","shutdown"])Object.defineProperty(g,u,{enumerable:false});return g}Be();Be();function Er(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function hn(e){let t=e,n=true,r=false,o;for(;;){let s=q(t);if(s==="ZodOptional")n=false,t=W(t);else if(s==="ZodNullable")n=false,r=true,t=W(t);else if(s==="ZodDefault")n=false,o=nn(t),t=W(t);else if(s==="ZodEffects"||s==="ZodPipe"||s==="ZodTransform"){let a=en(t);if(!a)break;t=a;}else break}return {inner:t,required:n,nullable:r,defaultValue:o}}function ie(e,t=""){if(q(e)==="ZodObject"){let r=ne(e);return Object.entries(r).map(([o,s])=>bn(t?`${t}.${o}`:o,o,s))}return [bn(t||"value",t||"value",e)]}function bn(e,t,n){let{inner:r,required:o,nullable:s,defaultValue:a}=hn(n),f=q(r),d=Er(t.split(".").pop()??t);switch(f){case "ZodString":{let m=on(r),v=m.includes("email"),R=m.includes("url");return {name:e,label:d,type:"text",required:o,nullable:s,defaultValue:a,hint:v?"email":R?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:d,type:"number",required:o,nullable:s,defaultValue:a};case "ZodBoolean":return {name:e,label:d,type:"checkbox",required:o,nullable:s,defaultValue:a};case "ZodDate":case "ZodCoerce":return {name:e,label:d,type:"datetime-local",required:o,nullable:s,defaultValue:a};case "ZodEnum":{let m=je(r);return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:m}}case "ZodNativeEnum":{let m=Me(r),v=Object.values(m).filter(R=>typeof R=="string");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:v}}case "ZodLiteral":{let m=String(He(r)??"");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:[m]}}case "ZodUnion":{let m=rn(r);if(m.length>0&&m.every(R=>q(R)==="ZodLiteral")){let R=m.map(A=>String(He(A)??""));return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:R}}return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON"}}case "ZodObject":{let m=ie(r,e);return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,nested:m,hint:"JSON object"}}case "ZodArray":{let m=tn(r);if(!m)return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"};let{inner:v}=hn(m),R=q(v),A,S,w;switch(R){case "ZodString":A="text";break;case "ZodNumber":case "ZodBigInt":A="number";break;case "ZodBoolean":A="checkbox";break;case "ZodDate":A="datetime-local";break;case "ZodEnum":A="select",S=je(v);break;case "ZodNativeEnum":A="select",S=Object.values(Me(v)).filter(C=>typeof C=="string");break;case "ZodObject":A="object",w=ie(v);break;default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"}}return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,arrayElementType:A,arrayElementOptions:S,arrayElementFields:w}}default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON"}}}function ht(e,t=0){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,o=e.name,s=e.required?" required":"",a=e.defaultValue==="__null__",f=!a&&e.defaultValue!=null?String(e.defaultValue):"",d=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
85
85
  <input type="hidden" id="${r}__isnull" name="${o}__isnull" value="${a?"1":""}">
86
86
  <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">
87
87
  <input type="checkbox" class="checkbox checkbox-xs" ${a?"checked":""}
@@ -93,59 +93,59 @@ ${n}
93
93
  })(this)">
94
94
  <span>null</span>
95
95
  </label>
96
- </span>`:"",m;switch(e.type){case "checkbox":if(e.nullable){let b=a?"__null__":f==="true"?"true":f==="false"?"false":"__null__";return `
96
+ </span>`:"",m;switch(e.type){case "checkbox":if(e.nullable){let v=a?"__null__":f==="true"?"true":f==="false"?"false":"__null__";return `
97
97
  <div class="form-control mb-3 ${n}">
98
98
  <label for="${r}" class="label pb-1">
99
99
  <span class="label-text font-medium">
100
- ${F(e.label)}
100
+ ${j(e.label)}
101
101
  <span class="text-base-content/40 text-xs ml-1">(nullable)</span>
102
102
  </span>
103
103
  </label>
104
104
  <select id="${r}" name="${o}" class="select select-bordered select-sm w-full">
105
- <option value="__null__"${b==="__null__"?" selected":""}>\u2014 null \u2014</option>
106
- <option value="true"${b==="true"?" selected":""}>\u2713 true</option>
107
- <option value="false"${b==="false"?" selected":""}>\u2717 false</option>
105
+ <option value="__null__"${v==="__null__"?" selected":""}>\u2014 null \u2014</option>
106
+ <option value="true"${v==="true"?" selected":""}>\u2713 true</option>
107
+ <option value="false"${v==="false"?" selected":""}>\u2717 false</option>
108
108
  </select>
109
109
  </div>`}return `
110
110
  <div class="form-control ${n}">
111
111
  <label class="label cursor-pointer justify-start gap-3">
112
112
  <input type="checkbox" id="${r}" name="${o}" value="true"${f==="true"?" checked":""} class="checkbox checkbox-primary checkbox-sm">
113
113
  <span class="label-text font-medium">
114
- ${F(e.label)}${e.required?' <span class="text-error">*</span>':""}
114
+ ${j(e.label)}${e.required?' <span class="text-error">*</span>':""}
115
115
  </span>
116
116
  </label>
117
117
  </div>`;case "select":m=`<select id="${r}" name="${o}"${s}${a?' disabled style="opacity:0.35"':""} class="select select-bordered select-sm w-full">
118
118
  ${e.required&&!e.nullable?"":'<option value="">\u2014 optional \u2014</option>'}
119
- ${(e.options??[]).map(b=>`<option value="${F(b)}"${f===b?" selected":""}>${F(b)}</option>`).join(`
119
+ ${(e.options??[]).map(v=>`<option value="${j(v)}"${f===v?" selected":""}>${j(v)}</option>`).join(`
120
120
  `)}
121
- </select>`;break;case "textarea":if(e.arrayElementType)return vr(e,t);if(e.nested&&e.nested.length>0){let b=e.nested.map(v=>lt(v,t+1)).join(`
121
+ </select>`;break;case "textarea":if(e.arrayElementType)return Pr(e,t);if(e.nested&&e.nested.length>0){let v=e.nested.map(R=>ht(R,t+1)).join(`
122
122
  `);return `
123
123
  <fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}">
124
124
  <legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
125
- ${F(e.label)}${e.required?' <span class="text-error">*</span>':""}
125
+ ${j(e.label)}${e.required?' <span class="text-error">*</span>':""}
126
126
  </legend>
127
- ${b}
127
+ ${v}
128
128
  </fieldset>`}m=`<textarea id="${r}" name="${o}"${s} rows="3"${a?' disabled style="opacity:0.35"':""}
129
129
  data-json
130
130
  class="textarea textarea-bordered textarea-sm w-full font-mono text-xs"
131
- placeholder="${F(e.hint??"JSON")}">${F(f)}</textarea>`;break;default:m=`<input type="${e.type}" id="${r}" name="${o}"${s}${a?' disabled style="opacity:0.35"':""}
132
- value="${F(f)}"
131
+ placeholder="${j(e.hint??"JSON")}">${j(f)}</textarea>`;break;default:m=`<input type="${e.type}" id="${r}" name="${o}"${s}${a?' disabled style="opacity:0.35"':""}
132
+ value="${j(f)}"
133
133
  class="input input-bordered input-sm w-full"${e.hint==="email"?' autocomplete="email"':e.hint==="url"?' autocomplete="url"':""}>`;}return `
134
134
  <div class="form-control mb-3 ${n}">
135
135
  <label for="${r}" class="label pb-1">
136
136
  <span class="label-text font-medium">
137
- ${F(e.label)}${e.required?' <span class="text-error">*</span>':""}
138
- ${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${F(e.hint)})</span>`:""}
137
+ ${j(e.label)}${e.required?' <span class="text-error">*</span>':""}
138
+ ${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${j(e.hint)})</span>`:""}
139
139
  </span>
140
140
  </label>
141
141
  <div class="flex items-center gap-2">
142
142
  <div class="flex-1 min-w-0">${m}</div>
143
143
  ${d}
144
144
  </div>
145
- </div>`}function F(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function vr(e,t){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,o=e.defaultValue==="__null__",s=e.arrayElementType==="object",a=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{a=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(a)||(a=[]);let f=s?a.map(b=>pn(e,b??{})).join(`
146
- `):a.map(b=>un(e,b)).join(`
147
- `),d=s?pn(e,{}):un(e,""),m=e.nullable?`<span class="flex items-center gap-1 mt-2">
148
- <input type="hidden" id="${r}__isnull" name="${F(e.name)}__isnull" value="${o?"1":""}">
145
+ </div>`}function j(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Pr(e,t){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,o=e.defaultValue==="__null__",s=e.arrayElementType==="object",a=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{a=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(a)||(a=[]);let f=s?a.map(v=>xn(e,v??{})).join(`
146
+ `):a.map(v=>wn(e,v)).join(`
147
+ `),d=s?xn(e,{}):wn(e,""),m=e.nullable?`<span class="flex items-center gap-1 mt-2">
148
+ <input type="hidden" id="${r}__isnull" name="${j(e.name)}__isnull" value="${o?"1":""}">
149
149
  <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">
150
150
  <input type="checkbox" class="checkbox checkbox-xs" ${o?"checked":""}
151
151
  onchange="(function(cb){
@@ -159,64 +159,64 @@ ${n}
159
159
  </label>
160
160
  </span>`:"";return `
161
161
  <fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}"
162
- data-frs-array="${F(e.name)}" data-frs-array-type="${F(e.arrayElementType??"text")}">
162
+ data-frs-array="${j(e.name)}" data-frs-array-type="${j(e.arrayElementType??"text")}">
163
163
  <legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
164
- ${F(e.label)}${e.required?' <span class="text-error">*</span>':""}
164
+ ${j(e.label)}${e.required?' <span class="text-error">*</span>':""}
165
165
  </legend>
166
- <input type="hidden" id="${r}" name="${F(e.name)}" value="${F(JSON.stringify(a))}"${o?" disabled":""}>
166
+ <input type="hidden" id="${r}" name="${j(e.name)}" value="${j(JSON.stringify(a))}"${o?" disabled":""}>
167
167
  <div data-frs-array-items${o?' style="opacity:0.35"':""}>
168
168
  ${f}
169
169
  </div>
170
170
  <template data-frs-array-tpl>${d}</template>
171
171
  <button type="button" class="btn btn-xs btn-outline mt-1" data-frs-array-add>+ Add</button>
172
172
  ${m}
173
- </fieldset>`}function un(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">
173
+ </fieldset>`}function wn(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">
174
174
  <option value="">\u2014</option>
175
- ${(e.arrayElementOptions??[]).map(o=>`<option value="${F(o)}"${n===o?" selected":""}>${F(o)}</option>`).join("")}
175
+ ${(e.arrayElementOptions??[]).map(o=>`<option value="${j(o)}"${n===o?" selected":""}>${j(o)}</option>`).join("")}
176
176
  </select>`;break;case "checkbox":r=`<label class="flex items-center gap-2 flex-1 cursor-pointer">
177
177
  <input type="checkbox" data-frs-val class="checkbox checkbox-sm checkbox-primary"${n==="true"?" checked":""}>
178
178
  <span class="text-sm">true</span>
179
- </label>`;break;case "number":r=`<input type="number" data-frs-val value="${F(n)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":r=`<input type="datetime-local" data-frs-val value="${F(n)}" class="input input-bordered input-sm flex-1">`;break;default:r=`<input type="text" data-frs-val value="${F(n)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
179
+ </label>`;break;case "number":r=`<input type="number" data-frs-val value="${j(n)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":r=`<input type="datetime-local" data-frs-val value="${j(n)}" class="input input-bordered input-sm flex-1">`;break;default:r=`<input type="text" data-frs-val value="${j(n)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
180
180
  ${r}
181
181
  <button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>&times;</button>
182
- </div>`}function pn(e,t){return `<div class="border border-base-200 rounded p-3 mb-2" data-frs-array-item>
182
+ </div>`}function xn(e,t){return `<div class="border border-base-200 rounded p-3 mb-2" data-frs-array-item>
183
183
  <div class="flex justify-end mb-1">
184
184
  <button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>&times;</button>
185
185
  </div>
186
186
  ${(e.arrayElementFields??[]).map(o=>{let s=t[o.name],a=s==null?"":typeof s=="object"?JSON.stringify(s):String(s);switch(o.type){case "checkbox":return `<div class="form-control mb-2">
187
187
  <label class="label cursor-pointer justify-start gap-3">
188
- <input type="checkbox" data-frs-key="${F(o.name)}" class="checkbox checkbox-sm checkbox-primary"${a==="true"?" checked":""}>
189
- <span class="label-text text-sm">${F(o.label)}</span>
188
+ <input type="checkbox" data-frs-key="${j(o.name)}" class="checkbox checkbox-sm checkbox-primary"${a==="true"?" checked":""}>
189
+ <span class="label-text text-sm">${j(o.label)}</span>
190
190
  </label>
191
191
  </div>`;case "select":return `<div class="form-control mb-2">
192
- <label class="label pb-1"><span class="label-text text-sm">${F(o.label)}</span></label>
193
- <select data-frs-key="${F(o.name)}" class="select select-bordered select-sm w-full">
192
+ <label class="label pb-1"><span class="label-text text-sm">${j(o.label)}</span></label>
193
+ <select data-frs-key="${j(o.name)}" class="select select-bordered select-sm w-full">
194
194
  ${o.required?"":'<option value="">\u2014</option>'}
195
- ${(o.options??[]).map(f=>`<option value="${F(f)}"${a===f?" selected":""}>${F(f)}</option>`).join("")}
195
+ ${(o.options??[]).map(f=>`<option value="${j(f)}"${a===f?" selected":""}>${j(f)}</option>`).join("")}
196
196
  </select>
197
197
  </div>`;case "number":return `<div class="form-control mb-2">
198
- <label class="label pb-1"><span class="label-text text-sm">${F(o.label)}</span></label>
199
- <input type="number" data-frs-key="${F(o.name)}" value="${F(a)}" class="input input-bordered input-sm w-full">
198
+ <label class="label pb-1"><span class="label-text text-sm">${j(o.label)}</span></label>
199
+ <input type="number" data-frs-key="${j(o.name)}" value="${j(a)}" class="input input-bordered input-sm w-full">
200
200
  </div>`;case "datetime-local":return `<div class="form-control mb-2">
201
- <label class="label pb-1"><span class="label-text text-sm">${F(o.label)}</span></label>
202
- <input type="datetime-local" data-frs-key="${F(o.name)}" value="${F(a)}" class="input input-bordered input-sm w-full">
201
+ <label class="label pb-1"><span class="label-text text-sm">${j(o.label)}</span></label>
202
+ <input type="datetime-local" data-frs-key="${j(o.name)}" value="${j(a)}" class="input input-bordered input-sm w-full">
203
203
  </div>`;case "textarea":return `<div class="form-control mb-2">
204
- <label class="label pb-1"><span class="label-text text-sm">${F(o.label)}</span></label>
205
- <textarea data-frs-key="${F(o.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${F(a)}</textarea>
204
+ <label class="label pb-1"><span class="label-text text-sm">${j(o.label)}</span></label>
205
+ <textarea data-frs-key="${j(o.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${j(a)}</textarea>
206
206
  </div>`;default:return `<div class="form-control mb-2">
207
- <label class="label pb-1"><span class="label-text text-sm">${F(o.label)}</span></label>
208
- <input type="text" data-frs-key="${F(o.name)}" value="${F(a)}" class="input input-bordered input-sm w-full">
207
+ <label class="label pb-1"><span class="label-text text-sm">${j(o.label)}</span></label>
208
+ <input type="text" data-frs-key="${j(o.name)}" value="${j(a)}" class="input input-bordered input-sm w-full">
209
209
  </div>`}}).join(`
210
210
  `)}
211
- </div>`}function ge(e,t,n,r="Save"){let o=e.map(s=>lt(s)).join(`
211
+ </div>`}function ge(e,t,n,r="Save"){let o=e.map(s=>ht(s)).join(`
212
212
  `);return `
213
- <form action="${F(t)}" method="${n}" novalidate data-frs-form>
213
+ <form action="${j(t)}" method="${n}" novalidate data-frs-form>
214
214
  ${o}
215
215
  <div class="flex gap-2 mt-4 pt-4 border-t border-base-200">
216
- <button type="submit" class="btn btn-primary btn-sm">${F(r)}</button>
216
+ <button type="submit" class="btn btn-primary btn-sm">${j(r)}</button>
217
217
  <button type="button" class="btn btn-ghost btn-sm" onclick="history.back()">Cancel</button>
218
218
  </div>
219
- </form>`}var xr=new Set(["<","<=",">",">=","!="]),wr=new Set(["array-contains","array-contains-any"]);function ct(e){return e==="desc"?"DESCENDING":"ASCENDING"}function Sr(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function kr(e,t,n,r,o){let s=[],a=new Set;for(let d of r)if(d.op==="=="||d.op==="in"||d.op==="not-in"){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,order:"ASCENDING"});}for(let d of r)if(wr.has(d.op)){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,arrayConfig:"CONTAINS"});}for(let d of r)if(xr.has(d.op)){if(a.has(d.field))continue;a.add(d.field);let m=o?.field===d.field?ct(o.dir):"ASCENDING";s.push({fieldPath:d.field,order:m});}if(o&&!a.has(o.field)&&s.push({fieldPath:o.field,order:ct(o.dir)}),s.length===1&&n)return Ar(e,t,s[0]);let f=o&&s.some(d=>d.fieldPath===o.field)?ct(o.dir):"ASCENDING";return s.push({fieldPath:"__name__",order:f}),Rr(e,t,n,s)}function Rr(e,t,n,r,o="(default)"){let s=`projects/${e}/databases/${o}/collectionGroups/${t}/indexes/_`,a=[...pt(1,s),...et(2,n?2:1)];for(let m of r)a.push(...fn(3,mn(m)));let f=o==="(default)"?"-default-":o,d=encodeURIComponent(yn(a));return `https://console.firebase.google.com/project/${e}/firestore/databases/${f}/indexes?create_composite=${d}`}function Cr(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function dt(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function ut(e,t){return e<<3|t}function pt(e,t){let n=Array.from(new TextEncoder().encode(t));return [ut(e,2),...dt(n.length),...n]}function et(e,t){return [ut(e,0),...dt(t)]}function fn(e,t){return [ut(e,2),...dt(t.length),...t]}function mn(e){let t=[...pt(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...et(3,1)):t.push(...et(2,e.order==="DESCENDING"?2:1)),t}function yn(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 Ar(e,t,n,r="(default)"){let o=`projects/${e}/databases/${r}/collectionGroups/${t}/fields/${n.fieldPath}`,s=[...pt(1,o),...et(2,2),...fn(3,mn(n))],a=r==="(default)"?"-default-":r,f=encodeURIComponent(yn(s));return `https://console.firebase.google.com/project/${e}/firestore/databases/${a}/indexes/automatic?create_exemption=${f}`}function $r(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 o of n)if(typeof o=="string"&&o.length>0)return o;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function Se(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function Me(e,t){let n=e??{},r=Se(e),o;if(r&&(o=n.message?Cr(n.message):void 0,!o)){let s=$r(t.ref);if(s){let a=Sr(t.path);o=kr(s,a,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:o}}tt();var hn=`// \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
219
+ </form>`}var Dr=new Set(["<","<=",">",">=","!="]),Ir=new Set(["array-contains","array-contains-any"]);function bt(e){return e==="desc"?"DESCENDING":"ASCENDING"}function _r(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function Nr(e,t,n,r,o){let s=[],a=new Set;for(let d of r)if(d.op==="=="||d.op==="in"||d.op==="not-in"){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,order:"ASCENDING"});}for(let d of r)if(Ir.has(d.op)){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,arrayConfig:"CONTAINS"});}for(let d of r)if(Dr.has(d.op)){if(a.has(d.field))continue;a.add(d.field);let m=o?.field===d.field?bt(o.dir):"ASCENDING";s.push({fieldPath:d.field,order:m});}if(o&&!a.has(o.field)&&s.push({fieldPath:o.field,order:bt(o.dir)}),s.length===1&&n)return Mr(e,t,s[0]);let f=o&&s.some(d=>d.fieldPath===o.field)?bt(o.dir):"ASCENDING";return s.push({fieldPath:"__name__",order:f}),Fr(e,t,n,s)}function Fr(e,t,n,r,o="(default)"){let s=`projects/${e}/databases/${o}/collectionGroups/${t}/indexes/_`,a=[...vt(1,s),...nt(2,n?2:1)];for(let m of r)a.push(...vn(3,Sn(m)));let f=o==="(default)"?"-default-":o,d=encodeURIComponent(Rn(a));return `https://console.firebase.google.com/project/${e}/firestore/databases/${f}/indexes?create_composite=${d}`}function jr(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function wt(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function xt(e,t){return e<<3|t}function vt(e,t){let n=Array.from(new TextEncoder().encode(t));return [xt(e,2),...wt(n.length),...n]}function nt(e,t){return [xt(e,0),...wt(t)]}function vn(e,t){return [xt(e,2),...wt(t.length),...t]}function Sn(e){let t=[...vt(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...nt(3,1)):t.push(...nt(2,e.order==="DESCENDING"?2:1)),t}function Rn(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 Mr(e,t,n,r="(default)"){let o=`projects/${e}/databases/${r}/collectionGroups/${t}/fields/${n.fieldPath}`,s=[...vt(1,o),...nt(2,2),...vn(3,Sn(n))],a=r==="(default)"?"-default-":r,f=encodeURIComponent(Rn(s));return `https://console.firebase.google.com/project/${e}/firestore/databases/${a}/indexes/automatic?create_exemption=${f}`}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 o of n)if(typeof o=="string"&&o.length>0)return o;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function Re(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=Re(e),o;if(r&&(o=n.message?jr(n.message):void 0,!o)){let s=Hr(t.ref);if(s){let a=_r(t.path);o=Nr(s,a,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:o}}rt();var Tn=`// \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
220
220
  function frsGetBasePath() {
221
221
  var root = document.querySelector("[data-frs-panel-root]");
222
222
  var bp = root && root.getAttribute("data-frs-base-path");
@@ -1143,7 +1143,7 @@ function initColumnReorder(table) {
1143
1143
  });
1144
1144
  });
1145
1145
  }
1146
- `;function He(){return jsx("script",{dangerouslySetInnerHTML:{__html:hn}})}gt();function he(e){return "<!DOCTYPE html>"+renderToString(e)}var zr=["corporate","silk","dark"],Zr=()=>jsxs("div",{class:"dropdown dropdown-end","data-frs-theme-switcher":true,children:[jsxs("button",{type:"button",tabIndex:0,class:"btn btn-sm btn-ghost text-neutral-content gap-1.5","aria-label":"Switch theme",children:[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:[jsx("circle",{cx:"12",cy:"12",r:"4"}),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"})]}),jsx("span",{class:"text-xs hidden sm:inline","data-frs-theme-current":true,children:"Theme"})]}),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:zr.map(e=>jsx("li",{children:jsxs("button",{type:"button","data-frs-theme":e,class:"capitalize justify-between",children:[jsx("span",{children:e}),jsx("span",{class:"hidden text-primary","data-frs-theme-check":e,children:"\u2713"})]})},e))})]}),be=({opts:e,children:t})=>{let{title:n,breadcrumb:r,flash:o,basePath:s="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsx("script",{dangerouslySetInnerHTML:{__html:"(function(){try{var t=localStorage.getItem('frs-admin-theme');if(t){document.documentElement.setAttribute('data-theme',t);}}catch(_){}})();"}}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsxs("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:[jsx("div",{class:"flex-1",children:jsx("a",{href:s,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})}),jsx("div",{class:"flex-none",children:jsx(Zr,{})})]}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[r&&r.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:r.map((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),o&&jsxs("div",{role:"alert",class:`alert ${o.type==="success"?"alert-success":o.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsx("span",{class:"flex-1",children:o.message}),o.action&&jsx("a",{href:o.action.href,...o.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:o.action.label})]}),t]}),jsx(yt,{basePath:s}),jsx(He,{})]})]})};function ht(e,t){return he(jsx(be,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function bt(e,t){return he(jsx(be,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:e.map(n=>jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxs("div",{class:"card-body p-5",children:[jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var wn=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],Br=[{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"}],Mr=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function Hr(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return Br;case "ZodBoolean":return wn;case "ZodArray":return Mr;default:return wn}}var ve="__null__";function qr(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="${ve}"]');if(!o){o=document.createElement('option');o.value='${ve}';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='${ve}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${ve}"][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!=='${ve}')?i.dataset._prev:'';}}})(this)`}function Lr(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 Le({inputId:e,active:t}){return 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:[jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",checked:t,onchange:qr(e)}),jsx("span",{children:"\u2205"})]})}function Ur({col:e,active:t}){let n=t?.value??"",r=n===ve,o=`fv_input_${e.name.replace(/\./g,"__")}`,s=t?.op,a=s==="in"||s==="not-in";if(e.enumValues&&e.enumValues.length>0){if(a){let f=new Set(n.split(",").map(m=>m.trim()).filter(Boolean)),d=`eg_${e.name.replace(/\./g,"__")}`;return jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsx("input",{type:"hidden",id:o,name:`fv_${e.name}`,value:n}),e.enumValues.map(m=>jsxs("label",{class:"flex items-center gap-1 text-xs border border-base-300 rounded px-2 cursor-pointer hover:bg-base-200",children:[jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",value:m,checked:f.has(m),"data-enum-group":d,onchange:Lr(o,d)}),jsx("span",{children:m})]},m))]})}return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),e.enumValues.map(f=>jsx("option",{value:f,selected:n===f,children:f},f)),e.nullable&&jsx("option",{value:ve,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(Le,{inputId:o,active:r})]})}if(e.zodType==="ZodBoolean")return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),jsx("option",{value:"true",selected:n==="true",children:"true"}),jsx("option",{value:"false",selected:n==="false",children:"false"}),e.nullable&&jsx("option",{value:ve,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(Le,{inputId:o,active:r})]});if(e.zodType==="ZodArray"){let f=t?.op==="array-contains-any";return jsx("input",{id:o,type:"text",name:`fv_${e.name}`,value:n,placeholder:f?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Le,{inputId:o,active:r})]}):e.zodType==="ZodDate"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Le,{inputId:o,active:r})]}):jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Le,{inputId:o,active:r})]})}function vt({action:e,columnMeta:t,activeFilters:n,isGroup:r}){let o=Object.fromEntries(n.map(d=>[d.field,d])),s=n.length>0,a=n.length>=2||r&&s,f=t.filter(d=>d.zodType!=="ZodObject"&&d.zodType!=="ZodRecord");return jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:s?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",s&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:f.map(d=>{let m=Hr(d.zodType),b=o[d.name],v=b?.op??m[0].value;return jsxs("div",{class:"flex flex-col gap-1.5",children:[jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:d.name}),jsxs("div",{class:"flex gap-1.5",children:[m.length>1?jsx("select",{name:`fo_${d.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:m.map(S=>jsx("option",{value:S.value,selected:S.value===v,children:S.label},S.value))}):jsx("input",{type:"hidden",name:`fo_${d.name}`,value:m[0].value}),jsx(Ur,{col:d,active:b})]})]},d.name)})}),jsxs("div",{class:"flex flex-wrap gap-2 mt-4 pt-3 border-t border-base-200 items-center",children:[jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),s&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),a&&jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children: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 xt(e,t,n,r,o,s){let a=n==="create"?`Create ${e}`:`Edit ${e} / ${r??""}`,f=n==="create"?[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:"New document"}]:[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:`Edit ${r??""}`}];return he(jsx(be,{opts:{title:a,breadcrumb:f,basePath:o,flash:s},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}tt();mt();function wt(e,t,n){let r=new URLSearchParams;for(let o of e)r.set(`fv_${o.field}`,o.value),r.set(`fo_${o.field}`,o.op);return t&&(r.set("ob",t.field),r.set("od",t.dir)),n&&r.set("ps",String(n)),r}function Sn(e,t,n,r,o){let s=wt(e,r,o);return s.set("cursor",t),s.set("dir",n),`?${s.toString()}`}function Kr(e,t,n,r){let o=wt(n,void 0,r);return t?.field===e?t.dir==="asc"&&(o.set("ob",e),o.set("od","desc")):(o.set("ob",e),o.set("od","asc")),`?${o.toString()}`}function Vr(e,t,n){return `?${wt(t,n,e).toString()}`}function St(e,t,n,r,o,s,a=[],f=[],d=false,m=[],b,v,S,C,k,x,$,g=false){let i=`${r}/${e}`,u=`${i}/create`,c={};if($)for(let w of n)c[w]=Ee(Pe($,w));let l=(x??[]).filter(w=>{let O=c[w]??Ee(Pe($,w));return O==="string"||O==="number"||O==="bigint"||O==="boolean"||O==="enum"||O==="literal"}),p=l.length>0,y=d,h=y||p,R=l.map(w=>{let O=Pe($,w),A=Ee(O),E=a.find(T=>T.name===w);return {name:w,type:A,enumValues:E?.enumValues??null,nullable:E?.nullable??false}});return he(jsxs(be,{opts:{title:e,breadcrumb:[{label:"Repositories",href:r},{label:e}],basePath:r,flash:s},children:[a.length>0&&jsx(vt,{action:i,columnMeta:a,activeFilters:f,isGroup:C}),S&&jsxs("div",{role:"alert",class:`alert ${S.type==="index"?"alert-warning":"alert-error"} mb-6 shadow-sm`,children:[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:S.type==="index"?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"}):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"})}),jsxs("div",{class:"flex-1",children:[jsx("h3",{class:"font-bold",children:S.type==="index"?"Composite index required":"Query failed"}),jsx("div",{class:"text-sm",children:S.message})]}),S.indexUrl&&jsx("a",{href:S.indexUrl,target:"_blank",rel:"noopener noreferrer",class:"btn btn-sm btn-outline",children:"Create Index \u2192"})]}),jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3","data-frs-toolbar":true,children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length,typeof k=="number"&&jsxs(Fragment,{children:[" ","of"," ",jsx("span",{class:"font-semibold text-base-content/80",children:k})]})," ","document",(typeof k=="number"?k:t.length)!==1&&"s"]}),jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsx("span",{children:"Rows"}),jsx("div",{class:"join",children:[10,25,50,100].map(w=>jsx("a",{href:Vr(w,f,b),class:`join-item btn btn-xs ${v===w?"btn-active btn-primary":"btn-outline"}`,children:w},w))})]})]}),jsx("a",{href:u,class:"btn btn-primary btn-sm",children:"+ New"})]}),h&&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 k=="number"?String(k):"","data-frs-page-size":String(v??t.length),"data-frs-allow-delete":y?"1":"0","data-frs-allow-update":p?"1":"0","data-frs-fields":JSON.stringify(R),"data-frs-filters":JSON.stringify(f),children:[jsxs("div",{class:"flex-1 text-sm",children:[jsx("span",{"data-frs-bulk-summary":true,children:"0 selected"}),typeof k=="number"&&k>t.length&&jsxs("button",{type:"button",class:"ml-3 link text-sm hidden","data-frs-bulk-select-all":true,children:["Select all ",k," matching documents"]}),jsxs("span",{class:"hidden ml-3 italic","data-frs-bulk-all-active":true,children:["All ",k??"?"," matching documents are selected."," ",jsx("button",{type:"button",class:"link","data-frs-bulk-clear":true,children:"Clear selection"})]})]}),jsxs("div",{class:"flex gap-2",children:[p&&jsx("button",{type:"button",class:"btn btn-sm btn-outline","data-frs-bulk-action":"update",children:"Update field\u2026"}),y&&jsx("button",{type:"button",class:"btn btn-sm btn-error btn-outline","data-frs-bulk-action":"delete",children:"Delete"})]})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[h&&jsx("th",{class:"w-8",children:jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-page":true,"aria-label":"Select all on this page"})}),[...n].map((w,O)=>{let A=b?.field===w,E=A?b.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:Kr(w,b,f,v),class:`hover:text-base-content inline-flex items-center gap-0.5${A?" text-primary font-bold":""}`,children:[w,E]})},O)}),m.map((w,O)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:w.column},`rel-${O}`)),jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsx("tbody",{children:t.length===0?jsx("tr",{children:jsx("td",{colspan:n.length+m.length+1+(h?1:0),class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((w,O)=>{let A=String(w.docId??w.id??""),E=`${r}/${e}/${encodeURIComponent(A)}/edit`,T=`${r}/${e}/${encodeURIComponent(A)}/delete`;return jsxs("tr",{class:"hover","data-frs-row-id":A,children:[h&&jsx("td",{class:"align-middle py-2",children:jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-row":true,value:A,"aria-label":`Select ${A}`})}),n.map((P,N)=>{let j=w[P],D=c[P],I=D?qe(D,j):null;return jsx("td",{class:"align-top py-2",children:jsx(Oe,{val:j,mismatch:I})},N)}),m.map((P,N)=>{let j=w[P.key];if(j==null||j==="")return jsx("td",{class:"py-2"},`rel-${N}`);let D=P.type==="one"?`${r}/${P.targetRepo}/${encodeURIComponent(String(j))}/edit`:`${r}/${P.targetRepo}?fv_${P.targetKey}=${encodeURIComponent(String(j))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:D,class:"btn btn-xs btn-ghost btn-outline","data-frs-relation":true,"data-frs-rel-type":P.type,"data-frs-rel-repo":P.targetRepo,"data-frs-rel-fk":P.targetKey,"data-frs-rel-val":String(j),"data-frs-rel-label":P.column,children:P.column})},`rel-${N}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:E,class:"btn btn-xs btn-outline",children:"Edit"}),g&&jsx("a",{href:`${r}/${e}/${encodeURIComponent(A)}/history`,class:"btn btn-xs btn-outline",title:"View change history",children:"History"}),d&&jsx("form",{method:"post",action:T,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},O)})})]})}),(o.hasPrev||o.hasNext)&&jsxs("div",{class:"flex flex-col items-center mt-6 gap-2",children:[jsxs("div",{class:"flex justify-center items-center gap-2",children:[o.hasPrev?jsx("a",{href:Sn(f,o.prevCursor,"prev",b,v),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),o.hasNext?jsx("a",{href:Sn(f,o.nextCursor,"next",b,v),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]}),typeof k=="number"&&jsxs("div",{class:"text-xs text-base-content/50",children:[k," total document",k!==1?"s":"",f.length>0?" matching filters":""]})]}),h&&p&&jsxs("dialog",{id:"frs-bulk-update-modal",class:"modal",children:[jsxs("div",{class:"modal-box",children:[jsx("h3",{class:"font-bold text-lg mb-3",children:"Bulk update field"}),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."}),jsxs("form",{method:"dialog","data-frs-bulk-update-form":true,children:[jsxs("label",{class:"form-control w-full mb-3",children:[jsx("div",{class:"label",children:jsx("span",{class:"label-text text-xs uppercase tracking-wide",children:"Field"})}),jsxs("select",{class:"select select-bordered select-sm w-full",name:"field",required:true,"data-frs-bulk-field-select":true,children:[jsx("option",{value:"",children:"\u2014 Select a field \u2014"}),l.map(w=>jsx("option",{value:w,children:w},w))]})]}),jsx("div",{class:"mb-4","data-frs-bulk-value-container":true}),jsxs("div",{class:"modal-action",children:[jsx("button",{type:"button",class:"btn btn-sm btn-ghost","data-frs-bulk-update-cancel":true,children:"Cancel"}),jsx("button",{type:"submit",class:"btn btn-sm btn-primary","data-frs-bulk-update-submit":true,children:"Apply"})]})]})]}),jsx("form",{method:"dialog",class:"modal-backdrop",children:jsx("button",{children:"close"})})]})]}))}var Gr="";function Ue(e,t){return ht(e,t)}function kt(e,t){return bt(e,t)}function Rt(e,t,n,r,o,s,a,f,d,m,b,v,S,C,k,x,$,g){return St(e,t,n,r,o,s,a,f,d,m,b,v,S,C,k,x,$,g)}function xe(e,t,n,r,o,s){return xt(e,t,n,r,o,s)}var Ct="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Xr(){let e="";for(;e.length<20;){let t=randomBytes(20);for(let n=0;n<t.length&&e.length<20;n++){let r=t[n];r>=Ct.length*4||(e+=Ct.charAt(r%Ct.length));}}return e}function rt(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let r=n.split("/").filter(Boolean),o=[];for(let s=1;s<r.length;s+=2)o.push(r[s]);return o.length>0?o:void 0}async function Ie(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 s=await e.repo.get[r](t);if(s)return s}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function At(e,t,n){let r=e.documentKey??"docId",o=Me(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:r,op:"==",value:t}]});return o.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...o.indexUrl?{action:{href:o.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:o.message}}function Z(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function $t(e,t){e.status(302).set("Location",t).send("");}function Tt(e,t){let n=t.shape,r={};for(let[o,s]of Object.entries(n)){let a=Et(s);if(a==="ZodObject"){if(e[o+"__isnull"]==="1"){r[o]=null;continue}let m={},b=false;for(let[C,k]of Object.entries(e))C.startsWith(`${o}.`)&&(m[C.slice(o.length+1)]=k,b=true);if(b){let C=s;for(;;){let k=L(C);if(k==="ZodOptional"||k==="ZodNullable"||k==="ZodDefault")C=G(C);else break}r[o]=Tt(m,C);continue}let v=e[o],S=Array.isArray(v)?v[v.length-1]:v;if(S)try{r[o]=JSON.parse(S);}catch{r[o]=S;}continue}let f=e[o],d=Array.isArray(f)?f[f.length-1]:f;if(e[o+"__isnull"]==="1"){r[o]=null;continue}if(d===void 0||d===""){a==="ZodBoolean"&&(r[o]=false);continue}switch(a){case "ZodBoolean":d==="__null__"?r[o]=null:r[o]=d==="true"||d==="on"||d==="1";break;case "ZodNumber":case "ZodBigInt":r[o]=Number(d);break;case "ZodDate":r[o]=new Date(d);break;case "ZodArray":try{r[o]=JSON.parse(d);}catch{r[o]=d;}break;default:if(d.startsWith("{")||d.startsWith("["))try{r[o]=JSON.parse(d);break}catch{}r[o]=d;}}return r}function kn(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 Et(e){let t=e;for(;;){let n=L(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=G(t);else return n}}function Yr(e){let t=e;for(;;){let n=L(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=G(t);else return t}}function Cn(e){let t=e;for(;;){let n=L(t);if(n==="ZodOptional"||n==="ZodNullable")return true;if(n==="ZodDefault"){t=G(t);continue}return false}}function An(e){let t=Yr(e),n=L(t);if(n==="ZodEnum"){let r=Fe(t);return r.length>0?r:void 0}if(n==="ZodNativeEnum"){let r=je(t),o=Object.values(r).filter(s=>typeof s=="string");return o.length>0?o:void 0}if(n==="ZodLiteral"){let r=ze(t);return typeof r=="string"?[r]:void 0}}function $n(e,t,n=""){let r={};for(let o of Object.keys(t.shape)){let s=n?`${n}.${o}`:o,a=e[o];if(a===null){r[s]="__null__";continue}if(a===void 0)continue;let f=t.shape[o];for(;;){let m=L(f);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")f=G(f);else break}let d=L(f);if(d==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let m=$n(a,f,s);Object.assign(r,m);}else if(d==="ZodDate"){let m=kn(a);m!==null&&(r[s]=m);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let m=kn(a);r[s]=m??JSON.stringify(a,null,2);}else typeof a=="object"?r[s]=JSON.stringify(a,null,2):r[s]=String(a);}return r}function Ot(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?Ot(n.nested,t):void 0}))}function eo(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),r=[];for(let[o,s]of Object.entries(e)){if(!o.startsWith("fv_"))continue;let a=o.slice(3);if(!t.has(a))continue;let f=(s??"").trim();if(!f)continue;let d=e[`fo_${a}`]??"==",m=n.has(d)?d:"==";r.push({field:a,op:m,value:f});}return r}function Rn(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 o=r.value.split(",").map(s=>s.trim()).filter(s=>s!==""&&s!==t).map(s=>n(s));return [r.field,r.op,o]}return [r.field,r.op,n(r.value)]})}function Tn(e,t,n=""){let r=[];for(let o of e){let s=n?`${n}.${o}`:o,a=t.shape[o];if(!a){r.push({name:s,zodType:"ZodString"});continue}let f=Et(a);if(f==="ZodObject"){let d=a;for(;;){let b=L(d);if(b==="ZodOptional"||b==="ZodNullable"||b==="ZodDefault")d=G(d);else break}let m=ne(d);r.push(...Tn(Object.keys(m),d,s));}else r.push({name:s,zodType:f,nullable:Cn(a),enumValues:An(a)});}return r}function to(e,t){let n=t.split("."),r=e;for(let o of n){for(;;){let a=L(r);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")r=G(r);else break}let s=ne(r);if(!(o in s))return null;r=s[o];}return r}function Re(e,t){if(!t||t.length===0)return e;let n=[],r=new Map;for(let s of t){let a=s.indexOf(".");if(a===-1)n.push(s);else {let f=s.slice(0,a),d=s.slice(a+1);r.has(f)||r.set(f,[]),r.get(f).push(d);}}let o={};for(let s of n)s in e.shape&&(o[s]=e.shape[s]);for(let[s,a]of r){if(!(s in e.shape))continue;let f=e.shape[s];for(;;){let d=L(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=G(f);else break}if(L(f)!=="ZodObject"){o[s]=e.shape[s];continue}o[s]=Re(f,a);}return z.object(o)}function fe(e,t,n){return te(e,t,n)}function On(e,t,n){let r=(i,u)=>{let c=fe(i,t,n),l=Object.values(e).map(p=>({name:p.name,path:p.path}));Z(u,kt(l,c));},o=async(i,u)=>{let c=i.params.repoName;if(!c){Z(u,"Bad request",400);return}let l=e[c];if(!l){Z(u,"Repository not found",404);return}let p=l.pageSize??25,y=i.query??{},h=y.cursor,R=y.dir==="prev"?"prev":"next",w=y.ob??"",O=y.od==="desc"?"desc":"asc",A=w?{field:w,dir:O}:void 0,E=parseInt(y.ps??""),T=Number.isFinite(E)&&E>0?Math.min(E,200):p,P=l.listColumns??Object.keys(l.schema.shape),N=l.documentKey??"docId",j=[N,...P.filter(W=>W!==N)];A&&(new Set([N,...P]).has(A.field)||(A=void 0));let D=l.filterableFields?(()=>{let W=[];for(let de of l.filterableFields)(de.includes(".")||P.includes(de))&&W.push(de);return W})():P,I=(()=>{let W=[];for(let de of D)if(de.includes(".")){let Ae=to(l.schema,de);W.push({name:de,zodType:Ae?Et(Ae):"ZodString",nullable:Ae?Cn(Ae):false,enumValues:Ae?An(Ae):void 0});}else W.push(...Tn([de],l.schema));return W})(),K=new Set(I.map(W=>W.name)),ce=eo(y,K),U=Rn(ce),se;if(h)try{let W=l.repo.ref;typeof W.doc=="function"&&(se=await W.doc(h).get());}catch{}let[Q,Ge]=await Promise.all([l.repo.query.paginate({pageSize:T,cursor:se,direction:R,...U.length>0?{where:U}:{},...A?{orderBy:[{field:A.field,direction:A.dir}]}:{}}).catch(W=>({queryError:Me(W,{ref:l.repo.ref,path:l.path,isGroup:!!l.isGroup,filters:ce,sort:A})})),l.repo.aggregate.count(U.length>0?{where:U}:{}).catch(()=>{})]),Ce="queryError"in Q,Vn=Ce?[]:Q.data,Wn=Ce?"":Q.nextCursor?.id??"",Gn=Ce?"":Q.prevCursor?.id??"",Jn=Ce?Q.queryError:void 0,Qn=fe(i,t,n);Z(u,Rt(l.name,Vn,j,Qn,{hasPrev:Ce?false:Q.hasPrevPage,hasNext:Ce?false:Q.hasNextPage,prevCursor:Gn,nextCursor:Wn},void 0,I,ce,l.allowDelete??false,l.relationalMeta,A,T,Jn,l.isGroup,Ge,l.mutableFields,l.schema,l.historyEnabled));},s=(i,u)=>{let c=i.params.repoName;if(!c){Z(u,"Bad request",400);return}let l=e[c];if(!l){Z(u,"Repository not found",404);return}let p=fe(i,t,n),y=Re(l.schema,l.createFields),h=ie(y),R=`${p}/${l.name}/create`,w=ge(h,R,"POST","Create document");Z(u,xe(l.name,w,"create",null,p));},a=async(i,u)=>{let c=i.params.repoName;if(!c){Z(u,"Bad request",400);return}let l=e[c];if(!l){Z(u,"Repository not found",404);return}let p=fe(i,t,n),y=i.body??{},h=Tt(y,l.schema),R=Re(l.schema,l.createFields),w=R.safeParse(h);if(!w.success){let O=ie(R),A=`${p}/${l.name}/create`,E=ge(O,A,"POST","Create document"),T=w.error.issues.map(P=>`${P.path.join(".")}: ${P.message}`).join(", ");Z(u,xe(l.name,E,"create",null,p,{type:"error",message:`Validation error: ${T}`}),422);return}try{if(l.isGroup&&l.parentKeys&&l.parentKeys.length>0){let O={...w.data};l.createdKey&&(O[l.createdKey]=new Date);let A=l.parentKeys.filter(N=>!O[N]);if(A.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${A.join(", ")}`);let E=l.parentKeys.map(N=>O[N]),T=l.documentKey??"docId",P=O[T]||Xr();await l.repo.set(...E,P,O);}else await l.repo.create(w.data);$t(u,`${p}/${l.name}?flash=created`);}catch(O){let A=Re(l.schema,l.createFields),E=ie(A),T=`${p}/${l.name}/create`,P=ge(E,T,"POST","Create document");Z(u,xe(l.name,P,"create",null,p,{type:"error",message:`Save error: ${O.message}`}),500);}},f=async(i,u)=>{let c=i.params.repoName,l=i.params.id;if(!c||!l){Z(u,"Bad request",400);return}let p=e[c];if(!p){Z(u,"Repository not found",404);return}let y=fe(i,t,n),h=null;try{h=await Ie(p,l);}catch(T){let P=At(p,l,T),N=Se(T)?424:500;Z(u,Ue("",{title:`Edit ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`Edit ${l}`}],flash:P}),N);return}if(!h){Z(u,"Document not found",404);return}let R=$n(h,p.schema),w=Re(p.schema,p.mutableFields),O=Ot(ie(w),R),A=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,E=ge(O,A,"POST","Save changes");Z(u,xe(p.name,E,"edit",l,y));},d=async(i,u)=>{let c=i.params.repoName,l=i.params.id;if(!c||!l){Z(u,"Bad request",400);return}let p=e[c];if(!p){Z(u,"Repository not found",404);return}let y=fe(i,t,n),h=i.body??{},R=Tt(h,p.schema),w=Re(p.schema,p.mutableFields),A=w.partial().safeParse(R);if(!A.success){let E=Object.fromEntries(Object.entries(h).map(([D,I])=>[D,Array.isArray(I)?I.join(","):I??""])),T=Ot(ie(w),E),P=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,N=ge(T,P,"POST","Save changes"),j=A.error.issues.map(D=>`${D.path.join(".")}: ${D.message}`).join(", ");Z(u,xe(p.name,N,"edit",l,y,{type:"error",message:`Validation error: ${j}`}),422);return}try{let E=await Ie(p,l),T=(E&&rt(E,p.pathKey))??[l];await p.repo.update(...T,A.data),$t(u,`${y}/${p.name}?flash=updated`);}catch(E){let T=Re(p.schema,p.mutableFields),P=ie(T),N=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,j=ge(P,N,"POST","Save changes"),D=Se(E)?At(p,l,E):{type:"error",message:`Save error: ${E.message}`},I=Se(E)?424:500;Z(u,xe(p.name,j,"edit",l,y,D),I);}},m=async(i,u)=>{let c=i.params.repoName,l=i.params.id;if(!c||!l){Z(u,"Bad request",400);return}let p=e[c];if(!p){Z(u,"Repository not found",404);return}if(!p.allowDelete){Z(u,"Delete is not allowed for this repository",403);return}let y=fe(i,t,n);try{let h=await Ie(p,l),R=(h&&rt(h,p.pathKey))??[l];await p.repo.delete(...R),$t(u,`${y}/${p.name}?flash=deleted`);}catch(h){let R=Se(h)?At(p,l,h):{type:"error",message:`Delete error: ${h.message}`},w=Se(h)?424:500;Z(u,Ue("",{title:`Delete ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`Delete ${l}`}],flash:R}),w);}},b=async(i,u)=>{let c=i.params.repoName;if(!c){Z(u,"Bad request",400);return}let l=e[c];if(!l){Z(u,"Repository not found",404);return}let p=fe(i,t,n),y=i.query,h=y?.type==="many"?"many":"one",R=Math.max(1,Math.min(100,Number(y?.ps??25)||25)),w=l.listColumns??Object.keys(ne(l.schema)),{PanelOne:O,PanelMany:A}=await Promise.resolve().then(()=>(gt(),vn)),{renderToString:E}=await import('hono/jsx/dom/server');if(h==="one"){let I=String(y?.id??"");if(!I){Z(u,"<div class='p-6 text-error'>Missing id parameter.</div>",400);return}try{let K=await Ie(l,I),ce=E(O({doc:K,repoName:l.name,basePath:p,schema:l.schema,columns:w}));Z(u,ce);}catch(K){Z(u,`<div class='p-6 text-error text-sm'>Error: ${K.message}</div>`,500);}return}let T=String(y?.fk??""),P=String(y?.fv??"");if(!T||!P){Z(u,"<div class='p-6 text-error'>Missing fk/fv parameters.</div>",400);return}let N=y?.cursor??"",j=y?.dir==="prev"?"prev":"next",D;if(N)try{let I=l.repo.ref;typeof I.doc=="function"&&(D=await I.doc(N).get());}catch{}try{let I=await l.repo.query.paginate({pageSize:R,cursor:D,direction:j,where:[[T,"==",no(P)]]}),K=E(A({docs:I.data,repoName:l.name,basePath:p,fk:T,fv:P,columns:w,schema:l.schema,pagination:{hasPrev:I.hasPrevPage,hasNext:I.hasNextPage,prevCursor:I.prevCursor?.id??"",nextCursor:I.nextCursor?.id??"",pageSize:R}}));Z(u,K);}catch(I){Z(u,`<div class='p-6 text-error text-sm'>Error: ${I.message}</div>`,500);}},v=async(i,u)=>{let c=[];for(let l of u){let p;if(i.isGroup||i.parentKeys?.length){let y=await Ie(i,l);p=y?rt(y,i.pathKey):void 0;}p||(p=[l]);try{let y=i.repo.documentRef(...p);y&&c.push(y);}catch{}}return c},S=async(i,u)=>{let c=Rn(u),l=i.documentKey??"docId",p=[],y;for(;;){let h=await i.repo.query.paginate({pageSize:500,cursor:y,direction:"next",...c.length>0?{where:c}:{}});for(let R of h.data){let w=String(R[l]??R.id??"");w&&p.push(w);}if(!h.hasNextPage||!h.nextCursor)break;y=h.nextCursor;}return p},C=async(i,u)=>{let c=i.params.repoName;if(!c){ee(u,{error:"Bad request"},400);return}let l=e[c];if(!l){ee(u,{error:"Repository not found"},404);return}if(!l.allowDelete){ee(u,{error:"Delete is not allowed for this repository"},403);return}let p=i.body??{};try{let y=await x(l,p);if(y.length===0){ee(u,{deleted:0});return}let h=await v(l,y);for(let R=0;R<h.length;R+=500)await l.repo.bulk.delete(h.slice(R,R+500));ee(u,{deleted:h.length});}catch(y){ee(u,{error:y.message},500);}},k=async(i,u)=>{let c=i.params.repoName;if(!c){ee(u,{error:"Bad request"},400);return}let l=e[c];if(!l){ee(u,{error:"Repository not found"},404);return}let p=i.body??{},y=String(p.field??"");if(!y){ee(u,{error:"Missing 'field'"},400);return}if(!l.mutableFields||!l.mutableFields.includes(y)){ee(u,{error:`Field '${y}' is not bulk-updatable`},403);return}let h=l.schema.shape?.[y],R=p.value;if(h){let w=h.safeParse(p.value);if(!w.success){ee(u,{error:`Invalid value for '${y}': ${w.error.message}`},400);return}R=w.data;}try{let w=await x(l,p);if(w.length===0){ee(u,{updated:0});return}let A=(await v(l,w)).map(E=>({docRef:E,data:{[y]:R}}));for(let E=0;E<A.length;E+=500)await l.repo.bulk.update(A.slice(E,E+500));ee(u,{updated:A.length});}catch(w){ee(u,{error:w.message},500);}};async function x(i,u){if(u.selectAll){let c=$(u.filters,i);return await S(i,c)}return Array.isArray(u.ids)?u.ids.filter(c=>typeof c=="string"&&!!c):[]}function $(i,u){if(!Array.isArray(i))return [];let c=new Set((u.filterableFields??Object.keys(ne(u.schema))).map(y=>String(y))),l=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),p=[];for(let y of i)y&&typeof y=="object"&&typeof y.field=="string"&&c.has(y.field)&&typeof y.value=="string"&&l.has(String(y.op))&&p.push({field:y.field,op:y.op,value:y.value});return p}return {handleDashboard:r,handleList:o,handleCreateForm:s,handleCreateSubmit:a,handleEditForm:f,handleEditSubmit:d,handleDelete:m,handlePanel:b,handleBulkDelete:C,handleBulkUpdate:k,handleHistory:async(i,u)=>{let c=i.params.repoName,l=i.params.id;if(!c||!l){Z(u,"Bad request",400);return}let p=e[c];if(!p){Z(u,"Repository not found",404);return}if(!p.historyEnabled||!p.repo.history){Z(u,"History not enabled for this repository",404);return}let y=fe(i,t,n),h=p.historySubcollection??"history",R=[l];try{let I=await Ie(p,l),K=I?rt(I,p.pathKey):void 0;K&&K.length>0&&(R=K);}catch{}let w=parseInt(String(i.query?.limit??"")),O=Number.isFinite(w)&&w>0?Math.min(w,500):100,A=[],E;try{A=await p.repo.history.list(...R,{limit:O});}catch(I){E=I.message;}let T=I=>String(I??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),P=I=>{if(I===void 0)return '<span class="opacity-40">undefined</span>';if(I===null)return '<span class="opacity-40">null</span>';if(typeof I=="object")try{return `<code class="text-xs">${T(JSON.stringify(I))}</code>`}catch{return T(String(I))}return T(String(I))},N=I=>I?typeof I.toDate=="function"?I.toDate().toISOString():I instanceof Date?I.toISOString():T(String(I)):"",j=I=>`<span class="badge badge-sm ${I==="create"?"badge-success":I==="delete"?"badge-error":"badge-info"}">${T(I)}</span>`,D="";if(D+='<div class="flex items-center justify-between mb-4">',D+=`<a href="${y}/${p.name}/${encodeURIComponent(l)}/edit" class="btn btn-sm btn-outline">\u2190 Back to edit</a>`,D+=`<a href="${y}/${p.name}" class="btn btn-sm btn-outline">\u2190 Back to list</a>`,D+="</div>",D+=`<p class="text-sm text-base-content/60 mb-4">Subcollection: <code>${T(h)}</code> \xB7 Showing up to ${O} entries.</p>`,E)D+=`<div class="alert alert-error mb-4">${T(E)}</div>`;else if(A.length===0)D+='<div class="alert">No history entries found.</div>';else {D+='<div class="overflow-x-auto"><table class="table table-zebra table-sm">',D+="<thead><tr><th>When</th><th>Op</th><th>User</th><th>Reason / Comment</th><th>Changes</th></tr></thead><tbody>";for(let I of A){let K=I.meta??{},ce=[K.reason,K.comment].filter(Q=>Q!=null&&Q!=="").map(Q=>T(String(Q))).join(" \u2014 "),U="",se=Object.keys(I.changes??{});se.length===0?U='<span class="opacity-40">\u2014</span>':U='<ul class="space-y-1">'+se.map(Q=>{let Ge=I.changes[Q];return `<li><strong>${T(Q)}</strong>: ${P(Ge.oldValue)} \u2192 ${P(Ge.newValue)}</li>`}).join("")+"</ul>",D+="<tr>",D+=`<td class="whitespace-nowrap text-xs font-mono">${T(N(I.historySetAt))}</td>`,D+=`<td>${j(I.operation??"update")}</td>`,D+=`<td class="text-xs">${T(K.userEmail??K.userId??"")}</td>`,D+=`<td class="text-xs">${ce}</td>`,D+=`<td>${U}</td>`,D+="</tr>";}D+="</tbody></table></div>";}Z(u,Ue(D,{title:`History \u2014 ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`History ${l}`}]}));}}}function ee(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function no(e){return e==="true"?true:e==="false"?false:e!==""&&!isNaN(Number(e))?Number(e):e}var En="https://cdn.jsdelivr.net",Pn="https://www.gstatic.com",In=["default-src 'self'",`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${En} ${Pn}`,`style-src 'self' 'unsafe-inline' ${En}`,`connect-src 'self' ${Pn} https://*.googleapis.com https://*.firebaseio.com https://identitytoolkit.googleapis.com`,"img-src 'self' data:","font-src 'self' data:","frame-ancestors 'none'","base-uri 'self'","form-action 'self'"].join("; ");function Ke(e={}){let t=e.csp===void 0?In:e.csp,n=e.frameOptions===void 0?"DENY":e.frameOptions,r=e.referrerPolicy===void 0?"no-referrer":e.referrerPolicy,o=e.cacheControl===void 0?"private, no-store":e.cacheControl;return async(s,a,f)=>{typeof a?.setHeader=="function"&&(a.setHeader("X-Content-Type-Options","nosniff"),n&&a.setHeader("X-Frame-Options",n),r&&a.setHeader("Referrer-Policy",r),o&&a.setHeader("Cache-Control",o),t&&a.setHeader("Content-Security-Policy",t)),await f();}}async function ro(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function oo(e){let t={};if(!e)return t;for(let n of e.split("&")){let r=n.indexOf("=");if(r===-1)continue;let o=decodeURIComponent(n.slice(0,r).replace(/\+/g," ")),s=decodeURIComponent(n.slice(r+1).replace(/\+/g," ")),a=t[o];a===void 0?t[o]=s:Array.isArray(a)?a.push(s):t[o]=[a,s];}return t}function _n(e){let{basePath:t="/",repos:n,parseBody:r=true,securityHeaders:o,auth:s,middleware:a=[],httpsOptions:f}=e,d=t==="/"?"":t.replace(/\/$/,""),m={};for(let[C,k]of Object.entries(n)){let x=k.schema??k.repo.schema??null;if(!x)throw new Error(`[createAdminServer] Repository "${C}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let $,g,i;if(k.fieldsConfig){let l=k.fieldsConfig;$=[],g=[],i=[];for(let[p,y]of Object.entries(l))for(let h of y)h==="filterable"?$.push(p):h==="mutable"?g.push(p):h==="create"&&i.push(p);$.length===0&&($=void 0),g.length===0&&(g=void 0),i.length===0&&(i=void 0);}let u=(()=>{let l=k.repo._parentKeys;return l&&l.length>0?l:void 0})();if(u&&i)for(let l of u)i.includes(l)||i.push(l);let c={name:C,path:k.path,repo:k.repo,schema:x,documentKey:k.documentKey??"docId",pathKey:k.repo._pathKey??void 0,isGroup:!!k.repo._isGroup,parentKeys:u,createdKey:k.repo._createdKey??void 0,listColumns:k.listColumns,pageSize:k.pageSize,filterableFields:$,mutableFields:g,createFields:i,allowDelete:k.allowDelete??false,historyEnabled:!!k.repo.history,historySubcollection:(k.repo.history&&k.repo._historySubcollection)??void 0,relationalMeta:(()=>{if(!k.relationalFields||k.relationalFields.length===0)return;let l=k.repo.relationalKeys??{},p=[];for(let y of k.relationalFields){let h=l[y.key];h&&p.push({key:y.key,column:y.column,targetRepo:String(h.repo),targetKey:String(h.key),type:h.type});}return p.length>0?p:void 0})()};m[C]=c;}let b=On(m,d,Ut(f?.region)),v=new ae;if(o!==false&&v.use(Ke(o===void 0?{}:o)),r&&v.use(async(C,k,x)=>{let $=C,g=String($.headers?.["content-type"]??"");if(g.includes("application/x-www-form-urlencoded")){let i=await ro($);C.body=oo(i);}else if(g.includes("application/json")&&typeof $.body=="string")try{C.body=JSON.parse($.body);}catch{}await x();}),s)if(me(s)){for(let C of s.routes){let k=`${d}${C.path}`;C.method==="GET"?v.get(k,C.handler):v.post(k,C.handler);}v.use(s.middleware);}else if(typeof s=="function")v.use(s);else {let C=s.realm??"Admin",k="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");v.use((x,$,g)=>{if((x.headers?.authorization??"")!==k){$.status(401).set("WWW-Authenticate",`Basic realm="${C}"`).set("Content-Type","text/plain").send("Unauthorized");return}g();});}for(let C of a)v.use(C);v.get(`${d}/`,b.handleDashboard),v.get(`${d}`,b.handleDashboard),v.get(`${d}/:repoName/_panel`,b.handlePanel),v.post(`${d}/:repoName/_bulk/delete`,b.handleBulkDelete),v.post(`${d}/:repoName/_bulk/update`,b.handleBulkUpdate),v.get(`${d}/:repoName`,b.handleList),v.get(`${d}/:repoName/create`,b.handleCreateForm),v.post(`${d}/:repoName/create`,b.handleCreateSubmit),v.get(`${d}/:repoName/:id/edit`,b.handleEditForm),v.post(`${d}/:repoName/:id/edit`,b.handleEditSubmit),v.get(`${d}/:repoName/:id/history`,b.handleHistory),v.post(`${d}/:repoName/:id/delete`,b.handleDelete);let S=async(C,k)=>{await v.handle(C,k);};return f&&(S.httpsOptions=f),S}var Dn="preserve";function Fn(){return Dn}function so(e){return typeof e=="object"&&e!==null&&typeof e._seconds=="number"&&typeof e._nanoseconds=="number"}function jn(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(e instanceof Timestamp)return e.toDate();if(so(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 zn(e){return e}function Nt(e,t,n=200){let r=zn(t);e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(r));}function _e(e,t,n,r=200){Nt(e,{success:true,data:t,meta:n},r);}function q(e,t,n=400){Nt(e,{success:false,error:t},n);}function It(e,t,n,r,o){let s=Me(t,n),a=s.type==="index",f=a?424:500,m={success:false,error:a?s.message:o&&t instanceof Error?t.message:r};a&&(m.errorType="index",s.indexUrl&&(m.indexUrl=s.indexUrl)),Nt(e,m,f);}var _t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function lo(){let e="";for(;e.length<20;){let t=randomBytes(20);for(let n=0;n<t.length&&e.length<20;n++){let r=t[n];r>=_t.length*4||(e+=_t.charAt(r%_t.length));}}return e}function Ne(e){let t=e._def??e.def;if(!t)return e;let n=t.typeName??t.type;if(n==="ZodDate"||n==="date")return z.preprocess(r=>jn(r)??r,e);if(n==="ZodObject"||n==="object"){let r=e.shape,o={};for(let[s,a]of Object.entries(r))o[s]=Ne(a);return z.object(o)}if(n==="ZodArray"||n==="array"){let r=t.element??t.type;if(r)return z.array(Ne(r))}if(n==="ZodOptional"||n==="optional"){let r=t.innerType;if(r)return Ne(r).optional()}if(n==="ZodNullable"||n==="nullable"){let r=t.innerType;if(r)return Ne(r).nullable()}if(n==="ZodDefault"||n==="default"){let r=t.innerType,o=t.defaultValue;if(r){let s=Ne(r);return typeof o=="function"?s.default(o()):s.default(o)}}return e}function co(e,t,n=[]){let r=e.shape,o={},s=t&&t.length>0?t:Object.keys(r);for(let a of s){if(n.includes(a))continue;let f=a.split(".")[0];f&&r[f]&&(o[f]=r[f]);}return z.object(o)}function Zn(e,t,n,r=false,o=[]){try{let s=co(e,n,o),a=r?s.partial():s;return {success:!0,data:(Fn()==="normalize"?Ne(a):a).parse(t)}}catch(s){return s instanceof z.ZodError?{success:false,error:`Validation failed: ${s.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function uo(e,t){let n=[],r=t?new Set(t):null,o={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[s,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(s))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let d=s.match(/^(\w+)__(\w+)$/),m,b="==";if(d&&d[1]&&d[2]){m=d[1];let S=d[2];if(o[S])b=o[S];else continue}else if(!d)m=s;else continue;if(r&&!r.has(m))continue;let v=f;b==="in"||b==="not-in"||b==="array-contains-any"?v=f.split(",").map(S=>Bn(S.trim())):v=Bn(f),n.push({field:m,op:b,value:v});}return n}function Bn(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 ot(e){return e?{docId:e.id}:null}async function Mn(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 o=await r.doc(n).get();return o.exists?o:void 0}catch{return}}function Hn(e,t,n,r=false){async function o(g,i,u,c){if(!r)return true;let l=i.rules?.[u];if(!l)return q(g,`Operation "${u}" is not allowed for this repository`,403),false;try{return await l(c)?!0:(q(g,"Forbidden",403),!1)}catch(p){let y=n&&p instanceof Error?p.message:"Forbidden";return q(g,y,403),false}}async function s(g,i,u,c){if(!r)return c;let l=g.rules?.filter;if(!l)return c;let p=[];for(let y of c)try{await l({user:i,doc:y,params:u})&&p.push(y);}catch{}return p}function a(g){return g?.user??null}function f(g,i){return !g||!e[g]?(q(i,`Repository "${g}" not found`,404),null):e[g]}function d(g,i){if(!i)return;let u=g[i];if(typeof u!="string"||!u)return;let c=u.split("/").filter(Boolean),l=[];for(let p=1;p<c.length;p+=2)l.push(c[p]);return l.length>0?l:void 0}async function m(g,i){let u=`by${g.documentKey.charAt(0).toUpperCase()}${g.documentKey.slice(1)}`,c=g.repo.get[u];if(typeof c=="function")try{let p=await c(i);if(p)return p}catch{}return (await g.repo.query.by({where:[[g.documentKey,"==",i]],limit:1}))[0]??null}async function b(g,i){let u=g.params||{},c=f(u.repoName,i);if(!c)return;let l=a(g);if(!await o(i,c,"list",{user:l,query:g.query??{},params:u}))return;let p=[],y;try{let h=g.query??{},R=Math.min(Number(h.pageSize)||c.pageSize,100),w=h.cursor,O=h.direction?.toLowerCase()==="prev"?"prev":"next",A=h.orderBy,E=h.orderDir?.toLowerCase()==="desc"?"desc":"asc",T=h.select,P=T?T.split(",").map(U=>U.trim()):void 0,N;c.allowedIncludes&&h.includes&&(N=(typeof h.includes=="string"?h.includes.split(",").map(se=>se.trim()):Array.isArray(h.includes)?h.includes:[]).filter(se=>typeof se=="string"&&c.allowedIncludes.includes(se)),N?.length===0&&(N=void 0));let j=uo(h,c.filterableFields);p=j.map(U=>({field:U.field,op:U.op,value:String(U.value??"")})),A&&(y={field:A,dir:E});let D={pageSize:R,direction:O};if(w)try{let U=typeof w=="string"?JSON.parse(w):w;D.cursor=await Mn(c,U);}catch{}if(A){if(c.orderableFields&&!c.orderableFields.includes(A)){q(i,`Field not orderable: ${A}`,400);return}D.orderBy=[{field:A,direction:E}];}j.length>0&&(D.where=j.map(U=>[U.field,U.op,U.value])),P&&(D.select=P),N&&(D.include=N);let I=await c.repo.query.paginate(D),ce={items:await s(c,a(g),u,I.data),hasNextPage:I.hasNextPage,hasPrevPage:I.hasPrevPage,nextCursor:ot(I.nextCursor),prevCursor:ot(I.prevCursor)};_e(i,ce,{pageSize:R,hasMore:I.hasNextPage});}catch(h){It(i,h,{ref:c.repo.ref,path:c.path,isGroup:!!c.isGroup,filters:p,sort:y},"Failed to fetch documents",n);}}async function v(g,i){let u=g.params||{},c=f(u.repoName,i);if(!c)return;let l=a(g);if(!await o(i,c,"list",{user:l,query:g.body??{},params:u}))return;let p=[],y;try{let h=g.body??{},R=Math.min(h.pageSize||c.pageSize,100),w=h.direction==="prev"?"prev":"next";h.where&&(p=h.where.map(P=>({field:String(P[0]),op:P[1],value:String(P[2]??"")}))),h.orderBy&&h.orderBy[0]&&(y={field:h.orderBy[0].field,dir:h.orderBy[0].direction==="desc"?"desc":"asc"});let O={pageSize:R,direction:w};if(h.cursor)try{let P=typeof h.cursor=="string"?JSON.parse(h.cursor):h.cursor;O.cursor=await Mn(c,P);}catch{}if(c.allowedIncludes&&h.includes&&h.includes.length>0){let P=h.includes.filter(N=>typeof N=="string"?c.allowedIncludes.includes(N):typeof N=="object"&&N!==null&&"relation"in N&&typeof N.relation=="string"?c.allowedIncludes.includes(N.relation):!1);P.length>0&&(O.include=P);}if(h.where&&h.where.length>0){if(c.filterableFields){let P=new Set(c.filterableFields),N=h.where.filter(j=>!P.has(j[0]));if(N.length>0){q(i,`Fields not filterable: ${N.map(j=>j[0]).join(", ")}`,400);return}}O.where=h.where;}if(h.orWhere&&h.orWhere.length>0){if(c.filterableFields){let P=new Set(c.filterableFields),N=h.orWhere.filter(j=>!P.has(j[0]));if(N.length>0){q(i,`Fields not filterable: ${N.map(j=>j[0]).join(", ")}`,400);return}}O.orWhere=h.orWhere;}if(h.orWhereGroups&&h.orWhereGroups.length>0){if(c.filterableFields){let P=new Set(c.filterableFields);for(let N of h.orWhereGroups){let j=N.filter(D=>!P.has(D[0]));if(j.length>0){q(i,`Fields not filterable: ${j.map(D=>D[0]).join(", ")}`,400);return}}}O.orWhereGroups=h.orWhereGroups;}if(h.orderBy&&h.orderBy.length>0){if(c.orderableFields){let P=new Set(c.orderableFields),N=h.orderBy.filter(j=>!P.has(j.field));if(N.length>0){q(i,`Fields not orderable: ${N.map(j=>j.field).join(", ")}`,400);return}}O.orderBy=h.orderBy;}h.select&&h.select.length>0&&(O.select=h.select);let A=await c.repo.query.paginate(O),T={items:await s(c,a(g),u,A.data),hasNextPage:A.hasNextPage,hasPrevPage:A.hasPrevPage,nextCursor:ot(A.nextCursor),prevCursor:ot(A.prevCursor)};_e(i,T,{pageSize:R,hasMore:A.hasNextPage});}catch(h){It(i,h,{ref:c.repo.ref,path:c.path,isGroup:!!c.isGroup,filters:p,sort:y},"Failed to query documents",n);}}async function S(g,i){let u=g.params||{},c=f(u.repoName,i);if(!c)return;let l=u.id;if(!l){q(i,"Document ID required",400);return}try{let p=await m(c,l);if(!p){q(i,"Document not found",404);return}let y=a(g);if(!await o(i,c,"get",{user:y,doc:p,params:u}))return;if(r&&c.rules?.filter)try{if(!await c.rules.filter({user:y,doc:p,params:u})){q(i,"Document not found",404);return}}catch{q(i,"Document not found",404);return}_e(i,p);}catch(p){It(i,p,{ref:c.repo.ref,path:c.path,isGroup:!!c.isGroup,filters:[{field:c.documentKey,op:"==",value:l}]},"Failed to fetch document",n);}}async function C(g,i){let u=g.params||{},c=f(u.repoName,i);if(c)try{let l=g.body??{},p=a(g);if(!await o(i,c,"create",{user:p,body:l,params:u}))return;let y=Zn(c.schema,l,c.createFields,!1,c.systemKeys);if(!y.success){q(i,y.error,400);return}if(c.validate){let R=await c.validate(y.data,"create");if(R){q(i,R,400);return}}let h;if(c.isGroup&&c.parentKeys&&c.parentKeys.length>0){let R={...y.data};c.createdKey&&(R[c.createdKey]=new Date);let w=c.parentKeys.filter(E=>!R[E]);if(w.length>0){q(i,`Missing parent key(s) for subcollection create: ${w.join(", ")}`,400);return}let O=c.parentKeys.map(E=>R[E]),A=R[c.documentKey]||lo();h=await c.repo.set(...O,A,R);}else h=await c.repo.create(y.data);_e(i,h,void 0,201);}catch(l){let p=n&&l instanceof Error?l.message:"Failed to create document";q(i,p,500);}}async function k(g,i,u){let c=g.params||{},l=f(c.repoName,i);if(!l)return;let p=c.id;if(!p){q(i,"Document ID required",400);return}try{let y=g.body??{},h=await m(l,p);if(!h){q(i,"Document not found",404);return}let R=a(g);if(!await o(i,l,"update",{user:R,doc:h,body:y,params:c}))return;let w=Zn(l.schema,y,l.mutableFields,u,l.systemKeys);if(!w.success){q(i,w.error,400);return}if(l.validate){let E=await l.validate(w.data,"update");if(E){q(i,E,400);return}}let O=d(h,l.pathKey)??[p],A=await l.repo.update(...O,w.data);_e(i,A);}catch(y){let h=n&&y instanceof Error?y.message:"Failed to update document";q(i,h,500);}}async function x(g,i){let u=g.params||{},c=f(u.repoName,i);if(!c)return;if(!c.allowDelete){q(i,"Delete not allowed for this repository",403);return}let l=u.id;if(!l){q(i,"Document ID required",400);return}try{let p=await m(c,l);if(!p){q(i,"Document not found",404);return}let y=a(g);if(!await o(i,c,"delete",{user:y,doc:p,params:u}))return;let h=d(p,c.pathKey)??[l];await c.repo.delete(...h),_e(i,{deleted:!0});}catch(p){let y=n&&p instanceof Error?p.message:"Failed to delete document";q(i,y,500);}}function $(g,i){i.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:b,handleQuery:v,handleGet:S,handleCreate:C,handleUpdate:k,handleDelete:x,handleOptions:$}}function Dt(e){try{return 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 oe(e){return {$ref:`#/components/schemas/${e}`}}function Y(e){return {description:e,content:{"application/json":{schema:oe("ErrorResponse")}}}}function We(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function qn(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 po(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 fo(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],r=[];for(let o of t){r.push({name:o,in:"query",schema:{type:"string"},description:`Filter by ${o} (equality)`});for(let s of n)r.push({name:`${o}__${s}`,in:"query",schema:{type:"string"},description:`Filter ${o} with operator ${s}`});}return r}function mo(){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 yo(e,t,n,r,o){let s={},a=e.name,f=`${t}/${e.name}`,d=`${f}/{${e.documentKey}}`,m={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};s[f]={get:{operationId:`list${we(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...po(e),...fo(e)],responses:{200:qn(oe(n)),500:Y("Internal server error")}},post:{operationId:`create${we(e.name)}`,summary:`Create a ${le(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:oe(r??n)}}},responses:{201:We("Document created",oe(n)),400:Y("Validation error"),500:Y("Internal server error")}}},s[`${f}/query`]={post:{operationId:`query${we(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:oe("QueryRequestBody")}}},responses:{200:qn(oe(n)),400:Y("Invalid query"),500:Y("Internal server error")}}};let b={};return b.get={operationId:`get${we(le(e.name))}`,summary:`Get a single ${le(e.name)}`,tags:[a],parameters:[m],responses:{200:We("Document found",oe(n)),404:Y("Document not found"),500:Y("Internal server error")}},b.put={operationId:`update${we(le(e.name))}`,summary:`Update a ${le(e.name)} (full replace)`,tags:[a],parameters:[m],requestBody:{required:true,content:{"application/json":{schema:oe(o??n)}}},responses:{200:We("Document updated",oe(n)),400:Y("Validation error"),404:Y("Document not found"),500:Y("Internal server error")}},b.patch={operationId:`patch${we(le(e.name))}`,summary:`Partially update a ${le(e.name)}`,tags:[a],parameters:[m],requestBody:{required:true,content:{"application/json":{schema:{allOf:[oe(o??n)],description:"All fields are optional for partial updates"}}}},responses:{200:We("Document patched",oe(n)),400:Y("Validation error"),404:Y("Document not found"),500:Y("Internal server error")}},e.allowDelete&&(b.delete={operationId:`delete${we(le(e.name))}`,summary:`Delete a ${le(e.name)}`,tags:[a],parameters:[m],responses:{200:We("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:Y("Document not found"),500:Y("Internal server error")}}),s[d]=b,s}function jt(e,t,n={}){let{title:r="CRUD API",version:o="1.0.0",description:s,servers:a,auth:f=false}=n,d=t==="/"?"":t.replace(/\/$/,""),m={},b={},v=[];m.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},m.QueryRequestBody=mo();for(let[x,$]of Object.entries(e)){let g=we(le(x)),i=`${g}Create`,u=`${g}Update`;m[g]=Dt($.schema);let c=w=>{let O=w&&w.length>0?w:Object.keys($.schema.shape),A={};for(let E of O){let T=E.split(".")[0];T&&$.schema.shape[T]&&!$.systemKeys.includes(T)&&(A[T]=$.schema.shape[T]);}return A},l=null,p=c($.createFields);Object.keys(p).length>0&&(m[i]=Dt(z.object(p)),l=i);let y=null,h=c($.mutableFields);Object.keys(h).length>0&&(m[u]=Dt(z.object(h)),y=u);let R=yo($,d,g,l,y);Object.assign(b,R),v.push({name:x,description:`Operations on ${x} (collection: ${$.path})`});}let S={},C;return f==="basic"?(S.basicAuth={type:"http",scheme:"basic"},C=[{basicAuth:[]}]):f==="bearer"&&(S.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},C=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:r,version:o,...s?{description:s}:{}},...a&&a.length>0?{servers:a}:{},paths:b,components:{schemas:m,...Object.keys(S).length>0?{securitySchemes:S}:{}},...C?{security:C}:{},tags:v}}function we(e){return e.charAt(0).toUpperCase()+e.slice(1)}function le(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 go(e,t){return `<!DOCTYPE html>
1146
+ `;function Le(){return jsx("script",{dangerouslySetInnerHTML:{__html:Tn}})}Tt();function he(e){return "<!DOCTYPE html>"+renderToString(e)}var Gr=["corporate","silk","dark"],Jr=()=>jsxs("div",{class:"dropdown dropdown-end","data-frs-theme-switcher":true,children:[jsxs("button",{type:"button",tabIndex:0,class:"btn btn-sm btn-ghost text-neutral-content gap-1.5","aria-label":"Switch theme",children:[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:[jsx("circle",{cx:"12",cy:"12",r:"4"}),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"})]}),jsx("span",{class:"text-xs hidden sm:inline","data-frs-theme-current":true,children:"Theme"})]}),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:Gr.map(e=>jsx("li",{children:jsxs("button",{type:"button","data-frs-theme":e,class:"capitalize justify-between",children:[jsx("span",{children:e}),jsx("span",{class:"hidden text-primary","data-frs-theme-check":e,children:"\u2713"})]})},e))})]}),be=({opts:e,children:t})=>{let{title:n,breadcrumb:r,flash:o,basePath:s="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsx("script",{dangerouslySetInnerHTML:{__html:"(function(){try{var t=localStorage.getItem('frs-admin-theme');if(t){document.documentElement.setAttribute('data-theme',t);}}catch(_){}})();"}}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsxs("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:[jsx("div",{class:"flex-1",children:jsx("a",{href:s,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})}),jsx("div",{class:"flex-none",children:jsx(Jr,{})})]}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[r&&r.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:r.map((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),o&&jsxs("div",{role:"alert",class:`alert ${o.type==="success"?"alert-success":o.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsx("span",{class:"flex-1",children:o.message}),o.action&&jsx("a",{href:o.action.href,...o.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:o.action.label})]}),t]}),jsx(kt,{basePath:s}),jsx(Le,{})]})]})};function Ct(e,t){return he(jsx(be,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function At(e,t){return he(jsx(be,{opts:{title:"Repositories",basePath:t},children:e.length===0?jsxs("div",{class:"text-center py-20 text-base-content/50",children:[jsx("p",{class:"text-lg font-medium mb-1",children:"No repositories configured"}),jsx("p",{class:"text-sm",children:"Add a repository to your FRS config to get started."})]}):jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:e.map(n=>jsx("a",{href:`${t}/${n.name}`,class:"card bg-base-100 border border-base-300 hover:shadow-md no-underline transition-shadow",children:jsxs("div",{class:"card-body p-5",children:[jsx("h2",{class:"card-title text-sm font-semibold",children:n.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:n.path})]})},n.name))})}))}var $n=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],Xr=[{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"}],Yr=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function eo(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return Xr;case "ZodBoolean":return $n;case "ZodArray":return Yr;default:return $n}}var we="__null__";function to(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="${we}"]');if(!o){o=document.createElement('option');o.value='${we}';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='${we}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${we}"][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!=='${we}')?i.dataset._prev:'';}}})(this)`}function no(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 Ue({inputId:e,active:t}){return 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:[jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",checked:t,onchange:to(e)}),jsx("span",{children:"\u2205"})]})}function ro({col:e,active:t}){let n=t?.value??"",r=n===we,o=`fv_input_${e.name.replace(/\./g,"__")}`,s=t?.op,a=s==="in"||s==="not-in";if(e.enumValues&&e.enumValues.length>0){if(a){let f=new Set(n.split(",").map(m=>m.trim()).filter(Boolean)),d=`eg_${e.name.replace(/\./g,"__")}`;return jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsx("input",{type:"hidden",id:o,name:`fv_${e.name}`,value:n}),e.enumValues.map(m=>jsxs("label",{class:"flex items-center gap-1 text-xs border border-base-300 rounded px-2 cursor-pointer hover:bg-base-200",children:[jsx("input",{type:"checkbox",class:"checkbox checkbox-xs",value:m,checked:f.has(m),"data-enum-group":d,onchange:no(o,d)}),jsx("span",{children:m})]},m))]})}return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),e.enumValues.map(f=>jsx("option",{value:f,selected:n===f,children:f},f)),e.nullable&&jsx("option",{value:we,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(Ue,{inputId:o,active:r})]})}if(e.zodType==="ZodBoolean")return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:r?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:n===""&&!r,children:"\u2014"}),jsx("option",{value:"true",selected:n==="true",children:"true"}),jsx("option",{value:"false",selected:n==="false",children:"false"}),e.nullable&&jsx("option",{value:we,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(Ue,{inputId:o,active:r})]});if(e.zodType==="ZodArray"){let f=t?.op==="array-contains-any";return jsx("input",{id:o,type:"text",name:`fv_${e.name}`,value:n,placeholder:f?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Ue,{inputId:o,active:r})]}):e.zodType==="ZodDate"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Ue,{inputId:o,active:r})]}):jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,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&&jsx(Ue,{inputId:o,active:r})]})}function Ot({action:e,columnMeta:t,activeFilters:n,isGroup:r}){let o=Object.fromEntries(n.map(d=>[d.field,d])),s=n.length>0,a=n.length>=2||r&&s,f=t.filter(d=>d.zodType!=="ZodObject"&&d.zodType!=="ZodRecord");return jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:s?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",s&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[n.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:f.map(d=>{let m=eo(d.zodType),v=o[d.name],R=v?.op??m[0].value;return jsxs("div",{class:"flex flex-col gap-1.5",children:[jsx("label",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:d.name}),jsxs("div",{class:"flex gap-1.5",children:[m.length>1?jsx("select",{name:`fo_${d.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:m.map(A=>jsx("option",{value:A.value,selected:A.value===R,children:A.label},A.value))}):jsx("input",{type:"hidden",name:`fo_${d.name}`,value:m[0].value}),jsx(ro,{col:d,active:v})]})]},d.name)})}),jsxs("div",{class:"flex flex-wrap gap-2 mt-4 pt-3 border-t border-base-200 items-center",children:[jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),s&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),a&&jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children: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 $t(e,t,n,r,o,s){let a=n==="create"?`Create ${e}`:`Edit ${e} / ${r??""}`,f=n==="create"?[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:"New document"}]:[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:`Edit ${r??""}`}];return he(jsx(be,{opts:{title:a,breadcrumb:f,basePath:o,flash:s},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}rt();Rt();function Et(e,t,n){let r=new URLSearchParams;for(let o of e)r.set(`fv_${o.field}`,o.value),r.set(`fo_${o.field}`,o.op);return t&&(r.set("ob",t.field),r.set("od",t.dir)),n&&r.set("ps",String(n)),r}function En(e,t,n,r,o){let s=Et(e,r,o);return s.set("cursor",t),s.set("dir",n),`?${s.toString()}`}function oo(e,t,n,r){let o=Et(n,void 0,r);return t?.field===e?t.dir==="asc"&&(o.set("ob",e),o.set("od","desc")):(o.set("ob",e),o.set("od","asc")),`?${o.toString()}`}function so(e,t,n){return `?${Et(t,n,e).toString()}`}function Pt(e,t,n,r,o,s,a=[],f=[],d=false,m=[],v,R,A,S,w,C,b,g=false){let u=`${r}/${e}`,c=`${u}/create`,i={};if(b)for(let x of n)i[x]=Pe(De(b,x));let l=(C??[]).filter(x=>{let O=i[x]??Pe(De(b,x));return O==="string"||O==="number"||O==="bigint"||O==="boolean"||O==="enum"||O==="literal"}),p=l.length>0,y=d,h=y||p,E=l.map(x=>{let O=De(b,x),T=Pe(O),$=a.find(P=>P.name===x);return {name:x,type:T,enumValues:$?.enumValues??null,nullable:$?.nullable??false}});return he(jsxs(be,{opts:{title:e,breadcrumb:[{label:"Repositories",href:r},{label:e}],basePath:r,flash:s},children:[a.length>0&&jsx(Ot,{action:u,columnMeta:a,activeFilters:f,isGroup:S}),A&&jsxs("div",{role:"alert",class:`alert ${A.type==="index"?"alert-warning":"alert-error"} mb-6 shadow-sm`,children:[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:A.type==="index"?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"}):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"})}),jsxs("div",{class:"flex-1",children:[jsx("h3",{class:"font-bold",children:A.type==="index"?"Composite index required":"Query failed"}),jsx("div",{class:"text-sm",children:A.message})]}),A.indexUrl&&jsx("a",{href:A.indexUrl,target:"_blank",rel:"noopener noreferrer",class:"btn btn-sm btn-outline",children:"Create Index \u2192"})]}),jsxs("div",{class:"flex flex-wrap justify-between items-center mb-4 gap-3","data-frs-toolbar":true,children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length,typeof w=="number"&&jsxs(Fragment,{children:[" ","of"," ",jsx("span",{class:"font-semibold text-base-content/80",children:w})]})," ","document",(typeof w=="number"?w:t.length)!==1&&"s"]}),jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsx("span",{children:"Rows"}),jsx("div",{class:"join",children:[10,25,50,100].map(x=>jsx("a",{href:so(x,f,v),class:`join-item btn btn-xs ${R===x?"btn-active btn-primary":"btn-outline"}`,children:x},x))})]})]}),jsx("a",{href:c,class:"btn btn-primary btn-sm",children:"+ New"})]}),h&&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 w=="number"?String(w):"","data-frs-page-size":String(R??t.length),"data-frs-allow-delete":y?"1":"0","data-frs-allow-update":p?"1":"0","data-frs-fields":JSON.stringify(E),"data-frs-filters":JSON.stringify(f),children:[jsxs("div",{class:"flex-1 text-sm",children:[jsx("span",{"data-frs-bulk-summary":true,children:"0 selected"}),typeof w=="number"&&w>t.length&&jsxs("button",{type:"button",class:"ml-3 link text-sm hidden","data-frs-bulk-select-all":true,children:["Select all ",w," matching documents"]}),jsxs("span",{class:"hidden ml-3 italic","data-frs-bulk-all-active":true,children:["All ",w??"?"," matching documents are selected."," ",jsx("button",{type:"button",class:"link","data-frs-bulk-clear":true,children:"Clear selection"})]})]}),jsxs("div",{class:"flex gap-2",children:[p&&jsx("button",{type:"button",class:"btn btn-sm btn-outline","data-frs-bulk-action":"update",children:"Update field\u2026"}),y&&jsx("button",{type:"button",class:"btn btn-sm btn-error btn-outline","data-frs-bulk-action":"delete",children:"Delete"})]})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[h&&jsx("th",{class:"w-8",children: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,O)=>{let T=v?.field===x,$=T?v.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:oo(x,v,f,R),class:`hover:text-base-content inline-flex items-center gap-0.5${T?" text-primary font-bold":""}`,children:[x,$]})},O)}),m.map((x,O)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:x.column},`rel-${O}`)),jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsx("tbody",{children:t.length===0?jsx("tr",{children:jsx("td",{colspan:n.length+m.length+1+(h?1:0),class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((x,O)=>{let T=String(x.docId??x.id??""),$=`${r}/${e}/${encodeURIComponent(T)}/edit`,P=`${r}/${e}/${encodeURIComponent(T)}/delete`;return jsxs("tr",{class:"hover","data-frs-row-id":T,children:[h&&jsx("td",{class:"align-middle py-2",children:jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-row":true,value:T,"aria-label":`Select ${T}`})}),n.map((k,I)=>{let F=x[k],N=i[k],D=N?qe(N,F):null;return jsx("td",{class:"align-top py-2",children:jsx(Ee,{val:F,mismatch:D})},I)}),m.map((k,I)=>{let F=x[k.key];if(F==null||F==="")return jsx("td",{class:"py-2"},`rel-${I}`);let N=k.type==="one"?`${r}/${k.targetRepo}/${encodeURIComponent(String(F))}/edit`:`${r}/${k.targetRepo}?fv_${k.targetKey}=${encodeURIComponent(String(F))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:N,class:"btn btn-xs btn-ghost btn-outline","data-frs-relation":true,"data-frs-rel-type":k.type,"data-frs-rel-repo":k.targetRepo,"data-frs-rel-fk":k.targetKey,"data-frs-rel-val":String(F),"data-frs-rel-label":k.column,children:k.column})},`rel-${I}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:$,class:"btn btn-xs btn-outline",children:"Edit"}),g&&jsx("a",{href:`${r}/${e}/${encodeURIComponent(T)}/history`,class:"btn btn-xs btn-outline",title:"View change history",children:"History"}),d&&jsx("form",{method:"post",action:P,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},O)})})]})}),(o.hasPrev||o.hasNext)&&jsxs("div",{class:"flex flex-col items-center mt-6 gap-2",children:[jsxs("div",{class:"flex justify-center items-center gap-2",children:[o.hasPrev?jsx("a",{href:En(f,o.prevCursor,"prev",v,R),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),o.hasNext?jsx("a",{href:En(f,o.nextCursor,"next",v,R),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]}),typeof w=="number"&&jsxs("div",{class:"text-xs text-base-content/50",children:[w," total document",w!==1?"s":"",f.length>0?" matching filters":""]})]}),h&&p&&jsxs("dialog",{id:"frs-bulk-update-modal",class:"modal",children:[jsxs("div",{class:"modal-box",children:[jsx("h3",{class:"font-bold text-lg mb-3",children:"Bulk update field"}),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."}),jsxs("form",{method:"dialog","data-frs-bulk-update-form":true,children:[jsxs("label",{class:"form-control w-full mb-3",children:[jsx("div",{class:"label",children:jsx("span",{class:"label-text text-xs uppercase tracking-wide",children:"Field"})}),jsxs("select",{class:"select select-bordered select-sm w-full",name:"field",required:true,"data-frs-bulk-field-select":true,children:[jsx("option",{value:"",children:"\u2014 Select a field \u2014"}),l.map(x=>jsx("option",{value:x,children:x},x))]})]}),jsx("div",{class:"mb-4","data-frs-bulk-value-container":true}),jsxs("div",{class:"modal-action",children:[jsx("button",{type:"button",class:"btn btn-sm btn-ghost","data-frs-bulk-update-cancel":true,children:"Cancel"}),jsx("button",{type:"submit",class:"btn btn-sm btn-primary","data-frs-bulk-update-submit":true,children:"Apply"})]})]})]}),jsx("form",{method:"dialog",class:"modal-backdrop",children:jsx("button",{children:"close"})})]})]}))}var io="";function Ke(e,t){return Ct(e,t)}function Dt(e,t){return At(e,t)}function It(e,t,n,r,o,s,a,f,d,m,v,R,A,S,w,C,b,g){return Pt(e,t,n,r,o,s,a,f,d,m,v,R,A,S,w,C,b,g)}function xe(e,t,n,r,o,s){return $t(e,t,n,r,o,s)}var _t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function uo(){let e="";for(;e.length<20;){let t=randomBytes(20);for(let n=0;n<t.length&&e.length<20;n++){let r=t[n];r>=_t.length*4||(e+=_t.charAt(r%_t.length));}}return e}function st(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let r=n.split("/").filter(Boolean),o=[];for(let s=1;s<r.length;s+=2)o.push(r[s]);return o.length>0?o:void 0}async function Ie(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 s=await e.repo.get[r](t);if(s)return s}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function Nt(e,t,n){let r=e.documentKey??"docId",o=Ze(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:r,op:"==",value:t}]});return o.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...o.indexUrl?{action:{href:o.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:o.message}}function H(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Ft(e,t){e.status(302).set("Location",t).send("");}function jt(e,t){let n=t.shape,r={};for(let[o,s]of Object.entries(n)){let a=Ht(s);if(a==="ZodObject"){if(e[o+"__isnull"]==="1"){r[o]=null;continue}let m={},v=false;for(let[S,w]of Object.entries(e))S.startsWith(`${o}.`)&&(m[S.slice(o.length+1)]=w,v=true);if(v){let S=s;for(;;){let w=q(S);if(w==="ZodOptional"||w==="ZodNullable"||w==="ZodDefault")S=W(S);else break}r[o]=jt(m,S);continue}let R=e[o],A=Array.isArray(R)?R[R.length-1]:R;if(A)try{r[o]=JSON.parse(A);}catch{r[o]=A;}continue}let f=e[o],d=Array.isArray(f)?f[f.length-1]:f;if(e[o+"__isnull"]==="1"){r[o]=null;continue}if(d===void 0||d===""){a==="ZodBoolean"&&(r[o]=false);continue}switch(a){case "ZodBoolean":d==="__null__"?r[o]=null:r[o]=d==="true"||d==="on"||d==="1";break;case "ZodNumber":case "ZodBigInt":r[o]=Number(d);break;case "ZodDate":r[o]=new Date(d);break;case "ZodArray":try{r[o]=JSON.parse(d);}catch{r[o]=d;}break;default:if(d.startsWith("{")||d.startsWith("["))try{r[o]=JSON.parse(d);break}catch{}r[o]=d;}}return r}function Pn(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 Ht(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=W(t);else return n}}function po(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=W(t);else return t}}function In(e){let t=e;for(;;){let n=q(t);if(n==="ZodOptional"||n==="ZodNullable")return true;if(n==="ZodDefault"){t=W(t);continue}return false}}function _n(e){let t=po(e),n=q(t);if(n==="ZodEnum"){let r=je(t);return r.length>0?r:void 0}if(n==="ZodNativeEnum"){let r=Me(t),o=Object.values(r).filter(s=>typeof s=="string");return o.length>0?o:void 0}if(n==="ZodLiteral"){let r=He(t);return typeof r=="string"?[r]:void 0}}function Nn(e,t,n=""){let r={};for(let o of Object.keys(t.shape)){let s=n?`${n}.${o}`:o,a=e[o];if(a===null){r[s]="__null__";continue}if(a===void 0)continue;let f=t.shape[o];for(;;){let m=q(f);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")f=W(f);else break}let d=q(f);if(d==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let m=Nn(a,f,s);Object.assign(r,m);}else if(d==="ZodDate"){let m=Pn(a);m!==null&&(r[s]=m);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let m=Pn(a);r[s]=m??JSON.stringify(a,null,2);}else typeof a=="object"?r[s]=JSON.stringify(a,null,2):r[s]=String(a);}return r}function Mt(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?Mt(n.nested,t):void 0}))}function fo(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),r=[];for(let[o,s]of Object.entries(e)){if(!o.startsWith("fv_"))continue;let a=o.slice(3);if(!t.has(a))continue;let f=(s??"").trim();if(!f)continue;let d=e[`fo_${a}`]??"==",m=n.has(d)?d:"==";r.push({field:a,op:m,value:f});}return r}function Dn(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 o=r.value.split(",").map(s=>s.trim()).filter(s=>s!==""&&s!==t).map(s=>n(s));return [r.field,r.op,o]}return [r.field,r.op,n(r.value)]})}function Fn(e,t,n=""){let r=[];for(let o of e){let s=n?`${n}.${o}`:o,a=t.shape[o];if(!a){r.push({name:s,zodType:"ZodString"});continue}let f=Ht(a);if(f==="ZodObject"){let d=a;for(;;){let v=q(d);if(v==="ZodOptional"||v==="ZodNullable"||v==="ZodDefault")d=W(d);else break}let m=ne(d);r.push(...Fn(Object.keys(m),d,s));}else r.push({name:s,zodType:f,nullable:In(a),enumValues:_n(a)});}return r}function mo(e,t){let n=t.split("."),r=e;for(let o of n){for(;;){let a=q(r);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")r=W(r);else break}let s=ne(r);if(!(o in s))return null;r=s[o];}return r}function Te(e,t){if(!t||t.length===0)return e;let n=[],r=new Map;for(let s of t){let a=s.indexOf(".");if(a===-1)n.push(s);else {let f=s.slice(0,a),d=s.slice(a+1);r.has(f)||r.set(f,[]),r.get(f).push(d);}}let o={};for(let s of n)s in e.shape&&(o[s]=e.shape[s]);for(let[s,a]of r){if(!(s in e.shape))continue;let f=e.shape[s];for(;;){let d=q(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=W(f);else break}if(q(f)!=="ZodObject"){o[s]=e.shape[s];continue}o[s]=Te(f,a);}return z.object(o)}function fe(e,t,n){return te(e,t,n)}function jn(e,t,n){let r=(u,c)=>{let i=fe(u,t,n),l=Object.values(e).map(p=>({name:p.name,path:p.path}));H(c,Dt(l,i));},o=async(u,c)=>{let i=u.params.repoName;if(!i){H(c,"Bad request",400);return}let l=e[i];if(!l){H(c,"Repository not found",404);return}let p=l.pageSize??25,y=u.query??{},h=y.cursor,E=y.dir==="prev"?"prev":"next",x=y.ob??"",O=y.od==="desc"?"desc":"asc",T=x?{field:x,dir:O}:void 0,$=parseInt(y.ps??""),P=Number.isFinite($)&&$>0?Math.min($,200):p,k=l.listColumns??Object.keys(l.schema.shape),I=l.documentKey??"docId",F=[I,...k.filter(Q=>Q!==I)];T&&(new Set([I,...k]).has(T.field)||(T=void 0));let N=l.filterableFields?(()=>{let Q=[];for(let de of l.filterableFields)(de.includes(".")||k.includes(de))&&Q.push(de);return Q})():k,D=(()=>{let Q=[];for(let de of N)if(de.includes(".")){let Ae=mo(l.schema,de);Q.push({name:de,zodType:Ae?Ht(Ae):"ZodString",nullable:Ae?In(Ae):false,enumValues:Ae?_n(Ae):void 0});}else Q.push(...Fn([de],l.schema));return Q})(),K=new Set(D.map(Q=>Q.name)),ce=fo(y,K),U=Dn(ce),se;if(h)try{let Q=l.repo.ref;typeof Q.doc=="function"&&(se=await Q.doc(h).get());}catch{}let[J,Ge]=await Promise.all([l.repo.query.paginate({pageSize:P,cursor:se,direction:E,...U.length>0?{where:U}:{},...T?{orderBy:[{field:T.field,direction:T.dir}]}:{}}).catch(Q=>({queryError:Ze(Q,{ref:l.repo.ref,path:l.path,isGroup:!!l.isGroup,filters:ce,sort:T})})),l.repo.aggregate.count(U.length>0?{where:U}:{}).catch(()=>{})]),Ce="queryError"in J,Gn=Ce?[]:J.data,Jn=Ce?"":J.nextCursor?.id??"",Xn=Ce?"":J.prevCursor?.id??"",Yn=Ce?J.queryError:void 0,er=fe(u,t,n);H(c,It(l.name,Gn,F,er,{hasPrev:Ce?false:J.hasPrevPage,hasNext:Ce?false:J.hasNextPage,prevCursor:Xn,nextCursor:Jn},void 0,D,ce,l.allowDelete??false,l.relationalMeta,T,P,Yn,l.isGroup,Ge,l.mutableFields,l.schema,l.historyEnabled));},s=(u,c)=>{let i=u.params.repoName;if(!i){H(c,"Bad request",400);return}let l=e[i];if(!l){H(c,"Repository not found",404);return}let p=fe(u,t,n),y=Te(l.schema,l.createFields),h=ie(y),E=`${p}/${l.name}/create`,x=ge(h,E,"POST","Create document");H(c,xe(l.name,x,"create",null,p));},a=async(u,c)=>{let i=u.params.repoName;if(!i){H(c,"Bad request",400);return}let l=e[i];if(!l){H(c,"Repository not found",404);return}let p=fe(u,t,n),y=u.body??{},h=jt(y,l.schema),E=Te(l.schema,l.createFields),x=E.safeParse(h);if(!x.success){let O=ie(E),T=`${p}/${l.name}/create`,$=ge(O,T,"POST","Create document"),P=x.error.issues.map(k=>`${k.path.join(".")}: ${k.message}`).join(", ");H(c,xe(l.name,$,"create",null,p,{type:"error",message:`Validation error: ${P}`}),422);return}try{if(l.isGroup&&l.parentKeys&&l.parentKeys.length>0){let O={...x.data};l.createdKey&&(O[l.createdKey]=new Date);let T=l.parentKeys.filter(I=>!O[I]);if(T.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${T.join(", ")}`);let $=l.parentKeys.map(I=>O[I]),P=l.documentKey??"docId",k=O[P]||uo();await l.repo.set(...$,k,O);}else await l.repo.create(x.data);Ft(c,`${p}/${l.name}?flash=created`);}catch(O){let T=Te(l.schema,l.createFields),$=ie(T),P=`${p}/${l.name}/create`,k=ge($,P,"POST","Create document");H(c,xe(l.name,k,"create",null,p,{type:"error",message:`Save error: ${O.message}`}),500);}},f=async(u,c)=>{let i=u.params.repoName,l=u.params.id;if(!i||!l){H(c,"Bad request",400);return}let p=e[i];if(!p){H(c,"Repository not found",404);return}let y=fe(u,t,n),h=null;try{h=await Ie(p,l);}catch(P){let k=Nt(p,l,P),I=Re(P)?424:500;H(c,Ke("",{title:`Edit ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`Edit ${l}`}],flash:k}),I);return}if(!h){H(c,"Document not found",404);return}let E=Nn(h,p.schema),x=Te(p.schema,p.mutableFields),O=Mt(ie(x),E),T=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,$=ge(O,T,"POST","Save changes");H(c,xe(p.name,$,"edit",l,y));},d=async(u,c)=>{let i=u.params.repoName,l=u.params.id;if(!i||!l){H(c,"Bad request",400);return}let p=e[i];if(!p){H(c,"Repository not found",404);return}let y=fe(u,t,n),h=u.body??{},E=jt(h,p.schema),x=Te(p.schema,p.mutableFields),T=x.partial().safeParse(E);if(!T.success){let $=Object.fromEntries(Object.entries(h).map(([N,D])=>[N,Array.isArray(D)?D.join(","):D??""])),P=Mt(ie(x),$),k=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,I=ge(P,k,"POST","Save changes"),F=T.error.issues.map(N=>`${N.path.join(".")}: ${N.message}`).join(", ");H(c,xe(p.name,I,"edit",l,y,{type:"error",message:`Validation error: ${F}`}),422);return}try{let $=await Ie(p,l),P=($&&st($,p.pathKey))??[l];await p.repo.update(...P,T.data),Ft(c,`${y}/${p.name}?flash=updated`);}catch($){let P=Te(p.schema,p.mutableFields),k=ie(P),I=`${y}/${p.name}/${encodeURIComponent(l)}/edit`,F=ge(k,I,"POST","Save changes"),N=Re($)?Nt(p,l,$):{type:"error",message:`Save error: ${$.message}`},D=Re($)?424:500;H(c,xe(p.name,F,"edit",l,y,N),D);}},m=async(u,c)=>{let i=u.params.repoName,l=u.params.id;if(!i||!l){H(c,"Bad request",400);return}let p=e[i];if(!p){H(c,"Repository not found",404);return}if(!p.allowDelete){H(c,"Delete is not allowed for this repository",403);return}let y=fe(u,t,n);try{let h=await Ie(p,l),E=(h&&st(h,p.pathKey))??[l];await p.repo.delete(...E),Ft(c,`${y}/${p.name}?flash=deleted`);}catch(h){let E=Re(h)?Nt(p,l,h):{type:"error",message:`Delete error: ${h.message}`},x=Re(h)?424:500;H(c,Ke("",{title:`Delete ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`Delete ${l}`}],flash:E}),x);}},v=async(u,c)=>{let i=u.params.repoName;if(!i){H(c,"Bad request",400);return}let l=e[i];if(!l){H(c,"Repository not found",404);return}let p=fe(u,t,n),y=u.query,h=y?.type==="many"?"many":"one",E=Math.max(1,Math.min(100,Number(y?.ps??25)||25)),x=l.listColumns??Object.keys(ne(l.schema)),{PanelOne:O,PanelMany:T}=await Promise.resolve().then(()=>(Tt(),An)),{renderToString:$}=await import('hono/jsx/dom/server');if(h==="one"){let D=String(y?.id??"");if(!D){H(c,"<div class='p-6 text-error'>Missing id parameter.</div>",400);return}try{let K=await Ie(l,D),ce=$(O({doc:K,repoName:l.name,basePath:p,schema:l.schema,columns:x}));H(c,ce);}catch(K){H(c,`<div class='p-6 text-error text-sm'>Error: ${K.message}</div>`,500);}return}let P=String(y?.fk??""),k=String(y?.fv??"");if(!P||!k){H(c,"<div class='p-6 text-error'>Missing fk/fv parameters.</div>",400);return}let I=y?.cursor??"",F=y?.dir==="prev"?"prev":"next",N;if(I)try{let D=l.repo.ref;typeof D.doc=="function"&&(N=await D.doc(I).get());}catch{}try{let D=await l.repo.query.paginate({pageSize:E,cursor:N,direction:F,where:[[P,"==",yo(k)]]}),K=$(T({docs:D.data,repoName:l.name,basePath:p,fk:P,fv:k,columns:x,schema:l.schema,pagination:{hasPrev:D.hasPrevPage,hasNext:D.hasNextPage,prevCursor:D.prevCursor?.id??"",nextCursor:D.nextCursor?.id??"",pageSize:E}}));H(c,K);}catch(D){H(c,`<div class='p-6 text-error text-sm'>Error: ${D.message}</div>`,500);}},R=async(u,c)=>{let i=[];for(let l of c){let p;if(u.isGroup||u.parentKeys?.length){let y=await Ie(u,l);p=y?st(y,u.pathKey):void 0;}p||(p=[l]);try{let y=u.repo.documentRef(...p);y&&i.push(y);}catch{}}return i},A=async(u,c)=>{let i=Dn(c),l=u.documentKey??"docId",p=[],y;for(;;){let h=await u.repo.query.paginate({pageSize:500,cursor:y,direction:"next",...i.length>0?{where:i}:{}});for(let E of h.data){let x=String(E[l]??E.id??"");x&&p.push(x);}if(!h.hasNextPage||!h.nextCursor)break;y=h.nextCursor;}return p},S=async(u,c)=>{let i=u.params.repoName;if(!i){ee(c,{error:"Bad request"},400);return}let l=e[i];if(!l){ee(c,{error:"Repository not found"},404);return}if(!l.allowDelete){ee(c,{error:"Delete is not allowed for this repository"},403);return}let p=u.body??{};try{let y=await C(l,p);if(y.length===0){ee(c,{deleted:0});return}let h=await R(l,y);for(let E=0;E<h.length;E+=500)await l.repo.bulk.delete(h.slice(E,E+500));ee(c,{deleted:h.length});}catch(y){ee(c,{error:y.message},500);}},w=async(u,c)=>{let i=u.params.repoName;if(!i){ee(c,{error:"Bad request"},400);return}let l=e[i];if(!l){ee(c,{error:"Repository not found"},404);return}let p=u.body??{},y=String(p.field??"");if(!y){ee(c,{error:"Missing 'field'"},400);return}if(!l.mutableFields||!l.mutableFields.includes(y)){ee(c,{error:`Field '${y}' is not bulk-updatable`},403);return}let h=l.schema.shape?.[y],E=p.value;if(h){let x=h.safeParse(p.value);if(!x.success){ee(c,{error:`Invalid value for '${y}': ${x.error.message}`},400);return}E=x.data;}try{let x=await C(l,p);if(x.length===0){ee(c,{updated:0});return}let T=(await R(l,x)).map($=>({docRef:$,data:{[y]:E}}));for(let $=0;$<T.length;$+=500)await l.repo.bulk.update(T.slice($,$+500));ee(c,{updated:T.length});}catch(x){ee(c,{error:x.message},500);}};async function C(u,c){if(c.selectAll){let i=b(c.filters,u);return await A(u,i)}return Array.isArray(c.ids)?c.ids.filter(i=>typeof i=="string"&&!!i):[]}function b(u,c){if(!Array.isArray(u))return [];let i=new Set((c.filterableFields??Object.keys(ne(c.schema))).map(y=>String(y))),l=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),p=[];for(let y of u)y&&typeof y=="object"&&typeof y.field=="string"&&i.has(y.field)&&typeof y.value=="string"&&l.has(String(y.op))&&p.push({field:y.field,op:y.op,value:y.value});return p}return {handleDashboard:r,handleList:o,handleCreateForm:s,handleCreateSubmit:a,handleEditForm:f,handleEditSubmit:d,handleDelete:m,handlePanel:v,handleBulkDelete:S,handleBulkUpdate:w,handleHistory:async(u,c)=>{let i=u.params.repoName,l=u.params.id;if(!i||!l){H(c,"Bad request",400);return}let p=e[i];if(!p){H(c,"Repository not found",404);return}if(!p.historyEnabled||!p.repo.history){H(c,"History not enabled for this repository",404);return}let y=fe(u,t,n),h=p.historySubcollection??"history",E=[l];try{let D=await Ie(p,l),K=D?st(D,p.pathKey):void 0;K&&K.length>0&&(E=K);}catch{}let x=parseInt(String(u.query?.limit??"")),O=Number.isFinite(x)&&x>0?Math.min(x,500):100,T=[],$;try{T=await p.repo.history.list(...E,{limit:O});}catch(D){$=D.message;}let P=D=>String(D??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),k=D=>{if(D===void 0)return '<span class="opacity-40">undefined</span>';if(D===null)return '<span class="opacity-40">null</span>';if(typeof D=="object")try{return `<code class="text-xs">${P(JSON.stringify(D))}</code>`}catch{return P(String(D))}return P(String(D))},I=D=>D?typeof D.toDate=="function"?D.toDate().toISOString():D instanceof Date?D.toISOString():P(String(D)):"",F=D=>`<span class="badge badge-sm ${D==="create"?"badge-success":D==="delete"?"badge-error":"badge-info"}">${P(D)}</span>`,N="";if(N+='<div class="flex items-center justify-between mb-4">',N+=`<a href="${y}/${p.name}/${encodeURIComponent(l)}/edit" class="btn btn-sm btn-outline">\u2190 Back to edit</a>`,N+=`<a href="${y}/${p.name}" class="btn btn-sm btn-outline">\u2190 Back to list</a>`,N+="</div>",N+=`<p class="text-sm text-base-content/60 mb-4">Subcollection: <code>${P(h)}</code> \xB7 Showing up to ${O} entries.</p>`,$)N+=`<div class="alert alert-error mb-4">${P($)}</div>`;else if(T.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 D of T){let K=D.meta??{},ce=[K.reason,K.comment].filter(J=>J!=null&&J!=="").map(J=>P(String(J))).join(" \u2014 "),U="",se=Object.keys(D.changes??{});se.length===0?U='<span class="opacity-40">\u2014</span>':U='<ul class="space-y-1">'+se.map(J=>{let Ge=D.changes[J];return `<li><strong>${P(J)}</strong>: ${k(Ge.oldValue)} \u2192 ${k(Ge.newValue)}</li>`}).join("")+"</ul>",N+="<tr>",N+=`<td class="whitespace-nowrap text-xs font-mono">${P(I(D.historySetAt))}</td>`,N+=`<td>${F(D.operation??"update")}</td>`,N+=`<td class="text-xs">${P(K.userEmail??K.userId??"")}</td>`,N+=`<td class="text-xs">${ce}</td>`,N+=`<td>${U}</td>`,N+="</tr>";}N+="</tbody></table></div>";}H(c,Ke(N,{title:`History \u2014 ${p.name} / ${l}`,basePath:y,breadcrumb:[{label:"Repositories",href:y},{label:p.name,href:`${y}/${p.name}`},{label:`History ${l}`}]}));}}}function ee(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function yo(e){return e==="true"?true:e==="false"?false:e!==""&&!isNaN(Number(e))?Number(e):e}var Mn="https://cdn.jsdelivr.net",Hn="https://www.gstatic.com",Bn=["default-src 'self'",`script-src 'self' 'unsafe-inline' 'unsafe-eval' ${Mn} ${Hn}`,`style-src 'self' 'unsafe-inline' ${Mn}`,`connect-src 'self' ${Hn} https://*.googleapis.com https://*.firebaseio.com https://identitytoolkit.googleapis.com`,"img-src 'self' data:","font-src 'self' data:","frame-ancestors 'none'","base-uri 'self'","form-action 'self'"].join("; ");function Ve(e={}){let t=e.csp===void 0?Bn:e.csp,n=e.frameOptions===void 0?"DENY":e.frameOptions,r=e.referrerPolicy===void 0?"no-referrer":e.referrerPolicy,o=e.cacheControl===void 0?"private, no-store":e.cacheControl;return async(s,a,f)=>{typeof a?.setHeader=="function"&&(a.setHeader("X-Content-Type-Options","nosniff"),n&&a.setHeader("X-Frame-Options",n),r&&a.setHeader("Referrer-Policy",r),o&&a.setHeader("Cache-Control",o),t&&a.setHeader("Content-Security-Policy",t)),await f();}}async function go(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function ho(e){let t={};if(!e)return t;for(let n of e.split("&")){let r=n.indexOf("=");if(r===-1)continue;let o=decodeURIComponent(n.slice(0,r).replace(/\+/g," ")),s=decodeURIComponent(n.slice(r+1).replace(/\+/g," ")),a=t[o];a===void 0?t[o]=s:Array.isArray(a)?a.push(s):t[o]=[a,s];}return t}function zn(e){let{basePath:t="/",repos:n,parseBody:r=true,securityHeaders:o,auth:s,middleware:a=[],httpsOptions:f}=e,d=t==="/"?"":t.replace(/\/$/,""),m={};for(let[S,w]of Object.entries(n)){let C=w.schema??w.repo.schema??null;if(!C)throw new Error(`[createAdminServer] Repository "${S}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let b,g,u;if(w.fieldsConfig){let l=w.fieldsConfig;b=[],g=[],u=[];for(let[p,y]of Object.entries(l))for(let h of y)h==="filterable"?b.push(p):h==="mutable"?g.push(p):h==="create"&&u.push(p);b.length===0&&(b=void 0),g.length===0&&(g=void 0),u.length===0&&(u=void 0);}let c=(()=>{let l=w.repo._parentKeys;return l&&l.length>0?l:void 0})();if(c&&u)for(let l of c)u.includes(l)||u.push(l);let i={name:S,path:w.path,repo:w.repo,schema:C,documentKey:w.documentKey??"docId",pathKey:w.repo._pathKey??void 0,isGroup:!!w.repo._isGroup,parentKeys:c,createdKey:w.repo._createdKey??void 0,listColumns:w.listColumns,pageSize:w.pageSize,filterableFields:b,mutableFields:g,createFields:u,allowDelete:w.allowDelete??false,historyEnabled:!!w.repo._historyConfig?.enabled,historySubcollection:(w.repo._historyConfig?.enabled&&w.repo._historySubcollection)??void 0,relationalMeta:(()=>{if(!w.relationalFields||w.relationalFields.length===0)return;let l=w.repo.relationalKeys??{},p=[];for(let y of w.relationalFields){let h=l[y.key];h&&p.push({key:y.key,column:y.column,targetRepo:String(h.repo),targetKey:String(h.key),type:h.type});}return p.length>0?p:void 0})()};m[S]=i;}let v=jn(m,d,Yt(f?.region)),R=new ae;if(o!==false&&R.use(Ve(o===void 0?{}:o)),r&&R.use(async(S,w,C)=>{let b=S,g=String(b.headers?.["content-type"]??"");if(g.includes("application/x-www-form-urlencoded")){let u=await go(b);S.body=ho(u);}else if(g.includes("application/json")&&typeof b.body=="string")try{S.body=JSON.parse(b.body);}catch{}await C();}),s)if(me(s)){for(let S of s.routes){let w=`${d}${S.path}`;S.method==="GET"?R.get(w,S.handler):R.post(w,S.handler);}R.use(s.middleware);}else if(typeof s=="function")R.use(s);else {let S=s.realm??"Admin",w="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");R.use((C,b,g)=>{if((C.headers?.authorization??"")!==w){b.status(401).set("WWW-Authenticate",`Basic realm="${S}"`).set("Content-Type","text/plain").send("Unauthorized");return}g();});}for(let S of a)R.use(S);R.get(`${d}/`,v.handleDashboard),R.get(`${d}`,v.handleDashboard),R.get(`${d}/:repoName/_panel`,v.handlePanel),R.post(`${d}/:repoName/_bulk/delete`,v.handleBulkDelete),R.post(`${d}/:repoName/_bulk/update`,v.handleBulkUpdate),R.get(`${d}/:repoName`,v.handleList),R.get(`${d}/:repoName/create`,v.handleCreateForm),R.post(`${d}/:repoName/create`,v.handleCreateSubmit),R.get(`${d}/:repoName/:id/edit`,v.handleEditForm),R.post(`${d}/:repoName/:id/edit`,v.handleEditSubmit),R.get(`${d}/:repoName/:id/history`,v.handleHistory),R.post(`${d}/:repoName/:id/delete`,v.handleDelete);let A=async(S,w)=>{await R.handle(S,w);};return f&&(A.httpsOptions=f),A}function Zt(e,t,n=200){let r=Se(t);e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(r));}function _e(e,t,n,r=200){Zt(e,{success:true,data:t,meta:n},r);}function L(e,t,n=400){Zt(e,{success:false,error:t},n);}function Bt(e,t,n,r,o){let s=Ze(t,n),a=s.type==="index",f=a?424:500,m={success:false,error:a?s.message:o&&t instanceof Error?t.message:r};a&&(m.errorType="index",s.indexUrl&&(m.indexUrl=s.indexUrl)),Zt(e,m,f);}var zt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function wo(){let e="";for(;e.length<20;){let t=randomBytes(20);for(let n=0;n<t.length&&e.length<20;n++){let r=t[n];r>=zt.length*4||(e+=zt.charAt(r%zt.length));}}return e}function Ne(e){let t=e._def??e.def;if(!t)return e;let n=t.typeName??t.type;if(n==="ZodDate"||n==="date")return z.preprocess(r=>Jt(r)??r,e);if(n==="ZodObject"||n==="object"){let r=e.shape,o={};for(let[s,a]of Object.entries(r))o[s]=Ne(a);return z.object(o)}if(n==="ZodArray"||n==="array"){let r=t.element??t.type;if(r)return z.array(Ne(r))}if(n==="ZodOptional"||n==="optional"){let r=t.innerType;if(r)return Ne(r).optional()}if(n==="ZodNullable"||n==="nullable"){let r=t.innerType;if(r)return Ne(r).nullable()}if(n==="ZodDefault"||n==="default"){let r=t.innerType,o=t.defaultValue;if(r){let s=Ne(r);return typeof o=="function"?s.default(o()):s.default(o)}}return e}function xo(e,t,n=[]){let r=e.shape,o={},s=t&&t.length>0?t:Object.keys(r);for(let a of s){if(n.includes(a))continue;let f=a.split(".")[0];f&&r[f]&&(o[f]=r[f]);}return z.object(o)}function Zn(e,t,n,r=false,o=[]){try{let s=xo(e,n,o),a=r?s.partial():s;return {success:!0,data:(Gt()==="normalize"?Ne(a):a).parse(t)}}catch(s){return s instanceof z.ZodError?{success:false,error:`Validation failed: ${s.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function vo(e,t){let n=[],r=t?new Set(t):null,o={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[s,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(s))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let d=s.match(/^(\w+)__(\w+)$/),m,v="==";if(d&&d[1]&&d[2]){m=d[1];let A=d[2];if(o[A])v=o[A];else continue}else if(!d)m=s;else continue;if(r&&!r.has(m))continue;let R=f;v==="in"||v==="not-in"||v==="array-contains-any"?R=f.split(",").map(A=>Ln(A.trim())):R=Ln(f),n.push({field:m,op:v,value:R});}return n}function Ln(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 at(e){return e?{docId:e.id}:null}async function qn(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 o=await r.doc(n).get();return o.exists?o:void 0}catch{return}}function Un(e,t,n,r=false){async function o(g,u,c,i){if(!r)return true;let l=u.rules?.[c];if(!l)return L(g,`Operation "${c}" is not allowed for this repository`,403),false;try{return await l(i)?!0:(L(g,"Forbidden",403),!1)}catch(p){let y=n&&p instanceof Error?p.message:"Forbidden";return L(g,y,403),false}}async function s(g,u,c,i){if(!r)return i;let l=g.rules?.filter;if(!l)return i;let p=[];for(let y of i)try{await l({user:u,doc:y,params:c})&&p.push(y);}catch{}return p}function a(g){return g?.user??null}function f(g,u){return !g||!e[g]?(L(u,`Repository "${g}" not found`,404),null):e[g]}function d(g,u){if(!u)return;let c=g[u];if(typeof c!="string"||!c)return;let i=c.split("/").filter(Boolean),l=[];for(let p=1;p<i.length;p+=2)l.push(i[p]);return l.length>0?l:void 0}async function m(g,u){let c=`by${g.documentKey.charAt(0).toUpperCase()}${g.documentKey.slice(1)}`,i=g.repo.get[c];if(typeof i=="function")try{let p=await i(u);if(p)return p}catch{}return (await g.repo.query.by({where:[[g.documentKey,"==",u]],limit:1}))[0]??null}async function v(g,u){let c=g.params||{},i=f(c.repoName,u);if(!i)return;let l=a(g);if(!await o(u,i,"list",{user:l,query:g.query??{},params:c}))return;let p=[],y;try{let h=g.query??{},E=Math.min(Number(h.pageSize)||i.pageSize,100),x=h.cursor,O=h.direction?.toLowerCase()==="prev"?"prev":"next",T=h.orderBy,$=h.orderDir?.toLowerCase()==="desc"?"desc":"asc",P=h.select,k=P?P.split(",").map(U=>U.trim()):void 0,I;i.allowedIncludes&&h.includes&&(I=(typeof h.includes=="string"?h.includes.split(",").map(se=>se.trim()):Array.isArray(h.includes)?h.includes:[]).filter(se=>typeof se=="string"&&i.allowedIncludes.includes(se)),I?.length===0&&(I=void 0));let F=vo(h,i.filterableFields);p=F.map(U=>({field:U.field,op:U.op,value:String(U.value??"")})),T&&(y={field:T,dir:$});let N={pageSize:E,direction:O};if(x)try{let U=typeof x=="string"?JSON.parse(x):x;N.cursor=await qn(i,U);}catch{}if(T){if(i.orderableFields&&!i.orderableFields.includes(T)){L(u,`Field not orderable: ${T}`,400);return}N.orderBy=[{field:T,direction:$}];}F.length>0&&(N.where=F.map(U=>[U.field,U.op,U.value])),k&&(N.select=k),I&&(N.include=I);let D=await i.repo.query.paginate(N),ce={items:await s(i,a(g),c,D.data),hasNextPage:D.hasNextPage,hasPrevPage:D.hasPrevPage,nextCursor:at(D.nextCursor),prevCursor:at(D.prevCursor)};_e(u,ce,{pageSize:E,hasMore:D.hasNextPage});}catch(h){Bt(u,h,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:p,sort:y},"Failed to fetch documents",n);}}async function R(g,u){let c=g.params||{},i=f(c.repoName,u);if(!i)return;let l=a(g);if(!await o(u,i,"list",{user:l,query:g.body??{},params:c}))return;let p=[],y;try{let h=g.body??{},E=Math.min(h.pageSize||i.pageSize,100),x=h.direction==="prev"?"prev":"next";h.where&&(p=h.where.map(k=>({field:String(k[0]),op:k[1],value:String(k[2]??"")}))),h.orderBy&&h.orderBy[0]&&(y={field:h.orderBy[0].field,dir:h.orderBy[0].direction==="desc"?"desc":"asc"});let O={pageSize:E,direction:x};if(h.cursor)try{let k=typeof h.cursor=="string"?JSON.parse(h.cursor):h.cursor;O.cursor=await qn(i,k);}catch{}if(i.allowedIncludes&&h.includes&&h.includes.length>0){let k=h.includes.filter(I=>typeof I=="string"?i.allowedIncludes.includes(I):typeof I=="object"&&I!==null&&"relation"in I&&typeof I.relation=="string"?i.allowedIncludes.includes(I.relation):!1);k.length>0&&(O.include=k);}if(h.where&&h.where.length>0){if(i.filterableFields){let k=new Set(i.filterableFields),I=h.where.filter(F=>!k.has(F[0]));if(I.length>0){L(u,`Fields not filterable: ${I.map(F=>F[0]).join(", ")}`,400);return}}O.where=h.where;}if(h.orWhere&&h.orWhere.length>0){if(i.filterableFields){let k=new Set(i.filterableFields),I=h.orWhere.filter(F=>!k.has(F[0]));if(I.length>0){L(u,`Fields not filterable: ${I.map(F=>F[0]).join(", ")}`,400);return}}O.orWhere=h.orWhere;}if(h.orWhereGroups&&h.orWhereGroups.length>0){if(i.filterableFields){let k=new Set(i.filterableFields);for(let I of h.orWhereGroups){let F=I.filter(N=>!k.has(N[0]));if(F.length>0){L(u,`Fields not filterable: ${F.map(N=>N[0]).join(", ")}`,400);return}}}O.orWhereGroups=h.orWhereGroups;}if(h.orderBy&&h.orderBy.length>0){if(i.orderableFields){let k=new Set(i.orderableFields),I=h.orderBy.filter(F=>!k.has(F.field));if(I.length>0){L(u,`Fields not orderable: ${I.map(F=>F.field).join(", ")}`,400);return}}O.orderBy=h.orderBy;}h.select&&h.select.length>0&&(O.select=h.select);let T=await i.repo.query.paginate(O),P={items:await s(i,a(g),c,T.data),hasNextPage:T.hasNextPage,hasPrevPage:T.hasPrevPage,nextCursor:at(T.nextCursor),prevCursor:at(T.prevCursor)};_e(u,P,{pageSize:E,hasMore:T.hasNextPage});}catch(h){Bt(u,h,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:p,sort:y},"Failed to query documents",n);}}async function A(g,u){let c=g.params||{},i=f(c.repoName,u);if(!i)return;let l=c.id;if(!l){L(u,"Document ID required",400);return}try{let p=await m(i,l);if(!p){L(u,"Document not found",404);return}let y=a(g);if(!await o(u,i,"get",{user:y,doc:p,params:c}))return;if(r&&i.rules?.filter)try{if(!await i.rules.filter({user:y,doc:p,params:c})){L(u,"Document not found",404);return}}catch{L(u,"Document not found",404);return}_e(u,p);}catch(p){Bt(u,p,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:[{field:i.documentKey,op:"==",value:l}]},"Failed to fetch document",n);}}async function S(g,u){let c=g.params||{},i=f(c.repoName,u);if(i)try{let l=g.body??{},p=a(g);if(!await o(u,i,"create",{user:p,body:l,params:c}))return;let y=Zn(i.schema,l,i.createFields,!1,i.systemKeys);if(!y.success){L(u,y.error,400);return}if(i.validate){let E=await i.validate(y.data,"create");if(E){L(u,E,400);return}}let h;if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let E={...y.data};i.createdKey&&(E[i.createdKey]=new Date);let x=i.parentKeys.filter($=>!E[$]);if(x.length>0){L(u,`Missing parent key(s) for subcollection create: ${x.join(", ")}`,400);return}let O=i.parentKeys.map($=>E[$]),T=E[i.documentKey]||wo();h=await i.repo.set(...O,T,E);}else h=await i.repo.create(y.data);_e(u,h,void 0,201);}catch(l){let p=n&&l instanceof Error?l.message:"Failed to create document";L(u,p,500);}}async function w(g,u,c){let i=g.params||{},l=f(i.repoName,u);if(!l)return;let p=i.id;if(!p){L(u,"Document ID required",400);return}try{let y=g.body??{},h=await m(l,p);if(!h){L(u,"Document not found",404);return}let E=a(g);if(!await o(u,l,"update",{user:E,doc:h,body:y,params:i}))return;let x=Zn(l.schema,y,l.mutableFields,c,l.systemKeys);if(!x.success){L(u,x.error,400);return}if(l.validate){let $=await l.validate(x.data,"update");if($){L(u,$,400);return}}let O=d(h,l.pathKey)??[p],T=await l.repo.update(...O,x.data);_e(u,T);}catch(y){let h=n&&y instanceof Error?y.message:"Failed to update document";L(u,h,500);}}async function C(g,u){let c=g.params||{},i=f(c.repoName,u);if(!i)return;if(!i.allowDelete){L(u,"Delete not allowed for this repository",403);return}let l=c.id;if(!l){L(u,"Document ID required",400);return}try{let p=await m(i,l);if(!p){L(u,"Document not found",404);return}let y=a(g);if(!await o(u,i,"delete",{user:y,doc:p,params:c}))return;let h=d(p,i.pathKey)??[l];await i.repo.delete(...h),_e(u,{deleted:!0});}catch(p){let y=n&&p instanceof Error?p.message:"Failed to delete document";L(u,y,500);}}function b(g,u){u.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:v,handleQuery:R,handleGet:A,handleCreate:S,handleUpdate:w,handleDelete:C,handleOptions:b}}function Lt(e){try{return 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 oe(e){return {$ref:`#/components/schemas/${e}`}}function Y(e){return {description:e,content:{"application/json":{schema:oe("ErrorResponse")}}}}function We(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function Kn(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 So(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 Ro(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],r=[];for(let o of t){r.push({name:o,in:"query",schema:{type:"string"},description:`Filter by ${o} (equality)`});for(let s of n)r.push({name:`${o}__${s}`,in:"query",schema:{type:"string"},description:`Filter ${o} with operator ${s}`});}return r}function ko(){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 To(e,t,n,r,o){let s={},a=e.name,f=`${t}/${e.name}`,d=`${f}/{${e.documentKey}}`,m={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};s[f]={get:{operationId:`list${ve(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...So(e),...Ro(e)],responses:{200:Kn(oe(n)),500:Y("Internal server error")}},post:{operationId:`create${ve(e.name)}`,summary:`Create a ${le(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:oe(r??n)}}},responses:{201:We("Document created",oe(n)),400:Y("Validation error"),500:Y("Internal server error")}}},s[`${f}/query`]={post:{operationId:`query${ve(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:oe("QueryRequestBody")}}},responses:{200:Kn(oe(n)),400:Y("Invalid query"),500:Y("Internal server error")}}};let v={};return v.get={operationId:`get${ve(le(e.name))}`,summary:`Get a single ${le(e.name)}`,tags:[a],parameters:[m],responses:{200:We("Document found",oe(n)),404:Y("Document not found"),500:Y("Internal server error")}},v.put={operationId:`update${ve(le(e.name))}`,summary:`Update a ${le(e.name)} (full replace)`,tags:[a],parameters:[m],requestBody:{required:true,content:{"application/json":{schema:oe(o??n)}}},responses:{200:We("Document updated",oe(n)),400:Y("Validation error"),404:Y("Document not found"),500:Y("Internal server error")}},v.patch={operationId:`patch${ve(le(e.name))}`,summary:`Partially update a ${le(e.name)}`,tags:[a],parameters:[m],requestBody:{required:true,content:{"application/json":{schema:{allOf:[oe(o??n)],description:"All fields are optional for partial updates"}}}},responses:{200:We("Document patched",oe(n)),400:Y("Validation error"),404:Y("Document not found"),500:Y("Internal server error")}},e.allowDelete&&(v.delete={operationId:`delete${ve(le(e.name))}`,summary:`Delete a ${le(e.name)}`,tags:[a],parameters:[m],responses:{200:We("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:Y("Document not found"),500:Y("Internal server error")}}),s[d]=v,s}function Ut(e,t,n={}){let{title:r="CRUD API",version:o="1.0.0",description:s,servers:a,auth:f=false}=n,d=t==="/"?"":t.replace(/\/$/,""),m={},v={},R=[];m.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},m.QueryRequestBody=ko();for(let[C,b]of Object.entries(e)){let g=ve(le(C)),u=`${g}Create`,c=`${g}Update`;m[g]=Lt(b.schema);let i=x=>{let O=x&&x.length>0?x:Object.keys(b.schema.shape),T={};for(let $ of O){let P=$.split(".")[0];P&&b.schema.shape[P]&&!b.systemKeys.includes(P)&&(T[P]=b.schema.shape[P]);}return T},l=null,p=i(b.createFields);Object.keys(p).length>0&&(m[u]=Lt(z.object(p)),l=u);let y=null,h=i(b.mutableFields);Object.keys(h).length>0&&(m[c]=Lt(z.object(h)),y=c);let E=To(b,d,g,l,y);Object.assign(v,E),R.push({name:C,description:`Operations on ${C} (collection: ${b.path})`});}let A={},S;return f==="basic"?(A.basicAuth={type:"http",scheme:"basic"},S=[{basicAuth:[]}]):f==="bearer"&&(A.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},S=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:r,version:o,...s?{description:s}:{}},...a&&a.length>0?{servers:a}:{},paths:v,components:{schemas:m,...Object.keys(A).length>0?{securitySchemes:A}:{}},...S?{security:S}:{},tags:R}}function ve(e){return e.charAt(0).toUpperCase()+e.slice(1)}function le(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 Co(e,t){return `<!DOCTYPE html>
1147
1147
  <html lang="en">
1148
1148
  <head>
1149
1149
  <meta charset="utf-8" />
@@ -1154,5 +1154,5 @@ function initColumnReorder(table) {
1154
1154
  <script id="api-reference" data-url="${t}"></script>
1155
1155
  <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
1156
1156
  </body>
1157
- </html>`}async function ho(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Ln(e){let{basePath:t="/",repos:n,parseBody:r=true,securityHeaders:o,auth:s,middleware:a=[],verbose:f=false,httpsOptions:d}=e,m=t==="/"?"":t.replace(/\/$/,""),b={};for(let[u,c]of Object.entries(n)){let l=c.schema??c.repo.schema??null;if(!l)throw new Error(`[createCrudServer] Repository "${u}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let p,y,h,R;if(c.fieldsConfig){let A=c.fieldsConfig;p=[],y=[],h=[],R=[];for(let[E,T]of Object.entries(A))for(let P of T)P==="filterable"?p.push(E):P==="orderable"?y.push(E):P==="mutable"?h.push(E):P==="create"&&R.push(E);y.length===0&&(y=p),p.length===0&&(p=void 0),y&&y.length===0&&(y=void 0),h.length===0&&(h=void 0),R.length===0&&(R=void 0);}let w=(()=>{let A=c.repo._parentKeys;return A&&A.length>0?A:void 0})();if(w&&R)for(let A of w)R.includes(A)||R.push(A);let O={name:u,path:c.path,repo:c.repo,schema:l,systemKeys:c.repo._systemKeys??[c.documentKey??"docId"],documentKey:c.documentKey??"docId",pathKey:c.repo._pathKey??void 0,isGroup:!!c.repo._isGroup,parentKeys:w,createdKey:c.repo._createdKey??void 0,pageSize:c.pageSize??25,filterableFields:p,orderableFields:y,mutableFields:h,createFields:R,allowDelete:c.allowDelete??false,allowedIncludes:c.allowedIncludes,validate:c.validate,rules:c.rules};b[u]=O;}let S=Hn(b,m,f,!!s),C=e.openapi,k=C&&typeof C=="object"?C:{},x=null;function $(){if(!x){let u=s?me(s)||typeof s=="function"?"bearer":"basic":false;x=jt(b,m,{...k,auth:k.auth??u});}return x}let g=new ae;if(o!==false){let u=o===void 0?{csp:false}:o;g.use(Ke(u));}if(g.use((u,c,l)=>{c.set("Access-Control-Allow-Origin","*"),c.set("Access-Control-Allow-Credentials","true"),l();}),r&&g.use(async(u,c,l)=>{let p=u;if(String(p.headers?.["content-type"]??"").includes("application/json")){if(typeof p.body=="string")try{u.body=JSON.parse(p.body);}catch{}else if(Buffer.isBuffer(u.rawBody))try{let h=await ho(p);u.body=JSON.parse(h);}catch{}}await l();}),s)if(me(s)){for(let u of s.routes){let c=`${m}${u.path}`;u.method==="GET"?g.get(c,u.handler):g.post(c,u.handler);}g.use(s.middleware);}else if(typeof s=="function")g.use(s);else {let u=s.realm??"API",c="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");g.use((l,p,y)=>{if((l.headers?.authorization??"")!==c){p.status(401).set("WWW-Authenticate",`Basic realm="${u}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}y();});}for(let u of a)g.use(u);if(C!==false){let u=`${m}/__spec.json`,c=`${m}/__docs`;g.get(u,(l,p)=>{let y=$();p.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(y,null,2));}),g.get(c,(l,p)=>{let y=te(l,m)+"/__spec.json",h=go(k.title??"CRUD API",y);p.status(200).set("Content-Type","text/html; charset=utf-8").send(h);});}g.use((u,c,l)=>{if(u.method==="OPTIONS"){S.handleOptions(u,c);return}l();}),g.get(`${m}/:repoName`,S.handleList),g.post(`${m}/:repoName/query`,S.handleQuery),g.get(`${m}/:repoName/:id`,S.handleGet),g.post(`${m}/:repoName`,S.handleCreate),g.put(`${m}/:repoName/:id`,(u,c)=>S.handleUpdate(u,c,false)),g.patch(`${m}/:repoName/:id`,(u,c)=>S.handleUpdate(u,c,true)),g.delete(`${m}/:repoName/:id`,S.handleDelete);let i=async(u,c)=>{await g.handle(u,c);};return i.spec=$,d&&(i.httpsOptions=d),i}function Un(e,t){if(!t.onRequest)return e;let n=e.httpsOptions??t.httpsOptions;return n?t.onRequest(n,e):t.onRequest(e)}function Kn(e,t,n){let r={};for(let[o,s]of Object.entries(t)){if(!s)continue;let a=e[o];if(!a)throw new Error(`[createServers.${n}] Unknown repo "${o}" \u2014 not present in the registry passed to createServers().`);r[o]={...s,repo:a};}return r}function bo(e,t={}){return {admin(n){let r=Kn(e,n.repos,"admin"),o=_n({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Un(o,t)},crud(n){let r=Kn(e,n.repos,"crud"),o=Ln({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Un(o,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}),ln(e,r)},history(n){return Lt(e,n)}}}export{Gr as CSS,He as ClientScript,In as DEFAULT_HTML_CSP,ae as MiniRouter,bo as createServers,kt as renderDashboard,lt as renderField,ge as renderForm,xe as renderFormPage,Rt as renderList,Ue as renderPage,Ke as securityHeaders,ie as zodToFields};//# sourceMappingURL=index.js.map
1157
+ </html>`}async function Ao(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Vn(e){let{basePath:t="/",repos:n,parseBody:r=true,securityHeaders:o,auth:s,middleware:a=[],verbose:f=false,httpsOptions:d}=e,m=t==="/"?"":t.replace(/\/$/,""),v={};for(let[c,i]of Object.entries(n)){let l=i.schema??i.repo.schema??null;if(!l)throw new Error(`[createCrudServer] Repository "${c}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let p,y,h,E;if(i.fieldsConfig){let T=i.fieldsConfig;p=[],y=[],h=[],E=[];for(let[$,P]of Object.entries(T))for(let k of P)k==="filterable"?p.push($):k==="orderable"?y.push($):k==="mutable"?h.push($):k==="create"&&E.push($);y.length===0&&(y=p),p.length===0&&(p=void 0),y&&y.length===0&&(y=void 0),h.length===0&&(h=void 0),E.length===0&&(E=void 0);}let x=(()=>{let T=i.repo._parentKeys;return T&&T.length>0?T:void 0})();if(x&&E)for(let T of x)E.includes(T)||E.push(T);let O={name:c,path:i.path,repo:i.repo,schema:l,systemKeys:i.repo._systemKeys??[i.documentKey??"docId"],documentKey:i.documentKey??"docId",pathKey:i.repo._pathKey??void 0,isGroup:!!i.repo._isGroup,parentKeys:x,createdKey:i.repo._createdKey??void 0,pageSize:i.pageSize??25,filterableFields:p,orderableFields:y,mutableFields:h,createFields:E,allowDelete:i.allowDelete??false,allowedIncludes:i.allowedIncludes,validate:i.validate,rules:i.rules};v[c]=O;}let A=Un(v,m,f,!!s),S=e.openapi,w=S&&typeof S=="object"?S:{},C=null;function b(){if(!C){let c=s?me(s)||typeof s=="function"?"bearer":"basic":false;C=Ut(v,m,{...w,auth:w.auth??c});}return C}let g=new ae;if(o!==false){let c=o===void 0?{csp:false}:o;g.use(Ve(c));}if(g.use((c,i,l)=>{i.set("Access-Control-Allow-Origin","*"),i.set("Access-Control-Allow-Credentials","true"),l();}),r&&g.use(async(c,i,l)=>{let p=c;if(String(p.headers?.["content-type"]??"").includes("application/json")){if(typeof p.body=="string")try{c.body=JSON.parse(p.body);}catch{}else if(Buffer.isBuffer(c.rawBody))try{let h=await Ao(p);c.body=JSON.parse(h);}catch{}}await l();}),s)if(me(s)){for(let c of s.routes){let i=`${m}${c.path}`;c.method==="GET"?g.get(i,c.handler):g.post(i,c.handler);}g.use(s.middleware);}else if(typeof s=="function")g.use(s);else {let c=s.realm??"API",i="Basic "+Buffer.from(`${s.username}:${s.password}`).toString("base64");g.use((l,p,y)=>{if((l.headers?.authorization??"")!==i){p.status(401).set("WWW-Authenticate",`Basic realm="${c}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}y();});}for(let c of a)g.use(c);if(S!==false){let c=`${m}/__spec.json`,i=`${m}/__docs`;g.get(c,(l,p)=>{let y=b();p.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(y,null,2));}),g.get(i,(l,p)=>{let y=te(l,m)+"/__spec.json",h=Co(w.title??"CRUD API",y);p.status(200).set("Content-Type","text/html; charset=utf-8").send(h);});}g.use((c,i,l)=>{if(c.method==="OPTIONS"){A.handleOptions(c,i);return}l();}),g.get(`${m}/:repoName`,A.handleList),g.post(`${m}/:repoName/query`,A.handleQuery),g.get(`${m}/:repoName/:id`,A.handleGet),g.post(`${m}/:repoName`,A.handleCreate),g.put(`${m}/:repoName/:id`,(c,i)=>A.handleUpdate(c,i,false)),g.patch(`${m}/:repoName/:id`,(c,i)=>A.handleUpdate(c,i,true)),g.delete(`${m}/:repoName/:id`,A.handleDelete);let u=async(c,i)=>{await g.handle(c,i);};return u.spec=b,d&&(u.httpsOptions=d),u}function Qn(e,t){if(!t.onRequest)return e;let n=e.httpsOptions??t.httpsOptions,r=n?t.onRequest(n,e):t.onRequest(e),o=e.spec;return typeof o=="function"&&(r.spec=o),r}function Wn(e,t,n){let r={},o=e?.rawMapping;for(let[s,a]of Object.entries(t)){if(!a)continue;if(!(o?s in o:!!e[s]))throw new Error(`[createServers.${n}] Unknown repo "${s}" \u2014 not present in the registry passed to createServers().`);let d=o?Xe(o[s],()=>e[s]):e[s];r[s]={...a,repo:d};}return r}function Oo(e,t={}){return {admin(n){let r=Wn(e,n.repos,"admin"),o=zn({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Qn(o,t)},crud(n){let r=Wn(e,n.repos,"crud"),o=Vn({...n,repos:r,httpsOptions:n.httpsOptions??t.httpsOptions});return Qn(o,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}),gn(e,r)},history(n){return Kt(e,n)}}}export{io as CSS,Le as ClientScript,Bn as DEFAULT_HTML_CSP,ae as MiniRouter,Oo as createServers,Dt as renderDashboard,ht as renderField,ge as renderForm,xe as renderFormPage,It as renderList,Ke as renderPage,Ve as securityHeaders,ie as zodToFields};//# sourceMappingURL=index.js.map
1158
1158
  //# sourceMappingURL=index.js.map