@lpdjs/firestore-repo-service 2.1.11 → 2.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-B3vqoqmx.d.ts → index-BJQXYHTC.d.ts} +4 -0
- package/dist/{index-C4RgCxza.d.cts → index-BjH87AI4.d.cts} +4 -0
- package/dist/index.cjs +51 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +51 -51
- package/dist/index.js.map +1 -1
- package/dist/servers/admin/index.cjs +42 -42
- 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 +42 -42
- package/dist/servers/admin/index.js.map +1 -1
- package/dist/servers/crud/index.cjs +2 -2
- package/dist/servers/crud/index.cjs.map +1 -1
- package/dist/servers/crud/index.js +2 -2
- package/dist/servers/crud/index.js.map +1 -1
- package/dist/servers/index.cjs +60 -60
- package/dist/servers/index.cjs.map +1 -1
- package/dist/servers/index.d.cts +2 -2
- package/dist/servers/index.d.ts +2 -2
- package/dist/servers/index.js +60 -60
- package/dist/servers/index.js.map +1 -1
- package/package.json +1 -1
package/dist/servers/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PageOptions, C as ColumnMeta, F as FilterState, R as RelationalFieldMeta, S as SortState, Q as QueryError } from '../index-
|
|
2
|
-
export { A as AdminRepoConfig, a as AdminRepoEntry, b as AdminServerOptions, B as BasicAuthConfig, d as Middleware, M as MiniRouter, e as RepoRegistry, f as RouteHandler, c as createAdminServer } from '../index-
|
|
1
|
+
import { P as PageOptions, C as ColumnMeta, F as FilterState, R as RelationalFieldMeta, S as SortState, Q as QueryError } from '../index-BjH87AI4.cjs';
|
|
2
|
+
export { A as AdminRepoConfig, a as AdminRepoEntry, b as AdminServerOptions, B as BasicAuthConfig, d as Middleware, M as MiniRouter, e as RepoRegistry, f as RouteHandler, c as createAdminServer } from '../index-BjH87AI4.cjs';
|
|
3
3
|
export { createCrudServer } from './crud/index.cjs';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
export { A as ApiResponse, l as CrudRepoConfig, r as CrudRepoEntry, s as CrudRepoRegistry, m as CrudServerOptions, n as FieldRole, L as ListResponseData, o as QueryRequestBody, p as RepoFieldPath, q as RepoRelationKeys, U as UserFieldPath } from '../types-CYVwoOQx.cjs';
|
package/dist/servers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PageOptions, C as ColumnMeta, F as FilterState, R as RelationalFieldMeta, S as SortState, Q as QueryError } from '../index-
|
|
2
|
-
export { A as AdminRepoConfig, a as AdminRepoEntry, b as AdminServerOptions, B as BasicAuthConfig, d as Middleware, M as MiniRouter, e as RepoRegistry, f as RouteHandler, c as createAdminServer } from '../index-
|
|
1
|
+
import { P as PageOptions, C as ColumnMeta, F as FilterState, R as RelationalFieldMeta, S as SortState, Q as QueryError } from '../index-BJQXYHTC.js';
|
|
2
|
+
export { A as AdminRepoConfig, a as AdminRepoEntry, b as AdminServerOptions, B as BasicAuthConfig, d as Middleware, M as MiniRouter, e as RepoRegistry, f as RouteHandler, c as createAdminServer } from '../index-BJQXYHTC.js';
|
|
3
3
|
export { createCrudServer } from './crud/index.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
export { A as ApiResponse, l as CrudRepoConfig, r as CrudRepoEntry, s as CrudRepoRegistry, m as CrudServerOptions, n as FieldRole, L as ListResponseData, o as QueryRequestBody, p as RepoFieldPath, q as RepoRelationKeys, U as UserFieldPath } from '../types-CYVwoOQx.js';
|
package/dist/servers/index.js
CHANGED
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
import {z
|
|
2
|
-
<input type="hidden" id="${
|
|
1
|
+
import {z}from'zod';import {jsx,jsxs,Fragment}from'hono/jsx/jsx-runtime';import {renderToString}from'hono/jsx/dom/server';import {Timestamp}from'firebase-admin/firestore';var 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 Z(e){let t=e,r=t._zod?.def?.type;if(r)return Zt[r]??`Zod${r.charAt(0).toUpperCase()}${r.slice(1)}`;let n=t._def?.typeName;return n||""}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 Xe(e){let t=e;if(t._zod?.def?.element)return t._zod.def.element;if(t._def?.type)return t._def.type}function Ye(e){let t=e;if(t._zod?.def?.defaultValue!==void 0)return t._zod.def.defaultValue;let r=t._def?.defaultValue;return typeof r=="function"?r():r}function pe(e){let t=e;return t.shape&&typeof t.shape=="object"?t.shape:t._zod?.def?.shape&&typeof t._zod.def.shape=="object"?t._zod.def.shape:t._def?.shape?typeof t._def.shape=="function"?t._def.shape():t._def.shape:{}}function fe(e){let t=e;return Array.isArray(t.options)?t.options:t._zod?.def?.entries?Object.values(t._zod.def.entries):Array.isArray(t._def?.values)?t._def.values:[]}function me(e){let t=e;return t._zod?.def?.entries?t._zod.def.entries:t.enum&&typeof t.enum=="object"?t.enum:t._def?.values&&typeof t._def.values=="object"?t._def.values:{}}function we(e){let t=e;return Array.isArray(t._zod?.def?.values)?t._zod.def.values[0]:t._def?.value}function et(e){let t=e,r=[],n=t._zod?.def?.checks;if(Array.isArray(n)){for(let s of n)s.format&&r.push(s.format);if(r.length>0)return r}let o=t._def?.checks;if(Array.isArray(o))for(let s of o)s.kind&&r.push(s.kind);return r}function jt(e){return e.replace(/([A-Z])/g," $1").replace(/_/g," ").replace(/^\s/,"").replace(/^./,t=>t.toUpperCase())}function tt(e){let t=e,r=true,n=false,o;for(;;){let s=Z(t);if(s==="ZodOptional")r=false,t=q(t);else if(s==="ZodNullable")r=false,n=true,t=q(t);else if(s==="ZodDefault")r=false,o=Ye(t),t=q(t);else break}return {inner:t,required:r,nullable:n,defaultValue:o}}function H(e,t=""){if(Z(e)==="ZodObject"){let n=pe(e);return Object.entries(n).map(([o,s])=>nt(t?`${t}.${o}`:o,o,s))}return [nt(t||"value",t||"value",e)]}function nt(e,t,r){let{inner:n,required:o,nullable:s,defaultValue:a}=tt(r),f=Z(n),d=jt(t.split(".").pop()??t);switch(f){case "ZodString":{let c=et(n),p=c.includes("email"),w=c.includes("url");return {name:e,label:d,type:"text",required:o,nullable:s,defaultValue:a,hint:p?"email":w?"url":void 0}}case "ZodNumber":case "ZodBigInt":return {name:e,label:d,type:"number",required:o,nullable:s,defaultValue:a};case "ZodBoolean":return {name:e,label:d,type:"checkbox",required:o,nullable:s,defaultValue:a};case "ZodDate":case "ZodCoerce":return {name:e,label:d,type:"datetime-local",required:o,nullable:s,defaultValue:a};case "ZodEnum":{let c=fe(n);return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:c}}case "ZodNativeEnum":{let c=me(n),p=Object.values(c).filter(w=>typeof w=="string");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:p}}case "ZodLiteral":{let c=String(we(n)??"");return {name:e,label:d,type:"select",required:o,nullable:s,defaultValue:a,options:[c]}}case "ZodObject":{let c=H(n,e);return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,nested:c,hint:"JSON object"}}case "ZodArray":{let c=Xe(n);if(!c)return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"};let{inner:p}=tt(c),w=Z(p),i,l,g;switch(w){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",l=fe(p);break;case "ZodNativeEnum":i="select",l=Object.values(me(p)).filter(b=>typeof b=="string");break;case "ZodObject":i="object",g=H(p);break;default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON array"}}return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,arrayElementType:i,arrayElementOptions:l,arrayElementFields:g}}default:return {name:e,label:d,type:"textarea",required:o,nullable:s,defaultValue:a,hint:"JSON"}}}function ke(e,t=0){let r=t>0?`ml-${t*4}`:"",n=`field_${e.name.replace(/\./g,"__")}`,o=e.name,s=e.required?" required":"",a=e.defaultValue==="__null__",f=!a&&e.defaultValue!=null?String(e.defaultValue):"",d=e.nullable&&e.type!=="checkbox"?`<span class="flex items-center gap-1 shrink-0">
|
|
2
|
+
<input type="hidden" id="${n}__isnull" name="${o}__isnull" value="${a?"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
4
|
<input type="checkbox" class="checkbox checkbox-xs" ${a?"checked":""}
|
|
5
5
|
onchange="(function(cb){
|
|
6
|
-
var inp = document.getElementById('${
|
|
7
|
-
var h = document.getElementById('${
|
|
6
|
+
var inp = document.getElementById('${n}');
|
|
7
|
+
var h = document.getElementById('${n}__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>`:"",c;switch(e.type){case "checkbox":if(e.nullable){let p=a?"__null__":f==="true"?"true":f==="false"?"false":"__null__";return `
|
|
14
|
+
<div class="form-control mb-3 ${r}">
|
|
15
|
+
<label for="${n}" class="label pb-1">
|
|
16
16
|
<span class="label-text font-medium">
|
|
17
17
|
${$(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="${
|
|
21
|
+
<select id="${n}" name="${o}" class="select select-bordered select-sm w-full">
|
|
22
22
|
<option value="__null__"${p==="__null__"?" selected":""}>\u2014 null \u2014</option>
|
|
23
23
|
<option value="true"${p==="true"?" selected":""}>\u2713 true</option>
|
|
24
24
|
<option value="false"${p==="false"?" selected":""}>\u2717 false</option>
|
|
25
25
|
</select>
|
|
26
26
|
</div>`}return `
|
|
27
|
-
<div class="form-control ${
|
|
27
|
+
<div class="form-control ${r}">
|
|
28
28
|
<label class="label cursor-pointer justify-start gap-3">
|
|
29
|
-
<input type="checkbox" id="${
|
|
29
|
+
<input type="checkbox" id="${n}" name="${o}" value="true"${f==="true"?" checked":""} class="checkbox checkbox-primary checkbox-sm">
|
|
30
30
|
<span class="label-text font-medium">
|
|
31
31
|
${$(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
32
32
|
</span>
|
|
33
33
|
</label>
|
|
34
|
-
</div>`;case "select":
|
|
34
|
+
</div>`;case "select":c=`<select id="${n}" name="${o}"${s}${a?' 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
36
|
${(e.options??[]).map(p=>`<option value="${$(p)}"${f===p?" selected":""}>${$(p)}</option>`).join(`
|
|
37
37
|
`)}
|
|
38
|
-
</select>`;break;case "textarea":if(e.arrayElementType)return
|
|
38
|
+
</select>`;break;case "textarea":if(e.arrayElementType)return Ft(e,t);if(e.nested&&e.nested.length>0){let p=e.nested.map(w=>ke(w,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 ${r}">
|
|
41
41
|
<legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
|
|
42
42
|
${$(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
43
43
|
</legend>
|
|
44
44
|
${p}
|
|
45
|
-
</fieldset>`}
|
|
45
|
+
</fieldset>`}c=`<textarea id="${n}" name="${o}"${s} rows="3"${a?' 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="${$(e.hint??"JSON")}">${$(f)}</textarea>`;break;default:
|
|
48
|
+
placeholder="${$(e.hint??"JSON")}">${$(f)}</textarea>`;break;default:c=`<input type="${e.type}" id="${n}" name="${o}"${s}${a?' disabled style="opacity:0.35"':""}
|
|
49
49
|
value="${$(f)}"
|
|
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 ${r}">
|
|
52
|
+
<label for="${n}" class="label pb-1">
|
|
53
53
|
<span class="label-text font-medium">
|
|
54
54
|
${$(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
55
55
|
${e.hint?`<span class="text-base-content/40 text-xs ml-1">(${$(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">${c}</div>
|
|
60
|
+
${d}
|
|
61
61
|
</div>
|
|
62
|
-
</div>`}function $(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function
|
|
63
|
-
`):a.map(p=>
|
|
64
|
-
`),
|
|
65
|
-
<input type="hidden" id="${
|
|
62
|
+
</div>`}function $(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Ft(e,t){let r=t>0?`ml-${t*4}`:"",n=`field_${e.name.replace(/\./g,"__")}`,o=e.defaultValue==="__null__",s=e.arrayElementType==="object",a=[];if(e.defaultValue!=null&&e.defaultValue!==""&&e.defaultValue!=="__null__")try{a=JSON.parse(String(e.defaultValue));}catch{}Array.isArray(a)||(a=[]);let f=s?a.map(p=>ot(e,p??{})).join(`
|
|
63
|
+
`):a.map(p=>rt(e,p)).join(`
|
|
64
|
+
`),d=s?ot(e,{}):rt(e,""),c=e.nullable?`<span class="flex items-center gap-1 mt-2">
|
|
65
|
+
<input type="hidden" id="${n}__isnull" name="${$(e.name)}__isnull" value="${o?"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" ${o?"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('${n}__isnull');
|
|
71
|
+
var hidden = document.getElementById('${n}');
|
|
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 ${
|
|
78
|
+
<fieldset class="fieldset border border-base-300 rounded-box p-3 mb-3 ${r}"
|
|
79
79
|
data-frs-array="${$(e.name)}" data-frs-array-type="${$(e.arrayElementType??"text")}">
|
|
80
80
|
<legend class="fieldset-legend text-xs font-semibold text-base-content/60 px-1">
|
|
81
81
|
${$(e.label)}${e.required?' <span class="text-error">*</span>':""}
|
|
82
82
|
</legend>
|
|
83
|
-
<input type="hidden" id="${
|
|
84
|
-
<div data-frs-array-items${
|
|
83
|
+
<input type="hidden" id="${n}" name="${$(e.name)}" value="${$(JSON.stringify(a))}"${o?" disabled":""}>
|
|
84
|
+
<div data-frs-array-items${o?' style="opacity:0.35"':""}>
|
|
85
85
|
${f}
|
|
86
86
|
</div>
|
|
87
|
-
<template data-frs-array-tpl>${
|
|
87
|
+
<template data-frs-array-tpl>${d}</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
|
+
${c}
|
|
90
|
+
</fieldset>`}function rt(e,t){let r=t!=null?String(t):"",n;switch(e.arrayElementType){case "select":n=`<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(o=>`<option value="${$(o)}"${r===o?" selected":""}>${$(o)}</option>`).join("")}
|
|
93
|
+
</select>`;break;case "checkbox":n=`<label class="flex items-center gap-2 flex-1 cursor-pointer">
|
|
94
|
+
<input type="checkbox" data-frs-val class="checkbox checkbox-sm checkbox-primary"${r==="true"?" checked":""}>
|
|
95
95
|
<span class="text-sm">true</span>
|
|
96
|
-
</label>`;break;case "number":
|
|
97
|
-
${
|
|
96
|
+
</label>`;break;case "number":n=`<input type="number" data-frs-val value="${$(r)}" class="input input-bordered input-sm flex-1">`;break;case "datetime-local":n=`<input type="datetime-local" data-frs-val value="${$(r)}" class="input input-bordered input-sm flex-1">`;break;default:n=`<input type="text" data-frs-val value="${$(r)}" class="input input-bordered input-sm flex-1">`;}return `<div class="flex items-center gap-2 mb-2" data-frs-array-item>
|
|
97
|
+
${n}
|
|
98
98
|
<button type="button" class="btn btn-xs btn-ghost text-error" data-frs-array-rm>×</button>
|
|
99
|
-
</div>`}function
|
|
99
|
+
</div>`}function ot(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(o=>{let s=t[o.name],a=s==null?"":typeof s=="object"?JSON.stringify(s):String(s);switch(o.type){case "checkbox":return `<div class="form-control mb-2">
|
|
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="${$(o.name)}" class="checkbox checkbox-sm checkbox-primary"${a==="true"?" checked":""}>
|
|
106
|
+
<span class="label-text text-sm">${$(o.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">${$(o.label)}</span></label>
|
|
110
|
+
<select data-frs-key="${$(o.name)}" class="select select-bordered select-sm w-full">
|
|
111
|
+
${o.required?"":'<option value="">\u2014</option>'}
|
|
112
|
+
${(o.options??[]).map(f=>`<option value="${$(f)}"${a===f?" selected":""}>${$(f)}</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">${$(o.label)}</span></label>
|
|
116
|
+
<input type="number" data-frs-key="${$(o.name)}" value="${$(a)}" 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">${$(o.label)}</span></label>
|
|
119
|
+
<input type="datetime-local" data-frs-key="${$(o.name)}" value="${$(a)}" 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">${$(o.label)}</span></label>
|
|
122
|
+
<textarea data-frs-key="${$(o.name)}" rows="2" class="textarea textarea-bordered textarea-sm w-full font-mono text-xs" placeholder="JSON">${$(a)}</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">${$(o.label)}</span></label>
|
|
125
|
+
<input type="text" data-frs-key="${$(o.name)}" value="${$(a)}" class="input input-bordered input-sm w-full">
|
|
126
126
|
</div>`}}).join(`
|
|
127
127
|
`)}
|
|
128
|
-
</div>`}function W(e,t,n
|
|
128
|
+
</div>`}function W(e,t,r,n="Save"){let o=e.map(s=>ke(s)).join(`
|
|
129
129
|
`);return `
|
|
130
|
-
<form action="${$(t)}" method="${
|
|
131
|
-
${
|
|
130
|
+
<form action="${$(t)}" method="${r}" novalidate data-frs-form>
|
|
131
|
+
${o}
|
|
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">${$(n)}</button>
|
|
134
134
|
<button type="button" class="btn btn-ghost btn-sm" onclick="history.back()">Cancel</button>
|
|
135
135
|
</div>
|
|
136
|
-
</form>`}function
|
|
136
|
+
</form>`}function st({val:e}){return jsx("span",{class:"text-sm text-base-content/80 font-mono tabular-nums whitespace-nowrap",children:e.toLocaleString()})}function Oe({val: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(st,{val:e});if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")return jsx(st,{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((r,n)=>jsx("li",{class:"break-all",children:typeof r=="object"?JSON.stringify(r):String(r)},n)),e.length>8&&jsxs("li",{class:"text-base-content/40 italic",children:["+",e.length-8," more\u2026"]})]});if(typeof e=="object"&&e!==null){let r=Object.entries(e);return r.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:[r.slice(0,8).map(([n,o])=>jsxs(Fragment,{children:[jsx("dt",{class:"text-base-content/50 font-semibold whitespace-nowrap",children:n}),jsx("dd",{class:"break-all",children:String(o??"")})]})),r.length>8&&jsxs("dt",{class:"col-span-2 text-base-content/40 italic",children:["+",r.length-8," more\u2026"]})]})}let t=String(e);return jsx("span",{class:"text-sm break-all",children:t})}var at=`// \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
137
|
document.addEventListener("submit", function (e) {
|
|
138
138
|
var form = e.target;
|
|
139
139
|
if (!form.hasAttribute("data-frs-form")) return;
|
|
@@ -552,7 +552,7 @@ function initColumnReorder(table) {
|
|
|
552
552
|
});
|
|
553
553
|
});
|
|
554
554
|
}
|
|
555
|
-
`;function ue(){return jsx("script",{dangerouslySetInnerHTML:{__html:tt}})}function Q(e){return "<!DOCTYPE html>"+renderToString(e)}var X=({opts:e,children:t})=>{let{title:n,breadcrumb:s,flash:r,basePath:o="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[n," \u2014 FRS Admin"]}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/themes.css",rel:"stylesheet",type:"text/css"}),jsx("link",{href:"https://cdn.jsdelivr.net/npm/daisyui@5/daisyui.css",rel:"stylesheet",type:"text/css"}),jsx("script",{src:"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"})]}),jsxs("body",{class:"bg-base-200/50 min-h-screen flex flex-col",children:[jsx("div",{class:"navbar bg-neutral text-neutral-content shadow-sm sticky top-0 z-50 px-6",children:jsx("div",{class:"flex-1",children:jsx("a",{href:o,class:"font-bold text-lg tracking-tight hover:opacity-80 transition-opacity",children:"FRS Admin"})})}),jsxs("main",{class:"px-6 py-8 w-full flex-1",children:[s&&s.length>0&&jsx("div",{class:"text-sm breadcrumbs mb-4",children:jsx("ul",{children:s.map((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:n}),r&&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(ue,{})]})]})};function we(e,t){return Q(jsx(X,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function Se(e,t){return Q(jsx(X,{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 rt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],Pt=[{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"}],_t=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function Dt(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return Pt;case "ZodBoolean":return rt;case "ZodArray":return _t;default:return rt}}function Ft({col:e,active:t}){let n=t?.value??"";if(e.zodType==="ZodBoolean")return jsxs("select",{name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",children:[jsx("option",{value:"",selected:n==="",children:"\u2014"}),jsx("option",{value:"true",selected:n==="true",children:"true"}),jsx("option",{value:"false",selected:n==="false",children:"false"})]});if(e.zodType==="ZodArray"){let s=t?.op==="array-contains-any";return jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:s?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsx("input",{type:"number",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"}):e.zodType==="ZodDate"?jsx("input",{type:"datetime-local",name:`fv_${e.name}`,value:n,class:"input input-sm input-bordered w-full"}):jsx("input",{type:"text",name:`fv_${e.name}`,value:n,placeholder:"value",class:"input input-sm input-bordered w-full"})}function $e({action:e,columnMeta:t,activeFilters:n,isGroup:s}){let r=Object.fromEntries(n.map(c=>[c.field,c])),o=n.length>0,a=n.length>=2||s&&o,f=t.filter(c=>c.zodType!=="ZodObject"&&c.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:[n.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:f.map(c=>{let d=Dt(c.zodType),p=r[c.name],R=p?.op??d[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:c.name}),jsxs("div",{class:"flex gap-1.5",children:[d.length>1?jsx("select",{name:`fo_${c.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:d.map(i=>jsx("option",{value:i.value,selected:i.value===R,children:i.label},i.value))}):jsx("input",{type:"hidden",name:`fo_${c.name}`,value:d[0].value}),jsx(Ft,{col:c,active:p})]})]},c.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"}),a&&jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),s?"Collection group queries require a composite index":"Multiple filters may require a composite index"]})]})]})})]})}function Ce(e,t,n,s,r,o){let a=n==="create"?`Create ${e}`:`Edit ${e} / ${s??""}`,f=n==="create"?[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:"New document"}]:[{label:"Repositories",href:r},{label:e,href:`${r}/${e}`},{label:`Edit ${s??""}`}];return Q(jsx(X,{opts:{title:a,breadcrumb:f,basePath:r,flash:o},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}function Oe(e,t,n){let s=new URLSearchParams;for(let r of e)s.set(`fv_${r.field}`,r.value),s.set(`fo_${r.field}`,r.op);return t&&(s.set("ob",t.field),s.set("od",t.dir)),n&&s.set("ps",String(n)),s}function st(e,t,n,s,r){let o=Oe(e,s,r);return o.set("cursor",t),o.set("dir",n),`?${o.toString()}`}function Nt(e,t,n,s){let r=Oe(n,void 0,s);return t?.field===e?t.dir==="asc"&&(r.set("ob",e),r.set("od","desc")):(r.set("ob",e),r.set("od","asc")),`?${r.toString()}`}function jt(e,t,n){return `?${Oe(t,n,e).toString()}`}function ke(e,t,n,s,r,o,a=[],f=[],c=false,d=[],p,R,i,l){let g=`${s}/${e}`,b=`${g}/create`;return Q(jsxs(X,{opts:{title:e,breadcrumb:[{label:"Repositories",href:s},{label:e}],basePath:s,flash:o},children:[a.length>0&&jsx($e,{action:g,columnMeta:a,activeFilters:f,isGroup:l}),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(u=>jsx("a",{href:jt(u,f,p),class:`join-item btn btn-xs ${R===u?"btn-active btn-primary":"btn-outline"}`,children:u},u))})]})]}),jsx("a",{href:b,class:"btn btn-primary btn-sm",children:"+ New"})]}),jsx("div",{class:"overflow-x-auto rounded-box border border-base-300 bg-base-100","data-frs-table-wrap":true,children:jsxs("table",{class:"table table-sm w-full","data-frs-table":true,"data-frs-repo":e,"data-frs-colcount":n.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[[...n].map((u,y)=>{let h=p?.field===u,m=h?p.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:Nt(u,p,f,R),class:`hover:text-base-content inline-flex items-center gap-0.5${h?" text-primary font-bold":""}`,children:[u,m]})},y)}),d.map((u,y)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:u.column},`rel-${y}`)),jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide text-right",children:"Actions"})]})}),jsx("tbody",{children:t.length===0?jsx("tr",{children:jsx("td",{colspan:n.length+d.length+1,class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((u,y)=>{let h=String(u.docId??u.id??""),m=`${s}/${e}/${encodeURIComponent(h)}/edit`,v=`${s}/${e}/${encodeURIComponent(h)}/delete`;return jsxs("tr",{class:"hover",children:[n.map((x,w)=>jsx("td",{class:"align-top py-2",children:jsx(Re,{val:u[x]})},w)),d.map((x,w)=>{let S=u[x.key];if(S==null||S==="")return jsx("td",{class:"py-2"},`rel-${w}`);let A=`${s}/${x.targetRepo}?fv_${x.targetKey}=${encodeURIComponent(String(S))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:A,class:"btn btn-xs btn-ghost btn-outline",children:x.column})},`rel-${w}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:m,class:"btn btn-xs btn-outline",children:"Edit"}),c&&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"})})]})})]},y)})})]})}),(r.hasPrev||r.hasNext)&&jsxs("div",{class:"flex justify-center items-center mt-6 gap-2",children:[r.hasPrev?jsx("a",{href:st(f,r.prevCursor,"prev",p,R),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),r.hasNext?jsx("a",{href:st(f,r.nextCursor,"next",p,R),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]})]}))}var Zt="";function ye(e,t){return we(e,t)}function Ae(e,t){return Se(e,t)}function Ee(e,t,n,s,r,o,a,f,c,d,p,R,i,l){return ke(e,t,n,s,r,o,a,f,c,d,p,R,i,l)}function Y(e,t,n,s,r,o){return Ce(e,t,n,s,r,o)}var zt=new Set(["<","<=",">",">=","!="]),Bt=new Set(["array-contains","array-contains-any"]);function Te(e){return e==="desc"?"DESCENDING":"ASCENDING"}function qt(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function Mt(e,t,n,s,r){let o=[],a=new Set;for(let c of s)if(c.op==="=="||c.op==="in"||c.op==="not-in"){if(a.has(c.field))continue;a.add(c.field),o.push({fieldPath:c.field,order:"ASCENDING"});}for(let c of s)if(Bt.has(c.op)){if(a.has(c.field))continue;a.add(c.field),o.push({fieldPath:c.field,arrayConfig:"CONTAINS"});}for(let c of s)if(zt.has(c.op)){if(a.has(c.field))continue;a.add(c.field);let d=r?.field===c.field?Te(r.dir):"ASCENDING";o.push({fieldPath:c.field,order:d});}if(r&&!a.has(r.field)&&o.push({fieldPath:r.field,order:Te(r.dir)}),o.length===1&&n)return Lt(e,t,o[0]);let f=r&&o.some(c=>c.fieldPath===r.field)?Te(r.dir):"ASCENDING";return o.push({fieldPath:"__name__",order:f}),Ut(e,t,n,o)}function Ut(e,t,n,s,r="(default)"){let o=`projects/${e}/databases/${r}/collectionGroups/${t}/indexes/_`,a=[..._e(1,o),...ge(2,n?2:1)];for(let d of s)a.push(...ot(3,at(d)));let f=r==="(default)"?"-default-":r,c=encodeURIComponent(it(a));return `https://console.firebase.google.com/project/${e}/firestore/databases/${f}/indexes?create_composite=${c}`}function Kt(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function Ie(e){let t=[],n=e>>>0;for(;n>=128;)t.push(n&127|128),n>>>=7;return t.push(n&127),t}function Pe(e,t){return e<<3|t}function _e(e,t){let n=Array.from(new TextEncoder().encode(t));return [Pe(e,2),...Ie(n.length),...n]}function ge(e,t){return [Pe(e,0),...Ie(t)]}function ot(e,t){return [Pe(e,2),...Ie(t.length),...t]}function at(e){let t=[..._e(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...ge(3,1)):t.push(...ge(2,e.order==="DESCENDING"?2:1)),t}function it(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 Lt(e,t,n,s="(default)"){let r=`projects/${e}/databases/${s}/collectionGroups/${t}/fields/${n.fieldPath}`,o=[..._e(1,r),...ge(2,2),...ot(3,at(n))],a=s==="(default)"?"-default-":s,f=encodeURIComponent(it(o));return `https://console.firebase.google.com/project/${e}/firestore/databases/${a}/indexes/automatic?create_exemption=${f}`}function Ht(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 r of n)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 re(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function pe(e,t){let n=e??{},s=re(e),r;if(s&&(r=n.message?Kt(n.message):void 0,!r)){let o=Ht(t.ref);if(o){let a=qt(t.path);r=Mt(o,a,t.isGroup,t.filters,t.sort);}}return {type:s?"index":"error",message:s?"This query requires a composite index that does not exist yet.":n.message??"Query failed",indexUrl:r}}var lt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Vt(){let e="";for(let t=0;t<20;t++)e+=lt.charAt(Math.floor(Math.random()*lt.length));return e}function ct(e,t){if(!t)return;let n=e[t];if(typeof n!="string"||!n)return;let s=n.split("/").filter(Boolean),r=[];for(let o=1;o<s.length;o+=2)r.push(s[o]);return r.length>0?r:void 0}async function De(e,t){let n=e.documentKey??"docId",s=`by${n.charAt(0).toUpperCase()}${n.slice(1)}`;if(typeof e.repo.get[s]=="function")try{let o=await e.repo.get[s](t);if(o)return o}catch{}return (await e.repo.query.by({where:[[n,"==",t]],limit:1}))[0]??null}function Fe(e,t,n){let s=e.documentKey??"docId",r=pe(n,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:s,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(e,t,n=200){e.status(n).set("Content-Type","text/html; charset=utf-8").send(t);}function Ne(e,t){e.status(302).set("Location",t).send("");}function je(e,t){let n=t.shape,s={};for(let[r,o]of Object.entries(n)){let a=ze(o);if(a==="ZodObject"){if(e[r+"__isnull"]==="1"){s[r]=null;continue}let d={},p=false;for(let[l,g]of Object.entries(e))l.startsWith(`${r}.`)&&(d[l.slice(r.length+1)]=g,p=true);if(p){let l=o;for(;;){let g=z(l);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")l=U(l);else break}s[r]=je(d,l);continue}let R=e[r],i=Array.isArray(R)?R[R.length-1]:R;if(i)try{s[r]=JSON.parse(i);}catch{s[r]=i;}continue}let f=e[r],c=Array.isArray(f)?f[f.length-1]:f;if(e[r+"__isnull"]==="1"){s[r]=null;continue}if(c===void 0||c===""){a==="ZodBoolean"&&(s[r]=false);continue}switch(a){case "ZodBoolean":c==="__null__"?s[r]=null:s[r]=c==="true"||c==="on"||c==="1";break;case "ZodNumber":case "ZodBigInt":s[r]=Number(c);break;case "ZodDate":s[r]=new Date(c);break;case "ZodArray":try{s[r]=JSON.parse(c);}catch{s[r]=c;}break;default:if(c.startsWith("{")||c.startsWith("["))try{s[r]=JSON.parse(c);break}catch{}s[r]=c;}}return s}function dt(e){let t=null;if(e instanceof Date)t=e;else if(typeof e=="object"&&e!==null&&typeof e.toDate=="function")t=e.toDate();else if(typeof e=="object"&&e!==null&&"_seconds"in e&&"_nanoseconds"in e)t=new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));else if(typeof e=="string"||typeof e=="number"){let s=new Date(e);isNaN(s.getTime())||(t=s);}if(!t||isNaN(t.getTime()))return null;let n=s=>String(s).padStart(2,"0");return `${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}function ze(e){let t=e;for(;;){let n=z(t);if(n==="ZodOptional"||n==="ZodNullable"||n==="ZodDefault")t=U(t);else return n}}function ut(e,t,n=""){let s={};for(let r of Object.keys(t.shape)){let o=n?`${n}.${r}`:r,a=e[r];if(a===null){s[o]="__null__";continue}if(a===void 0)continue;let f=t.shape[r];for(;;){let d=z(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=U(f);else break}let c=z(f);if(c==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let d=ut(a,f,o);Object.assign(s,d);}else if(c==="ZodDate"){let d=dt(a);d!==null&&(s[o]=d);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let d=dt(a);s[o]=d??JSON.stringify(a,null,2);}else typeof a=="object"?s[o]=JSON.stringify(a,null,2):s[o]=String(a);}return s}function Ze(e,t){return e.map(n=>({...n,defaultValue:t[n.name]??n.defaultValue,nested:n.nested?Ze(n.nested,t):void 0}))}function Jt(e,t){let n=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),s=[];for(let[r,o]of Object.entries(e)){if(!r.startsWith("fv_"))continue;let a=r.slice(3);if(!t.has(a))continue;let f=(o??"").trim();if(!f)continue;let c=e[`fo_${a}`]??"==",d=n.has(c)?c:"==";s.push({field:a,op:d,value:f});}return s}function Wt(e){let t=n=>n==="true"?true:n==="false"?false:n!==""&&!isNaN(Number(n))?Number(n):n;return e.map(n=>{if(n.op==="array-contains-any"||n.op==="in"||n.op==="not-in"){let s=n.value.split(",").map(r=>t(r.trim())).filter(r=>r!=="");return [n.field,n.op,s]}return [n.field,n.op,t(n.value)]})}function pt(e,t,n=""){let s=[];for(let r of e){let o=n?`${n}.${r}`:r,a=t.shape[r];if(!a){s.push({name:o,zodType:"ZodString"});continue}let f=ze(a);if(f==="ZodObject"){let c=a;for(;;){let p=z(c);if(p==="ZodOptional"||p==="ZodNullable"||p==="ZodDefault")c=U(c);else break}let d=ce(c);s.push(...pt(Object.keys(d),c,o));}else s.push({name:o,zodType:f});}return s}function Qt(e,t){let n=t.split("."),s=e;for(let r of n){for(;;){let a=z(s);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")s=U(s);else break}let o=ce(s);if(!(r in o))return null;s=o[r];}return s}function oe(e,t){if(!t||t.length===0)return e;let n=[],s=new Map;for(let o of t){let a=o.indexOf(".");if(a===-1)n.push(o);else {let f=o.slice(0,a),c=o.slice(a+1);s.has(f)||s.set(f,[]),s.get(f).push(c);}}let r={};for(let o of n)o in e.shape&&(r[o]=e.shape[o]);for(let[o,a]of s){if(!(o in e.shape))continue;let f=e.shape[o];for(;;){let c=z(f);if(c==="ZodOptional"||c==="ZodNullable"||c==="ZodDefault")f=U(f);else break}if(z(f)!=="ZodObject"){r[o]=e.shape[o];continue}r[o]=oe(f,a);}return z$1.object(r)}function se(e,t){let n=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let o=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${o}/${a}/${f}${n}`}let s=process.env.K_SERVICE,r=e.hostname??e.headers?.host??"";return s&&r.includes("cloudfunctions.net")?`/${s.toLowerCase()}${n}`:n}function ft(e,t){return {handleDashboard:(d,p)=>{let R=se(d,t),i=Object.values(e).map(l=>({name:l.name,path:l.path}));E(p,Ae(i,R));},handleList:async(d,p)=>{let R=d.params.repoName;if(!R){E(p,"Bad request",400);return}let i=e[R];if(!i){E(p,"Repository not found",404);return}let l=i.pageSize??25,g=d.query??{},b=g.cursor,u=g.dir==="prev"?"prev":"next",y=g.ob??"",h=g.od==="desc"?"desc":"asc",m=y?{field:y,dir:h}:void 0,v=parseInt(g.ps??""),x=Number.isFinite(v)&&v>0?Math.min(v,200):l,w=i.listColumns??Object.keys(i.schema.shape),S=i.documentKey??"docId",A=[S,...w.filter(N=>N!==S)],C=i.filterableFields?(()=>{let N=[];for(let V of i.filterableFields)(V.includes(".")||w.includes(V))&&N.push(V);return N})():w,O=(()=>{let N=[];for(let V of C)if(V.includes(".")){let Le=Qt(i.schema,V);N.push({name:V,zodType:Le?ze(Le):"ZodString"});}else N.push(...pt([V],i.schema));return N})(),T=new Set(O.map(N=>N.name)),_=Jt(g,T),M=Wt(_),j;if(b)try{let N=i.repo.ref;typeof N.doc=="function"&&(j=await N.doc(b).get());}catch{}let G=await i.repo.query.paginate({pageSize:x,cursor:j,direction:u,...M.length>0?{where:M}:{},...m?{orderBy:[{field:m.field,direction:m.dir}]}:{}}).catch(N=>({queryError:pe(N,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:_,sort:m})})),I="queryError"in G,ae=I?[]:G.data,Rt=I?"":G.nextCursor?.id??"",wt=I?"":G.prevCursor?.id??"",St=I?G.queryError:void 0,$t=se(d,t);E(p,Ee(i.name,ae,A,$t,{hasPrev:I?false:G.hasPrevPage,hasNext:I?false:G.hasNextPage,prevCursor:wt,nextCursor:Rt},void 0,O,_,i.allowDelete??false,i.relationalMeta,m,x,St,i.isGroup));},handleCreateForm:(d,p)=>{let R=d.params.repoName;if(!R){E(p,"Bad request",400);return}let i=e[R];if(!i){E(p,"Repository not found",404);return}let l=se(d,t),g=oe(i.schema,i.createFields),b=L(g),u=`${l}/${i.name}/create`,y=W(b,u,"POST","Create document");E(p,Y(i.name,y,"create",null,l));},handleCreateSubmit:async(d,p)=>{let R=d.params.repoName;if(!R){E(p,"Bad request",400);return}let i=e[R];if(!i){E(p,"Repository not found",404);return}let l=se(d,t),g=d.body??{},b=je(g,i.schema),u=oe(i.schema,i.createFields),y=u.safeParse(b);if(!y.success){let h=L(u),m=`${l}/${i.name}/create`,v=W(h,m,"POST","Create document"),x=y.error.issues.map(w=>`${w.path.join(".")}: ${w.message}`).join(", ");E(p,Y(i.name,v,"create",null,l,{type:"error",message:`Validation error: ${x}`}),422);return}try{if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let h={...y.data};i.createdKey&&(h[i.createdKey]=new Date);let m=i.parentKeys.filter(S=>!h[S]);if(m.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${m.join(", ")}`);let v=i.parentKeys.map(S=>h[S]),x=i.documentKey??"docId",w=h[x]||Vt();await i.repo.set(...v,w,h);}else await i.repo.create(y.data);Ne(p,`${l}/${i.name}?flash=created`);}catch(h){let m=oe(i.schema,i.createFields),v=L(m),x=`${l}/${i.name}/create`,w=W(v,x,"POST","Create document");E(p,Y(i.name,w,"create",null,l,{type:"error",message:`Save error: ${h.message}`}),500);}},handleEditForm:async(d,p)=>{let R=d.params.repoName,i=d.params.id;if(!R||!i){E(p,"Bad request",400);return}let l=e[R];if(!l){E(p,"Repository not found",404);return}let g=se(d,t),b=null;try{b=await De(l,i);}catch(x){let w=Fe(l,i,x),S=re(x)?424:500;E(p,ye("",{title:`Edit ${l.name} / ${i}`,basePath:g,breadcrumb:[{label:"Repositories",href:g},{label:l.name,href:`${g}/${l.name}`},{label:`Edit ${i}`}],flash:w}),S);return}if(!b){E(p,"Document not found",404);return}let u=ut(b,l.schema),y=oe(l.schema,l.mutableFields),h=Ze(L(y),u),m=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,v=W(h,m,"POST","Save changes");E(p,Y(l.name,v,"edit",i,g));},handleEditSubmit:async(d,p)=>{let R=d.params.repoName,i=d.params.id;if(!R||!i){E(p,"Bad request",400);return}let l=e[R];if(!l){E(p,"Repository not found",404);return}let g=se(d,t),b=d.body??{},u=je(b,l.schema),y=oe(l.schema,l.mutableFields),m=y.partial().safeParse(u);if(!m.success){let v=Object.fromEntries(Object.entries(b).map(([C,O])=>[C,Array.isArray(O)?O.join(","):O??""])),x=Ze(L(y),v),w=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,S=W(x,w,"POST","Save changes"),A=m.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`).join(", ");E(p,Y(l.name,S,"edit",i,g,{type:"error",message:`Validation error: ${A}`}),422);return}try{let v=await De(l,i),x=(v&&ct(v,l.pathKey))??[i];await l.repo.update(...x,m.data),Ne(p,`${g}/${l.name}?flash=updated`);}catch(v){let x=oe(l.schema,l.mutableFields),w=L(x),S=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,A=W(w,S,"POST","Save changes"),C=re(v)?Fe(l,i,v):{type:"error",message:`Save error: ${v.message}`},O=re(v)?424:500;E(p,Y(l.name,A,"edit",i,g,C),O);}},handleDelete:async(d,p)=>{let R=d.params.repoName,i=d.params.id;if(!R||!i){E(p,"Bad request",400);return}let l=e[R];if(!l){E(p,"Repository not found",404);return}if(!l.allowDelete){E(p,"Delete is not allowed for this repository",403);return}let g=se(d,t);try{let b=await De(l,i),u=(b&&ct(b,l.pathKey))??[i];await l.repo.delete(...u),Ne(p,`${g}/${l.name}?flash=deleted`);}catch(b){let u=re(b)?Fe(l,i,b):{type:"error",message:`Delete error: ${b.message}`},y=re(b)?424:500;E(p,ye("",{title:`Delete ${l.name} / ${i}`,basePath:g,breadcrumb:[{label:"Repositories",href:g},{label:l.name,href:`${g}/${l.name}`},{label:`Delete ${i}`}],flash:u}),y);}}}}function Xt(e){let t=[],n=e.replace(/[.*+?^${}()|[\]\\]/g,s=>s===":"?s:`\\${s}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(s,r)=>(t.push(r),"([^/]+)"));return {pattern:new RegExp(`^${n}$`),paramNames:t}}function Yt(e){let t=e.path??e.url??"/",n=t.indexOf("?");return n===-1?t:t.slice(0,n)}var ee=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,n)=>{n.status(404).send("Not Found");};this.errorHandler=(t,n,s)=>{console.error("[MiniRouter]",t),s.status(500).send("Internal Server Error");};}use(t){return this.middlewares.push(t),this}get(t,n){return this.addRoute("GET",t,n)}post(t,n){return this.addRoute("POST",t,n)}put(t,n){return this.addRoute("PUT",t,n)}patch(t,n){return this.addRoute("PATCH",t,n)}delete(t,n){return this.addRoute("DELETE",t,n)}onNotFound(t){return this.notFoundHandler=t,this}onError(t){return this.errorHandler=t,this}addRoute(t,n,s){let{pattern:r,paramNames:o}=Xt(n);return this.routes.push({method:t.toUpperCase(),pattern:r,paramNames:o,handler:s}),this}async handle(t,n){let s=(t.method??"GET").toUpperCase(),r=Yt(t),o=null,a={};for(let d of this.routes){if(d.method!==s)continue;let p=r.match(d.pattern);if(p){o=d,a={},d.paramNames.forEach((R,i)=>{a[R]=decodeURIComponent(p[i+1]??"");});break}}let f=Object.assign(t,{params:a}),c=o?o.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,n,c);}catch(d){this.errorHandler(d,t,n);}}async runMiddlewareChain(t,n,s){let r=0,o=async()=>{if(r<this.middlewares.length){let a=this.middlewares[r++];await a(t,n,o);}else await s(t,n);};await o();}};async function en(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function tn(e){let t={};if(!e)return t;for(let n of e.split("&")){let s=n.indexOf("=");if(s===-1)continue;let r=decodeURIComponent(n.slice(0,s).replace(/\+/g," ")),o=decodeURIComponent(n.slice(s+1).replace(/\+/g," ")),a=t[r];a===void 0?t[r]=o:Array.isArray(a)?a.push(o):t[r]=[a,o];}return t}function nn(e){let{basePath:t="/",repos:n,parseBody:s=true,auth:r,middleware:o=[],httpsOptions:a}=e,f=t==="/"?"":t.replace(/\/$/,""),c={};for(let[i,l]of Object.entries(n)){let g=l.schema??l.repo.schema??null;if(!g)throw new Error(`[createAdminServer] Repository "${i}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let b,u,y;if(l.fieldsConfig){let v=l.fieldsConfig;b=[],u=[],y=[];for(let[x,w]of Object.entries(v))for(let S of w)S==="filterable"?b.push(x):S==="mutable"?u.push(x):S==="create"&&y.push(x);b.length===0&&(b=void 0),u.length===0&&(u=void 0),y.length===0&&(y=void 0);}let h=(()=>{let v=l.repo._parentKeys;return v&&v.length>0?v:void 0})();if(h&&y)for(let v of h)y.includes(v)||y.push(v);let m={name:i,path:l.path,repo:l.repo,schema:g,documentKey:l.documentKey??"docId",pathKey:l.repo._pathKey??void 0,isGroup:!!l.repo._isGroup,parentKeys:h,createdKey:l.repo._createdKey??void 0,listColumns:l.listColumns,pageSize:l.pageSize,filterableFields:b,mutableFields:u,createFields:y,allowDelete:l.allowDelete??false,relationalMeta:(()=>{if(!l.relationalFields||l.relationalFields.length===0)return;let v=l.repo.relationalKeys??{},x=[];for(let w of l.relationalFields){let S=v[w.key];S&&x.push({key:w.key,column:w.column,targetRepo:String(S.repo),targetKey:String(S.key),type:S.type});}return x.length>0?x:void 0})()};c[i]=m;}let d=ft(c,f),p=new ee;if(s&&p.use(async(i,l,g)=>{let b=i,u=String(b.headers?.["content-type"]??"");if(u.includes("application/x-www-form-urlencoded")){let y=await en(b);i.body=tn(y);}else if(u.includes("application/json")&&typeof b.body=="string")try{i.body=JSON.parse(b.body);}catch{}await g();}),r)if(typeof r=="function")p.use(r);else {let i=r.realm??"Admin",l="Basic "+Buffer.from(`${r.username}:${r.password}`).toString("base64");p.use((g,b,u)=>{if((g.headers?.authorization??"")!==l){b.status(401).set("WWW-Authenticate",`Basic realm="${i}"`).set("Content-Type","text/plain").send("Unauthorized");return}u();});}for(let i of o)p.use(i);p.get(`${f}/`,d.handleDashboard),p.get(`${f}`,d.handleDashboard),p.get(`${f}/:repoName`,d.handleList),p.get(`${f}/:repoName/create`,d.handleCreateForm),p.post(`${f}/:repoName/create`,d.handleCreateSubmit),p.get(`${f}/:repoName/:id/edit`,d.handleEditForm),p.post(`${f}/:repoName/:id/edit`,d.handleEditSubmit),p.post(`${f}/:repoName/:id/delete`,d.handleDelete);let R=async(i,l)=>{await p.handle(i,l);};return a&&(R.httpsOptions=a),R}function qe(e,t,n=200){e.status(n).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(t));}function le(e,t,n,s=200){qe(e,{success:true,data:t,meta:n},s);}function F(e,t,n=400){qe(e,{success:false,error:t},n);}function Be(e,t,n,s,r){let o=pe(t,n),a=o.type==="index",f=a?424:500,d={success:false,error:a?o.message:r&&t instanceof Error?t.message:s};a&&(d.errorType="index",o.indexUrl&&(d.indexUrl=o.indexUrl)),qe(e,d,f);}var mt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function rn(){let e="";for(let t=0;t<20;t++)e+=mt.charAt(Math.floor(Math.random()*mt.length));return e}function sn(e,t,n=[]){let s=e.shape,r={},o=t&&t.length>0?t:Object.keys(s);for(let a of o){if(n.includes(a))continue;let f=a.split(".")[0];f&&s[f]&&(r[f]=s[f]);}return z$1.object(r)}function yt(e,t,n,s=false,r=[]){try{let o=sn(e,n,r);return {success:!0,data:(s?o.partial():o).parse(t)}}catch(o){return o instanceof z$1.ZodError?{success:false,error:`Validation failed: ${o.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function on(e,t){let n=[],s=t?new Set(t):null,r={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[o,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(o))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let c=o.match(/^(\w+)__(\w+)$/),d,p="==";if(c&&c[1]&&c[2]){d=c[1];let i=c[2];if(r[i])p=r[i];else continue}else if(!c)d=o;else continue;if(s&&!s.has(d))continue;let R=f;p==="in"||p==="not-in"||p==="array-contains-any"?R=f.split(",").map(i=>gt(i.trim())):R=gt(f),n.push({field:d,op:p,value:R});}return n}function gt(e){if(e==="true")return true;if(e==="false")return false;if(e==="null")return null;let t=Number(e);return !isNaN(t)&&e!==""?t:e}function he(e){return e?{docId:e.id}:null}async function ht(e,t){if(!t||typeof t!="object")return;let n=t.docId;if(typeof n=="string")try{let s=e.repo.ref;if(typeof s.doc!="function")return;let r=await s.doc(n).get();return r.exists?r:void 0}catch{return}}function vt(e,t,n){function s(l,g){return !l||!e[l]?(F(g,`Repository "${l}" not found`,404),null):e[l]}function r(l,g){if(!g)return;let b=l[g];if(typeof b!="string"||!b)return;let u=b.split("/").filter(Boolean),y=[];for(let h=1;h<u.length;h+=2)y.push(u[h]);return y.length>0?y:void 0}async function o(l,g){let b=`by${l.documentKey.charAt(0).toUpperCase()}${l.documentKey.slice(1)}`,u=l.repo.get[b];if(typeof u=="function")try{let h=await u(g);if(h)return h}catch{}return (await l.repo.query.by({where:[[l.documentKey,"==",g]],limit:1}))[0]??null}async function a(l,g){let b=l.params||{},u=s(b.repoName,g);if(!u)return;let y=[],h;try{let m=l.query??{},v=Math.min(Number(m.pageSize)||u.pageSize,100),x=m.cursor,w=m.direction?.toLowerCase()==="prev"?"prev":"next",S=m.orderBy,A=m.orderDir?.toLowerCase()==="desc"?"desc":"asc",C=m.select,O=C?C.split(",").map(I=>I.trim()):void 0,T;u.allowedIncludes&&m.includes&&(T=(typeof m.includes=="string"?m.includes.split(",").map(ae=>ae.trim()):Array.isArray(m.includes)?m.includes:[]).filter(ae=>typeof ae=="string"&&u.allowedIncludes.includes(ae)),T?.length===0&&(T=void 0));let _=on(m,u.filterableFields);y=_.map(I=>({field:I.field,op:I.op,value:String(I.value??"")})),S&&(h={field:S,dir:A});let M={pageSize:v,direction:w};if(x)try{let I=typeof x=="string"?JSON.parse(x):x;M.cursor=await ht(u,I);}catch{}S&&(M.orderBy=[{field:S,direction:A}]),_.length>0&&(M.where=_.map(I=>[I.field,I.op,I.value])),O&&(M.select=O),T&&(M.include=T);let j=await u.repo.query.paginate(M),G={items:j.data,hasNextPage:j.hasNextPage,hasPrevPage:j.hasPrevPage,nextCursor:he(j.nextCursor),prevCursor:he(j.prevCursor)};le(g,G,{pageSize:v,hasMore:j.hasNextPage});}catch(m){Be(g,m,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:y,sort:h},"Failed to fetch documents",n);}}async function f(l,g){let b=l.params||{},u=s(b.repoName,g);if(!u)return;let y=[],h;try{let m=l.body??{},v=Math.min(m.pageSize||u.pageSize,100),x=m.direction==="prev"?"prev":"next";m.where&&(y=m.where.map(C=>({field:String(C[0]),op:C[1],value:String(C[2]??"")}))),m.orderBy&&m.orderBy[0]&&(h={field:m.orderBy[0].field,dir:m.orderBy[0].direction==="desc"?"desc":"asc"});let w={pageSize:v,direction:x};if(m.cursor)try{let C=typeof m.cursor=="string"?JSON.parse(m.cursor):m.cursor;w.cursor=await ht(u,C);}catch{}if(u.allowedIncludes&&m.includes&&m.includes.length>0){let C=m.includes.filter(O=>typeof O=="string"?u.allowedIncludes.includes(O):typeof O=="object"&&O!==null&&"relation"in O&&typeof O.relation=="string"?u.allowedIncludes.includes(O.relation):!1);C.length>0&&(w.include=C);}if(m.where&&m.where.length>0){if(u.filterableFields){let C=new Set(u.filterableFields),O=m.where.filter(T=>!C.has(T[0]));if(O.length>0){F(g,`Fields not filterable: ${O.map(T=>T[0]).join(", ")}`,400);return}}w.where=m.where;}if(m.orWhere&&m.orWhere.length>0){if(u.filterableFields){let C=new Set(u.filterableFields),O=m.orWhere.filter(T=>!C.has(T[0]));if(O.length>0){F(g,`Fields not filterable: ${O.map(T=>T[0]).join(", ")}`,400);return}}w.orWhere=m.orWhere;}if(m.orWhereGroups&&m.orWhereGroups.length>0){if(u.filterableFields){let C=new Set(u.filterableFields);for(let O of m.orWhereGroups){let T=O.filter(_=>!C.has(_[0]));if(T.length>0){F(g,`Fields not filterable: ${T.map(_=>_[0]).join(", ")}`,400);return}}}w.orWhereGroups=m.orWhereGroups;}m.orderBy&&m.orderBy.length>0&&(w.orderBy=m.orderBy),m.select&&m.select.length>0&&(w.select=m.select);let S=await u.repo.query.paginate(w),A={items:S.data,hasNextPage:S.hasNextPage,hasPrevPage:S.hasPrevPage,nextCursor:he(S.nextCursor),prevCursor:he(S.prevCursor)};le(g,A,{pageSize:v,hasMore:S.hasNextPage});}catch(m){Be(g,m,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:y,sort:h},"Failed to query documents",n);}}async function c(l,g){let b=l.params||{},u=s(b.repoName,g);if(!u)return;let y=b.id;if(!y){F(g,"Document ID required",400);return}try{let h=await o(u,y);if(!h){F(g,"Document not found",404);return}le(g,h);}catch(h){Be(g,h,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:[{field:u.documentKey,op:"==",value:y}]},"Failed to fetch document",n);}}async function d(l,g){let b=l.params||{},u=s(b.repoName,g);if(u)try{let y=l.body??{},h=yt(u.schema,y,u.createFields,!1,u.systemKeys);if(!h.success){F(g,h.error,400);return}if(u.validate){let v=await u.validate(h.data,"create");if(v){F(g,v,400);return}}let m;if(u.isGroup&&u.parentKeys&&u.parentKeys.length>0){let v={...h.data};u.createdKey&&(v[u.createdKey]=new Date);let x=u.parentKeys.filter(A=>!v[A]);if(x.length>0){F(g,`Missing parent key(s) for subcollection create: ${x.join(", ")}`,400);return}let w=u.parentKeys.map(A=>v[A]),S=v[u.documentKey]||rn();m=await u.repo.set(...w,S,v);}else m=await u.repo.create(h.data);le(g,m,void 0,201);}catch(y){let h=n&&y instanceof Error?y.message:"Failed to create document";F(g,h,500);}}async function p(l,g,b){let u=l.params||{},y=s(u.repoName,g);if(!y)return;let h=u.id;if(!h){F(g,"Document ID required",400);return}try{let m=l.body??{},v=yt(y.schema,m,y.mutableFields,b,y.systemKeys);if(!v.success){F(g,v.error,400);return}if(y.validate){let A=await y.validate(v.data,"update");if(A){F(g,A,400);return}}let x=await o(y,h),w=(x&&r(x,y.pathKey))??[h],S=await y.repo.update(...w,v.data);le(g,S);}catch(m){let v=n&&m instanceof Error?m.message:"Failed to update document";F(g,v,500);}}async function R(l,g){let b=l.params||{},u=s(b.repoName,g);if(!u)return;if(!u.allowDelete){F(g,"Delete not allowed for this repository",403);return}let y=b.id;if(!y){F(g,"Document ID required",400);return}try{let h=await o(u,y),m=(h&&r(h,u.pathKey))??[y];await u.repo.delete(...m),le(g,{deleted:!0});}catch(h){let m=n&&h instanceof Error?h.message:"Failed to delete document";F(g,m,500);}}function i(l,g){g.status(204).set("Access-Control-Allow-Methods","GET, POST, PUT, PATCH, DELETE, OPTIONS").set("Access-Control-Allow-Headers","Content-Type, Authorization").set("Access-Control-Max-Age","86400").send("");}return {handleList:a,handleQuery:f,handleGet:c,handleCreate:d,handleUpdate:p,handleDelete:R,handleOptions:i}}function Me(e){try{return z$1.toJSONSchema(e,{target:"openapi-3.1",unrepresentable:"any",override:t=>{let n=t.zodSchema?._zod?.def;n&&(n.type==="date"?(t.jsonSchema.type="string",t.jsonSchema.format="date-time"):n.type==="bigint"&&(t.jsonSchema.type="string",t.jsonSchema.format="int64"));}})}catch(t){return typeof console<"u"&&console.warn&&console.warn("[generateOpenAPISpec] Failed to convert Zod schema to JSON Schema; falling back to {type:object}.",t),{type:"object"}}}function K(e){return {$ref:`#/components/schemas/${e}`}}function Z(e){return {description:e,content:{"application/json":{schema:K("ErrorResponse")}}}}function fe(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function xt(e){return {description:"Paginated list of documents",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:{type:"object",properties:{items:{type:"array",items:e},nextCursor:{oneOf:[{type:"object"},{type:"null"}]},prevCursor:{oneOf:[{type:"object"},{type:"null"}]},hasNextPage:{type:"boolean"},hasPrevPage:{type:"boolean"}},required:["items","hasNextPage","hasPrevPage"]},meta:{type:"object",properties:{pageSize:{type:"integer"},hasMore:{type:"boolean"},cursor:{oneOf:[{type:"string"},{type:"null"}]}}}},required:["success","data"]}}}}}function an(e){return [{name:"pageSize",in:"query",schema:{type:"integer",default:e.pageSize,maximum:100},description:"Number of items per page"},{name:"cursor",in:"query",schema:{type:"string"},description:"Base64 pagination cursor"},{name:"orderBy",in:"query",schema:{type:"string"},description:"Field name to order by"},{name:"orderDir",in:"query",schema:{type:"string",enum:["asc","desc"]},description:"Order direction"},{name:"select",in:"query",schema:{type:"string"},description:"Comma-separated list of fields to return"}]}function ln(e){let t=e.filterableFields??Object.keys(e.schema.shape),n=["eq","ne","lt","lte","gt","gte","in","nin","contains"],s=[];for(let r of t){s.push({name:r,in:"query",schema:{type:"string"},description:`Filter by ${r} (equality)`});for(let o of n)s.push({name:`${r}__${o}`,in:"query",schema:{type:"string"},description:`Filter ${r} with operator ${o}`});}return s}function cn(){return {type:"object",properties:{where:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"AND conditions: [field, operator, value][]"},orWhere:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"Simple OR conditions (each independently OR'd)"},orWhereGroups:{type:"array",items:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3}},description:"Advanced OR groups (AND within, OR across groups)"},orderBy:{type:"array",items:{type:"object",properties:{field:{type:"string"},direction:{type:"string",enum:["asc","desc"]}},required:["field"]}},select:{type:"array",items:{type:"string"},description:"Fields to select (projection)"},pageSize:{type:"integer",maximum:100,description:"Number of items per page"},cursor:{oneOf:[{type:"string"},{type:"object"}],description:"Pagination cursor"},direction:{type:"string",enum:["next","prev"],description:"Pagination direction"},includes:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{relation:{type:"string"},select:{type:"array",items:{type:"string"}}},required:["relation"]}]},description:"Relations to include (populate)"}}}}function dn(e,t,n,s,r){let o={},a=e.name,f=`${t}/${e.name}`,c=`${f}/{${e.documentKey}}`,d={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};o[f]={get:{operationId:`list${te(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...an(e),...ln(e)],responses:{200:xt(K(n)),500:Z("Internal server error")}},post:{operationId:`create${te(e.name)}`,summary:`Create a ${H(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:K(s??n)}}},responses:{201:fe("Document created",K(n)),400:Z("Validation error"),500:Z("Internal server error")}}},o[`${f}/query`]={post:{operationId:`query${te(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:K("QueryRequestBody")}}},responses:{200:xt(K(n)),400:Z("Invalid query"),500:Z("Internal server error")}}};let p={};return p.get={operationId:`get${te(H(e.name))}`,summary:`Get a single ${H(e.name)}`,tags:[a],parameters:[d],responses:{200:fe("Document found",K(n)),404:Z("Document not found"),500:Z("Internal server error")}},p.put={operationId:`update${te(H(e.name))}`,summary:`Update a ${H(e.name)} (full replace)`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:K(r??n)}}},responses:{200:fe("Document updated",K(n)),400:Z("Validation error"),404:Z("Document not found"),500:Z("Internal server error")}},p.patch={operationId:`patch${te(H(e.name))}`,summary:`Partially update a ${H(e.name)}`,tags:[a],parameters:[d],requestBody:{required:true,content:{"application/json":{schema:{allOf:[K(r??n)],description:"All fields are optional for partial updates"}}}},responses:{200:fe("Document patched",K(n)),400:Z("Validation error"),404:Z("Document not found"),500:Z("Internal server error")}},e.allowDelete&&(p.delete={operationId:`delete${te(H(e.name))}`,summary:`Delete a ${H(e.name)}`,tags:[a],parameters:[d],responses:{200:fe("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:Z("Document not found"),500:Z("Internal server error")}}),o[c]=p,o}function Ke(e,t,n={}){let{title:s="CRUD API",version:r="1.0.0",description:o,servers:a,auth:f=false}=n,c=t==="/"?"":t.replace(/\/$/,""),d={},p={},R=[];d.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},d.QueryRequestBody=cn();for(let[b,u]of Object.entries(e)){let y=te(H(b)),h=`${y}Create`,m=`${y}Update`;d[y]=Me(u.schema);let v=O=>{let T=O&&O.length>0?O:Object.keys(u.schema.shape),_={};for(let M of T){let j=M.split(".")[0];j&&u.schema.shape[j]&&!u.systemKeys.includes(j)&&(_[j]=u.schema.shape[j]);}return _},x=null,w=v(u.createFields);Object.keys(w).length>0&&(d[h]=Me(z$1.object(w)),x=h);let S=null,A=v(u.mutableFields);Object.keys(A).length>0&&(d[m]=Me(z$1.object(A)),S=m);let C=dn(u,c,y,x,S);Object.assign(p,C),R.push({name:b,description:`Operations on ${b} (collection: ${u.path})`});}let i={},l;return f==="basic"?(i.basicAuth={type:"http",scheme:"basic"},l=[{basicAuth:[]}]):f==="bearer"&&(i.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},l=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:s,version:r,...o?{description:o}:{}},...a&&a.length>0?{servers:a}:{},paths:p,components:{schemas:d,...Object.keys(i).length>0?{securitySchemes:i}:{}},...l?{security:l}:{},tags:R}}function te(e){return e.charAt(0).toUpperCase()+e.slice(1)}function H(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}function un(e,t){return `<!DOCTYPE html>
|
|
555
|
+
`;function ge(){return jsx("script",{dangerouslySetInnerHTML:{__html:at}})}function Q(e){return "<!DOCTYPE html>"+renderToString(e)}var X=({opts:e,children:t})=>{let{title:r,breadcrumb:n,flash:o,basePath:s="/"}=e;return jsxs("html",{lang:"en","data-theme":"corporate",children:[jsxs("head",{children:[jsx("meta",{charset:"UTF-8"}),jsx("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),jsxs("title",{children:[r," \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:s,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((a,f)=>a.href?jsx("li",{children:jsx("a",{href:a.href,children:a.label})},f):jsx("li",{class:"text-base-content/60",children:a.label},f))})}),jsx("h1",{class:"text-2xl font-bold mb-6",children:r}),o&&jsxs("div",{role:"alert",class:`alert ${o.type==="success"?"alert-success":o.type==="warning"?"alert-warning":"alert-error"} mb-6`,children:[jsx("span",{class:"flex-1",children:o.message}),o.action&&jsx("a",{href:o.action.href,...o.action.external?{target:"_blank",rel:"noopener noreferrer"}:{},class:"btn btn-sm btn-outline",children:o.action.label})]}),t]}),jsx(ge,{})]})]})};function Ae(e,t){return Q(jsx(X,{opts:t,children:jsx("div",{dangerouslySetInnerHTML:{__html:e}})}))}function Te(e,t){return Q(jsx(X,{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(r=>jsx("a",{href:`${t}/${r.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:r.name}),jsx("p",{class:"text-xs text-base-content/50 font-mono",children:r.path})]})},r.name))})}))}var lt=[{value:"==",label:"="},{value:"!=",label:"\u2260"},{value:"in",label:"in"},{value:"not-in",label:"not in"}],Ut=[{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"}],Lt=[{value:"array-contains",label:"contains"},{value:"array-contains-any",label:"contains any"}];function Kt(e){switch(e){case "ZodNumber":case "ZodBigInt":case "ZodDate":return Ut;case "ZodBoolean":return lt;case "ZodArray":return Lt;default:return lt}}var Y="__null__";function Ht(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="${Y}"]');if(!o){o=document.createElement('option');o.value='${Y}';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='${Y}';i.readOnly=true;}i.style.opacity='0.55';}else{i.style.opacity='';if(i.tagName==='SELECT'){var o2=i.querySelector('option[value="${Y}"][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!=='${Y}')?i.dataset._prev:'';}}})(this)`}function Vt(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 he({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:Ht(e)}),jsx("span",{children:"\u2205"})]})}function Gt({col:e,active:t}){let r=t?.value??"",n=r===Y,o=`fv_input_${e.name.replace(/\./g,"__")}`,s=t?.op,a=s==="in"||s==="not-in";if(e.enumValues&&e.enumValues.length>0){if(a){let f=new Set(r.split(",").map(c=>c.trim()).filter(Boolean)),d=`eg_${e.name.replace(/\./g,"__")}`;return jsxs("div",{class:"flex flex-wrap items-center gap-1 w-full",children:[jsx("input",{type:"hidden",id:o,name:`fv_${e.name}`,value:r}),e.enumValues.map(c=>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:c,checked:f.has(c),"data-enum-group":d,onchange:Vt(o,d)}),jsx("span",{children:c})]},c))]})}return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:n?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:r===""&&!n,children:"\u2014"}),e.enumValues.map(f=>jsx("option",{value:f,selected:r===f,children:f},f)),e.nullable&&jsx("option",{value:Y,"data-_auto":"1",selected:n,children:"\u2205 null"})]}),e.nullable&&jsx(he,{inputId:o,active:n})]})}if(e.zodType==="ZodBoolean")return jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsxs("select",{id:o,name:`fv_${e.name}`,class:"select select-sm select-bordered w-full",style:n?"opacity:0.55":void 0,children:[jsx("option",{value:"",selected:r===""&&!n,children:"\u2014"}),jsx("option",{value:"true",selected:r==="true",children:"true"}),jsx("option",{value:"false",selected:r==="false",children:"false"}),e.nullable&&jsx("option",{value:Y,"data-_auto":"1",selected:n,children:"\u2205 null"})]}),e.nullable&&jsx(he,{inputId:o,active:n})]});if(e.zodType==="ZodArray"){let f=t?.op==="array-contains-any";return jsx("input",{id:o,type:"text",name:`fv_${e.name}`,value:r,placeholder:f?"val1, val2, \u2026":"value",class:"input input-sm input-bordered w-full"})}return e.zodType==="ZodNumber"||e.zodType==="ZodBigInt"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,type:n?"text":"number",name:`fv_${e.name}`,value:r,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(he,{inputId:o,active:n})]}):e.zodType==="ZodDate"?jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,type:n?"text":"datetime-local",name:`fv_${e.name}`,value:r,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(he,{inputId:o,active:n})]}):jsxs("div",{class:"flex items-center gap-1 w-full",children:[jsx("input",{id:o,type:"text",name:`fv_${e.name}`,value:r,placeholder:"value",class:"input input-sm input-bordered w-full",readOnly:n,style:n?"opacity:0.55":void 0}),e.nullable&&jsx(he,{inputId:o,active:n})]})}function _e({action:e,columnMeta:t,activeFilters:r,isGroup:n}){let o=Object.fromEntries(r.map(d=>[d.field,d])),s=r.length>0,a=r.length>=2||n&&s,f=t.filter(d=>d.zodType!=="ZodObject"&&d.zodType!=="ZodRecord");return jsxs("details",{class:"collapse collapse-arrow bg-base-100 border border-base-300 rounded-box mb-6 shadow-sm",open:s?true:void 0,children:[jsxs("summary",{class:"collapse-title text-sm font-medium py-2 min-h-0",children:["Filters",s&&jsxs("span",{class:"badge badge-primary badge-sm ml-2",children:[r.length," active"]})]}),jsx("div",{class:"collapse-content pb-4 pt-2",children:jsxs("form",{method:"get",action:e,children:[jsx("div",{class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:f.map(d=>{let c=Kt(d.zodType),p=o[d.name],w=p?.op??c[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:[c.length>1?jsx("select",{name:`fo_${d.name}`,class:"select select-sm select-bordered w-20 shrink-0",children:c.map(i=>jsx("option",{value:i.value,selected:i.value===w,children:i.label},i.value))}):jsx("input",{type:"hidden",name:`fo_${d.name}`,value:c[0].value}),jsx(Gt,{col:d,active:p})]})]},d.name)})}),jsxs("div",{class:"flex flex-wrap gap-2 mt-4 pt-3 border-t border-base-200 items-center",children:[jsx("button",{type:"submit",class:"btn btn-sm btn-primary",children:"Apply"}),s&&jsx("a",{href:e,class:"btn btn-sm btn-ghost",children:"Clear"}),a&&jsxs("span",{class:"text-xs text-warning ml-auto flex items-center gap-1",children:[jsx("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:jsx("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),n?"Collection group queries require a composite index":"Multiple filters may require a composite index"]})]})]})})]})}function Ee(e,t,r,n,o,s){let a=r==="create"?`Create ${e}`:`Edit ${e} / ${n??""}`,f=r==="create"?[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:"New document"}]:[{label:"Repositories",href:o},{label:e,href:`${o}/${e}`},{label:`Edit ${n??""}`}];return Q(jsx(X,{opts:{title:a,breadcrumb:f,basePath:o,flash:s},children:jsx("div",{class:"card bg-base-100 border border-base-300",children:jsx("div",{class:"card-body p-6",children:jsx("div",{dangerouslySetInnerHTML:{__html:t}})})})}))}function Ie(e,t,r){let n=new URLSearchParams;for(let o of e)n.set(`fv_${o.field}`,o.value),n.set(`fo_${o.field}`,o.op);return t&&(n.set("ob",t.field),n.set("od",t.dir)),r&&n.set("ps",String(r)),n}function ct(e,t,r,n,o){let s=Ie(e,n,o);return s.set("cursor",t),s.set("dir",r),`?${s.toString()}`}function Jt(e,t,r,n){let o=Ie(r,void 0,n);return t?.field===e?t.dir==="asc"&&(o.set("ob",e),o.set("od","desc")):(o.set("ob",e),o.set("od","asc")),`?${o.toString()}`}function Wt(e,t,r){return `?${Ie(t,r,e).toString()}`}function De(e,t,r,n,o,s,a=[],f=[],d=false,c=[],p,w,i,l){let g=`${n}/${e}`,b=`${g}/create`;return Q(jsxs(X,{opts:{title:e,breadcrumb:[{label:"Repositories",href:n},{label:e}],basePath:n,flash:s},children:[a.length>0&&jsx(_e,{action:g,columnMeta:a,activeFilters:f,isGroup:l}),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(u=>jsx("a",{href:Wt(u,f,p),class:`join-item btn btn-xs ${w===u?"btn-active btn-primary":"btn-outline"}`,children:u},u))})]})]}),jsx("a",{href:b,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":r.length,children:[jsx("thead",{children:jsxs("tr",{class:"bg-base-200/50",children:[[...r].map((u,y)=>{let h=p?.field===u,m=h?p.dir==="asc"?" \u25B2":" \u25BC":"";return jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:jsxs("a",{href:Jt(u,p,f,w),class:`hover:text-base-content inline-flex items-center gap-0.5${h?" text-primary font-bold":""}`,children:[u,m]})},y)}),c.map((u,y)=>jsx("th",{class:"text-xs font-semibold text-base-content/60 uppercase tracking-wide",children:u.column},`rel-${y}`)),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:r.length+c.length+1,class:"text-center py-16 text-base-content/40",children:"No documents found"})}):t.map((u,y)=>{let h=String(u.docId??u.id??""),m=`${n}/${e}/${encodeURIComponent(h)}/edit`,v=`${n}/${e}/${encodeURIComponent(h)}/delete`;return jsxs("tr",{class:"hover",children:[r.map((x,R)=>jsx("td",{class:"align-top py-2",children:jsx(Oe,{val:u[x]})},R)),c.map((x,R)=>{let S=u[x.key];if(S==null||S==="")return jsx("td",{class:"py-2"},`rel-${R}`);let T=`${n}/${x.targetRepo}?fv_${x.targetKey}=${encodeURIComponent(String(S))}`;return jsx("td",{class:"align-middle py-2",children:jsx("a",{href:T,class:"btn btn-xs btn-ghost btn-outline",children:x.column})},`rel-${R}`)}),jsx("td",{class:"align-middle text-right whitespace-nowrap py-2",children:jsxs("div",{class:"flex gap-1 justify-end",children:[jsx("a",{href:m,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"})})]})})]},y)})})]})}),(o.hasPrev||o.hasNext)&&jsxs("div",{class:"flex justify-center items-center mt-6 gap-2",children:[o.hasPrev?jsx("a",{href:ct(f,o.prevCursor,"prev",p,w),class:"btn btn-sm btn-outline",children:"\u2190 Previous"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"\u2190 Previous"}),o.hasNext?jsx("a",{href:ct(f,o.nextCursor,"next",p,w),class:"btn btn-sm btn-outline",children:"Next \u2192"}):jsx("button",{class:"btn btn-sm btn-outline",disabled:true,children:"Next \u2192"})]})]}))}var Qt="";function Se(e,t){return Ae(e,t)}function Ne(e,t){return Te(e,t)}function Pe(e,t,r,n,o,s,a,f,d,c,p,w,i,l){return De(e,t,r,n,o,s,a,f,d,c,p,w,i,l)}function ee(e,t,r,n,o,s){return Ee(e,t,r,n,o,s)}var Xt=new Set(["<","<=",">",">=","!="]),Yt=new Set(["array-contains","array-contains-any"]);function Ze(e){return e==="desc"?"DESCENDING":"ASCENDING"}function en(e){let t=e.split("/").filter(Boolean);return t[t.length-1]??e}function tn(e,t,r,n,o){let s=[],a=new Set;for(let d of n)if(d.op==="=="||d.op==="in"||d.op==="not-in"){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,order:"ASCENDING"});}for(let d of n)if(Yt.has(d.op)){if(a.has(d.field))continue;a.add(d.field),s.push({fieldPath:d.field,arrayConfig:"CONTAINS"});}for(let d of n)if(Xt.has(d.op)){if(a.has(d.field))continue;a.add(d.field);let c=o?.field===d.field?Ze(o.dir):"ASCENDING";s.push({fieldPath:d.field,order:c});}if(o&&!a.has(o.field)&&s.push({fieldPath:o.field,order:Ze(o.dir)}),s.length===1&&r)return on(e,t,s[0]);let f=o&&s.some(d=>d.fieldPath===o.field)?Ze(o.dir):"ASCENDING";return s.push({fieldPath:"__name__",order:f}),nn(e,t,r,s)}function nn(e,t,r,n,o="(default)"){let s=`projects/${e}/databases/${o}/collectionGroups/${t}/indexes/_`,a=[...ze(1,s),...$e(2,r?2:1)];for(let c of n)a.push(...dt(3,ut(c)));let f=o==="(default)"?"-default-":o,d=encodeURIComponent(pt(a));return `https://console.firebase.google.com/project/${e}/firestore/databases/${f}/indexes?create_composite=${d}`}function rn(e){return e.match(/https:\/\/console\.firebase\.google\.com[^\s)"]*/)?.[0]}function je(e){let t=[],r=e>>>0;for(;r>=128;)t.push(r&127|128),r>>>=7;return t.push(r&127),t}function Fe(e,t){return e<<3|t}function ze(e,t){let r=Array.from(new TextEncoder().encode(t));return [Fe(e,2),...je(r.length),...r]}function $e(e,t){return [Fe(e,0),...je(t)]}function dt(e,t){return [Fe(e,2),...je(t.length),...t]}function ut(e){let t=[...ze(1,e.fieldPath)];return e.arrayConfig==="CONTAINS"?t.push(...$e(3,1)):t.push(...$e(2,e.order==="DESCENDING"?2:1)),t}function pt(e){let t=String.fromCharCode(...e),r;if(typeof Buffer<"u")r=Buffer.from(e).toString("base64");else if(typeof btoa<"u")r=btoa(t);else throw new Error("No base64 encoder available");return r.replace(/=+$/,"")}function on(e,t,r,n="(default)"){let o=`projects/${e}/databases/${n}/collectionGroups/${t}/fields/${r.fieldPath}`,s=[...ze(1,o),...$e(2,2),...dt(3,ut(r))],a=n==="(default)"?"-default-":n,f=encodeURIComponent(pt(s));return `https://console.firebase.google.com/project/${e}/firestore/databases/${a}/indexes/automatic?create_exemption=${f}`}function sn(e){let t=e,r=[t?.firestore?.projectId,t?.firestore?.app?.options?.projectId,t?.firestore?._settings?.projectId,t?.firestore?.databaseId?.projectId,t?._firestore?.projectId];for(let o of r)if(typeof o=="string"&&o.length>0)return o;return process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT||process.env.FIREBASE_PROJECT_ID||void 0}function oe(e){let t=e;return t?t.code===9?true:typeof t.message=="string"?t.message.includes("requires an index"):false:false}function be(e,t){let r=e??{},n=oe(e),o;if(n&&(o=r.message?rn(r.message):void 0,!o)){let s=sn(t.ref);if(s){let a=en(t.path);o=tn(s,a,t.isGroup,t.filters,t.sort);}}return {type:n?"index":"error",message:n?"This query requires a composite index that does not exist yet.":r.message??"Query failed",indexUrl:o}}var ft="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function ln(){let e="";for(let t=0;t<20;t++)e+=ft.charAt(Math.floor(Math.random()*ft.length));return e}function mt(e,t){if(!t)return;let r=e[t];if(typeof r!="string"||!r)return;let n=r.split("/").filter(Boolean),o=[];for(let s=1;s<n.length;s+=2)o.push(n[s]);return o.length>0?o:void 0}async function Be(e,t){let r=e.documentKey??"docId",n=`by${r.charAt(0).toUpperCase()}${r.slice(1)}`;if(typeof e.repo.get[n]=="function")try{let s=await e.repo.get[n](t);if(s)return s}catch{}return (await e.repo.query.by({where:[[r,"==",t]],limit:1}))[0]??null}function qe(e,t,r){let n=e.documentKey??"docId",o=be(r,{ref:e.repo.ref,path:e.path,isGroup:!!e.isGroup,filters:[{field:n,op:"==",value:t}]});return o.type==="index"?{type:"warning",message:"Loading this document requires a composite index that does not exist yet.",...o.indexUrl?{action:{href:o.indexUrl,label:"Create Index \u2192",external:true}}:{}}:{type:"error",message:o.message}}function _(e,t,r=200){e.status(r).set("Content-Type","text/html; charset=utf-8").send(t);}function Me(e,t){e.status(302).set("Location",t).send("");}function Ue(e,t){let r=t.shape,n={};for(let[o,s]of Object.entries(r)){let a=Ke(s);if(a==="ZodObject"){if(e[o+"__isnull"]==="1"){n[o]=null;continue}let c={},p=false;for(let[l,g]of Object.entries(e))l.startsWith(`${o}.`)&&(c[l.slice(o.length+1)]=g,p=true);if(p){let l=s;for(;;){let g=Z(l);if(g==="ZodOptional"||g==="ZodNullable"||g==="ZodDefault")l=q(l);else break}n[o]=Ue(c,l);continue}let w=e[o],i=Array.isArray(w)?w[w.length-1]:w;if(i)try{n[o]=JSON.parse(i);}catch{n[o]=i;}continue}let f=e[o],d=Array.isArray(f)?f[f.length-1]:f;if(e[o+"__isnull"]==="1"){n[o]=null;continue}if(d===void 0||d===""){a==="ZodBoolean"&&(n[o]=false);continue}switch(a){case "ZodBoolean":d==="__null__"?n[o]=null:n[o]=d==="true"||d==="on"||d==="1";break;case "ZodNumber":case "ZodBigInt":n[o]=Number(d);break;case "ZodDate":n[o]=new Date(d);break;case "ZodArray":try{n[o]=JSON.parse(d);}catch{n[o]=d;}break;default:if(d.startsWith("{")||d.startsWith("["))try{n[o]=JSON.parse(d);break}catch{}n[o]=d;}}return n}function yt(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 r=n=>String(n).padStart(2,"0");return `${t.getFullYear()}-${r(t.getMonth()+1)}-${r(t.getDate())}T${r(t.getHours())}:${r(t.getMinutes())}`}function Ke(e){let t=e;for(;;){let r=Z(t);if(r==="ZodOptional"||r==="ZodNullable"||r==="ZodDefault")t=q(t);else return r}}function cn(e){let t=e;for(;;){let r=Z(t);if(r==="ZodOptional"||r==="ZodNullable"||r==="ZodDefault")t=q(t);else return t}}function gt(e){let t=e;for(;;){let r=Z(t);if(r==="ZodOptional"||r==="ZodNullable")return true;if(r==="ZodDefault"){t=q(t);continue}return false}}function ht(e){let t=cn(e),r=Z(t);if(r==="ZodEnum"){let n=fe(t);return n.length>0?n:void 0}if(r==="ZodNativeEnum"){let n=me(t),o=Object.values(n).filter(s=>typeof s=="string");return o.length>0?o:void 0}if(r==="ZodLiteral"){let n=we(t);return typeof n=="string"?[n]:void 0}}function bt(e,t,r=""){let n={};for(let o of Object.keys(t.shape)){let s=r?`${r}.${o}`:o,a=e[o];if(a===null){n[s]="__null__";continue}if(a===void 0)continue;let f=t.shape[o];for(;;){let c=Z(f);if(c==="ZodOptional"||c==="ZodNullable"||c==="ZodDefault")f=q(f);else break}let d=Z(f);if(d==="ZodObject"&&typeof a=="object"&&a!==null&&!Array.isArray(a)){let c=bt(a,f,s);Object.assign(n,c);}else if(d==="ZodDate"){let c=yt(a);c!==null&&(n[s]=c);}else if(typeof a=="object"&&a!==null&&!Array.isArray(a)&&("_seconds"in a||typeof a.toDate=="function")){let c=yt(a);n[s]=c??JSON.stringify(a,null,2);}else typeof a=="object"?n[s]=JSON.stringify(a,null,2):n[s]=String(a);}return n}function Le(e,t){return e.map(r=>({...r,defaultValue:t[r.name]??r.defaultValue,nested:r.nested?Le(r.nested,t):void 0}))}function dn(e,t){let r=new Set(["==","!=","<","<=",">",">=","in","not-in","array-contains","array-contains-any"]),n=[];for(let[o,s]of Object.entries(e)){if(!o.startsWith("fv_"))continue;let a=o.slice(3);if(!t.has(a))continue;let f=(s??"").trim();if(!f)continue;let d=e[`fo_${a}`]??"==",c=r.has(d)?d:"==";n.push({field:a,op:c,value:f});}return n}function un(e){let t="__null__",r=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 o=n.value.split(",").map(s=>s.trim()).filter(s=>s!==""&&s!==t).map(s=>r(s));return [n.field,n.op,o]}return [n.field,n.op,r(n.value)]})}function vt(e,t,r=""){let n=[];for(let o of e){let s=r?`${r}.${o}`:o,a=t.shape[o];if(!a){n.push({name:s,zodType:"ZodString"});continue}let f=Ke(a);if(f==="ZodObject"){let d=a;for(;;){let p=Z(d);if(p==="ZodOptional"||p==="ZodNullable"||p==="ZodDefault")d=q(d);else break}let c=pe(d);n.push(...vt(Object.keys(c),d,s));}else n.push({name:s,zodType:f,nullable:gt(a),enumValues:ht(a)});}return n}function pn(e,t){let r=t.split("."),n=e;for(let o of r){for(;;){let a=Z(n);if(a==="ZodOptional"||a==="ZodNullable"||a==="ZodDefault")n=q(n);else break}let s=pe(n);if(!(o in s))return null;n=s[o];}return n}function ae(e,t){if(!t||t.length===0)return e;let r=[],n=new Map;for(let s of t){let a=s.indexOf(".");if(a===-1)r.push(s);else {let f=s.slice(0,a),d=s.slice(a+1);n.has(f)||n.set(f,[]),n.get(f).push(d);}}let o={};for(let s of r)s in e.shape&&(o[s]=e.shape[s]);for(let[s,a]of n){if(!(s in e.shape))continue;let f=e.shape[s];for(;;){let d=Z(f);if(d==="ZodOptional"||d==="ZodNullable"||d==="ZodDefault")f=q(f);else break}if(Z(f)!=="ZodObject"){o[s]=e.shape[s];continue}o[s]=ae(f,a);}return z.object(o)}function se(e,t){let r=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let s=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=(process.env.FUNCTION_TARGET??"").replace(/\./g,"-");return `/${s}/${a}/${f}${r}`}let n=process.env.K_SERVICE,o=e.hostname??e.headers?.host??"";return n&&o.includes("cloudfunctions.net")?`/${n.toLowerCase()}${r}`:r}function xt(e,t){return {handleDashboard:(c,p)=>{let w=se(c,t),i=Object.values(e).map(l=>({name:l.name,path:l.path}));_(p,Ne(i,w));},handleList:async(c,p)=>{let w=c.params.repoName;if(!w){_(p,"Bad request",400);return}let i=e[w];if(!i){_(p,"Repository not found",404);return}let l=i.pageSize??25,g=c.query??{},b=g.cursor,u=g.dir==="prev"?"prev":"next",y=g.ob??"",h=g.od==="desc"?"desc":"asc",m=y?{field:y,dir:h}:void 0,v=parseInt(g.ps??""),x=Number.isFinite(v)&&v>0?Math.min(v,200):l,R=i.listColumns??Object.keys(i.schema.shape),S=i.documentKey??"docId",T=[S,...R.filter(F=>F!==S)],C=i.filterableFields?(()=>{let F=[];for(let J of i.filterableFields)(J.includes(".")||R.includes(J))&&F.push(J);return F})():R,k=(()=>{let F=[];for(let J of C)if(J.includes(".")){let le=pn(i.schema,J);F.push({name:J,zodType:le?Ke(le):"ZodString",nullable:le?gt(le):false,enumValues:le?ht(le):void 0});}else F.push(...vt([J],i.schema));return F})(),E=new Set(k.map(F=>F.name)),N=dn(g,E),L=un(N),z;if(b)try{let F=i.repo.ref;typeof F.doc=="function"&&(z=await F.doc(b).get());}catch{}let G=await i.repo.query.paginate({pageSize:x,cursor:z,direction:u,...L.length>0?{where:L}:{},...m?{orderBy:[{field:m.field,direction:m.dir}]}:{}}).catch(F=>({queryError:be(F,{ref:i.repo.ref,path:i.path,isGroup:!!i.isGroup,filters:N,sort:m})})),I="queryError"in G,ie=I?[]:G.data,It=I?"":G.nextCursor?.id??"",Dt=I?"":G.prevCursor?.id??"",Nt=I?G.queryError:void 0,Pt=se(c,t);_(p,Pe(i.name,ie,T,Pt,{hasPrev:I?false:G.hasPrevPage,hasNext:I?false:G.hasNextPage,prevCursor:Dt,nextCursor:It},void 0,k,N,i.allowDelete??false,i.relationalMeta,m,x,Nt,i.isGroup));},handleCreateForm:(c,p)=>{let w=c.params.repoName;if(!w){_(p,"Bad request",400);return}let i=e[w];if(!i){_(p,"Repository not found",404);return}let l=se(c,t),g=ae(i.schema,i.createFields),b=H(g),u=`${l}/${i.name}/create`,y=W(b,u,"POST","Create document");_(p,ee(i.name,y,"create",null,l));},handleCreateSubmit:async(c,p)=>{let w=c.params.repoName;if(!w){_(p,"Bad request",400);return}let i=e[w];if(!i){_(p,"Repository not found",404);return}let l=se(c,t),g=c.body??{},b=Ue(g,i.schema),u=ae(i.schema,i.createFields),y=u.safeParse(b);if(!y.success){let h=H(u),m=`${l}/${i.name}/create`,v=W(h,m,"POST","Create document"),x=y.error.issues.map(R=>`${R.path.join(".")}: ${R.message}`).join(", ");_(p,ee(i.name,v,"create",null,l,{type:"error",message:`Validation error: ${x}`}),422);return}try{if(i.isGroup&&i.parentKeys&&i.parentKeys.length>0){let h={...y.data};i.createdKey&&(h[i.createdKey]=new Date);let m=i.parentKeys.filter(S=>!h[S]);if(m.length>0)throw new Error(`Missing parent key(s) for subcollection create: ${m.join(", ")}`);let v=i.parentKeys.map(S=>h[S]),x=i.documentKey??"docId",R=h[x]||ln();await i.repo.set(...v,R,h);}else await i.repo.create(y.data);Me(p,`${l}/${i.name}?flash=created`);}catch(h){let m=ae(i.schema,i.createFields),v=H(m),x=`${l}/${i.name}/create`,R=W(v,x,"POST","Create document");_(p,ee(i.name,R,"create",null,l,{type:"error",message:`Save error: ${h.message}`}),500);}},handleEditForm:async(c,p)=>{let w=c.params.repoName,i=c.params.id;if(!w||!i){_(p,"Bad request",400);return}let l=e[w];if(!l){_(p,"Repository not found",404);return}let g=se(c,t),b=null;try{b=await Be(l,i);}catch(x){let R=qe(l,i,x),S=oe(x)?424:500;_(p,Se("",{title:`Edit ${l.name} / ${i}`,basePath:g,breadcrumb:[{label:"Repositories",href:g},{label:l.name,href:`${g}/${l.name}`},{label:`Edit ${i}`}],flash:R}),S);return}if(!b){_(p,"Document not found",404);return}let u=bt(b,l.schema),y=ae(l.schema,l.mutableFields),h=Le(H(y),u),m=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,v=W(h,m,"POST","Save changes");_(p,ee(l.name,v,"edit",i,g));},handleEditSubmit:async(c,p)=>{let w=c.params.repoName,i=c.params.id;if(!w||!i){_(p,"Bad request",400);return}let l=e[w];if(!l){_(p,"Repository not found",404);return}let g=se(c,t),b=c.body??{},u=Ue(b,l.schema),y=ae(l.schema,l.mutableFields),m=y.partial().safeParse(u);if(!m.success){let v=Object.fromEntries(Object.entries(b).map(([C,k])=>[C,Array.isArray(k)?k.join(","):k??""])),x=Le(H(y),v),R=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,S=W(x,R,"POST","Save changes"),T=m.error.issues.map(C=>`${C.path.join(".")}: ${C.message}`).join(", ");_(p,ee(l.name,S,"edit",i,g,{type:"error",message:`Validation error: ${T}`}),422);return}try{let v=await Be(l,i),x=(v&&mt(v,l.pathKey))??[i];await l.repo.update(...x,m.data),Me(p,`${g}/${l.name}?flash=updated`);}catch(v){let x=ae(l.schema,l.mutableFields),R=H(x),S=`${g}/${l.name}/${encodeURIComponent(i)}/edit`,T=W(R,S,"POST","Save changes"),C=oe(v)?qe(l,i,v):{type:"error",message:`Save error: ${v.message}`},k=oe(v)?424:500;_(p,ee(l.name,T,"edit",i,g,C),k);}},handleDelete:async(c,p)=>{let w=c.params.repoName,i=c.params.id;if(!w||!i){_(p,"Bad request",400);return}let l=e[w];if(!l){_(p,"Repository not found",404);return}if(!l.allowDelete){_(p,"Delete is not allowed for this repository",403);return}let g=se(c,t);try{let b=await Be(l,i),u=(b&&mt(b,l.pathKey))??[i];await l.repo.delete(...u),Me(p,`${g}/${l.name}?flash=deleted`);}catch(b){let u=oe(b)?qe(l,i,b):{type:"error",message:`Delete error: ${b.message}`},y=oe(b)?424:500;_(p,Se("",{title:`Delete ${l.name} / ${i}`,basePath:g,breadcrumb:[{label:"Repositories",href:g},{label:l.name,href:`${g}/${l.name}`},{label:`Delete ${i}`}],flash:u}),y);}}}}function fn(e){let t=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,n=>n===":"?n:`\\${n}`).replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g,(n,o)=>(t.push(o),"([^/]+)"));return {pattern:new RegExp(`^${r}$`),paramNames:t}}function mn(e){let t=e.path??e.url??"/",r=t.indexOf("?");return r===-1?t:t.slice(0,r)}var te=class{constructor(){this.routes=[];this.middlewares=[];this.notFoundHandler=(t,r)=>{r.status(404).send("Not Found");};this.errorHandler=(t,r,n)=>{console.error("[MiniRouter]",t),n.status(500).send("Internal Server Error");};}use(t){return this.middlewares.push(t),this}get(t,r){return this.addRoute("GET",t,r)}post(t,r){return this.addRoute("POST",t,r)}put(t,r){return this.addRoute("PUT",t,r)}patch(t,r){return this.addRoute("PATCH",t,r)}delete(t,r){return this.addRoute("DELETE",t,r)}onNotFound(t){return this.notFoundHandler=t,this}onError(t){return this.errorHandler=t,this}addRoute(t,r,n){let{pattern:o,paramNames:s}=fn(r);return this.routes.push({method:t.toUpperCase(),pattern:o,paramNames:s,handler:n}),this}async handle(t,r){let n=(t.method??"GET").toUpperCase(),o=mn(t),s=null,a={};for(let c of this.routes){if(c.method!==n)continue;let p=o.match(c.pattern);if(p){s=c,a={},c.paramNames.forEach((w,i)=>{a[w]=decodeURIComponent(p[i+1]??"");});break}}let f=Object.assign(t,{params:a}),d=s?s.handler:this.notFoundHandler;try{await this.runMiddlewareChain(f,r,d);}catch(c){this.errorHandler(c,t,r);}}async runMiddlewareChain(t,r,n){let o=0,s=async()=>{if(o<this.middlewares.length){let a=this.middlewares[o++];await a(t,r,s);}else await n(t,r);};await s();}};async function yn(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function gn(e){let t={};if(!e)return t;for(let r of e.split("&")){let n=r.indexOf("=");if(n===-1)continue;let o=decodeURIComponent(r.slice(0,n).replace(/\+/g," ")),s=decodeURIComponent(r.slice(n+1).replace(/\+/g," ")),a=t[o];a===void 0?t[o]=s:Array.isArray(a)?a.push(s):t[o]=[a,s];}return t}function hn(e){let{basePath:t="/",repos:r,parseBody:n=true,auth:o,middleware:s=[],httpsOptions:a}=e,f=t==="/"?"":t.replace(/\/$/,""),d={};for(let[i,l]of Object.entries(r)){let g=l.schema??l.repo.schema??null;if(!g)throw new Error(`[createAdminServer] Repository "${i}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let b,u,y;if(l.fieldsConfig){let v=l.fieldsConfig;b=[],u=[],y=[];for(let[x,R]of Object.entries(v))for(let S of R)S==="filterable"?b.push(x):S==="mutable"?u.push(x):S==="create"&&y.push(x);b.length===0&&(b=void 0),u.length===0&&(u=void 0),y.length===0&&(y=void 0);}let h=(()=>{let v=l.repo._parentKeys;return v&&v.length>0?v:void 0})();if(h&&y)for(let v of h)y.includes(v)||y.push(v);let m={name:i,path:l.path,repo:l.repo,schema:g,documentKey:l.documentKey??"docId",pathKey:l.repo._pathKey??void 0,isGroup:!!l.repo._isGroup,parentKeys:h,createdKey:l.repo._createdKey??void 0,listColumns:l.listColumns,pageSize:l.pageSize,filterableFields:b,mutableFields:u,createFields:y,allowDelete:l.allowDelete??false,relationalMeta:(()=>{if(!l.relationalFields||l.relationalFields.length===0)return;let v=l.repo.relationalKeys??{},x=[];for(let R of l.relationalFields){let S=v[R.key];S&&x.push({key:R.key,column:R.column,targetRepo:String(S.repo),targetKey:String(S.key),type:S.type});}return x.length>0?x:void 0})()};d[i]=m;}let c=xt(d,f),p=new te;if(n&&p.use(async(i,l,g)=>{let b=i,u=String(b.headers?.["content-type"]??"");if(u.includes("application/x-www-form-urlencoded")){let y=await yn(b);i.body=gn(y);}else if(u.includes("application/json")&&typeof b.body=="string")try{i.body=JSON.parse(b.body);}catch{}await g();}),o)if(typeof o=="function")p.use(o);else {let i=o.realm??"Admin",l="Basic "+Buffer.from(`${o.username}:${o.password}`).toString("base64");p.use((g,b,u)=>{if((g.headers?.authorization??"")!==l){b.status(401).set("WWW-Authenticate",`Basic realm="${i}"`).set("Content-Type","text/plain").send("Unauthorized");return}u();});}for(let i of s)p.use(i);p.get(`${f}/`,c.handleDashboard),p.get(`${f}`,c.handleDashboard),p.get(`${f}/:repoName`,c.handleList),p.get(`${f}/:repoName/create`,c.handleCreateForm),p.post(`${f}/:repoName/create`,c.handleCreateSubmit),p.get(`${f}/:repoName/:id/edit`,c.handleEditForm),p.post(`${f}/:repoName/:id/edit`,c.handleEditSubmit),p.post(`${f}/:repoName/:id/delete`,c.handleDelete);let w=async(i,l)=>{await p.handle(i,l);};return a&&(w.httpsOptions=a),w}var Rt="preserve";function St(){return Rt}function bn(e){return typeof e=="object"&&e!==null&&typeof e._seconds=="number"&&typeof e._nanoseconds=="number"}function $t(e){if(e==null)return null;if(e instanceof Date)return Number.isNaN(e.getTime())?null:e;if(e instanceof Timestamp)return e.toDate();if(bn(e))return new Date(e._seconds*1e3+Math.floor(e._nanoseconds/1e6));if(typeof e=="string"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}if(typeof e=="number"){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}return null}function Ct(e){return e}function Ge(e,t,r=200){let n=Ct(t);e.status(r).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(n));}function de(e,t,r,n=200){Ge(e,{success:true,data:t,meta:r},n);}function j(e,t,r=400){Ge(e,{success:false,error:t},r);}function Ve(e,t,r,n,o){let s=be(t,r),a=s.type==="index",f=a?424:500,c={success:false,error:a?s.message:o&&t instanceof Error?t.message:n};a&&(c.errorType="index",s.indexUrl&&(c.indexUrl=s.indexUrl)),Ge(e,c,f);}var kt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function xn(){let e="";for(let t=0;t<20;t++)e+=kt.charAt(Math.floor(Math.random()*kt.length));return e}function ue(e){let t=e._def??e.def;if(!t)return e;let r=t.typeName??t.type;if(r==="ZodDate"||r==="date")return z.preprocess(n=>$t(n)??n,e);if(r==="ZodObject"||r==="object"){let n=e.shape,o={};for(let[s,a]of Object.entries(n))o[s]=ue(a);return z.object(o)}if(r==="ZodArray"||r==="array"){let n=t.element??t.type;if(n)return z.array(ue(n))}if(r==="ZodOptional"||r==="optional"){let n=t.innerType;if(n)return ue(n).optional()}if(r==="ZodNullable"||r==="nullable"){let n=t.innerType;if(n)return ue(n).nullable()}if(r==="ZodDefault"||r==="default"){let n=t.innerType,o=t.defaultValue;if(n){let s=ue(n);return typeof o=="function"?s.default(o()):s.default(o)}}return e}function wn(e,t,r=[]){let n=e.shape,o={},s=t&&t.length>0?t:Object.keys(n);for(let a of s){if(r.includes(a))continue;let f=a.split(".")[0];f&&n[f]&&(o[f]=n[f]);}return z.object(o)}function Ot(e,t,r,n=false,o=[]){try{let s=wn(e,r,o),a=n?s.partial():s;return {success:!0,data:(St()==="normalize"?ue(a):a).parse(t)}}catch(s){return s instanceof z.ZodError?{success:false,error:`Validation failed: ${s.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join(", ")}`}:{success:false,error:"Validation failed"}}}function Rn(e,t){let r=[],n=t?new Set(t):null,o={eq:"==",ne:"!=",lt:"<",lte:"<=",gt:">",gte:">=",in:"in",nin:"not-in",contains:"array-contains",containsAny:"array-contains-any"};for(let[s,a]of Object.entries(e)){if(a===void 0||["cursor","limit","pageSize","orderBy","orderDir","select"].includes(s))continue;let f=Array.isArray(a)?a[0]:a;if(f===void 0||f==="")continue;let d=s.match(/^(\w+)__(\w+)$/),c,p="==";if(d&&d[1]&&d[2]){c=d[1];let i=d[2];if(o[i])p=o[i];else continue}else if(!d)c=s;else continue;if(n&&!n.has(c))continue;let w=f;p==="in"||p==="not-in"||p==="array-contains-any"?w=f.split(",").map(i=>At(i.trim())):w=At(f),r.push({field:c,op:p,value:w});}return r}function At(e){if(e==="true")return true;if(e==="false")return false;if(e==="null")return null;let t=Number(e);return !isNaN(t)&&e!==""?t:e}function Ce(e){return e?{docId:e.id}:null}async function Tt(e,t){if(!t||typeof t!="object")return;let r=t.docId;if(typeof r=="string")try{let n=e.repo.ref;if(typeof n.doc!="function")return;let o=await n.doc(r).get();return o.exists?o:void 0}catch{return}}function _t(e,t,r){function n(l,g){return !l||!e[l]?(j(g,`Repository "${l}" not found`,404),null):e[l]}function o(l,g){if(!g)return;let b=l[g];if(typeof b!="string"||!b)return;let u=b.split("/").filter(Boolean),y=[];for(let h=1;h<u.length;h+=2)y.push(u[h]);return y.length>0?y:void 0}async function s(l,g){let b=`by${l.documentKey.charAt(0).toUpperCase()}${l.documentKey.slice(1)}`,u=l.repo.get[b];if(typeof u=="function")try{let h=await u(g);if(h)return h}catch{}return (await l.repo.query.by({where:[[l.documentKey,"==",g]],limit:1}))[0]??null}async function a(l,g){let b=l.params||{},u=n(b.repoName,g);if(!u)return;let y=[],h;try{let m=l.query??{},v=Math.min(Number(m.pageSize)||u.pageSize,100),x=m.cursor,R=m.direction?.toLowerCase()==="prev"?"prev":"next",S=m.orderBy,T=m.orderDir?.toLowerCase()==="desc"?"desc":"asc",C=m.select,k=C?C.split(",").map(I=>I.trim()):void 0,E;u.allowedIncludes&&m.includes&&(E=(typeof m.includes=="string"?m.includes.split(",").map(ie=>ie.trim()):Array.isArray(m.includes)?m.includes:[]).filter(ie=>typeof ie=="string"&&u.allowedIncludes.includes(ie)),E?.length===0&&(E=void 0));let N=Rn(m,u.filterableFields);y=N.map(I=>({field:I.field,op:I.op,value:String(I.value??"")})),S&&(h={field:S,dir:T});let L={pageSize:v,direction:R};if(x)try{let I=typeof x=="string"?JSON.parse(x):x;L.cursor=await Tt(u,I);}catch{}S&&(L.orderBy=[{field:S,direction:T}]),N.length>0&&(L.where=N.map(I=>[I.field,I.op,I.value])),k&&(L.select=k),E&&(L.include=E);let z=await u.repo.query.paginate(L),G={items:z.data,hasNextPage:z.hasNextPage,hasPrevPage:z.hasPrevPage,nextCursor:Ce(z.nextCursor),prevCursor:Ce(z.prevCursor)};de(g,G,{pageSize:v,hasMore:z.hasNextPage});}catch(m){Ve(g,m,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:y,sort:h},"Failed to fetch documents",r);}}async function f(l,g){let b=l.params||{},u=n(b.repoName,g);if(!u)return;let y=[],h;try{let m=l.body??{},v=Math.min(m.pageSize||u.pageSize,100),x=m.direction==="prev"?"prev":"next";m.where&&(y=m.where.map(C=>({field:String(C[0]),op:C[1],value:String(C[2]??"")}))),m.orderBy&&m.orderBy[0]&&(h={field:m.orderBy[0].field,dir:m.orderBy[0].direction==="desc"?"desc":"asc"});let R={pageSize:v,direction:x};if(m.cursor)try{let C=typeof m.cursor=="string"?JSON.parse(m.cursor):m.cursor;R.cursor=await Tt(u,C);}catch{}if(u.allowedIncludes&&m.includes&&m.includes.length>0){let C=m.includes.filter(k=>typeof k=="string"?u.allowedIncludes.includes(k):typeof k=="object"&&k!==null&&"relation"in k&&typeof k.relation=="string"?u.allowedIncludes.includes(k.relation):!1);C.length>0&&(R.include=C);}if(m.where&&m.where.length>0){if(u.filterableFields){let C=new Set(u.filterableFields),k=m.where.filter(E=>!C.has(E[0]));if(k.length>0){j(g,`Fields not filterable: ${k.map(E=>E[0]).join(", ")}`,400);return}}R.where=m.where;}if(m.orWhere&&m.orWhere.length>0){if(u.filterableFields){let C=new Set(u.filterableFields),k=m.orWhere.filter(E=>!C.has(E[0]));if(k.length>0){j(g,`Fields not filterable: ${k.map(E=>E[0]).join(", ")}`,400);return}}R.orWhere=m.orWhere;}if(m.orWhereGroups&&m.orWhereGroups.length>0){if(u.filterableFields){let C=new Set(u.filterableFields);for(let k of m.orWhereGroups){let E=k.filter(N=>!C.has(N[0]));if(E.length>0){j(g,`Fields not filterable: ${E.map(N=>N[0]).join(", ")}`,400);return}}}R.orWhereGroups=m.orWhereGroups;}m.orderBy&&m.orderBy.length>0&&(R.orderBy=m.orderBy),m.select&&m.select.length>0&&(R.select=m.select);let S=await u.repo.query.paginate(R),T={items:S.data,hasNextPage:S.hasNextPage,hasPrevPage:S.hasPrevPage,nextCursor:Ce(S.nextCursor),prevCursor:Ce(S.prevCursor)};de(g,T,{pageSize:v,hasMore:S.hasNextPage});}catch(m){Ve(g,m,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:y,sort:h},"Failed to query documents",r);}}async function d(l,g){let b=l.params||{},u=n(b.repoName,g);if(!u)return;let y=b.id;if(!y){j(g,"Document ID required",400);return}try{let h=await s(u,y);if(!h){j(g,"Document not found",404);return}de(g,h);}catch(h){Ve(g,h,{ref:u.repo.ref,path:u.path,isGroup:!!u.isGroup,filters:[{field:u.documentKey,op:"==",value:y}]},"Failed to fetch document",r);}}async function c(l,g){let b=l.params||{},u=n(b.repoName,g);if(u)try{let y=l.body??{},h=Ot(u.schema,y,u.createFields,!1,u.systemKeys);if(!h.success){j(g,h.error,400);return}if(u.validate){let v=await u.validate(h.data,"create");if(v){j(g,v,400);return}}let m;if(u.isGroup&&u.parentKeys&&u.parentKeys.length>0){let v={...h.data};u.createdKey&&(v[u.createdKey]=new Date);let x=u.parentKeys.filter(T=>!v[T]);if(x.length>0){j(g,`Missing parent key(s) for subcollection create: ${x.join(", ")}`,400);return}let R=u.parentKeys.map(T=>v[T]),S=v[u.documentKey]||xn();m=await u.repo.set(...R,S,v);}else m=await u.repo.create(h.data);de(g,m,void 0,201);}catch(y){let h=r&&y instanceof Error?y.message:"Failed to create document";j(g,h,500);}}async function p(l,g,b){let u=l.params||{},y=n(u.repoName,g);if(!y)return;let h=u.id;if(!h){j(g,"Document ID required",400);return}try{let m=l.body??{},v=Ot(y.schema,m,y.mutableFields,b,y.systemKeys);if(!v.success){j(g,v.error,400);return}if(y.validate){let T=await y.validate(v.data,"update");if(T){j(g,T,400);return}}let x=await s(y,h),R=(x&&o(x,y.pathKey))??[h],S=await y.repo.update(...R,v.data);de(g,S);}catch(m){let v=r&&m instanceof Error?m.message:"Failed to update document";j(g,v,500);}}async function w(l,g){let b=l.params||{},u=n(b.repoName,g);if(!u)return;if(!u.allowDelete){j(g,"Delete not allowed for this repository",403);return}let y=b.id;if(!y){j(g,"Document ID required",400);return}try{let h=await s(u,y),m=(h&&o(h,u.pathKey))??[y];await u.repo.delete(...m),de(g,{deleted:!0});}catch(h){let m=r&&h instanceof Error?h.message:"Failed to delete document";j(g,m,500);}}function i(l,g){g.status(204).set("Access-Control-Allow-Methods","GET, POST, PUT, PATCH, DELETE, OPTIONS").set("Access-Control-Allow-Headers","Content-Type, Authorization").set("Access-Control-Max-Age","86400").send("");}return {handleList:a,handleQuery:f,handleGet:d,handleCreate:c,handleUpdate:p,handleDelete:w,handleOptions:i}}function Je(e){try{return z.toJSONSchema(e,{target:"openapi-3.1",unrepresentable:"any",override:t=>{let r=t.zodSchema?._zod?.def;r&&(r.type==="date"?(t.jsonSchema.type="string",t.jsonSchema.format="date-time"):r.type==="bigint"&&(t.jsonSchema.type="string",t.jsonSchema.format="int64"));}})}catch(t){return typeof console<"u"&&console.warn&&console.warn("[generateOpenAPISpec] Failed to convert Zod schema to JSON Schema; falling back to {type:object}.",t),{type:"object"}}}function K(e){return {$ref:`#/components/schemas/${e}`}}function B(e){return {description:e,content:{"application/json":{schema:K("ErrorResponse")}}}}function xe(e,t){return {description:e,content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:t},required:["success","data"]}}}}}function Et(e){return {description:"Paginated list of documents",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean",enum:[true]},data:{type:"object",properties:{items:{type:"array",items:e},nextCursor:{oneOf:[{type:"object"},{type:"null"}]},prevCursor:{oneOf:[{type:"object"},{type:"null"}]},hasNextPage:{type:"boolean"},hasPrevPage:{type:"boolean"}},required:["items","hasNextPage","hasPrevPage"]},meta:{type:"object",properties:{pageSize:{type:"integer"},hasMore:{type:"boolean"},cursor:{oneOf:[{type:"string"},{type:"null"}]}}}},required:["success","data"]}}}}}function Sn(e){return [{name:"pageSize",in:"query",schema:{type:"integer",default:e.pageSize,maximum:100},description:"Number of items per page"},{name:"cursor",in:"query",schema:{type:"string"},description:"Base64 pagination cursor"},{name:"orderBy",in:"query",schema:{type:"string"},description:"Field name to order by"},{name:"orderDir",in:"query",schema:{type:"string",enum:["asc","desc"]},description:"Order direction"},{name:"select",in:"query",schema:{type:"string"},description:"Comma-separated list of fields to return"}]}function $n(e){let t=e.filterableFields??Object.keys(e.schema.shape),r=["eq","ne","lt","lte","gt","gte","in","nin","contains"],n=[];for(let o of t){n.push({name:o,in:"query",schema:{type:"string"},description:`Filter by ${o} (equality)`});for(let s of r)n.push({name:`${o}__${s}`,in:"query",schema:{type:"string"},description:`Filter ${o} with operator ${s}`});}return n}function Cn(){return {type:"object",properties:{where:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"AND conditions: [field, operator, value][]"},orWhere:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3},description:"Simple OR conditions (each independently OR'd)"},orWhereGroups:{type:"array",items:{type:"array",items:{type:"array",items:{},minItems:3,maxItems:3}},description:"Advanced OR groups (AND within, OR across groups)"},orderBy:{type:"array",items:{type:"object",properties:{field:{type:"string"},direction:{type:"string",enum:["asc","desc"]}},required:["field"]}},select:{type:"array",items:{type:"string"},description:"Fields to select (projection)"},pageSize:{type:"integer",maximum:100,description:"Number of items per page"},cursor:{oneOf:[{type:"string"},{type:"object"}],description:"Pagination cursor"},direction:{type:"string",enum:["next","prev"],description:"Pagination direction"},includes:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{relation:{type:"string"},select:{type:"array",items:{type:"string"}}},required:["relation"]}]},description:"Relations to include (populate)"}}}}function kn(e,t,r,n,o){let s={},a=e.name,f=`${t}/${e.name}`,d=`${f}/{${e.documentKey}}`,c={name:e.documentKey,in:"path",required:true,schema:{type:"string"},description:"Unique document identifier"};s[f]={get:{operationId:`list${ne(e.name)}`,summary:`List ${e.name} (paginated)`,tags:[a],parameters:[...Sn(e),...$n(e)],responses:{200:Et(K(r)),500:B("Internal server error")}},post:{operationId:`create${ne(e.name)}`,summary:`Create a ${V(e.name)}`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:K(n??r)}}},responses:{201:xe("Document created",K(r)),400:B("Validation error"),500:B("Internal server error")}}},s[`${f}/query`]={post:{operationId:`query${ne(e.name)}`,summary:`Query ${e.name} with advanced filters`,tags:[a],requestBody:{required:true,content:{"application/json":{schema:K("QueryRequestBody")}}},responses:{200:Et(K(r)),400:B("Invalid query"),500:B("Internal server error")}}};let p={};return p.get={operationId:`get${ne(V(e.name))}`,summary:`Get a single ${V(e.name)}`,tags:[a],parameters:[c],responses:{200:xe("Document found",K(r)),404:B("Document not found"),500:B("Internal server error")}},p.put={operationId:`update${ne(V(e.name))}`,summary:`Update a ${V(e.name)} (full replace)`,tags:[a],parameters:[c],requestBody:{required:true,content:{"application/json":{schema:K(o??r)}}},responses:{200:xe("Document updated",K(r)),400:B("Validation error"),404:B("Document not found"),500:B("Internal server error")}},p.patch={operationId:`patch${ne(V(e.name))}`,summary:`Partially update a ${V(e.name)}`,tags:[a],parameters:[c],requestBody:{required:true,content:{"application/json":{schema:{allOf:[K(o??r)],description:"All fields are optional for partial updates"}}}},responses:{200:xe("Document patched",K(r)),400:B("Validation error"),404:B("Document not found"),500:B("Internal server error")}},e.allowDelete&&(p.delete={operationId:`delete${ne(V(e.name))}`,summary:`Delete a ${V(e.name)}`,tags:[a],parameters:[c],responses:{200:xe("Document deleted",{type:"object",properties:{id:{type:"string"}}}),404:B("Document not found"),500:B("Internal server error")}}),s[d]=p,s}function Qe(e,t,r={}){let{title:n="CRUD API",version:o="1.0.0",description:s,servers:a,auth:f=false}=r,d=t==="/"?"":t.replace(/\/$/,""),c={},p={},w=[];c.ErrorResponse={type:"object",properties:{success:{type:"boolean",enum:[false]},error:{type:"string"}},required:["success","error"]},c.QueryRequestBody=Cn();for(let[b,u]of Object.entries(e)){let y=ne(V(b)),h=`${y}Create`,m=`${y}Update`;c[y]=Je(u.schema);let v=k=>{let E=k&&k.length>0?k:Object.keys(u.schema.shape),N={};for(let L of E){let z=L.split(".")[0];z&&u.schema.shape[z]&&!u.systemKeys.includes(z)&&(N[z]=u.schema.shape[z]);}return N},x=null,R=v(u.createFields);Object.keys(R).length>0&&(c[h]=Je(z.object(R)),x=h);let S=null,T=v(u.mutableFields);Object.keys(T).length>0&&(c[m]=Je(z.object(T)),S=m);let C=kn(u,d,y,x,S);Object.assign(p,C),w.push({name:b,description:`Operations on ${b} (collection: ${u.path})`});}let i={},l;return f==="basic"?(i.basicAuth={type:"http",scheme:"basic"},l=[{basicAuth:[]}]):f==="bearer"&&(i.bearerAuth={type:"http",scheme:"bearer",bearerFormat:"JWT"},l=[{bearerAuth:[]}]),{openapi:"3.1.0",info:{title:n,version:o,...s?{description:s}:{}},...a&&a.length>0?{servers:a}:{},paths:p,components:{schemas:c,...Object.keys(i).length>0?{securitySchemes:i}:{}},...l?{security:l}:{},tags:w}}function ne(e){return e.charAt(0).toUpperCase()+e.slice(1)}function V(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}function On(e,t){return `<!DOCTYPE html>
|
|
556
556
|
<html lang="en">
|
|
557
557
|
<head>
|
|
558
558
|
<meta charset="utf-8" />
|
|
@@ -563,5 +563,5 @@ function initColumnReorder(table) {
|
|
|
563
563
|
<script id="api-reference" data-url="${t}"></script>
|
|
564
564
|
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
565
565
|
</body>
|
|
566
|
-
</html>`}function
|
|
566
|
+
</html>`}function An(e,t){let r=t==="/"?"":t.replace(/\/$/,"");if(process.env.FUNCTIONS_EMULATOR==="true"){let s=process.env.GCLOUD_PROJECT??process.env.GOOGLE_CLOUD_PROJECT??"demo-project",a=process.env.FUNCTION_REGION??"us-central1",f=process.env.FUNCTION_TARGET??"";return `/${s}/${a}/${f}${r}`}let n=process.env.K_SERVICE,o=e?.hostname??e?.headers?.host??"";return n&&o.includes("cloudfunctions.net")?`/${n.toLowerCase()}${r}`:r}async function Tn(e){return typeof e.rawBody=="string"?e.rawBody:Buffer.isBuffer(e.rawBody)?e.rawBody.toString("utf8"):""}function _n(e){let{basePath:t="/",repos:r,parseBody:n=true,auth:o,middleware:s=[],verbose:a=false,httpsOptions:f}=e,d=t==="/"?"":t.replace(/\/$/,""),c={};for(let[y,h]of Object.entries(r)){let m=h.schema??h.repo.schema??null;if(!m)throw new Error(`[createCrudServer] Repository "${y}" has no Zod schema. Either use createRepositoryConfig(schema)(config) or pass schema: explicitly.`);let v,x,R;if(h.fieldsConfig){let C=h.fieldsConfig;v=[],x=[],R=[];for(let[k,E]of Object.entries(C))for(let N of E)N==="filterable"?v.push(k):N==="mutable"?x.push(k):N==="create"&&R.push(k);v.length===0&&(v=void 0),x.length===0&&(x=void 0),R.length===0&&(R=void 0);}let S=(()=>{let C=h.repo._parentKeys;return C&&C.length>0?C:void 0})();if(S&&R)for(let C of S)R.includes(C)||R.push(C);let T={name:y,path:h.path,repo:h.repo,schema:m,systemKeys:h.repo._systemKeys??[h.documentKey??"docId"],documentKey:h.documentKey??"docId",pathKey:h.repo._pathKey??void 0,isGroup:!!h.repo._isGroup,parentKeys:S,createdKey:h.repo._createdKey??void 0,pageSize:h.pageSize??25,filterableFields:v,mutableFields:x,createFields:R,allowDelete:h.allowDelete??false,allowedIncludes:h.allowedIncludes,validate:h.validate};c[y]=T;}let p=_t(c,d,a),w=e.openapi,i=w&&typeof w=="object"?w:{},l=null;function g(){if(!l){let y=o&&typeof o!="function"?"basic":o?"bearer":false;l=Qe(c,d,{...i,auth:i.auth??y});}return l}let b=new te;if(b.use((y,h,m)=>{h.set("Access-Control-Allow-Origin","*"),h.set("Access-Control-Allow-Credentials","true"),m();}),n&&b.use(async(y,h,m)=>{let v=y;if(String(v.headers?.["content-type"]??"").includes("application/json")){if(typeof v.body=="string")try{y.body=JSON.parse(v.body);}catch{}else if(Buffer.isBuffer(y.rawBody))try{let R=await Tn(v);y.body=JSON.parse(R);}catch{}}await m();}),o)if(typeof o=="function")b.use(o);else {let y=o.realm??"API",h="Basic "+Buffer.from(`${o.username}:${o.password}`).toString("base64");b.use((m,v,x)=>{if((m.headers?.authorization??"")!==h){v.status(401).set("WWW-Authenticate",`Basic realm="${y}"`).set("Content-Type","application/json").send(JSON.stringify({success:false,error:"Unauthorized"}));return}x();});}for(let y of s)b.use(y);if(w!==false){let y=`${d}/__spec.json`,h=`${d}/__docs`;b.get(y,(m,v)=>{let x=g();v.status(200).set("Content-Type","application/json; charset=utf-8").send(JSON.stringify(x,null,2));}),b.get(h,(m,v)=>{let x=An(m,d)+"/__spec.json",R=On(i.title??"CRUD API",x);v.status(200).set("Content-Type","text/html; charset=utf-8").send(R);});}b.use((y,h,m)=>{if(y.method==="OPTIONS"){p.handleOptions(y,h);return}m();}),b.get(`${d}/:repoName`,p.handleList),b.post(`${d}/:repoName/query`,p.handleQuery),b.get(`${d}/:repoName/:id`,p.handleGet),b.post(`${d}/:repoName`,p.handleCreate),b.put(`${d}/:repoName/:id`,(y,h)=>p.handleUpdate(y,h,false)),b.patch(`${d}/:repoName/:id`,(y,h)=>p.handleUpdate(y,h,true)),b.delete(`${d}/:repoName/:id`,p.handleDelete);let u=async(y,h)=>{await b.handle(y,h);};return u.spec=g,f&&(u.httpsOptions=f),u}export{Qt as CSS,ge as ClientScript,te as MiniRouter,hn as createAdminServer,_n as createCrudServer,Ne as renderDashboard,ke as renderField,W as renderForm,ee as renderFormPage,Pe as renderList,Se as renderPage,H as zodToFields};//# sourceMappingURL=index.js.map
|
|
567
567
|
//# sourceMappingURL=index.js.map
|