@lpdjs/firestore-repo-service 2.2.4 → 2.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -19
- package/dist/create-servers-D4-NGpKm.d.ts +105 -0
- package/dist/create-servers-DmggzSb3.d.cts +105 -0
- package/dist/{index-BiWZwHS_.d.ts → index-Cvip2Sgt.d.ts} +1 -1
- package/dist/{index-B3-vAYx0.d.cts → index-DpD4DEqH.d.cts} +1 -1
- package/dist/index.cjs +619 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +619 -57
- package/dist/index.js.map +1 -1
- package/dist/openapi-B3P2F8op.d.ts +69 -0
- package/dist/openapi-UJJ1aCFk.d.cts +69 -0
- package/dist/queue-D_-aMf4H.d.ts +52 -0
- package/dist/queue-Dk1Ezhkf.d.cts +52 -0
- package/dist/servers/admin/index.cjs +547 -75
- package/dist/servers/admin/index.cjs.map +1 -1
- package/dist/servers/admin/index.d.cts +1 -1
- package/dist/servers/admin/index.d.ts +1 -1
- package/dist/servers/admin/index.js +547 -75
- package/dist/servers/admin/index.js.map +1 -1
- package/dist/servers/crud/index.d.cts +5 -69
- package/dist/servers/crud/index.d.ts +5 -69
- package/dist/servers/index.cjs +637 -75
- package/dist/servers/index.cjs.map +1 -1
- package/dist/servers/index.d.cts +10 -5
- package/dist/servers/index.d.ts +10 -5
- package/dist/servers/index.js +637 -75
- package/dist/servers/index.js.map +1 -1
- package/dist/sync/bigquery.d.cts +1 -1
- package/dist/sync/bigquery.d.ts +1 -1
- package/dist/sync/index.cjs +33 -33
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +5 -107
- package/dist/sync/index.d.ts +5 -107
- package/dist/sync/index.js +33 -33
- package/dist/sync/index.js.map +1 -1
- package/dist/{types-BbCdscqh.d.cts → types-CX5AbZWV.d.cts} +1 -1
- package/dist/{types-BbCdscqh.d.ts → types-CX5AbZWV.d.ts} +1 -1
- package/package.json +1 -1
|
@@ -1,139 +1,611 @@
|
|
|
1
|
-
import {z}from'zod';import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {renderToString}from'hono/jsx/dom/server';var dt={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 O(e){let t=e,a=t._zod?.def?.type;if(a)return dt[a]??`Zod${a.charAt(0).toUpperCase()}${a.slice(1)}`;let n=t._def?.typeName;return n||""}function Z(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function Ae(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function Ze(e){let t=e;if(t._zod?.def?.defaultValue!==void 0)return t._zod.def.defaultValue;let a=t._def?.defaultValue;return typeof a=="function"?a():a}function Y(e){let t=e;return t.shape&&typeof t.shape=="object"?t.shape:t._zod?.def?.shape&&typeof t._zod.def.shape=="object"?t._zod.def.shape:t._def?.shape?typeof t._def.shape=="function"?t._def.shape():t._def.shape:{}}function ee(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 te(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 oe(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function Ne(e){let t=e,a=[],n=t._zod?.def?.checks;if(Array.isArray(n)){for(let o of n)o.format&&a.push(o.format);if(a.length>0)return a}let r=t._def?.checks;if(Array.isArray(r))for(let o of r)o.kind&&a.push(o.kind);return a}function ct(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function Ie(e){let t=e,a=true,n=false,r;for(;;){let o=O(t);if(o==="ZodOptional")a=false,t=Z(t);else if(o==="ZodNullable")a=false,n=true,t=Z(t);else if(o==="ZodDefault")a=false,r=Ze(t),t=Z(t);else break}return {inner:t,required:a,nullable:n,defaultValue:r}}function F(e,t=""){if(O(e)==="ZodObject"){let n=Y(e);return Object.entries(n).map(([r,o])=>De(t?`${t}.${r}`:r,r,o))}return [De(t||"value",t||"value",e)]}function De(e,t,a){let{inner:n,required:r,nullable:o,defaultValue:s}=Ie(a),p=O(n),d=ct(t.split(".").pop()??t);switch(p){case "ZodString":{let l=Ne(n),c=l.includes("email"),f=l.includes("url");return {name:e,label:d,type:"text",required:r,nullable:o,defaultValue:s,hint:c?"email":f?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:d,type:"number",required:r,nullable:o,defaultValue:s};case "ZodBoolean":return {name:e,label:d,type:"checkbox",required:r,nullable:o,defaultValue:s};case "ZodDate":case "ZodCoerce":return {name:e,label:d,type:"datetime-local",required:r,nullable:o,defaultValue:s};case "ZodEnum":{let l=ee(n);return {name:e,label:d,type:"select",required:r,nullable:o,defaultValue:s,options:l}}case "ZodNativeEnum":{let l=te(n),c=Object.values(l).filter(f=>typeof f=="string");return {name:e,label:d,type:"select",required:r,nullable:o,defaultValue:s,options:c}}case "ZodLiteral":{let l=String(oe(n)??"");return {name:e,label:d,type:"select",required:r,nullable:o,defaultValue:s,options:[l]}}case "ZodObject":{let l=F(n,e);return {name:e,label:d,type:"textarea",required:r,nullable:o,defaultValue:s,nested:l,hint:"JSON object"}}case "ZodArray":{let l=Ae(n);if(!l)return {name:e,label:d,type:"textarea",required:r,nullable:o,defaultValue:s,hint:"JSON array"};let{inner:c}=Ie(l),f=O(c),i,u,m;switch(f){case "ZodString":i="text";break;case "ZodNumber":case "ZodBigInt":i="number";break;case "ZodBoolean":i="checkbox";break;case "ZodDate":i="datetime-local";break;case "ZodEnum":i="select",u=ee(c);break;case "ZodNativeEnum":i="select",u=Object.values(te(c)).filter(g=>typeof g=="string");break;case "ZodObject":i="object",m=F(c);break;default:return {name:e,label:d,type:"textarea",required:r,nullable:o,defaultValue:s,hint:"JSON array"}}return {name:e,label:d,type:"textarea",required:r,nullable:o,defaultValue:s,arrayElementType:i,arrayElementOptions:u,arrayElementFields:m}}default:return {name:e,label:d,type:"textarea",required:r,nullable:o,defaultValue:s,hint:"JSON"}}}function je(e,t=0){let a=t>0?`ml-${t*4}`:"",n=`field_${e.name.replace(/\./g,"__")}`,r=e.name,o=e.required?" required":"",s=e.defaultValue==="__null__",p=!s&&e.defaultValue!=null?String(e.defaultValue):"",d=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
|
|
2
|
-
<input type="hidden" id="${
|
|
1
|
+
import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {z}from'zod';import {renderToString}from'hono/jsx/dom/server';var Nt=Object.defineProperty;var Se=(e,t)=>()=>(e&&(t=e(e=0)),t);var It=(e,t)=>{for(var n in t)Nt(e,n,{get:t[n],enumerable:true});};function j(e){let t=e,n=t._zod?.def?.type;if(n)return zt[n]??`Zod${n.charAt(0).toUpperCase()}${n.slice(1)}`;let r=t._def?.typeName;return r||""}function q(e){let t=e;if(t._zod?.def?.innerType)return t._zod.def.innerType;if(t._def?.innerType)return t._def.innerType}function Ye(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function et(e){let t=e;if(t._zod?.def?.defaultValue!==void 0)return t._zod.def.defaultValue;let n=t._def?.defaultValue;return typeof n=="function"?n():n}function Q(e){let t=e;return t.shape&&typeof t.shape=="object"?t.shape:t._zod?.def?.shape&&typeof t._zod.def.shape=="object"?t._zod.def.shape:t._def?.shape?typeof t._def.shape=="function"?t._def.shape():t._def.shape:{}}function ye(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 ge(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 Re(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function tt(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 a=t._def?.checks;if(Array.isArray(a))for(let s of a)s.kind&&n.push(s.kind);return n}var zt,$e=Se(()=>{zt={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 it({val:e}){return jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function Ft({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 pe({val:e,mismatch:t}){let n=jt(e);return t?jsxs("span",{class:"inline-flex items-start gap-0.5",children:[n,jsx(Ft,{message:t})]}):n}function jt(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(it,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsx(it,{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,a])=>jsxs(Fragment,{children:[jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:r}),jsx("dd",{class:"break-all",children:String(a??"")})]})),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 Ae=Se(()=>{});function fe(e){if(!e)return "unknown";let t=_e(e);switch(j(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 _e(e){let t=j(e);if(t==="ZodOptional"||t==="ZodNullable"||t==="ZodDefault"){let n=q(e);return n?_e(n):e}return e}function me(e,t){if(!e)return;let n=t.split("."),r=e;for(let a of n){if(!r)return;let s=_e(r);if(j(s)!=="ZodObject")return;r=Q(s)[a];}return r}function Ut(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 he(e,t){if(e==="unknown")return null;let n=Ut(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 Oe=Se(()=>{$e();});var ct={};It(ct,{PanelMany:()=>Ht,PanelOne:()=>qt,RightPanel:()=>Ze});function qt({doc:e,repoName:t,basePath:n,schema:r,columns:a}){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??""),o=`${n}/${t}/${encodeURIComponent(s)}/edit`,d=dt(r,a);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:o,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:a.map(l=>{let p=e[l],m=d[l],E=m?he(m,p):null;return jsxs(Fragment,{children:[jsx("dt",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide pt-0.5",children:l}),jsx("dd",{class:"min-w-0",children:jsx(pe,{val:p,mismatch:E})})]})})})]})}function Ht({docs:e,repoName:t,basePath:n,fk:r,fv:a,columns:s,schema:o,pagination:d}){let l=`${n}/${t}?fv_${r}=${encodeURIComponent(a)}`,p=dt(o,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:a}),jsx("span",{class:"opacity-50",children:" \xB7 "}),jsxs("span",{children:[e.length," doc",e.length!==1?"s":""]})]}),jsx("a",{href:l,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((m,E)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:m},E)),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((m,E)=>{let h=String(m.docId??m.id??""),w=`${n}/${t}/${encodeURIComponent(h)}/edit`;return jsxs("tr",{class:"hover",children:[s.map((A,F)=>{let b=m[A],c=p[A],g=c?he(c,b):null;return jsx("td",{class:"align-top py-1.5",children:jsx(pe,{val:b,mismatch:g})},F)}),jsx("td",{class:"text-right py-1.5",children:jsx("a",{href:w,class:"btn btn-xs btn-ghost",children:"Edit"})})]},E)})})]})}),(d.hasPrev||d.hasNext)&&jsxs("div",{class:"flex justify-center items-center gap-2",children:[d.hasPrev?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"prev","data-cursor":d.prevCursor,children:"\u2190 Previous"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"\u2190 Previous"}),d.hasNext?jsx("button",{type:"button",class:"btn btn-xs btn-outline","data-frs-panel-page":"next","data-cursor":d.nextCursor,children:"Next \u2192"}):jsx("button",{class:"btn btn-xs btn-outline",disabled:true,children:"Next \u2192"})]})]})}function dt(e,t){if(!e)return {};let n={};for(let r of t)n[r]=fe(me(e,r));return n}var Ze,Ne=Se(()=>{Ae();Oe();Ze=()=>jsxs("div",{class:"fixed inset-0 z-[100] hidden pointer-events-none","data-frs-panel-root":true,"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"})})})]})]});});$e();$e();function Pt(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function nt(e){let t=e,n=true,r=false,a;for(;;){let s=j(t);if(s==="ZodOptional")n=false,t=q(t);else if(s==="ZodNullable")n=false,r=true,t=q(t);else if(s==="ZodDefault")n=false,a=et(t),t=q(t);else break}return {inner:t,required:n,nullable:r,defaultValue:a}}function X(e,t=""){if(j(e)==="ZodObject"){let r=Q(e);return Object.entries(r).map(([a,s])=>rt(t?`${t}.${a}`:a,a,s))}return [rt(t||"value",t||"value",e)]}function rt(e,t,n){let{inner:r,required:a,nullable:s,defaultValue:o}=nt(n),d=j(r),l=Pt(t.split(".").pop()??t);switch(d){case "ZodString":{let p=tt(r),m=p.includes("email"),E=p.includes("url");return {name:e,label:l,type:"text",required:a,nullable:s,defaultValue:o,hint:m?"email":E?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:l,type:"number",required:a,nullable:s,defaultValue:o};case "ZodBoolean":return {name:e,label:l,type:"checkbox",required:a,nullable:s,defaultValue:o};case "ZodDate":case "ZodCoerce":return {name:e,label:l,type:"datetime-local",required:a,nullable:s,defaultValue:o};case "ZodEnum":{let p=ye(r);return {name:e,label:l,type:"select",required:a,nullable:s,defaultValue:o,options:p}}case "ZodNativeEnum":{let p=ge(r),m=Object.values(p).filter(E=>typeof E=="string");return {name:e,label:l,type:"select",required:a,nullable:s,defaultValue:o,options:m}}case "ZodLiteral":{let p=String(Re(r)??"");return {name:e,label:l,type:"select",required:a,nullable:s,defaultValue:o,options:[p]}}case "ZodObject":{let p=X(r,e);return {name:e,label:l,type:"textarea",required:a,nullable:s,defaultValue:o,nested:p,hint:"JSON object"}}case "ZodArray":{let p=Ye(r);if(!p)return {name:e,label:l,type:"textarea",required:a,nullable:s,defaultValue:o,hint:"JSON array"};let{inner:m}=nt(p),E=j(m),h,w,A;switch(E){case "ZodString":h="text";break;case "ZodNumber":case "ZodBigInt":h="number";break;case "ZodBoolean":h="checkbox";break;case "ZodDate":h="datetime-local";break;case "ZodEnum":h="select",w=ye(m);break;case "ZodNativeEnum":h="select",w=Object.values(ge(m)).filter(F=>typeof F=="string");break;case "ZodObject":h="object",A=X(m);break;default:return {name:e,label:l,type:"textarea",required:a,nullable:s,defaultValue:o,hint:"JSON array"}}return {name:e,label:l,type:"textarea",required:a,nullable:s,defaultValue:o,arrayElementType:h,arrayElementOptions:w,arrayElementFields:A}}default:return {name:e,label:l,type:"textarea",required:a,nullable:s,defaultValue:o,hint:"JSON"}}}function ot(e,t=0){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,a=e.name,s=e.required?" required":"",o=e.defaultValue==="__null__",d=!o&&e.defaultValue!=null?String(e.defaultValue):"",l=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
|
|
2
|
+
<input type="hidden" id="${r}__isnull" name="${a}__isnull" value="${o?"1":""}">
|
|
3
3
|
<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">
|
|
4
|
-
<input type="checkbox" class="checkbox checkbox-xs" ${
|
|
4
|
+
<input type="checkbox" class="checkbox checkbox-xs" ${o?"checked":""}
|
|
5
5
|
onchange="(function(cb){
|
|
6
|
-
var inp = document.getElementById('${
|
|
7
|
-
var h = document.getElementById('${
|
|
6
|
+
var inp = document.getElementById('${r}');
|
|
7
|
+
var h = document.getElementById('${r}__isnull');
|
|
8
8
|
if (cb.checked) { inp.disabled=true; inp.style.opacity='0.35'; h.value='1'; }
|
|
9
9
|
else { inp.disabled=false; inp.style.opacity=''; h.value=''; }
|
|
10
10
|
})(this)">
|
|
11
11
|
<span>null</span>
|
|
12
12
|
</label>
|
|
13
|
-
</span>`:"",
|
|
14
|
-
<div class="form-control mb-3 ${
|
|
15
|
-
<label for="${
|
|
13
|
+
</span>`:"",p;switch(e.type){case "checkbox":if(e.nullable){let m=o?"__null__":d==="true"?"true":d==="false"?"false":"__null__";return `
|
|
14
|
+
<div class="form-control mb-3 ${n}">
|
|
15
|
+
<label for="${r}" class="label pb-1">
|
|
16
16
|
<span class="label-text font-medium">
|
|
17
|
-
${
|
|
17
|
+
${R(e.label)}
|
|
18
18
|
<span class="text-base-content/40 text-xs ml-1">(nullable)</span>
|
|
19
19
|
</span>
|
|
20
20
|
</label>
|
|
21
|
-
<select id="${
|
|
22
|
-
<option value="__null__"${
|
|
23
|
-
<option value="true"${
|
|
24
|
-
<option value="false"${
|
|
21
|
+
<select id="${r}" name="${a}" class="select select-bordered select-sm w-full">
|
|
22
|
+
<option value="__null__"${m==="__null__"?" selected":""}>\u2014 null \u2014</option>
|
|
23
|
+
<option value="true"${m==="true"?" selected":""}>\u2713 true</option>
|
|
24
|
+
<option value="false"${m==="false"?" selected":""}>\u2717 false</option>
|
|
25
25
|
</select>
|
|
26
26
|
</div>`}return `
|
|
27
|
-
<div class="form-control ${
|
|
27
|
+
<div class="form-control ${n}">
|
|
28
28
|
<label class="label cursor-pointer justify-start gap-3">
|
|
29
|
-
<input type="checkbox" id="${
|
|
29
|
+
<input type="checkbox" id="${r}" name="${a}" value="true"${d==="true"?" checked":""} class="checkbox checkbox-primary checkbox-sm">
|
|
30
30
|
<span class="label-text font-medium">
|
|
31
|
-
${
|
|
31
|
+
${R(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
32
32
|
</span>
|
|
33
33
|
</label>
|
|
34
|
-
</div>`;case "select":
|
|
34
|
+
</div>`;case "select":p=`<select id="${r}" name="${a}"${s}${o?' disabled style="opacity:0.35"':""} class="select select-bordered select-sm w-full">
|
|
35
35
|
${e.required&&!e.nullable?"":'<option value="">\u2014 optional \u2014</option>'}
|
|
36
|
-
${(e.options??[]).map(
|
|
36
|
+
${(e.options??[]).map(m=>`<option value="${R(m)}"${d===m?" selected":""}>${R(m)}</option>`).join(`
|
|
37
37
|
`)}
|
|
38
|
-
</select>`;break;case "textarea":if(e.arrayElementType)return
|
|
38
|
+
</select>`;break;case "textarea":if(e.arrayElementType)return Dt(e,t);if(e.nested&&e.nested.length>0){let m=e.nested.map(E=>ot(E,t+1)).join(`
|
|
39
39
|
`);return `
|
|
40
|
-
<fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${
|
|
40
|
+
<fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}">
|
|
41
41
|
<legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
|
|
42
|
-
${
|
|
42
|
+
${R(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
43
43
|
</legend>
|
|
44
|
-
${
|
|
45
|
-
</fieldset>`}
|
|
44
|
+
${m}
|
|
45
|
+
</fieldset>`}p=`<textarea id="${r}" name="${a}"${s} rows="3"${o?' disabled style="opacity:0.35"':""}
|
|
46
46
|
data-json
|
|
47
47
|
class="textarea textarea-bordered textarea-sm w-full font-mono text-xs"
|
|
48
|
-
placeholder="${
|
|
49
|
-
value="${
|
|
48
|
+
placeholder="${R(e.hint??"JSON")}">${R(d)}</textarea>`;break;default:p=`<input type="${e.type}" id="${r}" name="${a}"${s}${o?' disabled style="opacity:0.35"':""}
|
|
49
|
+
value="${R(d)}"
|
|
50
50
|
class="input input-bordered input-sm w-full"${e.hint==="email"?' autocomplete="email"':e.hint==="url"?' autocomplete="url"':""}>`;}return `
|
|
51
|
-
<div class="form-control mb-3 ${
|
|
52
|
-
<label for="${
|
|
51
|
+
<div class="form-control mb-3 ${n}">
|
|
52
|
+
<label for="${r}" class="label pb-1">
|
|
53
53
|
<span class="label-text font-medium">
|
|
54
|
-
${
|
|
55
|
-
${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${
|
|
54
|
+
${R(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
55
|
+
${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${R(e.hint)})</span>`:""}
|
|
56
56
|
</span>
|
|
57
57
|
</label>
|
|
58
58
|
<div class="flex items-center gap-2">
|
|
59
|
-
<div class="flex-1 min-w-0">${
|
|
60
|
-
${
|
|
59
|
+
<div class="flex-1 min-w-0">${p}</div>
|
|
60
|
+
${l}
|
|
61
61
|
</div>
|
|
62
|
-
</div>`}function
|
|
63
|
-
`):
|
|
64
|
-
`),
|
|
65
|
-
<input type="hidden" id="${
|
|
62
|
+
</div>`}function R(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Dt(e,t){let n=t>0?`ml-${t*4}`:"",r=`field_${e.name.replace(/\./g,"__")}`,a=e.defaultValue==="__null__",s=e.arrayElementType==="object",o=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{o=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(o)||(o=[]);let d=s?o.map(m=>st(e,m??{})).join(`
|
|
63
|
+
`):o.map(m=>at(e,m)).join(`
|
|
64
|
+
`),l=s?st(e,{}):at(e,""),p=e.nullable?`<span class="flex items-center gap-1 mt-2">
|
|
65
|
+
<input type="hidden" id="${r}__isnull" name="${R(e.name)}__isnull" value="${a?"1":""}">
|
|
66
66
|
<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">
|
|
67
|
-
<input type="checkbox" class="checkbox checkbox-xs" ${
|
|
67
|
+
<input type="checkbox" class="checkbox checkbox-xs" ${a?"checked":""}
|
|
68
68
|
onchange="(function(cb){
|
|
69
69
|
var fs = cb.closest('[data-frs-array]');
|
|
70
|
-
var h = document.getElementById('${
|
|
71
|
-
var hidden = document.getElementById('${
|
|
70
|
+
var h = document.getElementById('${r}__isnull');
|
|
71
|
+
var hidden = document.getElementById('${r}');
|
|
72
72
|
if (cb.checked) { fs.querySelector('[data-frs-array-items]').style.opacity='0.35'; h.value='1'; hidden.disabled=true; }
|
|
73
73
|
else { fs.querySelector('[data-frs-array-items]').style.opacity=''; h.value=''; hidden.disabled=false; }
|
|
74
74
|
})(this)">
|
|
75
75
|
<span>null</span>
|
|
76
76
|
</label>
|
|
77
77
|
</span>`:"";return `
|
|
78
|
-
<fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${
|
|
79
|
-
data-frs-array="${
|
|
78
|
+
<fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${n}"
|
|
79
|
+
data-frs-array="${R(e.name)}" data-frs-array-type="${R(e.arrayElementType??"text")}">
|
|
80
80
|
<legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
|
|
81
|
-
${
|
|
81
|
+
${R(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
82
82
|
</legend>
|
|
83
|
-
<input type="hidden" id="${
|
|
84
|
-
<div data-frs-array-items${
|
|
85
|
-
${
|
|
83
|
+
<input type="hidden" id="${r}" name="${R(e.name)}" value="${R(JSON.stringify(o))}"${a?" disabled":""}>
|
|
84
|
+
<div data-frs-array-items${a?' style="opacity:0.35"':""}>
|
|
85
|
+
${d}
|
|
86
86
|
</div>
|
|
87
|
-
<template data-frs-array-tpl>${
|
|
87
|
+
<template data-frs-array-tpl>${l}</template>
|
|
88
88
|
<button type="button" class="btn btn-xs btn-outline mt-1" data-frs-array-add>+ Add</button>
|
|
89
|
-
${
|
|
90
|
-
</fieldset>`}function
|
|
89
|
+
${p}
|
|
90
|
+
</fieldset>`}function at(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">
|
|
91
91
|
<option value="">\u2014</option>
|
|
92
|
-
${(e.arrayElementOptions??[]).map(
|
|
93
|
-
</select>`;break;case "checkbox":
|
|
94
|
-
<input type="checkbox" data-frs-val class="checkbox checkbox-sm checkbox-primary"${
|
|
92
|
+
${(e.arrayElementOptions??[]).map(a=>`<option value="${R(a)}"${n===a?" selected":""}>${R(a)}</option>`).join("")}
|
|
93
|
+
</select>`;break;case "checkbox":r=`<label class="flex items-center gap-2 flex-1 cursor-pointer">
|
|
94
|
+
<input type="checkbox" data-frs-val class="checkbox checkbox-sm checkbox-primary"${n==="true"?" checked":""}>
|
|
95
95
|
<span class="text-sm">true</span>
|
|
96
|
-
</label>`;break;case "number":
|
|
97
|
-
${
|
|
96
|
+
</label>`;break;case "number":r=`<input type="number" data-frs-val value="${R(n)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":r=`<input type="datetime-local" data-frs-val value="${R(n)}" class="input input-bordered input-sm flex-1">`;break;default:r=`<input type="text" data-frs-val value="${R(n)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
|
|
97
|
+
${r}
|
|
98
98
|
<button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>×</button>
|
|
99
|
-
</div>`}function
|
|
99
|
+
</div>`}function st(e,t){return `<div class="border border-base-200 rounded p-3 mb-2" data-frs-array-item>
|
|
100
100
|
<div class="flex justify-end mb-1">
|
|
101
101
|
<button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>×</button>
|
|
102
102
|
</div>
|
|
103
|
-
${(e.arrayElementFields??[]).map(
|
|
103
|
+
${(e.arrayElementFields??[]).map(a=>{let s=t[a.name],o=s==null?"":typeof s=="object"?JSON.stringify(s):String(s);switch(a.type){case "checkbox":return `<div class="form-control mb-2">
|
|
104
104
|
<label class="label cursor-pointer justify-start gap-3">
|
|
105
|
-
<input type="checkbox" data-frs-key="${
|
|
106
|
-
<span class="label-text text-sm">${
|
|
105
|
+
<input type="checkbox" data-frs-key="${R(a.name)}" class="checkbox checkbox-sm checkbox-primary"${o==="true"?" checked":""}>
|
|
106
|
+
<span class="label-text text-sm">${R(a.label)}</span>
|
|
107
107
|
</label>
|
|
108
108
|
</div>`;case "select":return `<div class="form-control mb-2">
|
|
109
|
-
<label class="label pb-1"><span class="label-text text-sm">${
|
|
110
|
-
<select data-frs-key="${
|
|
111
|
-
${
|
|
112
|
-
${(
|
|
109
|
+
<label class="label pb-1"><span class="label-text text-sm">${R(a.label)}</span></label>
|
|
110
|
+
<select data-frs-key="${R(a.name)}" class="select select-bordered select-sm w-full">
|
|
111
|
+
${a.required?"":'<option value="">\u2014</option>'}
|
|
112
|
+
${(a.options??[]).map(d=>`<option value="${R(d)}"${o===d?" selected":""}>${R(d)}</option>`).join("")}
|
|
113
113
|
</select>
|
|
114
114
|
</div>`;case "number":return `<div class="form-control mb-2">
|
|
115
|
-
<label class="label pb-1"><span class="label-text text-sm">${
|
|
116
|
-
<input type="number" data-frs-key="${
|
|
115
|
+
<label class="label pb-1"><span class="label-text text-sm">${R(a.label)}</span></label>
|
|
116
|
+
<input type="number" data-frs-key="${R(a.name)}" value="${R(o)}" class="input input-bordered input-sm w-full">
|
|
117
117
|
</div>`;case "datetime-local":return `<div class="form-control mb-2">
|
|
118
|
-
<label class="label pb-1"><span class="label-text text-sm">${
|
|
119
|
-
<input type="datetime-local" data-frs-key="${
|
|
118
|
+
<label class="label pb-1"><span class="label-text text-sm">${R(a.label)}</span></label>
|
|
119
|
+
<input type="datetime-local" data-frs-key="${R(a.name)}" value="${R(o)}" class="input input-bordered input-sm w-full">
|
|
120
120
|
</div>`;case "textarea":return `<div class="form-control mb-2">
|
|
121
|
-
<label class="label pb-1"><span class="label-text text-sm">${
|
|
122
|
-
<textarea data-frs-key="${
|
|
121
|
+
<label class="label pb-1"><span class="label-text text-sm">${R(a.label)}</span></label>
|
|
122
|
+
<textarea data-frs-key="${R(a.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${R(o)}</textarea>
|
|
123
123
|
</div>`;default:return `<div class="form-control mb-2">
|
|
124
|
-
<label class="label pb-1"><span class="label-text text-sm">${
|
|
125
|
-
<input type="text" data-frs-key="${
|
|
124
|
+
<label class="label pb-1"><span class="label-text text-sm">${R(a.label)}</span></label>
|
|
125
|
+
<input type="text" data-frs-key="${R(a.name)}" value="${R(o)}" class="input input-bordered input-sm w-full">
|
|
126
126
|
</div>`}}).join(`
|
|
127
127
|
`)}
|
|
128
|
-
</div>`}function
|
|
128
|
+
</div>`}function ae(e,t,n,r="Save"){let a=e.map(s=>ot(s)).join(`
|
|
129
129
|
`);return `
|
|
130
|
-
<form action="${
|
|
131
|
-
${
|
|
130
|
+
<form action="${R(t)}" method="${n}" novalidate data-frs-form>
|
|
131
|
+
${a}
|
|
132
132
|
<div class="flex gap-2 mt-4 pt-4 border-t border-base-200">
|
|
133
|
-
<button type="submit" class="btn btn-primary btn-sm">${
|
|
133
|
+
<button type="submit" class="btn btn-primary btn-sm">${R(r)}</button>
|
|
134
134
|
<button type="button" class="btn btn-ghost btn-sm" onclick="history.back()">Cancel</button>
|
|
135
135
|
</div>
|
|
136
|
-
</form>`}
|
|
136
|
+
</form>`}Ae();var lt=`// \u2500\u2500 Right panel (relations preview) \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
|
|
137
|
+
(function () {
|
|
138
|
+
function panelEls() {
|
|
139
|
+
return {
|
|
140
|
+
root: document.querySelector("[data-frs-panel-root]"),
|
|
141
|
+
backdrop: document.querySelector("[data-frs-panel-backdrop]"),
|
|
142
|
+
panel: document.querySelector("[data-frs-panel]"),
|
|
143
|
+
title: document.querySelector("[data-frs-panel-title]"),
|
|
144
|
+
body: document.querySelector("[data-frs-panel-body]"),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function openPanel(label) {
|
|
148
|
+
var els = panelEls();
|
|
149
|
+
if (!els.root || !els.panel) return;
|
|
150
|
+
els.root.classList.remove("hidden");
|
|
151
|
+
els.root.setAttribute("aria-hidden", "false");
|
|
152
|
+
requestAnimationFrame(function () {
|
|
153
|
+
if (els.backdrop) els.backdrop.style.opacity = "1";
|
|
154
|
+
if (els.panel) els.panel.style.transform = "translateX(0)";
|
|
155
|
+
});
|
|
156
|
+
if (els.title) els.title.textContent = label || "Relation";
|
|
157
|
+
if (els.body) {
|
|
158
|
+
els.body.innerHTML =
|
|
159
|
+
'<div class="flex items-center justify-center py-12 text-base-content/40"><span class="loading loading-spinner loading-md"></span></div>';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function closePanel() {
|
|
163
|
+
var els = panelEls();
|
|
164
|
+
if (!els.root || !els.panel) return;
|
|
165
|
+
if (els.backdrop) els.backdrop.style.opacity = "0";
|
|
166
|
+
if (els.panel) els.panel.style.transform = "translateX(100%)";
|
|
167
|
+
setTimeout(function () {
|
|
168
|
+
els.root.classList.add("hidden");
|
|
169
|
+
els.root.setAttribute("aria-hidden", "true");
|
|
170
|
+
}, 200);
|
|
171
|
+
}
|
|
172
|
+
function basePathFromLocation() {
|
|
173
|
+
// The current list page is at <basePath>/<repoName>...; we strip everything after the basePath.
|
|
174
|
+
// We can't know basePath without context, so we derive it from the current URL up to the repoName segment.
|
|
175
|
+
// Caller passes the absolute fragment URL via data attribute; we just need the prefix here.
|
|
176
|
+
return window.location.pathname.replace(/\\/[^/]*\\/?$/, "");
|
|
177
|
+
}
|
|
178
|
+
function fetchPanel(url, label) {
|
|
179
|
+
openPanel(label);
|
|
180
|
+
fetch(url, { credentials: "same-origin" })
|
|
181
|
+
.then(function (r) {
|
|
182
|
+
return r.text();
|
|
183
|
+
})
|
|
184
|
+
.then(function (html) {
|
|
185
|
+
var els = panelEls();
|
|
186
|
+
if (els.body) els.body.innerHTML = html;
|
|
187
|
+
})
|
|
188
|
+
.catch(function (err) {
|
|
189
|
+
var els = panelEls();
|
|
190
|
+
if (els.body) {
|
|
191
|
+
els.body.innerHTML =
|
|
192
|
+
'<div class="p-6 text-error text-sm">Error: ' +
|
|
193
|
+
(err && err.message ? err.message : String(err)) +
|
|
194
|
+
"</div>";
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
document.addEventListener("click", function (e) {
|
|
199
|
+
var trigger = e.target.closest("[data-frs-relation]");
|
|
200
|
+
if (trigger) {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
var type = trigger.getAttribute("data-frs-rel-type");
|
|
203
|
+
var repo = trigger.getAttribute("data-frs-rel-repo");
|
|
204
|
+
var fk = trigger.getAttribute("data-frs-rel-fk");
|
|
205
|
+
var val = trigger.getAttribute("data-frs-rel-val");
|
|
206
|
+
var label = trigger.getAttribute("data-frs-rel-label") || "Relation";
|
|
207
|
+
var bp = basePathFromLocation();
|
|
208
|
+
var url;
|
|
209
|
+
if (type === "one") {
|
|
210
|
+
url =
|
|
211
|
+
bp +
|
|
212
|
+
"/" +
|
|
213
|
+
encodeURIComponent(repo) +
|
|
214
|
+
"/_panel?type=one&id=" +
|
|
215
|
+
encodeURIComponent(val);
|
|
216
|
+
} else {
|
|
217
|
+
url =
|
|
218
|
+
bp +
|
|
219
|
+
"/" +
|
|
220
|
+
encodeURIComponent(repo) +
|
|
221
|
+
"/_panel?type=many&fk=" +
|
|
222
|
+
encodeURIComponent(fk) +
|
|
223
|
+
"&fv=" +
|
|
224
|
+
encodeURIComponent(val);
|
|
225
|
+
}
|
|
226
|
+
fetchPanel(url, repo + " \xB7 " + label);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (e.target.closest("[data-frs-panel-close]")) {
|
|
230
|
+
closePanel();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (e.target.closest("[data-frs-panel-backdrop]")) {
|
|
234
|
+
closePanel();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
var pageBtn = e.target.closest("[data-frs-panel-page]");
|
|
238
|
+
if (pageBtn) {
|
|
239
|
+
// Recompute URL by inspecting the current open panel context \u2014 encoded in the body's first anchor "Full view \u2192"
|
|
240
|
+
// Simpler: rebuild via the previous URL stored in data-attr.
|
|
241
|
+
var fullViewLink = document.querySelector(
|
|
242
|
+
"[data-frs-panel-body] a.btn-outline[href]",
|
|
243
|
+
);
|
|
244
|
+
if (!fullViewLink) return;
|
|
245
|
+
var dir = pageBtn.getAttribute("data-frs-panel-page");
|
|
246
|
+
var cursor = pageBtn.getAttribute("data-cursor") || "";
|
|
247
|
+
var fullViewUrl = new URL(fullViewLink.href, window.location.href);
|
|
248
|
+
var repo = fullViewUrl.pathname.split("/").filter(Boolean).pop();
|
|
249
|
+
var bp = fullViewUrl.pathname.replace(/\\/[^/]+\\/?$/, "");
|
|
250
|
+
var fk = "";
|
|
251
|
+
var fv = "";
|
|
252
|
+
fullViewUrl.searchParams.forEach(function (v, k) {
|
|
253
|
+
if (k.indexOf("fv_") === 0) {
|
|
254
|
+
fk = k.slice(3);
|
|
255
|
+
fv = v;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
var url =
|
|
259
|
+
bp +
|
|
260
|
+
"/" +
|
|
261
|
+
encodeURIComponent(repo) +
|
|
262
|
+
"/_panel?type=many&fk=" +
|
|
263
|
+
encodeURIComponent(fk) +
|
|
264
|
+
"&fv=" +
|
|
265
|
+
encodeURIComponent(fv) +
|
|
266
|
+
"&cursor=" +
|
|
267
|
+
encodeURIComponent(cursor) +
|
|
268
|
+
"&dir=" +
|
|
269
|
+
encodeURIComponent(dir);
|
|
270
|
+
fetchPanel(url, repo);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
document.addEventListener("keydown", function (e) {
|
|
274
|
+
if (e.key === "Escape") closePanel();
|
|
275
|
+
});
|
|
276
|
+
})();
|
|
277
|
+
|
|
278
|
+
// \u2500\u2500 Bulk selection + actions \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
|
|
279
|
+
(function () {
|
|
280
|
+
var state = {
|
|
281
|
+
selectAllAcrossQuery: false,
|
|
282
|
+
// Keep a Set of selected ids on the current page (cleared on navigation).
|
|
283
|
+
selected: new Set(),
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
function bar() {
|
|
287
|
+
return document.querySelector("[data-frs-bulk-bar]");
|
|
288
|
+
}
|
|
289
|
+
function summarize() {
|
|
290
|
+
var b = bar();
|
|
291
|
+
if (!b) return;
|
|
292
|
+
var total = parseInt(b.getAttribute("data-frs-total") || "0", 10);
|
|
293
|
+
var summary = b.querySelector("[data-frs-bulk-summary]");
|
|
294
|
+
var selectAllBtn = b.querySelector("[data-frs-bulk-select-all]");
|
|
295
|
+
var allActive = b.querySelector("[data-frs-bulk-all-active]");
|
|
296
|
+
var pageSize = parseInt(b.getAttribute("data-frs-page-size") || "0", 10);
|
|
297
|
+
var n = state.selected.size;
|
|
298
|
+
if (state.selectAllAcrossQuery) {
|
|
299
|
+
if (allActive) allActive.classList.remove("hidden");
|
|
300
|
+
if (selectAllBtn) selectAllBtn.classList.add("hidden");
|
|
301
|
+
if (summary) summary.textContent = "";
|
|
302
|
+
b.classList.remove("hidden");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (n === 0) {
|
|
306
|
+
b.classList.add("hidden");
|
|
307
|
+
if (selectAllBtn) selectAllBtn.classList.add("hidden");
|
|
308
|
+
if (allActive) allActive.classList.add("hidden");
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
b.classList.remove("hidden");
|
|
312
|
+
if (allActive) allActive.classList.add("hidden");
|
|
313
|
+
if (summary) {
|
|
314
|
+
summary.textContent =
|
|
315
|
+
n + " selected" + (pageSize ? " on this page" : "");
|
|
316
|
+
}
|
|
317
|
+
if (selectAllBtn && total > n) {
|
|
318
|
+
selectAllBtn.classList.remove("hidden");
|
|
319
|
+
} else if (selectAllBtn) {
|
|
320
|
+
selectAllBtn.classList.add("hidden");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function syncHeader() {
|
|
324
|
+
var head = document.querySelector("[data-frs-select-page]");
|
|
325
|
+
if (!head) return;
|
|
326
|
+
var rows = document.querySelectorAll("[data-frs-select-row]");
|
|
327
|
+
var checked = 0;
|
|
328
|
+
rows.forEach(function (r) {
|
|
329
|
+
if (r.checked) checked++;
|
|
330
|
+
});
|
|
331
|
+
head.indeterminate = checked > 0 && checked < rows.length;
|
|
332
|
+
head.checked = rows.length > 0 && checked === rows.length;
|
|
333
|
+
}
|
|
334
|
+
document.addEventListener("change", function (e) {
|
|
335
|
+
if (e.target.matches("[data-frs-select-row]")) {
|
|
336
|
+
var id = e.target.value;
|
|
337
|
+
if (e.target.checked) state.selected.add(id);
|
|
338
|
+
else state.selected.delete(id);
|
|
339
|
+
state.selectAllAcrossQuery = false;
|
|
340
|
+
syncHeader();
|
|
341
|
+
summarize();
|
|
342
|
+
} else if (e.target.matches("[data-frs-select-page]")) {
|
|
343
|
+
var rows = document.querySelectorAll("[data-frs-select-row]");
|
|
344
|
+
rows.forEach(function (r) {
|
|
345
|
+
r.checked = e.target.checked;
|
|
346
|
+
if (e.target.checked) state.selected.add(r.value);
|
|
347
|
+
else state.selected.delete(r.value);
|
|
348
|
+
});
|
|
349
|
+
state.selectAllAcrossQuery = false;
|
|
350
|
+
summarize();
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
document.addEventListener("click", function (e) {
|
|
354
|
+
var sa = e.target.closest("[data-frs-bulk-select-all]");
|
|
355
|
+
if (sa) {
|
|
356
|
+
state.selectAllAcrossQuery = true;
|
|
357
|
+
summarize();
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
var clear = e.target.closest("[data-frs-bulk-clear]");
|
|
361
|
+
if (clear) {
|
|
362
|
+
state.selectAllAcrossQuery = false;
|
|
363
|
+
state.selected.clear();
|
|
364
|
+
document
|
|
365
|
+
.querySelectorAll("[data-frs-select-row]")
|
|
366
|
+
.forEach(function (r) {
|
|
367
|
+
r.checked = false;
|
|
368
|
+
});
|
|
369
|
+
syncHeader();
|
|
370
|
+
summarize();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
var actBtn = e.target.closest("[data-frs-bulk-action]");
|
|
374
|
+
if (actBtn) {
|
|
375
|
+
var action = actBtn.getAttribute("data-frs-bulk-action");
|
|
376
|
+
if (action === "delete") doBulkDelete();
|
|
377
|
+
else if (action === "update") openBulkUpdateModal();
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
function buildPayload() {
|
|
382
|
+
var b = bar();
|
|
383
|
+
if (!b) return null;
|
|
384
|
+
if (state.selectAllAcrossQuery) {
|
|
385
|
+
var filters = [];
|
|
386
|
+
try {
|
|
387
|
+
filters = JSON.parse(b.getAttribute("data-frs-filters") || "[]");
|
|
388
|
+
} catch (_) {}
|
|
389
|
+
return { selectAll: true, filters: filters };
|
|
390
|
+
}
|
|
391
|
+
return { ids: Array.from(state.selected) };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function repoEndpoint(action) {
|
|
395
|
+
var b = bar();
|
|
396
|
+
if (!b) return null;
|
|
397
|
+
var repo = b.getAttribute("data-frs-repo");
|
|
398
|
+
var bp = window.location.pathname.replace(/\\/[^/]*\\/?$/, "");
|
|
399
|
+
return bp + "/" + encodeURIComponent(repo) + "/_bulk/" + action;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function doBulkDelete() {
|
|
403
|
+
var payload = buildPayload();
|
|
404
|
+
if (!payload) return;
|
|
405
|
+
var n = state.selectAllAcrossQuery
|
|
406
|
+
? "all matching"
|
|
407
|
+
: payload.ids.length + "";
|
|
408
|
+
if (!confirm("Delete " + n + " documents? This cannot be undone.")) return;
|
|
409
|
+
var url = repoEndpoint("delete");
|
|
410
|
+
if (!url) return;
|
|
411
|
+
fetch(url, {
|
|
412
|
+
method: "POST",
|
|
413
|
+
credentials: "same-origin",
|
|
414
|
+
headers: { "Content-Type": "application/json" },
|
|
415
|
+
body: JSON.stringify(payload),
|
|
416
|
+
})
|
|
417
|
+
.then(function (r) {
|
|
418
|
+
return r.json().then(function (j) {
|
|
419
|
+
return { ok: r.ok, body: j };
|
|
420
|
+
});
|
|
421
|
+
})
|
|
422
|
+
.then(function (res) {
|
|
423
|
+
if (!res.ok) {
|
|
424
|
+
alert("Bulk delete failed: " + (res.body && res.body.error));
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
window.location.reload();
|
|
428
|
+
})
|
|
429
|
+
.catch(function (err) {
|
|
430
|
+
alert("Bulk delete failed: " + err.message);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function openBulkUpdateModal() {
|
|
435
|
+
var b = bar();
|
|
436
|
+
var dialog = document.getElementById("frs-bulk-update-modal");
|
|
437
|
+
if (!b || !dialog) return;
|
|
438
|
+
var fields = [];
|
|
439
|
+
try {
|
|
440
|
+
fields = JSON.parse(b.getAttribute("data-frs-fields") || "[]");
|
|
441
|
+
} catch (_) {}
|
|
442
|
+
if (fields.length === 0) return;
|
|
443
|
+
var summary = dialog.querySelector(
|
|
444
|
+
"[data-frs-bulk-update-summary]",
|
|
445
|
+
);
|
|
446
|
+
if (summary) {
|
|
447
|
+
summary.textContent = state.selectAllAcrossQuery
|
|
448
|
+
? "Update one field on all matching documents."
|
|
449
|
+
: "Update one field on " +
|
|
450
|
+
state.selected.size +
|
|
451
|
+
" selected document" +
|
|
452
|
+
(state.selected.size !== 1 ? "s" : "") +
|
|
453
|
+
".";
|
|
454
|
+
}
|
|
455
|
+
var select = dialog.querySelector("[data-frs-bulk-field-select]");
|
|
456
|
+
var valueContainer = dialog.querySelector(
|
|
457
|
+
"[data-frs-bulk-value-container]",
|
|
458
|
+
);
|
|
459
|
+
var renderValueInput = function () {
|
|
460
|
+
if (!valueContainer || !select) return;
|
|
461
|
+
var name = select.value;
|
|
462
|
+
var meta = fields.filter(function (f) {
|
|
463
|
+
return f.name === name;
|
|
464
|
+
})[0];
|
|
465
|
+
if (!meta) {
|
|
466
|
+
valueContainer.innerHTML = "";
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
var inputHtml = "";
|
|
470
|
+
var label =
|
|
471
|
+
'<div class="label"><span class="label-text text-xs uppercase tracking-wide">Value</span></div>';
|
|
472
|
+
if (meta.type === "boolean") {
|
|
473
|
+
inputHtml =
|
|
474
|
+
'<select name="value" class="select select-bordered select-sm w-full">' +
|
|
475
|
+
'<option value="true">true</option><option value="false">false</option>' +
|
|
476
|
+
"</select>";
|
|
477
|
+
} else if (
|
|
478
|
+
(meta.type === "enum" || meta.type === "literal") &&
|
|
479
|
+
meta.enumValues &&
|
|
480
|
+
meta.enumValues.length
|
|
481
|
+
) {
|
|
482
|
+
inputHtml =
|
|
483
|
+
'<select name="value" class="select select-bordered select-sm w-full">';
|
|
484
|
+
meta.enumValues.forEach(function (v) {
|
|
485
|
+
inputHtml +=
|
|
486
|
+
'<option value="' + escapeAttr(v) + '">' + escapeHtml(v) + "</option>";
|
|
487
|
+
});
|
|
488
|
+
inputHtml += "</select>";
|
|
489
|
+
} else if (meta.type === "number" || meta.type === "bigint") {
|
|
490
|
+
inputHtml =
|
|
491
|
+
'<input type="number" step="any" name="value" class="input input-bordered input-sm w-full" />';
|
|
492
|
+
} else {
|
|
493
|
+
inputHtml =
|
|
494
|
+
'<input type="text" name="value" class="input input-bordered input-sm w-full" />';
|
|
495
|
+
}
|
|
496
|
+
valueContainer.innerHTML =
|
|
497
|
+
'<label class="form-control w-full">' + label + inputHtml + "</label>";
|
|
498
|
+
};
|
|
499
|
+
if (select) {
|
|
500
|
+
select.value = "";
|
|
501
|
+
select.onchange = renderValueInput;
|
|
502
|
+
}
|
|
503
|
+
if (valueContainer) valueContainer.innerHTML = "";
|
|
504
|
+
var form = dialog.querySelector("[data-frs-bulk-update-form]");
|
|
505
|
+
if (form) {
|
|
506
|
+
form.onsubmit = function (e) {
|
|
507
|
+
e.preventDefault();
|
|
508
|
+
if (!select || !select.value) return;
|
|
509
|
+
var meta = fields.filter(function (f) {
|
|
510
|
+
return f.name === select.value;
|
|
511
|
+
})[0];
|
|
512
|
+
if (!meta) return;
|
|
513
|
+
var input = valueContainer.querySelector(
|
|
514
|
+
'input[name="value"], select[name="value"]',
|
|
515
|
+
);
|
|
516
|
+
if (!input) return;
|
|
517
|
+
var raw = input.value;
|
|
518
|
+
var typed;
|
|
519
|
+
if (meta.type === "boolean") typed = raw === "true";
|
|
520
|
+
else if (meta.type === "number") typed = raw === "" ? null : Number(raw);
|
|
521
|
+
else if (meta.type === "bigint") typed = raw === "" ? null : Number(raw);
|
|
522
|
+
else typed = raw;
|
|
523
|
+
var payload = buildPayload();
|
|
524
|
+
if (!payload) return;
|
|
525
|
+
payload.field = select.value;
|
|
526
|
+
payload.value = typed;
|
|
527
|
+
var url = repoEndpoint("update");
|
|
528
|
+
if (!url) return;
|
|
529
|
+
fetch(url, {
|
|
530
|
+
method: "POST",
|
|
531
|
+
credentials: "same-origin",
|
|
532
|
+
headers: { "Content-Type": "application/json" },
|
|
533
|
+
body: JSON.stringify(payload),
|
|
534
|
+
})
|
|
535
|
+
.then(function (r) {
|
|
536
|
+
return r.json().then(function (j) {
|
|
537
|
+
return { ok: r.ok, body: j };
|
|
538
|
+
});
|
|
539
|
+
})
|
|
540
|
+
.then(function (res) {
|
|
541
|
+
if (!res.ok) {
|
|
542
|
+
alert("Bulk update failed: " + (res.body && res.body.error));
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
dialog.close();
|
|
546
|
+
window.location.reload();
|
|
547
|
+
})
|
|
548
|
+
.catch(function (err) {
|
|
549
|
+
alert("Bulk update failed: " + err.message);
|
|
550
|
+
});
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
var cancel = dialog.querySelector("[data-frs-bulk-update-cancel]");
|
|
554
|
+
if (cancel)
|
|
555
|
+
cancel.onclick = function () {
|
|
556
|
+
dialog.close();
|
|
557
|
+
};
|
|
558
|
+
if (typeof dialog.showModal === "function") dialog.showModal();
|
|
559
|
+
else dialog.setAttribute("open", "");
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function escapeHtml(s) {
|
|
563
|
+
return String(s).replace(/[&<>"']/g, function (c) {
|
|
564
|
+
return (
|
|
565
|
+
{ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[
|
|
566
|
+
c
|
|
567
|
+
] || c
|
|
568
|
+
);
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
function escapeAttr(s) {
|
|
572
|
+
return escapeHtml(s);
|
|
573
|
+
}
|
|
574
|
+
})();
|
|
575
|
+
|
|
576
|
+
// \u2500\u2500 Theme switcher \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
|
|
577
|
+
(function () {
|
|
578
|
+
function syncThemeUI() {
|
|
579
|
+
var current =
|
|
580
|
+
document.documentElement.getAttribute("data-theme") || "corporate";
|
|
581
|
+
var label = document.querySelector("[data-frs-theme-current]");
|
|
582
|
+
if (label) label.textContent = current;
|
|
583
|
+
document.querySelectorAll("[data-frs-theme-check]").forEach(function (el) {
|
|
584
|
+
el.classList.toggle(
|
|
585
|
+
"hidden",
|
|
586
|
+
el.getAttribute("data-frs-theme-check") !== current,
|
|
587
|
+
);
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
document.addEventListener("DOMContentLoaded", syncThemeUI);
|
|
591
|
+
document.addEventListener("click", function (e) {
|
|
592
|
+
var btn = e.target.closest("[data-frs-theme]");
|
|
593
|
+
if (!btn) return;
|
|
594
|
+
var theme = btn.getAttribute("data-frs-theme");
|
|
595
|
+
if (!theme) return;
|
|
596
|
+
document.documentElement.setAttribute("data-theme", theme);
|
|
597
|
+
try {
|
|
598
|
+
localStorage.setItem("frs-admin-theme", theme);
|
|
599
|
+
} catch (_) {}
|
|
600
|
+
syncThemeUI();
|
|
601
|
+
// Close the dropdown by blurring focus (DaisyUI dropdown closes on focusout)
|
|
602
|
+
if (document.activeElement && document.activeElement.blur) {
|
|
603
|
+
document.activeElement.blur();
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
})();
|
|
607
|
+
|
|
608
|
+
// \u2500\u2500 Form validation + array serialization \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
|
|
137
609
|
document.addEventListener("submit", function (e) {
|
|
138
610
|
var form = e.target;
|
|
139
611
|
if (!form.hasAttribute("data-frs-form")) return;
|
|
@@ -552,6 +1024,6 @@ function initColumnReorder(table) {
|
|
|
552
1024
|
});
|
|
553
1025
|
});
|
|
554
1026
|
}
|
|
555
|
-
`;function se(){return jsx("script",{dangerouslySetInnerHTML:{__html:Me}})}function P(e){return "<!DOCTYPE html>"+renderToString(e)}var M=({opts:e,children:t})=>{let{title:a,breadcrumb:n,flash:r,basePath:o="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[a," \u2014 FRS Admin"]}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsx("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:jsx("div",{class:"flex-1",children:jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})})}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[n&&n.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:n.map((s,p)=>s.href?jsx("li",{children:jsx("a",{href:s.href,children:s.label})},p):jsx("li",{class:"text-base-content/60",children:s.label},p))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:a}),r&&jsxs("div",{role:"alert",class:`alert ${r.type==="success"?"alert-success":r.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsx("span",{class:"flex-1",children:r.message}),r.action&&jsx("a",{href:r.action.href,...r.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:r.action.label})]}),t]}),jsx(se,{})]})]})};function ue(e,t){return P(jsx(M,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function pe(e,t){return P(jsx(M,{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(a=>jsx("a",{href:`${t}/${a.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:a.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:a.path})]})},a.name))})}))}var qe=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],bt=[{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"}],gt=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function ht(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return bt;case "ZodBoolean":return qe;case "ZodArray":return gt;default:return qe}}var B="__null__";function vt(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="${B}"]');if(!o){o=document.createElement('option');o.value='${B}';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='${B}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${B}"][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!=='${B}')?i.dataset._prev:'';}}})(this)`}function xt(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 re({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:vt(e)}),jsx("span",{children:"\u2205"})]})}function wt({col:e,active:t}){let a=t?.value??"",n=a===B,r=`fv_input_${e.name.replace(/\./g,"__")}`,o=t?.op,s=o==="in"||o==="not-in";if(e.enumValues&&e.enumValues.length>0){if(s){let p=new Set(a.split(",").map(l=>l.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:r,name:`fv_${e.name}`,value:a}),e.enumValues.map(l=>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:l,checked:p.has(l),"data-enum-group":d,onchange:xt(r,d)}),jsx("span",{children:l})]},l))]})}return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:r,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:n?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:a===""&&!n,children:"\u2014"}),e.enumValues.map(p=>jsx("option",{value:p,selected:a===p,children:p},p)),e.nullable&&jsx("option",{value:B,"data-_auto":"1",selected:n,children:"\u2205 null"})]}),e.nullable&&jsx(re,{inputId:r,active:n})]})}if(e.zodType==="ZodBoolean")return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:r,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:n?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:a===""&&!n,children:"\u2014"}),jsx("option",{value:"true",selected:a==="true",children:"true"}),jsx("option",{value:"false",selected:a==="false",children:"false"}),e.nullable&&jsx("option",{value:B,"data-_auto":"1",selected:n,children:"\u2205 null"})]}),e.nullable&&jsx(re,{inputId:r,active:n})]});if(e.zodType==="ZodArray"){let p=t?.op==="array-contains-any";return jsx("input",{id:r,type:"text",name:`fv_${e.name}`,value:a,placeholder:p?"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:r,type:n?"text":"number",name:`fv_${e.name}`,value:a,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:n,style:n?"opacity:0.55":void 0,"data-_type":n?"number":void 0}),e.nullable&&jsx(re,{inputId:r,active:n})]}):e.zodType==="ZodDate"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:r,type:n?"text":"datetime-local",name:`fv_${e.name}`,value:a,class:"input input-sm input-bordered w-full",readOnly:n,style:n?"opacity:0.55":void 0,"data-_type":n?"datetime-local":void 0}),e.nullable&&jsx(re,{inputId:r,active:n})]}):jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:r,type:"text",name:`fv_${e.name}`,value:a,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:n,style:n?"opacity:0.55":void 0}),e.nullable&&jsx(re,{inputId:r,active:n})]})}function fe({action:e,columnMeta:t,activeFilters:a,isGroup:n}){let r=Object.fromEntries(a.map(d=>[d.field,d])),o=a.length>0,s=a.length>=2||n&&o,p=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:o?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",o&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[a.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:p.map(d=>{let l=ht(d.zodType),c=r[d.name],f=c?.op??l[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:[l.length>1?jsx("select",{name:`fo_${d.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:l.map(i=>jsx("option",{value:i.value,selected:i.value===f,children:i.label},i.value))}):jsx("input",{type:"hidden",name:`fo_${d.name}`,value:l[0].value}),jsx(wt,{col:d,active:c})]})]},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"}),o&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),s&&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"})}),n?"Collection group queries require a composite index":"Multiple filters may require a composite index"]})]})]})})]})}function me(e,t,a,n,r,o){let s=a==="create"?`Create ${e}`:`Edit ${e} / ${n??""}`,p=a==="create"?[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:"New document"}]:[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:`Edit ${n??""}`}];return P(jsx(M,{opts:{title:s,breadcrumb:p,basePath:r,flash:o},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}function ye(e,t,a){let n=new URLSearchParams;for(let r of e)n.set(`fv_${r.field}`,r.value),n.set(`fo_${r.field}`,r.op);return t&&(n.set("ob",t.field),n.set("od",t.dir)),a&&n.set("ps",String(a)),n}function Le(e,t,a,n,r){let o=ye(e,n,r);return o.set("cursor",t),o.set("dir",a),`?${o.toString()}`}function St(e,t,a,n){let r=ye(a,void 0,n);return t?.field===e?t.dir==="asc"&&(r.set("ob",e),r.set("od","desc")):(r.set("ob",e),r.set("od","asc")),`?${r.toString()}`}function $t(e,t,a){return `?${ye(t,a,e).toString()}`}function be(e,t,a,n,r,o,s=[],p=[],d=false,l=[],c,f,i,u){let m=`${n}/${e}`,g=`${m}/create`;return P(jsxs(M,{opts:{title:e,breadcrumb:[{label:"Repositories",href:n},{label:e}],basePath:n,flash:o},children:[s.length>0&&jsx(fe,{action:m,columnMeta:s,activeFilters:p,isGroup:u}),i&&jsxs("div",{role:"alert",class:`alert ${i.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:i.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:i.type==="index"?"Composite index required":"Query failed"}),jsx("div",{class:"text-sm",children:i.message})]}),i.indexUrl&&jsx("a",{href:i.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",children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length," document",t.length!==1&&"s"]}),jsxs("div",{class:"flex items-center gap-1.5 text-sm text-base-content/60",children:[jsx("span",{children:"Rows"}),jsx("div",{class:"join",children:[10,25,50,100].map(y=>jsx("a",{href:$t(y,p,c),class:`join-item btn btn-xs ${f===y?"btn-active btn-primary":"btn-outline"}`,children:y},y))})]})]}),jsx("a",{href:g,class:"btn btn-primary btn-sm",children:"+ New"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":a.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[[...a].map((y,h)=>{let k=c?.field===y,C=k?c.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:St(y,c,p,f),class:`hover:text-base-content inline-flex items-center gap-0.5${k?" text-primary font-bold":""}`,children:[y,C]})},h)}),l.map((y,h)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:y.column},`rel-${h}`)),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:a.length+l.length+1,class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((y,h)=>{let k=String(y.docId??y.id??""),C=`${n}/${e}/${encodeURIComponent(k)}/edit`,v=`${n}/${e}/${encodeURIComponent(k)}/delete`;return jsxs("tr",{class:"hover",children:[a.map((x,$)=>jsx("td",{class:"align-top py-2",children:jsx(ce,{val:y[x]})},$)),l.map((x,$)=>{let R=y[x.key];if(R==null||R==="")return jsx("td",{class:"py-2"},`rel-${$}`);let q=`${n}/${x.targetRepo}?fv_${x.targetKey}=${encodeURIComponent(String(R))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:q,class:"btn btn-xs btn-ghost btn-outline",children:x.column})},`rel-${$}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:C,class:"btn btn-xs btn-outline",children:"Edit"}),d&&jsx("form",{method:"post",action:v,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},h)})})]})}),(r.hasPrev||r.hasNext)&&jsxs("div",{class:"flex justify-center items-center mt-6 gap-2",children:[r.hasPrev?jsx("a",{href:Le(p,r.prevCursor,"prev",c,f),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),r.hasNext?jsx("a",{href:Le(p,r.nextCursor,"next",c,f),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]})]}))}function ge(e,t){return ue(e,t)}function Ue(e,t){return pe(e,t)}function Ve(e,t,a,n,r,o,s,p,d,l,c,f,i,u){return be(e,t,a,n,r,o,s,p,d,l,c,f,i,u)}function H(e,t,a,n,r,o){return me(e,t,a,n,r,o)}var Rt=new Set(["<","<=",">",">=","!="]),kt=new Set(["array-contains","array-contains-any"]);function he(e){return e==="desc"?"DESCENDING":"ASCENDING"}function Ct(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function _t(e,t,a,n,r){let o=[],s=new Set;for(let d of n)if(d.op==="=="||d.op==="in"||d.op==="not-in"){if(s.has(d.field))continue;s.add(d.field),o.push({fieldPath:d.field,order:"ASCENDING"});}for(let d of n)if(kt.has(d.op)){if(s.has(d.field))continue;s.add(d.field),o.push({fieldPath:d.field,arrayConfig:"CONTAINS"});}for(let d of n)if(Rt.has(d.op)){if(s.has(d.field))continue;s.add(d.field);let l=r?.field===d.field?he(r.dir):"ASCENDING";o.push({fieldPath:d.field,order:l});}if(r&&!s.has(r.field)&&o.push({fieldPath:r.field,order:he(r.dir)}),o.length===1&&a)return Ot(e,t,o[0]);let p=r&&o.some(d=>d.fieldPath===r.field)?he(r.dir):"ASCENDING";return o.push({fieldPath:"__name__",order:p}),Et(e,t,a,o)}function Et(e,t,a,n,r="(default)"){let o=`projects/${e}/databases/${r}/collectionGroups/${t}/indexes/_`,s=[...we(1,o),...le(2,a?2:1)];for(let l of n)s.push(...He(3,Ke(l)));let p=r==="(default)"?"-default-":r,d=encodeURIComponent(Je(s));return `https://console.firebase.google.com/project/${e}/firestore/databases/${p}/indexes?create_composite=${d}`}function Tt(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function ve(e){let t=[],a=e>>>0;for(;a>=128;)t.push(a&127|128),a>>>=7;return t.push(a&127),t}function xe(e,t){return e<<3|t}function we(e,t){let a=Array.from(new TextEncoder().encode(t));return [xe(e,2),...ve(a.length),...a]}function le(e,t){return [xe(e,0),...ve(t)]}function He(e,t){return [xe(e,2),...ve(t.length),...t]}function Ke(e){let t=[...we(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...le(3,1)):t.push(...le(2,e.order==="DESCENDING"?2:1)),t}function Je(e){let t=String.fromCharCode(...e),a;if(typeof Buffer<"u")a=Buffer.from(e).toString("base64");else if(typeof btoa<"u")a=btoa(t);else throw new Error("No base64 encoder available");return a.replace(/=+$/,"")}function Ot(e,t,a,n="(default)"){let r=`projects/${e}/databases/${n}/collectionGroups/${t}/fields/${a.fieldPath}`,o=[...we(1,r),...le(2,2),...He(3,Ke(a))],s=n==="(default)"?"-default-":n,p=encodeURIComponent(Je(o));return `https://console.firebase.google.com/project/${e}/firestore/databases/${s}/indexes/automatic?create_exemption=${p}`}function At(e){let t=e,a=[t?.firestore?.projectId,t?.firestore?.app?.options?.projectId,t?.firestore?._settings?.projectId,t?.firestore?.databaseId?.projectId,t?._firestore?.projectId];for(let r of a)if(typeof r=="string"&&r.length>0)return r;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function K(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function Se(e,t){let a=e??{},n=K(e),r;if(n&&(r=a.message?Tt(a.message):void 0,!r)){let o=At(t.ref);if(o){let s=Ct(t.path);r=_t(o,s,t.isGroup,t.filters,t.sort);}}return {type:n?"index":"error",message:n?"This query requires a composite index that does not exist yet.":a.message??"Query failed",indexUrl:r}}var Ge="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Nt(){let e="";for(let t=0;t<20;t++)e+=Ge.charAt(Math.floor(Math.random()*Ge.length));return e}function We(e,t){if(!t)return;let a=e[t];if(typeof a!="string"||!a)return;let n=a.split("/").filter(Boolean),r=[];for(let o=1;o<n.length;o+=2)r.push(n[o]);return r.length>0?r:void 0}async function $e(e,t){let a=e.documentKey??"docId",n=`by${a.charAt(0).toUpperCase()}${a.slice(1)}`;if(typeof e.repo.get[n]=="function")try{let o=await e.repo.get[n](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[a,"==",t]],limit:1}))[0]??null}function Re(e,t,a){let n=e.documentKey??"docId",r=Se(a,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:n,op:"==",value:t}]});return r.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...r.indexUrl?{action:{href:r.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:r.message}}function _(e,t,a=200){e.status(a).set("Content-Type","text/html; charset=utf-8").send(t);}function ke(e,t){e.status(302).set("Location",t).send("");}function Ce(e,t){let a=t.shape,n={};for(let[r,o]of Object.entries(a)){let s=Ee(o);if(s==="ZodObject"){if(e[r+"__isnull"]==="1"){n[r]=null;continue}let l={},c=false;for(let[u,m]of Object.entries(e))u.startsWith(`${r}.`)&&(l[u.slice(r.length+1)]=m,c=true);if(c){let u=o;for(;;){let m=O(u);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")u=Z(u);else break}n[r]=Ce(l,u);continue}let f=e[r],i=Array.isArray(f)?f[f.length-1]:f;if(i)try{n[r]=JSON.parse(i);}catch{n[r]=i;}continue}let p=e[r],d=Array.isArray(p)?p[p.length-1]:p;if(e[r+"__isnull"]==="1"){n[r]=null;continue}if(d===void 0||d===""){s==="ZodBoolean"&&(n[r]=false);continue}switch(s){case "ZodBoolean":d==="__null__"?n[r]=null:n[r]=d==="true"||d==="on"||d==="1";break;case "ZodNumber":case "ZodBigInt":n[r]=Number(d);break;case "ZodDate":n[r]=new Date(d);break;case "ZodArray":try{n[r]=JSON.parse(d);}catch{n[r]=d;}break;default:if(d.startsWith("{")||d.startsWith("["))try{n[r]=JSON.parse(d);break}catch{}n[r]=d;}}return n}function Qe(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 n=new Date(e);isNaN(n.getTime())||(t=n);}if(!t||isNaN(t.getTime()))return null;let a=n=>String(n).padStart(2,"0");return `${t.getFullYear()}-${a(t.getMonth()+1)}-${a(t.getDate())}T${a(t.getHours())}:${a(t.getMinutes())}`}function Ee(e){let t=e;for(;;){let a=O(t);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")t=Z(t);else return a}}function It(e){let t=e;for(;;){let a=O(t);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")t=Z(t);else return t}}function Xe(e){let t=e;for(;;){let a=O(t);if(a==="ZodOptional"||a==="ZodNullable")return true;if(a==="ZodDefault"){t=Z(t);continue}return false}}function Ye(e){let t=It(e),a=O(t);if(a==="ZodEnum"){let n=ee(t);return n.length>0?n:void 0}if(a==="ZodNativeEnum"){let n=te(t),r=Object.values(n).filter(o=>typeof o=="string");return r.length>0?r:void 0}if(a==="ZodLiteral"){let n=oe(t);return typeof n=="string"?[n]:void 0}}function et(e,t,a=""){let n={};for(let r of Object.keys(t.shape)){let o=a?`${a}.${r}`:r,s=e[r];if(s===null){n[o]="__null__";continue}if(s===void 0)continue;let p=t.shape[r];for(;;){let l=O(p);if(l==="ZodOptional"||l==="ZodNullable"||l==="ZodDefault")p=Z(p);else break}let d=O(p);if(d==="ZodObject"&&typeof s=="object"&&s!==null&&!Array.isArray(s)){let l=et(s,p,o);Object.assign(n,l);}else if(d==="ZodDate"){let l=Qe(s);l!==null&&(n[o]=l);}else if(typeof s=="object"&&s!==null&&!Array.isArray(s)&&("_seconds"in s||typeof s.toDate=="function")){let l=Qe(s);n[o]=l??JSON.stringify(s,null,2);}else typeof s=="object"?n[o]=JSON.stringify(s,null,2):n[o]=String(s);}return n}function _e(e,t){return e.map(a=>({...a,defaultValue:t[a.name]??a.defaultValue,nested:a.nested?_e(a.nested,t):void 0}))}function Dt(e,t){let a=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),n=[];for(let[r,o]of Object.entries(e)){if(!r.startsWith("fv_"))continue;let s=r.slice(3);if(!t.has(s))continue;let p=(o??"").trim();if(!p)continue;let d=e[`fo_${s}`]??"==",l=a.has(d)?d:"==";n.push({field:s,op:l,value:p});}return n}function Ft(e){let t="__null__",a=n=>n===t?null:n==="true"?true:n==="false"?false:n!==""&&!isNaN(Number(n))?Number(n):n;return e.map(n=>{if(n.op==="array-contains-any"||n.op==="in"||n.op==="not-in"){let r=n.value.split(",").map(o=>o.trim()).filter(o=>o!==""&&o!==t).map(o=>a(o));return [n.field,n.op,r]}return [n.field,n.op,a(n.value)]})}function tt(e,t,a=""){let n=[];for(let r of e){let o=a?`${a}.${r}`:r,s=t.shape[r];if(!s){n.push({name:o,zodType:"ZodString"});continue}let p=Ee(s);if(p==="ZodObject"){let d=s;for(;;){let c=O(d);if(c==="ZodOptional"||c==="ZodNullable"||c==="ZodDefault")d=Z(d);else break}let l=Y(d);n.push(...tt(Object.keys(l),d,o));}else n.push({name:o,zodType:p,nullable:Xe(s),enumValues:Ye(s)});}return n}function zt(e,t){let a=t.split("."),n=e;for(let r of a){for(;;){let s=O(n);if(s==="ZodOptional"||s==="ZodNullable"||s==="ZodDefault")n=Z(n);else break}let o=Y(n);if(!(r in o))return null;n=o[r];}return n}function G(e,t){if(!t||t.length===0)return e;let a=[],n=new Map;for(let o of t){let s=o.indexOf(".");if(s===-1)a.push(o);else {let p=o.slice(0,s),d=o.slice(s+1);n.has(p)||n.set(p,[]),n.get(p).push(d);}}let r={};for(let o of a)o in e.shape&&(r[o]=e.shape[o]);for(let[o,s]of n){if(!(o in e.shape))continue;let p=e.shape[o];for(;;){let d=O(p);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")p=Z(p);else break}if(O(p)!=="ZodObject"){r[o]=e.shape[o];continue}r[o]=G(p,s);}return z.object(r)}function J(e,t){let a=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let o=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",s=process.env.FUNCTION_REGION??"us-central1",p=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${s}/${p}${a}`}let n=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return n&&r.includes("cloudfunctions.net")?`/${n.toLowerCase()}${a}`:a}function nt(e,t){return {handleDashboard:(l,c)=>{let f=J(l,t),i=Object.values(e).map(u=>({name:u.name,path:u.path}));_(c,Ue(i,f));},handleList:async(l,c)=>{let f=l.params.repoName;if(!f){_(c,"Bad request",400);return}let i=e[f];if(!i){_(c,"Repository not found",404);return}let u=i.pageSize??25,m=l.query??{},g=m.cursor,y=m.dir==="prev"?"prev":"next",h=m.ob??"",k=m.od==="desc"?"desc":"asc",C=h?{field:h,dir:k}:void 0,v=parseInt(m.ps??""),x=Number.isFinite(v)&&v>0?Math.min(v,200):u,$=i.listColumns??Object.keys(i.schema.shape),R=i.documentKey??"docId",q=[R,...$.filter(A=>A!==R)],z=i.filterableFields?(()=>{let A=[];for(let D of i.filterableFields)(D.includes(".")||$.includes(D))&&A.push(D);return A})():$,j=(()=>{let A=[];for(let D of z)if(D.includes(".")){let Q=zt(i.schema,D);A.push({name:D,zodType:Q?Ee(Q):"ZodString",nullable:Q?Xe(Q):false,enumValues:Q?Ye(Q):void 0});}else A.push(...tt([D],i.schema));return A})(),rt=new Set(j.map(A=>A.name)),de=Dt(m,rt),Te=Ft(de),Oe;if(g)try{let A=i.repo.ref;typeof A.doc=="function"&&(Oe=await A.doc(g).get());}catch{}let L=await i.repo.query.paginate({pageSize:x,cursor:Oe,direction:y,...Te.length>0?{where:Te}:{},...C?{orderBy:[{field:C.field,direction:C.dir}]}:{}}).catch(A=>({queryError:Se(A,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:de,sort:C})})),W="queryError"in L,at=W?[]:L.data,ot=W?"":L.nextCursor?.id??"",st=W?"":L.prevCursor?.id??"",it=W?L.queryError:void 0,lt=J(l,t);_(c,Ve(i.name,at,q,lt,{hasPrev:W?false:L.hasPrevPage,hasNext:W?false:L.hasNextPage,prevCursor:st,nextCursor:ot},void 0,j,de,i.allowDelete??false,i.relationalMeta,C,x,it,i.isGroup));},handleCreateForm:(l,c)=>{let f=l.params.repoName;if(!f){_(c,"Bad request",400);return}let i=e[f];if(!i){_(c,"Repository not found",404);return}let u=J(l,t),m=G(i.schema,i.createFields),g=F(m),y=`${u}/${i.name}/create`,h=U(g,y,"POST","Create document");_(c,H(i.name,h,"create",null,u));},handleCreateSubmit:async(l,c)=>{let f=l.params.repoName;if(!f){_(c,"Bad request",400);return}let i=e[f];if(!i){_(c,"Repository not found",404);return}let u=J(l,t),m=l.body??{},g=Ce(m,i.schema),y=G(i.schema,i.createFields),h=y.safeParse(g);if(!h.success){let k=F(y),C=`${u}/${i.name}/create`,v=U(k,C,"POST","Create document"),x=h.error.issues.map($=>`${$.path.join(".")}: ${$.message}`).join(", ");_(c,H(i.name,v,"create",null,u,{type:"error",message:`Validation error: ${x}`}),422);return}try{if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let k={...h.data};i.createdKey&&(k[i.createdKey]=new Date);let C=i.parentKeys.filter(R=>!k[R]);if(C.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${C.join(", ")}`);let v=i.parentKeys.map(R=>k[R]),x=i.documentKey??"docId",$=k[x]||Nt();await i.repo.set(...v,$,k);}else await i.repo.create(h.data);ke(c,`${u}/${i.name}?flash=created`);}catch(k){let C=G(i.schema,i.createFields),v=F(C),x=`${u}/${i.name}/create`,$=U(v,x,"POST","Create document");_(c,H(i.name,$,"create",null,u,{type:"error",message:`Save error: ${k.message}`}),500);}},handleEditForm:async(l,c)=>{let f=l.params.repoName,i=l.params.id;if(!f||!i){_(c,"Bad request",400);return}let u=e[f];if(!u){_(c,"Repository not found",404);return}let m=J(l,t),g=null;try{g=await $e(u,i);}catch(x){let $=Re(u,i,x),R=K(x)?424:500;_(c,ge("",{title:`Edit ${u.name} / ${i}`,basePath:m,breadcrumb:[{label:"Repositories",href:m},{label:u.name,href:`${m}/${u.name}`},{label:`Edit ${i}`}],flash:$}),R);return}if(!g){_(c,"Document not found",404);return}let y=et(g,u.schema),h=G(u.schema,u.mutableFields),k=_e(F(h),y),C=`${m}/${u.name}/${encodeURIComponent(i)}/edit`,v=U(k,C,"POST","Save changes");_(c,H(u.name,v,"edit",i,m));},handleEditSubmit:async(l,c)=>{let f=l.params.repoName,i=l.params.id;if(!f||!i){_(c,"Bad request",400);return}let u=e[f];if(!u){_(c,"Repository not found",404);return}let m=J(l,t),g=l.body??{},y=Ce(g,u.schema),h=G(u.schema,u.mutableFields),C=h.partial().safeParse(y);if(!C.success){let v=Object.fromEntries(Object.entries(g).map(([z,j])=>[z,Array.isArray(j)?j.join(","):j??""])),x=_e(F(h),v),$=`${m}/${u.name}/${encodeURIComponent(i)}/edit`,R=U(x,$,"POST","Save changes"),q=C.error.issues.map(z=>`${z.path.join(".")}: ${z.message}`).join(", ");_(c,H(u.name,R,"edit",i,m,{type:"error",message:`Validation error: ${q}`}),422);return}try{let v=await $e(u,i),x=(v&&We(v,u.pathKey))??[i];await u.repo.update(...x,C.data),ke(c,`${m}/${u.name}?flash=updated`);}catch(v){let x=G(u.schema,u.mutableFields),$=F(x),R=`${m}/${u.name}/${encodeURIComponent(i)}/edit`,q=U($,R,"POST","Save changes"),z=K(v)?Re(u,i,v):{type:"error",message:`Save error: ${v.message}`},j=K(v)?424:500;_(c,H(u.name,q,"edit",i,m,z),j);}},handleDelete:async(l,c)=>{let f=l.params.repoName,i=l.params.id;if(!f||!i){_(c,"Bad request",400);return}let u=e[f];if(!u){_(c,"Repository not found",404);return}if(!u.allowDelete){_(c,"Delete is not allowed for this repository",403);return}let m=J(l,t);try{let g=await $e(u,i),y=(g&&We(g,u.pathKey))??[i];await u.repo.delete(...y),ke(c,`${m}/${u.name}?flash=deleted`);}catch(g){let y=K(g)?Re(u,i,g):{type:"error",message:`Delete error: ${g.message}`},h=K(g)?424:500;_(c,ge("",{title:`Delete ${u.name} / ${i}`,basePath:m,breadcrumb:[{label:"Repositories",href:m},{label:u.name,href:`${m}/${u.name}`},{label:`Delete ${i}`}],flash:y}),h);}}}}function jt(e){let t=[],a=e.replace(/[.*+?^${}()|[\]\\]/g,n=>n===":"?n:`\\${n}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(n,r)=>(t.push(r),"([^/]+)"));return {pattern:new RegExp(`^${a}$`),paramNames:t}}function Pt(e){let t=e.path??e.url??"/",a=t.indexOf("?");return a===-1?t:t.slice(0,a)}var ae=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,a)=>{a.status(404).send("Not Found");};this.errorHandler=(t,a,n)=>{console.error("[MiniRouter]",t),n.status(500).send("Internal Server Error");};}use(t){return this.middlewares.push(t),this}get(t,a){return this.addRoute("GET",t,a)}post(t,a){return this.addRoute("POST",t,a)}put(t,a){return this.addRoute("PUT",t,a)}patch(t,a){return this.addRoute("PATCH",t,a)}delete(t,a){return this.addRoute("DELETE",t,a)}onNotFound(t){return this.notFoundHandler=t,this}onError(t){return this.errorHandler=t,this}addRoute(t,a,n){let{pattern:r,paramNames:o}=jt(a);return this.routes.push({method:t.toUpperCase(),pattern:r,paramNames:o,handler:n}),this}async handle(t,a){let n=(t.method??"GET").toUpperCase(),r=Pt(t),o=null,s={};for(let l of this.routes){if(l.method!==n)continue;let c=r.match(l.pattern);if(c){o=l,s={},l.paramNames.forEach((f,i)=>{s[f]=decodeURIComponent(c[i+1]??"");});break}}let p=Object.assign(t,{params:s}),d=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(p,a,d);}catch(l){this.errorHandler(l,t,a);}}async runMiddlewareChain(t,a,n){let r=0,o=async()=>{if(r<this.middlewares.length){let s=this.middlewares[r++];await s(t,a,o);}else await n(t,a);};await o();}};async function Mt(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Bt(e){let t={};if(!e)return t;for(let a of e.split("&")){let n=a.indexOf("=");if(n===-1)continue;let r=decodeURIComponent(a.slice(0,n).replace(/\+/g," ")),o=decodeURIComponent(a.slice(n+1).replace(/\+/g," ")),s=t[r];s===void 0?t[r]=o:Array.isArray(s)?s.push(o):t[r]=[s,o];}return t}function Fn(e){let{basePath:t="/",repos:a,parseBody:n=true,auth:r,middleware:o=[],httpsOptions:s}=e,p=t==="/"?"":t.replace(/\/$/,""),d={};for(let[i,u]of Object.entries(a)){let m=u.schema??u.repo.schema??null;if(!m)throw new Error(`[createAdminServer] Repository "${i}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let g,y,h;if(u.fieldsConfig){let v=u.fieldsConfig;g=[],y=[],h=[];for(let[x,$]of Object.entries(v))for(let R of $)R==="filterable"?g.push(x):R==="mutable"?y.push(x):R==="create"&&h.push(x);g.length===0&&(g=void 0),y.length===0&&(y=void 0),h.length===0&&(h=void 0);}let k=(()=>{let v=u.repo._parentKeys;return v&&v.length>0?v:void 0})();if(k&&h)for(let v of k)h.includes(v)||h.push(v);let C={name:i,path:u.path,repo:u.repo,schema:m,documentKey:u.documentKey??"docId",pathKey:u.repo._pathKey??void 0,isGroup:!!u.repo._isGroup,parentKeys:k,createdKey:u.repo._createdKey??void 0,listColumns:u.listColumns,pageSize:u.pageSize,filterableFields:g,mutableFields:y,createFields:h,allowDelete:u.allowDelete??false,relationalMeta:(()=>{if(!u.relationalFields||u.relationalFields.length===0)return;let v=u.repo.relationalKeys??{},x=[];for(let $ of u.relationalFields){let R=v[$.key];R&&x.push({key:$.key,column:$.column,targetRepo:String(R.repo),targetKey:String(R.key),type:R.type});}return x.length>0?x:void 0})()};d[i]=C;}let l=nt(d,p),c=new ae;if(n&&c.use(async(i,u,m)=>{let g=i,y=String(g.headers?.["content-type"]??"");if(y.includes("application/x-www-form-urlencoded")){let h=await Mt(g);i.body=Bt(h);}else if(y.includes("application/json")&&typeof g.body=="string")try{i.body=JSON.parse(g.body);}catch{}await m();}),r)if(typeof r=="function")c.use(r);else {let i=r.realm??"Admin",u="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");c.use((m,g,y)=>{if((m.headers?.authorization??"")!==u){g.status(401).set("WWW-Authenticate",`Basic realm="${i}"`).set("Content-Type","text/plain").send("Unauthorized");return}y();});}for(let i of o)c.use(i);c.get(`${p}/`,l.handleDashboard),c.get(`${p}`,l.handleDashboard),c.get(`${p}/:repoName`,l.handleList),c.get(`${p}/:repoName/create`,l.handleCreateForm),c.post(`${p}/:repoName/create`,l.handleCreateSubmit),c.get(`${p}/:repoName/:id/edit`,l.handleEditForm),c.post(`${p}/:repoName/:id/edit`,l.handleEditSubmit),c.post(`${p}/:repoName/:id/delete`,l.handleDelete);let f=async(i,u)=>{await c.handle(i,u);};return s&&(f.httpsOptions=s),f}
|
|
556
|
-
export{
|
|
1027
|
+
`;function Ce(){return jsx("script",{dangerouslySetInnerHTML:{__html:lt}})}Ne();function Y(e){return "<!DOCTYPE html>"+renderToString(e)}var Kt=["corporate","silk","dark"],Gt=()=>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:Kt.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))})]}),ee=({opts:e,children:t})=>{let{title:n,breadcrumb:r,flash:a,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(Gt,{})})]}),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((o,d)=>o.href?jsx("li",{children:jsx("a",{href:o.href,children:o.label})},d):jsx("li",{class:"text-base-content/60",children:o.label},d))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),a&&jsxs("div",{role:"alert",class:`alert ${a.type==="success"?"alert-success":a.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsx("span",{class:"flex-1",children:a.message}),a.action&&jsx("a",{href:a.action.href,...a.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:a.action.label})]}),t]}),jsx(Ze,{}),jsx(Ce,{})]})]})};function Ie(e,t){return Y(jsx(ee,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function ze(e,t){return Y(jsx(ee,{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 pt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],Wt=[{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"}],Qt=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function Xt(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return Wt;case "ZodBoolean":return pt;case "ZodArray":return Qt;default:return pt}}var te="__null__";function Yt(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="${te}"]');if(!o){o=document.createElement('option');o.value='${te}';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='${te}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${te}"][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!=='${te}')?i.dataset._prev:'';}}})(this)`}function en(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 ve({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:Yt(e)}),jsx("span",{children:"\u2205"})]})}function tn({col:e,active:t}){let n=t?.value??"",r=n===te,a=`fv_input_${e.name.replace(/\./g,"__")}`,s=t?.op,o=s==="in"||s==="not-in";if(e.enumValues&&e.enumValues.length>0){if(o){let d=new Set(n.split(",").map(p=>p.trim()).filter(Boolean)),l=`eg_${e.name.replace(/\./g,"__")}`;return jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsx("input",{type:"hidden",id:a,name:`fv_${e.name}`,value:n}),e.enumValues.map(p=>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:p,checked:d.has(p),"data-enum-group":l,onchange:en(a,l)}),jsx("span",{children:p})]},p))]})}return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:a,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(d=>jsx("option",{value:d,selected:n===d,children:d},d)),e.nullable&&jsx("option",{value:te,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(ve,{inputId:a,active:r})]})}if(e.zodType==="ZodBoolean")return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:a,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:te,"data-_auto":"1",selected:r,children:"\u2205 null"})]}),e.nullable&&jsx(ve,{inputId:a,active:r})]});if(e.zodType==="ZodArray"){let d=t?.op==="array-contains-any";return jsx("input",{id:a,type:"text",name:`fv_${e.name}`,value:n,placeholder:d?"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:a,type:r?"text":"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0,"data-_type":r?"number":void 0}),e.nullable&&jsx(ve,{inputId:a,active:r})]}):e.zodType==="ZodDate"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:a,type:r?"text":"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0,"data-_type":r?"datetime-local":void 0}),e.nullable&&jsx(ve,{inputId:a,active:r})]}):jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:a,type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:r,style:r?"opacity:0.55":void 0}),e.nullable&&jsx(ve,{inputId:a,active:r})]})}function Pe({action:e,columnMeta:t,activeFilters:n,isGroup:r}){let a=Object.fromEntries(n.map(l=>[l.field,l])),s=n.length>0,o=n.length>=2||r&&s,d=t.filter(l=>l.zodType!=="ZodObject"&&l.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:d.map(l=>{let p=Xt(l.zodType),m=a[l.name],E=m?.op??p[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:l.name}),jsxs("div",{class:"flex gap-1.5",children:[p.length>1?jsx("select",{name:`fo_${l.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:p.map(h=>jsx("option",{value:h.value,selected:h.value===E,children:h.label},h.value))}):jsx("input",{type:"hidden",name:`fo_${l.name}`,value:p[0].value}),jsx(tn,{col:l,active:m})]})]},l.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"}),o&&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 De(e,t,n,r,a,s){let o=n==="create"?`Create ${e}`:`Edit ${e} / ${r??""}`,d=n==="create"?[{label:"Repositories",href:a},{label:e,href:`${a}/${e}`},{label:"New document"}]:[{label:"Repositories",href:a},{label:e,href:`${a}/${e}`},{label:`Edit ${r??""}`}];return Y(jsx(ee,{opts:{title:o,breadcrumb:d,basePath:a,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}})})})}))}Ae();Oe();function Fe(e,t,n){let r=new URLSearchParams;for(let a of e)r.set(`fv_${a.field}`,a.value),r.set(`fo_${a.field}`,a.op);return t&&(r.set("ob",t.field),r.set("od",t.dir)),n&&r.set("ps",String(n)),r}function ft(e,t,n,r,a){let s=Fe(e,r,a);return s.set("cursor",t),s.set("dir",n),`?${s.toString()}`}function nn(e,t,n,r){let a=Fe(n,void 0,r);return t?.field===e?t.dir==="asc"&&(a.set("ob",e),a.set("od","desc")):(a.set("ob",e),a.set("od","asc")),`?${a.toString()}`}function rn(e,t,n){return `?${Fe(t,n,e).toString()}`}function je(e,t,n,r,a,s,o=[],d=[],l=false,p=[],m,E,h,w,A,F,b){let c=`${r}/${e}`,g=`${c}/create`,i={};if(b)for(let v of n)i[v]=fe(me(b,v));let u=(F??[]).filter(v=>{let $=i[v]??fe(me(b,v));return $==="string"||$==="number"||$==="bigint"||$==="boolean"||$==="enum"||$==="literal"}),f=u.length>0,x=l,k=x||f,T=u.map(v=>{let $=me(b,v),S=fe($),I=o.find(D=>D.name===v);return {name:v,type:S,enumValues:I?.enumValues??null,nullable:I?.nullable??false}});return Y(jsxs(ee,{opts:{title:e,breadcrumb:[{label:"Repositories",href:r},{label:e}],basePath:r,flash:s},children:[o.length>0&&jsx(Pe,{action:c,columnMeta:o,activeFilters:d,isGroup:w}),h&&jsxs("div",{role:"alert",class:`alert ${h.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:h.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:h.type==="index"?"Composite index required":"Query failed"}),jsx("div",{class:"text-sm",children:h.message})]}),h.indexUrl&&jsx("a",{href:h.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",children:[jsxs("div",{class:"flex items-center gap-3",children:[jsxs("span",{class:"text-sm text-base-content/60",children:[t.length,typeof A=="number"&&jsxs(Fragment,{children:[" ","of ",jsx("span",{class:"font-semibold text-base-content/80",children:A})]})," ","document",(typeof A=="number"?A: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(v=>jsx("a",{href:rn(v,d,m),class:`join-item btn btn-xs ${E===v?"btn-active btn-primary":"btn-outline"}`,children:v},v))})]})]}),jsx("a",{href:g,class:"btn btn-primary btn-sm",children:"+ New"})]}),k&&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 A=="number"?String(A):"","data-frs-page-size":String(E??t.length),"data-frs-allow-delete":x?"1":"0","data-frs-allow-update":f?"1":"0","data-frs-fields":JSON.stringify(T),"data-frs-filters":JSON.stringify(d),children:[jsxs("div",{class:"flex-1 text-sm",children:[jsx("span",{"data-frs-bulk-summary":true,children:"0 selected"}),typeof A=="number"&&A>t.length&&jsxs("button",{type:"button",class:"ml-3 link link-primary text-sm hidden","data-frs-bulk-select-all":true,children:["Select all ",A," matching documents"]}),jsxs("span",{class:"hidden ml-3 italic","data-frs-bulk-all-active":true,children:["All ",A??"?"," 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:[f&&jsx("button",{type:"button",class:"btn btn-sm btn-outline","data-frs-bulk-action":"update",children:"Update field\u2026"}),x&&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:[k&&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((v,$)=>{let S=m?.field===v,I=S?m.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:nn(v,m,d,E),class:`hover:text-base-content inline-flex items-center gap-0.5${S?" text-primary font-bold":""}`,children:[v,I]})},$)}),p.map((v,$)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:v.column},`rel-${$}`)),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+p.length+1+(k?1:0),class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((v,$)=>{let S=String(v.docId??v.id??""),I=`${r}/${e}/${encodeURIComponent(S)}/edit`,D=`${r}/${e}/${encodeURIComponent(S)}/delete`;return jsxs("tr",{class:"hover","data-frs-row-id":S,children:[k&&jsx("td",{class:"align-middle py-2",children:jsx("input",{type:"checkbox",class:"checkbox checkbox-xs checkbox-primary","data-frs-select-row":true,value:S,"aria-label":`Select ${S}`})}),n.map((Z,J)=>{let M=v[Z],z=i[Z],G=z?he(z,M):null;return jsx("td",{class:"align-top py-2",children:jsx(pe,{val:M,mismatch:G})},J)}),p.map((Z,J)=>{let M=v[Z.key];if(M==null||M==="")return jsx("td",{class:"py-2"},`rel-${J}`);let z=Z.type==="one"?`${r}/${Z.targetRepo}/${encodeURIComponent(String(M))}/edit`:`${r}/${Z.targetRepo}?fv_${Z.targetKey}=${encodeURIComponent(String(M))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:z,class:"btn btn-xs btn-ghost btn-outline","data-frs-relation":true,"data-frs-rel-type":Z.type,"data-frs-rel-repo":Z.targetRepo,"data-frs-rel-fk":Z.targetKey,"data-frs-rel-val":String(M),"data-frs-rel-label":Z.column,children:Z.column})},`rel-${J}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:I,class:"btn btn-xs btn-outline",children:"Edit"}),l&&jsx("form",{method:"post",action:D,onsubmit:"return confirm('Delete this document?')",children:jsx("button",{type:"submit",class:"btn btn-xs btn-error btn-outline",children:"Delete"})})]})})]},$)})})]})}),(a.hasPrev||a.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:[a.hasPrev?jsx("a",{href:ft(d,a.prevCursor,"prev",m,E),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),a.hasNext?jsx("a",{href:ft(d,a.nextCursor,"next",m,E),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]}),typeof A=="number"&&jsxs("div",{class:"text-xs text-base-content/50",children:[A," total document",A!==1?"s":"",d.length>0?" matching filters":""]})]}),k&&f&&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"}),u.map(v=>jsx("option",{value:v,children:v},v))]})]}),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"})})]})]}))}function Me(e,t){return Ie(e,t)}function mt(e,t){return ze(e,t)}function bt(e,t,n,r,a,s,o,d,l,p,m,E,h,w,A,F,b){return je(e,t,n,r,a,s,o,d,l,p,m,E,h,w,A,F,b)}function oe(e,t,n,r,a,s){return De(e,t,n,r,a,s)}var sn=new Set(["<","<=",">",">=","!="]),on=new Set(["array-contains","array-contains-any"]);function Be(e){return e==="desc"?"DESCENDING":"ASCENDING"}function ln(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function dn(e,t,n,r,a){let s=[],o=new Set;for(let l of r)if(l.op==="=="||l.op==="in"||l.op==="not-in"){if(o.has(l.field))continue;o.add(l.field),s.push({fieldPath:l.field,order:"ASCENDING"});}for(let l of r)if(on.has(l.op)){if(o.has(l.field))continue;o.add(l.field),s.push({fieldPath:l.field,arrayConfig:"CONTAINS"});}for(let l of r)if(sn.has(l.op)){if(o.has(l.field))continue;o.add(l.field);let p=a?.field===l.field?Be(a.dir):"ASCENDING";s.push({fieldPath:l.field,order:p});}if(a&&!o.has(a.field)&&s.push({fieldPath:a.field,order:Be(a.dir)}),s.length===1&&n)return pn(e,t,s[0]);let d=a&&s.some(l=>l.fieldPath===a.field)?Be(a.dir):"ASCENDING";return s.push({fieldPath:"__name__",order:d}),cn(e,t,n,s)}function cn(e,t,n,r,a="(default)"){let s=`projects/${e}/databases/${a}/collectionGroups/${t}/indexes/_`,o=[...qe(1,s),...Te(2,n?2:1)];for(let p of r)o.push(...yt(3,gt(p)));let d=a==="(default)"?"-default-":a,l=encodeURIComponent(ht(o));return `https://console.firebase.google.com/project/${e}/firestore/databases/${d}/indexes?create_composite=${l}`}function un(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function Le(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function Ue(e,t){return e<<3|t}function qe(e,t){let n=Array.from(new TextEncoder().encode(t));return [Ue(e,2),...Le(n.length),...n]}function Te(e,t){return [Ue(e,0),...Le(t)]}function yt(e,t){return [Ue(e,2),...Le(t.length),...t]}function gt(e){let t=[...qe(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...Te(3,1)):t.push(...Te(2,e.order==="DESCENDING"?2:1)),t}function ht(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 pn(e,t,n,r="(default)"){let a=`projects/${e}/databases/${r}/collectionGroups/${t}/fields/${n.fieldPath}`,s=[...qe(1,a),...Te(2,2),...yt(3,gt(n))],o=r==="(default)"?"-default-":r,d=encodeURIComponent(ht(s));return `https://console.firebase.google.com/project/${e}/firestore/databases/${o}/indexes/automatic?create_exemption=${d}`}function fn(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 a of n)if(typeof a=="string"&&a.length>0)return a;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function ie(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function He(e,t){let n=e??{},r=ie(e),a;if(r&&(a=n.message?un(n.message):void 0,!a)){let s=fn(t.ref);if(s){let o=ln(t.path);a=dn(s,o,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:a}}var vt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function bn(){let e="";for(let t=0;t<20;t++)e+=vt.charAt(Math.floor(Math.random()*vt.length));return e}function Ve(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let r=n.split("/").filter(Boolean),a=[];for(let s=1;s<r.length;s+=2)a.push(r[s]);return a.length>0?a:void 0}async function xe(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 Je(e,t,n){let r=e.documentKey??"docId",a=He(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:r,op:"==",value:t}]});return a.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...a.indexUrl?{action:{href:a.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:a.message}}function O(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Ke(e,t){e.status(302).set("Location",t).send("");}function Ge(e,t){let n=t.shape,r={};for(let[a,s]of Object.entries(n)){let o=Qe(s);if(o==="ZodObject"){if(e[a+"__isnull"]==="1"){r[a]=null;continue}let p={},m=false;for(let[w,A]of Object.entries(e))w.startsWith(`${a}.`)&&(p[w.slice(a.length+1)]=A,m=true);if(m){let w=s;for(;;){let A=j(w);if(A==="ZodOptional"||A==="ZodNullable"||A==="ZodDefault")w=q(w);else break}r[a]=Ge(p,w);continue}let E=e[a],h=Array.isArray(E)?E[E.length-1]:E;if(h)try{r[a]=JSON.parse(h);}catch{r[a]=h;}continue}let d=e[a],l=Array.isArray(d)?d[d.length-1]:d;if(e[a+"__isnull"]==="1"){r[a]=null;continue}if(l===void 0||l===""){o==="ZodBoolean"&&(r[a]=false);continue}switch(o){case "ZodBoolean":l==="__null__"?r[a]=null:r[a]=l==="true"||l==="on"||l==="1";break;case "ZodNumber":case "ZodBigInt":r[a]=Number(l);break;case "ZodDate":r[a]=new Date(l);break;case "ZodArray":try{r[a]=JSON.parse(l);}catch{r[a]=l;}break;default:if(l.startsWith("{")||l.startsWith("["))try{r[a]=JSON.parse(l);break}catch{}r[a]=l;}}return r}function xt(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 Qe(e){let t=e;for(;;){let n=j(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=q(t);else return n}}function yn(e){let t=e;for(;;){let n=j(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=q(t);else return t}}function kt(e){let t=e;for(;;){let n=j(t);if(n==="ZodOptional"||n==="ZodNullable")return true;if(n==="ZodDefault"){t=q(t);continue}return false}}function St(e){let t=yn(e),n=j(t);if(n==="ZodEnum"){let r=ye(t);return r.length>0?r:void 0}if(n==="ZodNativeEnum"){let r=ge(t),a=Object.values(r).filter(s=>typeof s=="string");return a.length>0?a:void 0}if(n==="ZodLiteral"){let r=Re(t);return typeof r=="string"?[r]:void 0}}function Rt(e,t,n=""){let r={};for(let a of Object.keys(t.shape)){let s=n?`${n}.${a}`:a,o=e[a];if(o===null){r[s]="__null__";continue}if(o===void 0)continue;let d=t.shape[a];for(;;){let p=j(d);if(p==="ZodOptional"||p==="ZodNullable"||p==="ZodDefault")d=q(d);else break}let l=j(d);if(l==="ZodObject"&&typeof o=="object"&&o!==null&&!Array.isArray(o)){let p=Rt(o,d,s);Object.assign(r,p);}else if(l==="ZodDate"){let p=xt(o);p!==null&&(r[s]=p);}else if(typeof o=="object"&&o!==null&&!Array.isArray(o)&&("_seconds"in o||typeof o.toDate=="function")){let p=xt(o);r[s]=p??JSON.stringify(o,null,2);}else typeof o=="object"?r[s]=JSON.stringify(o,null,2):r[s]=String(o);}return r}function We(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?We(n.nested,t):void 0}))}function gn(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),r=[];for(let[a,s]of Object.entries(e)){if(!a.startsWith("fv_"))continue;let o=a.slice(3);if(!t.has(o))continue;let d=(s??"").trim();if(!d)continue;let l=e[`fo_${o}`]??"==",p=n.has(l)?l:"==";r.push({field:o,op:p,value:d});}return r}function wt(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 a=r.value.split(",").map(s=>s.trim()).filter(s=>s!==""&&s!==t).map(s=>n(s));return [r.field,r.op,a]}return [r.field,r.op,n(r.value)]})}function $t(e,t,n=""){let r=[];for(let a of e){let s=n?`${n}.${a}`:a,o=t.shape[a];if(!o){r.push({name:s,zodType:"ZodString"});continue}let d=Qe(o);if(d==="ZodObject"){let l=o;for(;;){let m=j(l);if(m==="ZodOptional"||m==="ZodNullable"||m==="ZodDefault")l=q(l);else break}let p=Q(l);r.push(...$t(Object.keys(p),l,s));}else r.push({name:s,zodType:d,nullable:kt(o),enumValues:St(o)});}return r}function hn(e,t){let n=t.split("."),r=e;for(let a of n){for(;;){let o=j(r);if(o==="ZodOptional"||o==="ZodNullable"||o==="ZodDefault")r=q(r);else break}let s=Q(r);if(!(a in s))return null;r=s[a];}return r}function le(e,t){if(!t||t.length===0)return e;let n=[],r=new Map;for(let s of t){let o=s.indexOf(".");if(o===-1)n.push(s);else {let d=s.slice(0,o),l=s.slice(o+1);r.has(d)||r.set(d,[]),r.get(d).push(l);}}let a={};for(let s of n)s in e.shape&&(a[s]=e.shape[s]);for(let[s,o]of r){if(!(s in e.shape))continue;let d=e.shape[s];for(;;){let l=j(d);if(l==="ZodOptional"||l==="ZodNullable"||l==="ZodDefault")d=q(d);else break}if(j(d)!=="ZodObject"){a[s]=e.shape[s];continue}a[s]=le(d,o);}return z.object(a)}function ne(e,t){let n=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let s=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",o=process.env.FUNCTION_REGION??"us-central1",d=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${s}/${o}/${d}${n}`}let r=process.env.K_SERVICE,a=e.hostname??e.headers?.host??"";return r&&a.includes("cloudfunctions.net")?`/${r.toLowerCase()}${n}`:n}function At(e,t){let n=(b,c)=>{let g=ne(b,t),i=Object.values(e).map(u=>({name:u.name,path:u.path}));O(c,mt(i,g));},r=async(b,c)=>{let g=b.params.repoName;if(!g){O(c,"Bad request",400);return}let i=e[g];if(!i){O(c,"Repository not found",404);return}let u=i.pageSize??25,f=b.query??{},x=f.cursor,k=f.dir==="prev"?"prev":"next",T=f.ob??"",v=f.od==="desc"?"desc":"asc",$=T?{field:T,dir:v}:void 0,S=parseInt(f.ps??""),I=Number.isFinite(S)&&S>0?Math.min(S,200):u,D=i.listColumns??Object.keys(i.schema.shape),Z=i.documentKey??"docId",J=[Z,...D.filter(U=>U!==Z)],M=i.filterableFields?(()=>{let U=[];for(let W of i.filterableFields)(W.includes(".")||D.includes(W))&&U.push(W);return U})():D,z=(()=>{let U=[];for(let W of M)if(W.includes(".")){let ce=hn(i.schema,W);U.push({name:W,zodType:ce?Qe(ce):"ZodString",nullable:ce?kt(ce):false,enumValues:ce?St(ce):void 0});}else U.push(...$t([W],i.schema));return U})(),G=new Set(z.map(U=>U.name)),be=gn(f,G),ke=wt(be),Xe;if(x)try{let U=i.repo.ref;typeof U.doc=="function"&&(Xe=await U.doc(x).get());}catch{}let[re,Ct]=await Promise.all([i.repo.query.paginate({pageSize:I,cursor:Xe,direction:k,...ke.length>0?{where:ke}:{},...$?{orderBy:[{field:$.field,direction:$.dir}]}:{}}).catch(U=>({queryError:He(U,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:be,sort:$})})),i.repo.aggregate.count(ke.length>0?{where:ke}:{}).catch(()=>{})]),de="queryError"in re,Et=de?[]:re.data,Tt=de?"":re.nextCursor?.id??"",_t=de?"":re.prevCursor?.id??"",Ot=de?re.queryError:void 0,Zt=ne(b,t);O(c,bt(i.name,Et,J,Zt,{hasPrev:de?false:re.hasPrevPage,hasNext:de?false:re.hasNextPage,prevCursor:_t,nextCursor:Tt},void 0,z,be,i.allowDelete??false,i.relationalMeta,$,I,Ot,i.isGroup,Ct,i.mutableFields,i.schema));},a=(b,c)=>{let g=b.params.repoName;if(!g){O(c,"Bad request",400);return}let i=e[g];if(!i){O(c,"Repository not found",404);return}let u=ne(b,t),f=le(i.schema,i.createFields),x=X(f),k=`${u}/${i.name}/create`,T=ae(x,k,"POST","Create document");O(c,oe(i.name,T,"create",null,u));},s=async(b,c)=>{let g=b.params.repoName;if(!g){O(c,"Bad request",400);return}let i=e[g];if(!i){O(c,"Repository not found",404);return}let u=ne(b,t),f=b.body??{},x=Ge(f,i.schema),k=le(i.schema,i.createFields),T=k.safeParse(x);if(!T.success){let v=X(k),$=`${u}/${i.name}/create`,S=ae(v,$,"POST","Create document"),I=T.error.issues.map(D=>`${D.path.join(".")}: ${D.message}`).join(", ");O(c,oe(i.name,S,"create",null,u,{type:"error",message:`Validation error: ${I}`}),422);return}try{if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let v={...T.data};i.createdKey&&(v[i.createdKey]=new Date);let $=i.parentKeys.filter(Z=>!v[Z]);if($.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${$.join(", ")}`);let S=i.parentKeys.map(Z=>v[Z]),I=i.documentKey??"docId",D=v[I]||bn();await i.repo.set(...S,D,v);}else await i.repo.create(T.data);Ke(c,`${u}/${i.name}?flash=created`);}catch(v){let $=le(i.schema,i.createFields),S=X($),I=`${u}/${i.name}/create`,D=ae(S,I,"POST","Create document");O(c,oe(i.name,D,"create",null,u,{type:"error",message:`Save error: ${v.message}`}),500);}},o=async(b,c)=>{let g=b.params.repoName,i=b.params.id;if(!g||!i){O(c,"Bad request",400);return}let u=e[g];if(!u){O(c,"Repository not found",404);return}let f=ne(b,t),x=null;try{x=await xe(u,i);}catch(I){let D=Je(u,i,I),Z=ie(I)?424:500;O(c,Me("",{title:`Edit ${u.name} / ${i}`,basePath:f,breadcrumb:[{label:"Repositories",href:f},{label:u.name,href:`${f}/${u.name}`},{label:`Edit ${i}`}],flash:D}),Z);return}if(!x){O(c,"Document not found",404);return}let k=Rt(x,u.schema),T=le(u.schema,u.mutableFields),v=We(X(T),k),$=`${f}/${u.name}/${encodeURIComponent(i)}/edit`,S=ae(v,$,"POST","Save changes");O(c,oe(u.name,S,"edit",i,f));},d=async(b,c)=>{let g=b.params.repoName,i=b.params.id;if(!g||!i){O(c,"Bad request",400);return}let u=e[g];if(!u){O(c,"Repository not found",404);return}let f=ne(b,t),x=b.body??{},k=Ge(x,u.schema),T=le(u.schema,u.mutableFields),$=T.partial().safeParse(k);if(!$.success){let S=Object.fromEntries(Object.entries(x).map(([M,z])=>[M,Array.isArray(z)?z.join(","):z??""])),I=We(X(T),S),D=`${f}/${u.name}/${encodeURIComponent(i)}/edit`,Z=ae(I,D,"POST","Save changes"),J=$.error.issues.map(M=>`${M.path.join(".")}: ${M.message}`).join(", ");O(c,oe(u.name,Z,"edit",i,f,{type:"error",message:`Validation error: ${J}`}),422);return}try{let S=await xe(u,i),I=(S&&Ve(S,u.pathKey))??[i];await u.repo.update(...I,$.data),Ke(c,`${f}/${u.name}?flash=updated`);}catch(S){let I=le(u.schema,u.mutableFields),D=X(I),Z=`${f}/${u.name}/${encodeURIComponent(i)}/edit`,J=ae(D,Z,"POST","Save changes"),M=ie(S)?Je(u,i,S):{type:"error",message:`Save error: ${S.message}`},z=ie(S)?424:500;O(c,oe(u.name,J,"edit",i,f,M),z);}},l=async(b,c)=>{let g=b.params.repoName,i=b.params.id;if(!g||!i){O(c,"Bad request",400);return}let u=e[g];if(!u){O(c,"Repository not found",404);return}if(!u.allowDelete){O(c,"Delete is not allowed for this repository",403);return}let f=ne(b,t);try{let x=await xe(u,i),k=(x&&Ve(x,u.pathKey))??[i];await u.repo.delete(...k),Ke(c,`${f}/${u.name}?flash=deleted`);}catch(x){let k=ie(x)?Je(u,i,x):{type:"error",message:`Delete error: ${x.message}`},T=ie(x)?424:500;O(c,Me("",{title:`Delete ${u.name} / ${i}`,basePath:f,breadcrumb:[{label:"Repositories",href:f},{label:u.name,href:`${f}/${u.name}`},{label:`Delete ${i}`}],flash:k}),T);}},p=async(b,c)=>{let g=b.params.repoName;if(!g){O(c,"Bad request",400);return}let i=e[g];if(!i){O(c,"Repository not found",404);return}let u=ne(b,t),f=b.query,x=f?.type==="many"?"many":"one",k=Math.max(1,Math.min(100,Number(f?.ps??25)||25)),T=i.listColumns??Object.keys(Q(i.schema)),{PanelOne:v,PanelMany:$}=await Promise.resolve().then(()=>(Ne(),ct)),{renderToString:S}=await import('hono/jsx/dom/server');if(x==="one"){let z=String(f?.id??"");if(!z){O(c,"<div class='p-6 text-error'>Missing id parameter.</div>",400);return}try{let G=await xe(i,z),be=S(v({doc:G,repoName:i.name,basePath:u,schema:i.schema,columns:T}));O(c,be);}catch(G){O(c,`<div class='p-6 text-error text-sm'>Error: ${G.message}</div>`,500);}return}let I=String(f?.fk??""),D=String(f?.fv??"");if(!I||!D){O(c,"<div class='p-6 text-error'>Missing fk/fv parameters.</div>",400);return}let Z=f?.cursor??"",J=f?.dir==="prev"?"prev":"next",M;if(Z)try{let z=i.repo.ref;typeof z.doc=="function"&&(M=await z.doc(Z).get());}catch{}try{let z=await i.repo.query.paginate({pageSize:k,cursor:M,direction:J,where:[[I,"==",vn(D)]]}),G=S($({docs:z.data,repoName:i.name,basePath:u,fk:I,fv:D,columns:T,schema:i.schema,pagination:{hasPrev:z.hasPrevPage,hasNext:z.hasNextPage,prevCursor:z.prevCursor?.id??"",nextCursor:z.nextCursor?.id??"",pageSize:k}}));O(c,G);}catch(z){O(c,`<div class='p-6 text-error text-sm'>Error: ${z.message}</div>`,500);}},m=async(b,c)=>{let g=[];for(let i of c){let u;if(b.isGroup||b.parentKeys?.length){let f=await xe(b,i);u=f?Ve(f,b.pathKey):void 0;}u||(u=[i]);try{let f=b.repo.documentRef(...u);f&&g.push(f);}catch{}}return g},E=async(b,c)=>{let g=wt(c),i=b.documentKey??"docId",u=[],f;for(;;){let x=await b.repo.query.paginate({pageSize:500,cursor:f,direction:"next",...g.length>0?{where:g}:{}});for(let k of x.data){let T=String(k[i]??k.id??"");T&&u.push(T);}if(!x.hasNextPage||!x.nextCursor)break;f=x.nextCursor;}return u},h=async(b,c)=>{let g=b.params.repoName;if(!g){V(c,{error:"Bad request"},400);return}let i=e[g];if(!i){V(c,{error:"Repository not found"},404);return}if(!i.allowDelete){V(c,{error:"Delete is not allowed for this repository"},403);return}let u=b.body??{};try{let f=await A(i,u);if(f.length===0){V(c,{deleted:0});return}let x=await m(i,f);for(let k=0;k<x.length;k+=500)await i.repo.bulk.delete(x.slice(k,k+500));V(c,{deleted:x.length});}catch(f){V(c,{error:f.message},500);}},w=async(b,c)=>{let g=b.params.repoName;if(!g){V(c,{error:"Bad request"},400);return}let i=e[g];if(!i){V(c,{error:"Repository not found"},404);return}let u=b.body??{},f=String(u.field??"");if(!f){V(c,{error:"Missing 'field'"},400);return}if(!i.mutableFields||!i.mutableFields.includes(f)){V(c,{error:`Field '${f}' is not bulk-updatable`},403);return}let x=i.schema.shape?.[f],k=u.value;if(x){let T=x.safeParse(u.value);if(!T.success){V(c,{error:`Invalid value for '${f}': ${T.error.message}`},400);return}k=T.data;}try{let T=await A(i,u);if(T.length===0){V(c,{updated:0});return}let $=(await m(i,T)).map(S=>({docRef:S,data:{[f]:k}}));for(let S=0;S<$.length;S+=500)await i.repo.bulk.update($.slice(S,S+500));V(c,{updated:$.length});}catch(T){V(c,{error:T.message},500);}};async function A(b,c){if(c.selectAll){let g=F(c.filters,b);return await E(b,g)}return Array.isArray(c.ids)?c.ids.filter(g=>typeof g=="string"&&!!g):[]}function F(b,c){if(!Array.isArray(b))return [];let g=new Set((c.filterableFields??Object.keys(Q(c.schema))).map(f=>String(f))),i=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),u=[];for(let f of b)f&&typeof f=="object"&&typeof f.field=="string"&&g.has(f.field)&&typeof f.value=="string"&&i.has(String(f.op))&&u.push({field:f.field,op:f.op,value:f.value});return u}return {handleDashboard:n,handleList:r,handleCreateForm:a,handleCreateSubmit:s,handleEditForm:o,handleEditSubmit:d,handleDelete:l,handlePanel:p,handleBulkDelete:h,handleBulkUpdate:w}}function V(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function vn(e){return e==="true"?true:e==="false"?false:e!==""&&!isNaN(Number(e))?Number(e):e}function xn(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,r=>r===":"?r:`\\${r}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(r,a)=>(t.push(a),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function wn(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var we=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:a,paramNames:s}=xn(n);return this.routes.push({method:t.toUpperCase(),pattern:a,paramNames:s,handler:r}),this}async handle(t,n){let r=(t.method??"GET").toUpperCase(),a=wn(t),s=null,o={};for(let p of this.routes){if(p.method!==r)continue;let m=a.match(p.pattern);if(m){s=p,o={},p.paramNames.forEach((E,h)=>{o[E]=decodeURIComponent(m[h+1]??"");});break}}let d=Object.assign(t,{params:o}),l=s?s.handler:this.notFoundHandler;try{await this.runMiddlewareChain(d,n,l);}catch(p){this.errorHandler(p,t,n);}}async runMiddlewareChain(t,n,r){let a=0,s=async()=>{if(a<this.middlewares.length){let o=this.middlewares[a++];await o(t,n,s);}else await r(t,n);};await s();}};async function kn(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function Sn(e){let t={};if(!e)return t;for(let n of e.split("&")){let r=n.indexOf("=");if(r===-1)continue;let a=decodeURIComponent(n.slice(0,r).replace(/\+/g," ")),s=decodeURIComponent(n.slice(r+1).replace(/\+/g," ")),o=t[a];o===void 0?t[a]=s:Array.isArray(o)?o.push(s):t[a]=[o,s];}return t}function $r(e){let{basePath:t="/",repos:n,parseBody:r=true,auth:a,middleware:s=[],httpsOptions:o}=e,d=t==="/"?"":t.replace(/\/$/,""),l={};for(let[h,w]of Object.entries(n)){let A=w.schema??w.repo.schema??null;if(!A)throw new Error(`[createAdminServer] Repository "${h}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let F,b,c;if(w.fieldsConfig){let u=w.fieldsConfig;F=[],b=[],c=[];for(let[f,x]of Object.entries(u))for(let k of x)k==="filterable"?F.push(f):k==="mutable"?b.push(f):k==="create"&&c.push(f);F.length===0&&(F=void 0),b.length===0&&(b=void 0),c.length===0&&(c=void 0);}let g=(()=>{let u=w.repo._parentKeys;return u&&u.length>0?u:void 0})();if(g&&c)for(let u of g)c.includes(u)||c.push(u);let i={name:h,path:w.path,repo:w.repo,schema:A,documentKey:w.documentKey??"docId",pathKey:w.repo._pathKey??void 0,isGroup:!!w.repo._isGroup,parentKeys:g,createdKey:w.repo._createdKey??void 0,listColumns:w.listColumns,pageSize:w.pageSize,filterableFields:F,mutableFields:b,createFields:c,allowDelete:w.allowDelete??false,relationalMeta:(()=>{if(!w.relationalFields||w.relationalFields.length===0)return;let u=w.repo.relationalKeys??{},f=[];for(let x of w.relationalFields){let k=u[x.key];k&&f.push({key:x.key,column:x.column,targetRepo:String(k.repo),targetKey:String(k.key),type:k.type});}return f.length>0?f:void 0})()};l[h]=i;}let p=At(l,d),m=new we;if(r&&m.use(async(h,w,A)=>{let F=h,b=String(F.headers?.["content-type"]??"");if(b.includes("application/x-www-form-urlencoded")){let c=await kn(F);h.body=Sn(c);}else if(b.includes("application/json")&&typeof F.body=="string")try{h.body=JSON.parse(F.body);}catch{}await A();}),a)if(typeof a=="function")m.use(a);else {let h=a.realm??"Admin",w="Basic "+Buffer.from(`${a.username}:${a.password}`).toString("base64");m.use((A,F,b)=>{if((A.headers?.authorization??"")!==w){F.status(401).set("WWW-Authenticate",`Basic realm="${h}"`).set("Content-Type","text/plain").send("Unauthorized");return}b();});}for(let h of s)m.use(h);m.get(`${d}/`,p.handleDashboard),m.get(`${d}`,p.handleDashboard),m.get(`${d}/:repoName/_panel`,p.handlePanel),m.post(`${d}/:repoName/_bulk/delete`,p.handleBulkDelete),m.post(`${d}/:repoName/_bulk/update`,p.handleBulkUpdate),m.get(`${d}/:repoName`,p.handleList),m.get(`${d}/:repoName/create`,p.handleCreateForm),m.post(`${d}/:repoName/create`,p.handleCreateSubmit),m.get(`${d}/:repoName/:id/edit`,p.handleEditForm),m.post(`${d}/:repoName/:id/edit`,p.handleEditSubmit),m.post(`${d}/:repoName/:id/delete`,p.handleDelete);let E=async(h,w)=>{await m.handle(h,w);};return o&&(E.httpsOptions=o),E}
|
|
1028
|
+
export{we as MiniRouter,$r as createAdminServer};//# sourceMappingURL=index.js.map
|
|
557
1029
|
//# sourceMappingURL=index.js.map
|